reactos操作系统实现(182)
UserDrawCaption函数是用来实现窗口标题显示。具体代码如下: #001 BOOL UserDrawCaption( #002 PWINDOW_OBJECT pWnd, #003 HDC hDc, #004 LPCRECT lpRc, #005 HFONT hFont, #006 HICON hIcon, #007 const PUNICODE_STRING str, #008 UINT uFlags) #009 { #010 BOOL Ret = FALSE; #011 HBITMAP hMemBmp = NULL,hOldBmp = NULL; #012 HBRUSH hOldBrush = NULL; #013 HDC hMemDc = NULL; #014 ULONG Height; #015 UINT VCenter = 0,Padding = 0; #016 RECT r = *lpRc; #017 LONG ButtonWidth,IconWidth; #018 BOOL HasIcon; #019 PWINDOW Wnd = NULL; #020 #021 //ASSERT(pWnd != NULL); #022
获取窗口句柄。 #023 if (pWnd) #024 Wnd = pWnd->Wnd; #025
创建兼容DC的内存位图。 #026 hMemBmp = NtGdiCreateCompatibleBitmap(hDc, #027 lpRc->right - lpRc->left, #028 lpRc->bottom - lpRc->top); #029 #030 if(!hMemBmp) #031 { #032 DPRINT1("%s: NtGdiCreateCompatibleBitmap() failed!/n",__FUNCTION__); #033 return FALSE; #034 } #035
创建兼容的内存设备。 #036 hMemDc = NtGdiCreateCompatibleDC(hDc); #037 if(!hMemDc) #038 { #039 DPRINT1("%s: NtGdiCreateCompatibleDC() failed!/n",__FUNCTION__); #040 goto cleanup; #041 } #042
关联内存设备和位图设备。 #043 hOldBmp = NtGdiSelectBitmap(hMemDc,hMemBmp); #044 if(!hOldBmp) #045 { #046 DPRINT1("%s: NtGdiSelectBitmap() failed!/n",__FUNCTION__); #047 goto cleanup; #048 } #049
获取窗口标题的高度。 #050 Height = UserGetSystemMetrics(SM_CYCAPTION) - 1; #051 VCenter = (lpRc->bottom - lpRc->top) / 2; #052 Padding = VCenter - (Height / 2); #053
判断窗口标题是否有图标显示。 #054 if ((!hIcon) && (Wnd != NULL)) #055 { #056 HasIcon = (uFlags & DC_ICON) && (Wnd->Style & WS_SYSMENU) #057 && !(uFlags & DC_SMALLCAP) && !(Wnd->ExStyle & WS_EX_DLGMODALFRAME) #058 && !(Wnd->ExStyle & WS_EX_TOOLWINDOW); #059 } #060 else #061 HasIcon = (BOOL) hIcon; #062
获取图标的宽度。 #063 IconWidth = UserGetSystemMetrics(SM_CXSIZE) + Padding; #064 #065 r.left = Padding; #066 r.right = r.left + (lpRc->right - lpRc->left); #067 r.top = Padding; #068 r.bottom = r.top + (Height / 2); #069
显示标题的背景。 #070 // Draw the caption background #071 if(uFlags & DC_INBUTTON) #072 { #073 hOldBrush = NtGdiSelectBrush(hMemDc, #074 IntGetSysColorBrush(COLOR_3DFACE)); #075 #076 if(!hOldBrush) #077 { #078 DPRINT1("%s: NtGdiSelectBrush() failed!/n",__FUNCTION__); #079 goto cleanup; #080 } #081 #082 if(!NtGdiPatBlt(hMemDc, #083 lpRc->right - lpRc->left, #084 lpRc->bottom - lpRc->top, #085 PATCOPY)) #086 { #087 DPRINT1("%s: NtGdiPatBlt() failed!/n",__FUNCTION__); #088 goto cleanup; #089 } #090 #091 if(HasIcon) r.left+=IconWidth; #092 } #093 else #094 { #095 r.right = (lpRc->right - lpRc->left); #096 if(uFlags & DC_SMALLCAP) #097 ButtonWidth = UserGetSystemMetrics(SM_CXSMSIZE) - 2; #098 else ButtonWidth = UserGetSystemMetrics(SM_CXSIZE) - 2; #099 #100 hOldBrush = NtGdiSelectBrush(hMemDc, #101 IntGetSysColorBrush(uFlags & DC_ACTIVE ? #102 COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION)); #103 #104 if(!hOldBrush) #105 { #106 DPRINT1("%s: NtGdiSelectBrush() failed!/n",__FUNCTION__); #107 goto cleanup; #108 } #109 #110 if(HasIcon && (uFlags & DC_GRADIENT)) #111 { #112 NtGdiPatBlt(hMemDc, #113 IconWidth+1, #114 lpRc->bottom - lpRc->top, #115 PATCOPY); #116 r.left+=IconWidth; #117 } #118 else #119 { #120 NtGdiPatBlt(hMemDc, #121 lpRc->right - lpRc->left, #122 lpRc->bottom - lpRc->top, #123 PATCOPY); #124 } #125 #126 if(uFlags & DC_GRADIENT) #127 { #128 static GRADIENT_RECT gcap = {0,1}; #129 TRIVERTEX vert[2]; #130 COLORREF Colors[2]; #131 PDC pMemDc; #132 #133 if (Wnd != NULL) #134 {
计算系统菜单显示位置。 #135 if(Wnd->Style & WS_SYSMENU) #136 { #137 r.right -= 3 + ButtonWidth; #138 if(!(uFlags & DC_SMALLCAP)) #139 { #140 if(Wnd->Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX)) #141 r.right -= 2 + 2 * ButtonWidth; #142 else r.right -= 2; #143 r.right -= 2; #144 } #145
显示按钮背景颜色。 #146 //Draw buttons background #147 if(!NtGdiSelectBrush(hMemDc, #148 IntGetSysColorBrush(uFlags & DC_ACTIVE ? #149 COLOR_GRADIENTACTIVECAPTION:COLOR_GRADIENTINACTIVECAPTION))) #150 { #151 DPRINT1("%s: NtGdiSelectBrush() failed!/n",__FUNCTION__); #152 goto cleanup; #153 } #154 #155 NtGdiPatBlt(hMemDc, #156 r.right, #157 0, #158 lpRc->right - lpRc->left - r.right, #159 lpRc->bottom - lpRc->top, #160 PATCOPY); #161 } #162 } #163 #164 Colors[0] = IntGetSysColor((uFlags & DC_ACTIVE) ? #165 COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION); #166 #167 Colors[1] = IntGetSysColor((uFlags & DC_ACTIVE) ? #168 COLOR_GRADIENTACTIVECAPTION : COLOR_GRADIENTINACTIVECAPTION); #169 #170 vert[0].x = r.left; #171 vert[0].y = 0; #172 vert[0].Red = (WORD)Colors[0]<<8; #173 vert[0].Green = (WORD)Colors[0] & 0xFF00; #174 vert[0].Blue = (WORD)(Colors[0]>>8) & 0xFF00; #175 vert[0].Alpha = 0; #176 #177 vert[1].x = r.right; #178 vert[1].y = lpRc->bottom - lpRc->top; #179 vert[1].Red = (WORD)Colors[1]<<8; #180 vert[1].Green = (WORD)Colors[1] & 0xFF00; #181 vert[1].Blue = (WORD)(Colors[1]>>8) & 0xFF00; #182 vert[1].Alpha = 0; #183 #184 pMemDc = DC_LockDc(hMemDc); #185 if(!pMemDc) #186 { #187 DPRINT1("%s: Can't lock dc!/n",__FUNCTION__); #188 goto cleanup; #189 } #190 #191 if(!IntGdiGradientFill(pMemDc,vert,2,&gcap, #192 1,GRADIENT_FILL_RECT_H)) #193 { #194 DPRINT1("%s: IntGdiGradientFill() failed!/n",__FUNCTION__); #195 } #196 #197 DC_UnlockDc(pMemDc); #198 } //if(uFlags & DC_GRADIENT) #199 } #200
显示系统菜单按钮。 #201 if(HasIcon) #202 { #203 r.top ++; #204 r.left -= --IconWidth; #205 /* FIXME: Draw the Icon when pWnd == NULL but hIcon is valid */ #206 if (pWnd != NULL) #207 UserDrawSysMenuButton(pWnd,hMemDc,&r,FALSE); #208 r.left += IconWidth; #209 r.top --; #210 } #211 #212 r.top ++; #213 r.left += 2; #214 #215 r.bottom = r.top + Height; #216
计算标题字符串显示位置。 #217 if((uFlags & DC_TEXT)) #218 { #219 if(!(uFlags & DC_GRADIENT)) #220 { #221 r.right = (lpRc->right - lpRc->left); #222 #223 if(uFlags & DC_SMALLCAP) #224 ButtonWidth = UserGetSystemMetrics(SM_CXSMSIZE) - 2; #225 else ButtonWidth = UserGetSystemMetrics(SM_CXSIZE) - 2; #226 #227 if ((Wnd != NULL) && (Wnd->Style & WS_SYSMENU)) #228 { #229 r.right -= 3 + ButtonWidth; #230 if(! (uFlags & DC_SMALLCAP)) #231 { #232 if(Wnd->Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX)) #233 r.right -= 2 + 2 * ButtonWidth; #234 else r.right -= 2; #235 r.right -= 2; #236 } #237 } #238 } #239
调用函数UserDrawCaptionText显示标题字符串。 #240 /* FIXME: hFont isn't handled */ #241 if (str) #242 UserDrawCaptionText(hMemDc,str,uFlags); #243 else if (pWnd != NULL) #244 UserDrawCaptionText(hMemDc,&pWnd->Wnd->WindowName,uFlags); #245 } #246 从内存设备显示到实际显示设备。 #247 if(!NtGdiBitBlt(hDc,lpRc->left,lpRc->top, #248 lpRc->right - lpRc->left,lpRc->bottom - lpRc->top, #249 hMemDc,SRCCOPY,0)) #250 { #251 DPRINT1("%s: NtGdiBitBlt() failed!/n",__FUNCTION__); #252 goto cleanup; #253 } #254 #255 Ret = TRUE; #256
删除创建的DC资源。 #257 cleanup: #258 if (hOldBrush) NtGdiSelectBrush(hMemDc,hOldBrush); #259 if (hOldBmp) NtGdiSelectBitmap(hMemDc,hOldBmp); #260 if (hMemBmp) NtGdiDeleteObject(hMemBmp); #261 if (hMemDc) NtGdiDeleteObjectApp(hMemDc); #262 #263 return Ret; #264} (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |