UserDrawCaptionText函数实现窗口上标题的显示。实现的代码如下:
#001 BOOL
#002 UserDrawCaptionText(HDC hDc,
#003 const PUNICODE_STRING Text,
#004 const LPRECT lpRc,
#005 UINT uFlags)
#006 {
#007 HFONT hOldFont = NULL, hFont = NULL;
#008 COLORREF OldTextColor;
#009 NONCLIENTMETRICSW nclm;
#010 NTSTATUS Status;
#011 #ifndef NDEBUG
#012 INT i;
#013 DPRINT("%s:", __FUNCTION__);
#014 for(i = 0; i < Text->Length/sizeof(WCHAR); i++)
#015 DbgPrint("%C", Text->Buffer[i]);
#016 DbgPrint(", %d/n", Text->Length/sizeof(WCHAR));
#017 #endif
#018
获取非客户区的大小。
#019 nclm.cbSize = sizeof(nclm);
#020 if(!IntSystemParametersInfo(SPI_GETNONCLIENTMETRICS,
#021 sizeof(NONCLIENTMETRICS), &nclm, 0))
#022 {
#023 DPRINT1("%s: IntSystemParametersInfo() failed!/n", __FUNCTION__);
#024 return FALSE;
#025 }
#026
设置显示文字方式为透明方式。
#027 IntGdiSetBkMode(hDc, TRANSPARENT);
#028
创建显示字符串的字体。
#029 if(uFlags & DC_SMALLCAP)
#030 Status = TextIntCreateFontIndirect(&nclm.lfSmCaptionFont, &hFont);
#031 else Status = TextIntCreateFontIndirect(&nclm.lfCaptionFont, &hFont);
#032
#033 if(!NT_SUCCESS(Status))
#034 {
#035 DPRINT1("%s: TextIntCreateFontIndirect() failed! Status: 0x%x/n",
#036 __FUNCTION__, Status);
#037 return FALSE;
#038 }
#039
选择字体到显示设备里。
#040 hOldFont = NtGdiSelectFont(hDc, hFont);
#041 if(!hOldFont)
#042 {
#043 DPRINT1("%s: SelectFont() failed!/n", __FUNCTION__);
#044 NtGdiDeleteObject(hFont);
#045 return FALSE;
#046 }
#047
设置字符串显示的颜色。
#048 if(uFlags & DC_INBUTTON)
#049 OldTextColor = IntGdiSetTextColor(hDc, IntGetSysColor(COLOR_BTNTEXT));
#050 else OldTextColor = IntGdiSetTextColor(hDc, IntGetSysColor(uFlags & DC_ACTIVE
#051 ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT));
#052
#053 //FIXME: If string doesn't fit to rc, truncate it and add ellipsis.
#054
调用函数GreExtTextOutW来显示字符串。
#055 GreExtTextOutW(hDc, lpRc->left,
#056 lpRc->top, 0, NULL, Text->Buffer,
#057 Text->Length/sizeof(WCHAR), NULL, 0);
#058
恢复前面的颜色和字体,删除创建的字体。
#059 IntGdiSetTextColor(hDc, OldTextColor);
#060 NtGdiSelectFont(hDc, hOldFont);
#061 NtGdiDeleteObject(hFont);
#062
#063 return TRUE;
#064 }