追蹤視窗變更
裝置驅動程式可以透過WNDOBJ追蹤視窗的變更,包括多監視器系統中的一個。 WNDOBJ 是驅動程式層級視窗物件,其中包含視窗的位置、大小和可見用戶端區域的相關資訊。 也就是說,藉由建立對應至應用程式視窗的 WNDOBJ,驅動程式就可以追蹤該視窗中的大小、位置和用戶端區域變更。
應用程式會使用 WIN32 API 來存取設備磁碟機所實作 的WNDOBJ_SETUP 功能。 存取權是透過 Win32 ExtEscape 函式取得。 GDI 會將這個逸出呼叫傳遞給具有DrvEscape的設備磁碟機,由設備磁碟機針對iEsc的值WNDOBJ_SETUP實作。
應用程式會 呼叫 ExtEscape (hdc,WNDOBJ_SETUP,...) ,並將控制碼傳遞至 CreateWindow 所建立的應用程式建立視窗 (,或透過驅動程式的輸入緩衝區) 一些對等的 Win32 函式。 如果驅動程式是要追蹤視窗,它會在ExtEscape呼叫的內容中呼叫EngCreateWnd,以建立指定視窗的 WNDOBJ 結構。 從該時間點開始,該視窗的任何變更都會向下傳遞至驅動程式。
驅動程式應該以類似下列的方式處理 ExtEscape 呼叫:
ULONG DrvEscape(
SURFOBJ *pso,
ULONG iEsc,
ULONG cjIn,
PVOID pvIn,
ULONG cjOut,
PVOID pvOut)
{
WNDOBJ *pwo;
WNDDATA *pwd;
if (iEsc == WNDOBJ_SETUP)
{
pwo = EngCreateWnd(pso,*((HWND *)pvIn),&DrvVideo,
WO_RGN_CLIENT, 0);
// Allocate space for caching client rects. Remember the pointer
// in the pvConsumer field.
pwd = EngAllocMem(0, sizeof(WNDDATA), DRIVER_TAG);
WNDOBJ_vSetConsumer(pwo,pwd);
// Update the rectangle list for this wndobj.
vUpdateRects(pwo);
return(1);
}
}
建立視窗物件牽涉到鎖定特殊視窗資源,因此EngCreateWnd應該只在DrvEscape或DrvSetPixelFormat中WNDOBJ_SETUP逸出的內容中呼叫。
EngCreateWnd函式支援多個驅動程式的視窗追蹤。 透過 EngCreateWnd,每個驅動程式都會識別自己的回呼常式,GDI 是要呼叫以取得對應視窗的變更。 例如,此功能可讓即時視訊驅動程式追蹤即時視訊視窗的變更,而 OpenGL 驅動程式正在追蹤 OpenGL 視窗的變更。
如果DrvSetPixelFormat或ExtEscape中建立新的WNDOBJ,GDI 會回呼至具有最新視窗狀態的驅動程式。 當 WNDOBJ 所參考的視窗終結時,GDI 也會回呼驅動程式。
作為加速器,驅動程式可以存取 WNDOBJ 結構的公用成員。
追蹤視窗變更牽涉到使用提供的三個回呼函式來支援 WNDOBJ 結構。 呼叫 WNDOBJ_cEnumStart 和 WNDOBJ_bEnum 回呼函式,即可列舉可見的用戶端區域。 驅動程式可以藉由呼叫 WNDOBJ_vSetConsumer 回呼函式,將自己的資料與 WNDOBJ 產生關聯。