reactos操作系统实现(189)

DCdevice context)是一个图形对象、图形属性和影响图形输出的集合结构体。CreateDC函数用给定名称为指定的设备创建设备环境。CreateDC一般用于创建打印机的设备环境,也可以用来得到屏幕(硬件屏幕,而不是窗口的客户区)的设备环境。请小心使用这个函数,因为它允许应用程序在屏幕上任何位置绘图,而不仅仅是在窗口的边界内。请用GetDCBeginPaint来获取屏幕窗口的设备环境。

#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, L"////.//DISPLAY",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  }

你可能感兴趣的:(react)