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, 0, 0,

#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, 0, 0,

#113              IconWidth+1,

#114              lpRc->bottom - lpRc->top,

#115              PATCOPY);

#116           r.left+=IconWidth;

#117        }

#118        else

#119        {

#120           NtGdiPatBlt(hMemDc, 0, 0,

#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, &r, uFlags);

#243         else if (pWnd != NULL)

#244            UserDrawCaptionText(hMemDc, &pWnd->Wnd->WindowName, &r, uFlags);

#245     }

#246 

从内存设备显示到实际显示设备。

#247     if(!NtGdiBitBlt(hDc, lpRc->left, lpRc->top,

#248        lpRc->right - lpRc->left, lpRc->bottom - lpRc->top,

#249        hMemDc, 0, 0, SRCCOPY, 0, 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  }

转载于:https://www.cnblogs.com/ajuanabc/archive/2010/01/18/2463502.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值