ba2440aaccb61ceb43099ed62c0a1195a797e997
[reactos.git] / win32ss / user / user32 / windows / nonclient.c
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 LRESULT 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 }