SelectObject函数是将对象选定到指定的设备场境中。具体实现代码如下:
#001 HGDIOBJ
#002 WINAPI
#003 SelectObject(HDC hDC,
#004 HGDIOBJ hGdiObj)
#005 {
#006 PDC_ATTR pDc_Attr;
#007 HGDIOBJ hOldObj = NULL;
#008 UINT uType;
#009 //
PTEB pTeb;
#010
获取这个HDC相关的属性。
#011 if(!GdiGetHandleUserData(hDC,
GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr))
#012 {
#013 SetLastError(ERROR_INVALID_HANDLE);
#014 return NULL;
#015 }
#016
获取选择DC的对象正确的句柄。
#017 hGdiObj = GdiFixUpHandle(hGdiObj);
#018 if (!GdiIsHandleValid(hGdiObj))
#019 {
#020 return NULL;
#021 }
#022
获取这个对象的类型。
#023 uType = GDI_HANDLE_GET_TYPE(hGdiObj);
#024
根据不同的类型调用合适的函数把对象设置到DC里。
#025 switch (uType)
#026 {
#027 case GDI_OBJECT_TYPE_REGION:
#028 return
(HGDIOBJ)ExtSelectClipRgn(hDC, hGdiObj, RGN_COPY);
#029
#030 case GDI_OBJECT_TYPE_BITMAP:
#031 return NtGdiSelectBitmap(hDC,
hGdiObj);
#032
#033 case GDI_OBJECT_TYPE_BRUSH:
#034 hOldObj = pDc_Attr->hbrush;
#035 pDc_Attr->ulDirty_ |=
DC_BRUSH_DIRTY;
#036 pDc_Attr->hbrush = hGdiObj;
#037 return hOldObj;
#038 //
return NtGdiSelectBrush(hDC, hGdiObj);
#039
#040 case GDI_OBJECT_TYPE_PEN:
#041 case GDI_OBJECT_TYPE_EXTPEN:
#042 hOldObj = pDc_Attr->hpen;
#043 pDc_Attr->ulDirty_ |=
DC_PEN_DIRTY;
#044 pDc_Attr->hpen = hGdiObj;
#045 return hOldObj;
#046 //
return NtGdiSelectPen(hDC, hGdiObj);
#047
#048 case GDI_OBJECT_TYPE_FONT:
#049 hOldObj = pDc_Attr->hlfntNew;
#050 if (hOldObj == hGdiObj) return
hOldObj;
#051 #if 0
#052 pDc_Attr->ulDirty_ &=
~SLOW_WIDTHS;
#053 pDc_Attr->ulDirty_ |=
DIRTY_CHARSET;
#054 pDc_Attr->hlfntNew = hGdiObj;
#055 pTeb = NtCurrentTeb();
#056 if (((pTeb->GdiTebBatch.HDC ==
0) ||
#057 (pTeb->GdiTebBatch.HDC ==
hDC)) &&
#058 ((pTeb->GdiTebBatch.Offset
+ sizeof(GDIBSOBJECT)) <= GDIBATCHBUFSIZE) &&
#059 (!(pDc_Attr->ulDirty_ &
DC_DIBSECTION)))
#060 {
#061 PGDIBSOBJECT pgO =
(PGDIBSOBJECT)(&pTeb->GdiTebBatch.Buffer[0] +
#062 pTeb->GdiTebBatch.Offset);
#063 pgO->gbHdr.Cmd =
GdiBCSelObj;
#064 pgO->gbHdr.Size =
sizeof(GDIBSOBJECT);
#065 pgO->hgdiobj = hGdiObj;
#066
#067 pTeb->GdiTebBatch.Offset +=
sizeof(GDIBSOBJECT);
#068 pTeb->GdiTebBatch.HDC = hDC;
#069 pTeb->GdiBatchCount++;
#070 if (pTeb->GdiBatchCount
>= GDI_BatchLimit) NtGdiFlush();
#071 return hOldObj;
#072 }
#073 #endif
#074 // default for select object font
#075 return NtGdiSelectFont(hDC,
hGdiObj);
#076
#077 #if 0
#078 case GDI_OBJECT_TYPE_METADC:
#079 return MFDRV_SelectObject( hDC,
hGdiObj);
#080 case GDI_OBJECT_TYPE_EMF:
#081 PLDC pLDC = GdiGetLDC(hDC);
#082 if ( !pLDC ) return NULL;
#083 return EMFDRV_SelectObject( hDC,
hGdiObj);
#084 #endif
#085 case GDI_OBJECT_TYPE_COLORSPACE:
#086 SetColorSpace(hDC, (HCOLORSPACE) hGdiObj);
#087 return NULL;
#088
#089 case GDI_OBJECT_TYPE_PALETTE:
#090 default:
#091
SetLastError(ERROR_INVALID_FUNCTION);
#092 return NULL;
#093 }
#094
#095 return NULL;
#096 }
#097