reactos操作系统实现(180)
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} (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |