1 /* 2 * ReactOS User32 Library 3 * - Window non-client area management 4 * 5 * Copyright (C) 2003 ReactOS Team 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22 #include <user32.h> 23 24 WINE_DEFAULT_DEBUG_CHANNEL(user32); 25 26 #define HASSIZEGRIP(Style, ExStyle, ParentStyle, WindowRect, ParentClientRect) \ 27 ((!(Style & WS_CHILD) && (Style & WS_THICKFRAME) && !(Style & WS_MAXIMIZE)) || \ 28 ((Style & WS_CHILD) && (ParentStyle & WS_THICKFRAME) && !(ParentStyle & WS_MAXIMIZE) && \ 29 (WindowRect.right - WindowRect.left == ParentClientRect.right) && \ 30 (WindowRect.bottom - WindowRect.top == ParentClientRect.bottom))) 31 32 33 /* PRIVATE FUNCTIONS **********************************************************/ 34 35 BOOL 36 UserHasWindowEdge(DWORD Style, DWORD ExStyle) 37 { 38 if (Style & WS_MINIMIZE) 39 return TRUE; 40 if (ExStyle & WS_EX_DLGMODALFRAME) 41 return TRUE; 42 if (ExStyle & WS_EX_STATICEDGE) 43 return FALSE; 44 if (Style & WS_THICKFRAME) 45 return TRUE; 46 Style &= WS_CAPTION; 47 if (Style == WS_DLGFRAME || Style == WS_CAPTION) 48 return TRUE; 49 return FALSE; 50 } 51 52 VOID 53 UserGetWindowBorders(DWORD Style, DWORD ExStyle, SIZE *Size, BOOL WithClient) 54 { 55 DWORD Border = 0; 56 57 if (UserHasWindowEdge(Style, ExStyle)) 58 Border += 2; 59 else if (ExStyle & WS_EX_STATICEDGE) 60 Border += 1; 61 if ((ExStyle & WS_EX_CLIENTEDGE) && WithClient) 62 Border += 2; 63 if (Style & WS_CAPTION || ExStyle & WS_EX_DLGMODALFRAME) 64 Border ++; 65 Size->cx = Size->cy = Border; 66 if ((Style & WS_THICKFRAME) && !(Style & WS_MINIMIZE)) 67 { 68 Size->cx += GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXDLGFRAME); 69 Size->cy += GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYDLGFRAME); 70 } 71 Size->cx *= GetSystemMetrics(SM_CXBORDER); 72 Size->cy *= GetSystemMetrics(SM_CYBORDER); 73 } 74 75 /* 76 RealUserDrawCaption: This function is passed through RegisterUserApiHook to uxtheme 77 to call it when the classic caption is needed to be drawn. 78 */ 79 BOOL WINAPI 80 RealUserDrawCaption(HWND hWnd, HDC hDC, LPCRECT lpRc, UINT uFlags) 81 { 82 ERR("Real DC flags %08x\n",uFlags); 83 return NtUserDrawCaption(hWnd, hDC, lpRc, uFlags); 84 } 85 86 87 /* PUBLIC FUNCTIONS ***********************************************************/ 88 89 BOOL WINAPI 90 RealAdjustWindowRectEx(LPRECT lpRect, 91 DWORD dwStyle, 92 BOOL bMenu, 93 DWORD dwExStyle) 94 { 95 SIZE BorderSize; 96 97 if (bMenu) 98 { 99 lpRect->top -= GetSystemMetrics(SM_CYMENU); 100 } 101 if ((dwStyle & WS_CAPTION) == WS_CAPTION) 102 { 103 if (dwExStyle & WS_EX_TOOLWINDOW) 104 lpRect->top -= GetSystemMetrics(SM_CYSMCAPTION); 105 else 106 lpRect->top -= GetSystemMetrics(SM_CYCAPTION); 107 } 108 UserGetWindowBorders(dwStyle, dwExStyle, &BorderSize, TRUE); 109 InflateRect( 110 lpRect, 111 BorderSize.cx, 112 BorderSize.cy); 113 114 return TRUE; 115 } 116 117 /* 118 * @implemented 119 */ 120 BOOL 121 WINAPI 122 DECLSPEC_HOTPATCH 123 AdjustWindowRectEx(LPRECT lpRect, 124 DWORD dwStyle, 125 BOOL bMenu, 126 DWORD dwExStyle) 127 { 128 BOOL Hook, Ret = FALSE; 129 130 LoadUserApiHook(); 131 132 Hook = BeginIfHookedUserApiHook(); 133 134 /* Bypass SEH and go direct. */ 135 if (!Hook) return RealAdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle); 136 137 _SEH2_TRY 138 { 139 Ret = guah.AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle); 140 } 141 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 142 { 143 } 144 _SEH2_END; 145 146 EndUserApiHook(); 147 148 return Ret; 149 } 150 151 152 /* 153 * @implemented 154 */ 155 BOOL 156 WINAPI 157 DECLSPEC_HOTPATCH 158 AdjustWindowRect(LPRECT lpRect, 159 DWORD dwStyle, 160 BOOL bMenu) 161 { 162 return AdjustWindowRectEx(lpRect, dwStyle, bMenu, 0); 163 } 164 165 // Enabling this will cause captions to draw smoother, but slower: 166 #define DOUBLE_BUFFER_CAPTION 167 168 /* 169 * @implemented 170 */ 171 BOOL WINAPI 172 DrawCaption(HWND hWnd, HDC hDC, LPCRECT lprc, UINT uFlags) 173 { 174 BOOL Hook, Ret = FALSE; 175 176 LoadUserApiHook(); 177 178 Hook = BeginIfHookedUserApiHook(); 179 180 /* Bypass SEH and go direct. */ 181 if (!Hook) return NtUserDrawCaption(hWnd, hDC, lprc, uFlags); 182 183 _SEH2_TRY 184 { 185 Ret = guah.DrawCaption(hWnd, hDC, lprc, uFlags); 186 } 187 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 188 { 189 } 190 _SEH2_END; 191 192 EndUserApiHook(); 193 194 return Ret; 195 } 196 197 /* 198 * @implemented 199 */ 200 BOOL 201 WINAPI 202 DrawCaptionTempW( 203 HWND hWnd, 204 HDC hDC, 205 const RECT *rect, 206 HFONT hFont, 207 HICON hIcon, 208 LPCWSTR str, 209 UINT uFlags 210 ) 211 { 212 UNICODE_STRING Text = {0}; 213 RtlInitUnicodeString(&Text, str); 214 return NtUserDrawCaptionTemp(hWnd, hDC, rect, hFont, hIcon, &Text, uFlags); 215 } 216 217 /* 218 * @implemented 219 */ 220 BOOL 221 WINAPI 222 DrawCaptionTempA( 223 HWND hwnd, 224 HDC hdc, 225 const RECT *rect, 226 HFONT hFont, 227 HICON hIcon, 228 LPCSTR str, 229 UINT uFlags 230 ) 231 { 232 LPWSTR strW; 233 INT len; 234 BOOL ret = FALSE; 235 236 if (!(uFlags & DC_TEXT) || !str) 237 return DrawCaptionTempW(hwnd, hdc, rect, hFont, hIcon, NULL, uFlags); 238 239 len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); 240 if ((strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)))) 241 { 242 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len ); 243 ret = DrawCaptionTempW(hwnd, hdc, rect, hFont, hIcon, strW, uFlags); 244 HeapFree(GetProcessHeap(), 0, strW); 245 } 246 return ret; 247 } 248