DefWndNCPaint函数实现窗口非客户区的显示部分,比如窗口的标题、最大化、最小化、关闭按钮、滚动条等等。
#001 LRESULT
#002 DefWndNCPaint(HWND hWnd,HRGN hRgn,BOOL Active)
#003 {
#004 HDC hDC;
#005 DWORD Style,ExStyle;
#006 HWND Parent;
#007 RECT ClientRect,WindowRect,CurrentRect,TempRect;
#008
如果窗口不可见,就不用进行显示操作。
#009 if (!IsWindowVisible(hWnd))
#010 return 0;
#011
获取窗口的类型。
#012 Style = GetWindowLongW(hWnd,GWL_STYLE);
#013
获取窗口的设备。
#014 hDC = GetDCEx(hWnd,hRgn,DCX_WINDOW | DCX_INTERSECTRGN | DCX_USESTYLE | DCX_KEEPCLIPRGN);
#015 if (hDC == 0)
#016 {
#017 return 0;
#018 }
#019
获取父窗口。
#020 Parent = GetParent(hWnd);
获取窗口扩展类型。
#021 ExStyle = GetWindowLongW(hWnd,GWL_EXSTYLE);
判断当前窗口是否为有焦点的窗口。
#022 if (Active == -1)
#023 {
#024 if (ExStyle & WS_EX_MDICHILD)
#025 {
#026 Active = IsChild(GetForegroundWindow(),hWnd);
#027 if (Active)
#028 Active = (hWnd == (HWND)SendMessageW(Parent,WM_MDIGETACTIVE,0));
#029 }
#030 else
#031 {
#032 Active = (GetForegroundWindow() == hWnd);
#033 }
#034 }
获取窗口的位置和大小。
#035 GetWindowRect(hWnd,&WindowRect);
获取窗口客户区的大小。
#036 GetClientRect(hWnd,&ClientRect);
#037
计算窗口的大小。
#038 CurrentRect.top = CurrentRect.left = 0;
#039 CurrentRect.right = WindowRect.right - WindowRect.left;
#040 CurrentRect.bottom = WindowRect.bottom - WindowRect.top;
#041
如果窗口有边沿类型,就需要画边沿窗口。
#042 /* Draw outer edge */
#043 if (UserHasWindowEdge(Style,ExStyle))
#044 {
显示窗口的边沿线。
#045 DrawEdge(hDC,&CurrentRect,EDGE_RAISED,BF_RECT | BF_ADJUST);
#046 } else
#047 if (ExStyle & WS_EX_STATICEDGE)
#048 {
显示固定边沿线。
#049 #if 0
#050 DrawEdge(hDC,BDR_SUNKENINNER,BF_RECT | BF_ADJUST | BF_FLAT);
#051 #else
#052 SelectObject(hDC,GetSysColorBrush(COLOR_BTNSHADOW));
#053 PatBlt(hDC,CurrentRect.left,CurrentRect.top,CurrentRect.right - CurrentRect.left,1,PATCOPY);
#054 PatBlt(hDC,CurrentRect.bottom - CurrentRect.top,PATCOPY);
#055
#056 SelectObject(hDC,GetSysColorBrush(COLOR_BTNHIGHLIGHT));
#057 PatBlt(hDC,CurrentRect.bottom - 1,PATCOPY);
#058 PatBlt(hDC,CurrentRect.right - 1,PATCOPY);
#059
#060 InflateRect(&CurrentRect,-1,-1);
#061 #endif
#062 }
#063
显示窗口细边框的样式。
#064 /* Firstly the "thick" frame */
#065 if ((Style & WS_THICKFRAME) && !(Style & WS_MINIMIZE))
#066 {
#067 DWORD Width =
#068 (GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXDLGFRAME)) *
#069 GetSystemMetrics(SM_CXBORDER);
#070 DWORD Height =
#071 (GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYDLGFRAME)) *
#072 GetSystemMetrics(SM_CYBORDER);
#073
#074 SelectObject(hDC,GetSysColorBrush(Active ? COLOR_ACTIVEBORDER :
#075 COLOR_INACTIVEBORDER));
#076
#077 /* Draw frame */
#078 PatBlt(hDC,Height,PATCOPY);
#079 PatBlt(hDC,Width,PATCOPY);
#080 #ifdef __REACTOS__
#081 PatBlt(hDC,-Height,PATCOPY);
#082 PatBlt(hDC,-Width,PATCOPY);
#083 #else
#084 PatBlt(hDC,CurrentRect.bottom,PATCOPY);
#085 PatBlt(hDC,CurrentRect.right,PATCOPY);
#086 #endif
#087
#088 InflateRect(&CurrentRect,-Height);
#089 }
#090
显示框架部分。
#091 /* Now the other bit of the frame */
#092 if (Style & (WS_DLGFRAME | WS_BORDER) || ExStyle & WS_EX_DLGMODALFRAME)
#093 {
#094 DWORD Width = GetSystemMetrics(SM_CXBORDER);
#095 DWORD Height = GetSystemMetrics(SM_CYBORDER);
#096
#097 SelectObject(hDC,GetSysColorBrush(
#098 (ExStyle & (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE)) ? COLOR_3DFACE :
#099 (ExStyle & WS_EX_STATICEDGE) ? COLOR_WINDOWFRAME :
#100 (Style & (WS_DLGFRAME | WS_THICKFRAME)) ? COLOR_3DFACE :
#101 COLOR_WINDOWFRAME));
#102
#103 /* Draw frame */
#104 PatBlt(hDC,PATCOPY);
#105 PatBlt(hDC,PATCOPY);
#106 #ifdef __REACTOS__
#107 PatBlt(hDC,PATCOPY);
#108 PatBlt(hDC,PATCOPY);
#109 #else
#110 PatBlt(hDC,PATCOPY);
#111 PatBlt(hDC,PATCOPY);
#112 #endif
#113
#114 InflateRect(&CurrentRect,-Height);
#115 }
#116
当窗口有标题时,就需要显示标题,也就是显示窗口最顶端的字符串。
#117 /* Draw caption */
#118 if ((Style & WS_CAPTION) == WS_CAPTION)
#119 {
#120 DWORD CaptionFlags = DC_ICON | DC_TEXT | DC_BUTTONS;
#121 HPEN PrevIoUsPen;
#122 BOOL Gradient = FALSE;
#123
#124 if(SystemParametersInfoW(SPI_GETGRADIENTCAPTIONS,&Gradient,0) && Gradient)
#125 {
#126 CaptionFlags |= DC_GRADIENT;
#127 }
#128
#129 TempRect = CurrentRect;
#130
#131 if (Active)
#132 {
#133 CaptionFlags |= DC_ACTIVE;
#134 }
#135
#136 if (ExStyle & WS_EX_TOOLWINDOW)
#137 {
#138 CaptionFlags |= DC_SMALLCAP;
#139 TempRect.bottom = TempRect.top + GetSystemMetrics(SM_CYSMCAPTION) - 1;
#140 CurrentRect.top += GetSystemMetrics(SM_CYSMCAPTION);
#141 }
#142 else
#143 {
#144 TempRect.bottom = TempRect.top + GetSystemMetrics(SM_CYCAPTION) - 1;
#145 CurrentRect.top += GetSystemMetrics(SM_CYCAPTION);
#146 }
#147
下面调用函数NtUserDrawCaption来显示窗口标题。
#148 NtUserDrawCaption(hWnd,hDC,&TempRect,CaptionFlags);
#149
#150 /* Draw buttons */
#151 if (Style & WS_SYSMENU)
#152 {
#153 UserDrawCaptionButton(&TempRect,Style,ExStyle,FALSE,DFCS_CAPTIONCLOSE);
#154 if ((Style & (WS_MAXIMIZEBox | WS_MINIMIZEBox)) && !(ExStyle & WS_EX_TOOLWINDOW))
#155 {
#156 UserDrawCaptionButton(&TempRect,DFCS_CAPTIONMIN);
#157 UserDrawCaptionButton(&TempRect,DFCS_CAPTIONMAX);
#158 }
#159 }
#160 if(!(Style & WS_MINIMIZE))
#161 {
#162 /* Line under caption */
#163 PrevIoUsPen = SelectObject(hDC,GetSysColorPen(
#164 ((ExStyle & (WS_EX_STATICEDGE | WS_EX_CLIENTEDGE |
#165 WS_EX_DLGMODALFRAME)) == WS_EX_STATICEDGE) ?
#166 COLOR_WINDOWFRAME : COLOR_3DFACE));
#167 MoveToEx(hDC,TempRect.left,TempRect.bottom,NULL);
#168 LineTo(hDC,TempRect.right,TempRect.bottom);
#169 SelectObject(hDC,PrevIoUsPen);
#170 }
#171 }
#172
#173 if(!(Style & WS_MINIMIZE))
#174 {
#175 HMENU menu = GetMenu(hWnd);
#176 /* Draw menu bar */
#177 if (menu && !(Style & WS_CHILD))
#178 {
#179 TempRect = CurrentRect;
#180 TempRect.bottom = TempRect.top + (UINT)NtUserSetMenuBarHeight(menu,0);
#181 CurrentRect.top += MenuDrawMenuBar(hDC,hWnd,FALSE);
#182 }
#183
显示客户区边界。
#184 if (ExStyle & WS_EX_CLIENTEDGE)
#185 {
#186 DrawEdge(hDC,EDGE_SUNKEN,BF_RECT | BF_ADJUST);
#187 }
#188
显示窗口的滚动条。
#189 /* Draw the scrollbars */
#190 if ((Style & WS_VSCROLL) && (Style & WS_HSCROLL) &&
#191 IntIsScrollBarVisible(hWnd,OBJID_VSCROLL) && IntIsScrollBarVisible(hWnd,OBJID_HSCROLL))
#192 {
#193 RECT ParentClientRect;
#194
#195 TempRect = CurrentRect;
#196 if (ExStyle & WS_EX_LEFTSCROLLBAR)
#197 TempRect.right = TempRect.left + GetSystemMetrics(SM_CXVSCROLL);
#198 else
#199 TempRect.left = TempRect.right - GetSystemMetrics(SM_CXVSCROLL);
#200 TempRect.top = TempRect.bottom - GetSystemMetrics(SM_CYHSCROLL);
#201 FillRect(hDC,GetSysColorBrush(COLOR_BTNFACE));
#202 /* FIXME: Correct drawing of size-Box with WS_EX_LEFTSCROLLBAR */
#203 if(Parent)
#204 GetClientRect(Parent,&ParentClientRect);
#205 if (HASSIZEGRIP(Style,GetWindowLongW(Parent,GWL_STYLE),ParentClientRect))
#206 {
#207 DrawFrameControl(hDC,DFC_SCROLL,DFCS_SCROLLSIZEGRIP);
#208 }
#209 IntDrawScrollBar(hWnd,SB_VERT);
#210 IntDrawScrollBar(hWnd,SB_HORZ);
#211 }
#212 else
#213 {
#214 if (Style & WS_VSCROLL && IntIsScrollBarVisible(hWnd,OBJID_VSCROLL))
#215 IntDrawScrollBar(hWnd,SB_VERT);
#216 else if (Style & WS_HSCROLL && IntIsScrollBarVisible(hWnd,OBJID_HSCROLL))
#217 IntDrawScrollBar(hWnd,SB_HORZ);
#218 }
#219 }
#220
#221 ReleaseDC(hWnd,hDC);
#222
#223 return 0;
#224}
原文链接:https://www.f2er.com/react/308341.html