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