reactos操作系统实现(189)
DC(device context)是一个图形对象、图形属性和影响图形输出的集合结构体。CreateDC函数用给定名称为指定的设备创建设备环境。CreateDC一般用于创建打印机的设备环境,也可以用来得到屏幕(硬件屏幕,而不是窗口的客户区)的设备环境。请小心使用这个函数,因为它允许应用程序在屏幕上任何位置绘图,而不仅仅是在窗口的边界内。请用GetDC或BeginPaint来获取屏幕窗口的设备环境。 #001 HDC #002 WINAPI #003 CreateDCW ( #004 LPCWSTR lpwszDriver, #005 LPCWSTR lpwszDevice, #006 LPCWSTR lpwszOutput, #007 CONST DEVMODEW *lpInitData #008 ) #009 { #010 #011 return IntCreateDICW ( lpwszDriver, #012 lpwszDevice, #013 lpwszOutput, #014 (PDEVMODEW) lpInitData, #015 0 ); #016 } lpwszDriver是指向空值结尾的字符串的指针,字符串说明设备驱动程序的文件名。比如“DISPLAY”指的是显示器驱动程序,而“WINSPOOL”就是指打印驱动程序。 lpwszDevice是批向空值结尾的字符串的指针,字符串指定了正在使用的专用输出设备的名称,比如打印管理程序名称。 lpwszOutput是没有使用参数,一般设置为NULL。 lpInitData是指向结构包含了设备驱动程序的设备专用初始化数据。设置为NULL时,就使用系统默认的初始化参数。
下面接着来分析函数IntCreateDICW的代码: #001 HDC #002 FASTCALL #003 IntCreateDICW ( LPCWSTR lpwszDriver, #004 LPCWSTR lpwszDevice, #005 LPCWSTR lpwszOutput, #006 PDEVMODEW lpInitData, #007 ULONG iType ) #008 { #009 UNICODE_STRING Device,Output; #010 HDC hDC = NULL; #011 BOOL Display = FALSE,Default = TRUE; #012 ULONG UMdhpdev = 0; #013 #014 HANDLE hspool = NULL; #015
加载打印驱动程序。 #016 if ( !ghSpooler && !LoadTheSpoolerDrv()) #017 { #018 DPRINT1("WinSpooler.Drv Did not load!/n"); #019 } #020 else #021 { #022 DPRINT("WinSpooler.Drv Loaded! hMod -> 0x%x/n",ghSpooler); #023 } #024
根据设备名称判断获取什么样的设备。 #025 if ((!lpwszDevice) && (!lpwszDriver)) #026 {
设置缺省设备名称。 #027 Default = FALSE; // Ask Win32k to set Default device. #028 Display = TRUE; // Most likely to be DISPLAY. #029 } #030 else #031 { #032 if ((lpwszDevice) && (wcslen(lpwszDevice) != 0)) // First #033 {
判断是否获取显示设备。 #034 if (!_wcsnicmp(lpwszDevice,L"////.//DISPLAY",11)) Display = TRUE; #035 RtlInitUnicodeString(&Device,lpwszDevice); #036 } #037 else #038 { #039 if (lpwszDriver) // Second #040 { #041 if ((!_wcsnicmp(lpwszDriver,L"DISPLAY",7)) || #042 (!_wcsnicmp(lpwszDriver,11))) Display = TRUE; #043 RtlInitUnicodeString(&Device,lpwszDriver); #044 } #045 } #046 } #047 #048 if (lpwszOutput) RtlInitUnicodeString(&Output,lpwszOutput); #049 #050 if (!Display) #051 { #052 //Handle Print device or something else. #053 DPRINT1("Not a DISPLAY device! %wZ/n",&Device); #054 } #055
调用WIN32K内核NtGdiOpenDCW函数打开设备。 #056 hDC = NtGdiOpenDCW( (Default ? &Device : NULL), #057 (PDEVMODEW) lpInitData, #058 (lpwszOutput ? &Output : NULL), #059 iType, // DCW 0 and ICW 1. #060 Display, #061 hspool, #062 (PVOID) NULL, // NULL for now. #063 (PVOID) &UMdhpdev ); #064 #if 0 #065 // Handle something other than a normal dc object. #066 if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) #067 { #068 PDC_ATTR Dc_Attr; #069 PLDC pLDC; #070 #071 GdiGetHandleUserData((HGDIOBJ) hDC,GDI_OBJECT_TYPE_DC,(PVOID) &Dc_Attr); #072 #073 pLDC = LocalAlloc(LMEM_ZEROINIT,sizeof(LDC)); #074 #075 Dc_Attr->pvLDC = pLDC; #076 pLDC->hDC = hDC; #077 pLDC->iType = LDC_LDC; // 1 (init) local DC,2 EMF LDC #078 DbgPrint("DC_ATTR Allocated -> 0x%x/n",Dc_Attr); #079 } #080 #endif
返回DC给应用程序。 #081 return hDC; #082} (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |