source: trunk/src/user32/win32wbasenonclient.cpp@ 10013

Last change on this file since 10013 was 10013, checked in by sandervl, 22 years ago

Tool windows don't have minimize or maximize buttons; always draw tool windows in win32 style as they are not compatible with PM frame controls

File size: 49.6 KB
Line 
1/* $Id: win32wbasenonclient.cpp,v 1.51 2003-04-11 15:22:34 sandervl Exp $ */
2/*
3 * Win32 Window Base Class for OS/2 (non-client methods)
4 *
5 * Copyright 2000 Christoph Bratschi (cbratschi@datacomm.ch)
6 *
7 * Based on Wine code (windows\nonclient.c)
8 * Corel Version 20000212
9 *
10 * Copyright 1994 Alexandre Julliard
11 *
12 * TODO: Not thread/process safe
13 *
14 * Project Odin Software License can be found in LICENSE.TXT
15 *
16 */
17#include <os2win.h>
18#include <win.h>
19#include <stdlib.h>
20#include <string.h>
21#include <stdarg.h>
22#include <assert.h>
23#include <misc.h>
24#include <heapstring.h>
25#include <win32wbase.h>
26#include "wndmsg.h"
27#include "oslibwin.h"
28#include "oslibmsg.h"
29#include "oslibutil.h"
30#include "oslibgdi.h"
31#include "oslibres.h"
32#include "oslibdos.h"
33#include "syscolor.h"
34#include "win32wndhandle.h"
35#include "dc.h"
36#include "win32wdesktop.h"
37#include "controls.h"
38#include "pmwindow.h"
39#include <menu.h>
40
41#define DBG_LOCALLOG DBG_win32wbasenonclient
42#include "dbglocal.h"
43
44/* bits in the dwKeyData */
45#define KEYDATA_ALT 0x2000
46#define KEYDATA_PREVSTATE 0x4000
47
48static INT bitmapW = 16,bitmapH = 14;
49static HBITMAP hbitmapClose = 0;
50static HBITMAP hbitmapCloseD = 0;
51static HBITMAP hbitmapMinimize = 0;
52static HBITMAP hbitmapMinimizeD = 0;
53static HBITMAP hbitmapMaximize = 0;
54static HBITMAP hbitmapMaximizeD = 0;
55static HBITMAP hbitmapRestore = 0;
56static HBITMAP hbitmapRestoreD = 0;
57static HBITMAP hbitmapContextHelp = 0;
58static HBITMAP hbitmapContextHelpD = 0;
59
60BYTE lpGrayMask[] = { 0xAA, 0xA0,
61 0x55, 0x50,
62 0xAA, 0xA0,
63 0x55, 0x50,
64 0xAA, 0xA0,
65 0x55, 0x50,
66 0xAA, 0xA0,
67 0x55, 0x50,
68 0xAA, 0xA0,
69 0x55, 0x50};
70
71static INT (* WINAPI ShellAboutA)(HWND,LPCSTR,LPCSTR,HICON) = 0;
72
73//******************************************************************************
74//******************************************************************************
75LONG Win32BaseWindow::HandleNCActivate(WPARAM wParam)
76{
77 WORD wStateChange;
78
79 if( wParam ) wStateChange = !(flags & WIN_NCACTIVATED);
80 else wStateChange = flags & WIN_NCACTIVATED;
81
82 if( wStateChange )
83 {
84 if (wParam) flags |= WIN_NCACTIVATED;
85 else flags &= ~WIN_NCACTIVATED;
86
87 if (!(dwStyle & WS_CAPTION)) return TRUE;
88
89 if(!(dwStyle & WS_MINIMIZE))
90 DoNCPaint((HRGN)1,FALSE);
91 }
92
93 return TRUE;
94}
95//******************************************************************************
96//******************************************************************************
97VOID Win32BaseWindow::TrackMinMaxHelpBox(WORD wParam)
98{
99 MSG msg;
100 HDC hdc;
101 BOOL pressed = TRUE;
102 UINT state;
103
104 if (wParam == HTMINBUTTON)
105 {
106 /* If the style is not present, do nothing */
107 if (!(dwStyle & WS_MINIMIZEBOX))
108 return;
109 /* Check if the sysmenu item for minimize is there */
110 state = GetMenuState(hSysMenu,SC_MINIMIZE,MF_BYCOMMAND);
111 } else if (wParam == HTMAXBUTTON)
112 {
113 /* If the style is not present, do nothing */
114 if (!(dwStyle & WS_MAXIMIZEBOX))
115 return;
116 /* Check if the sysmenu item for maximize is there */
117 state = GetMenuState(hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
118 } else state = 0;
119 SetCapture(Win32Hwnd);
120 hdc = GetWindowDC(Win32Hwnd);
121 if (wParam == HTMINBUTTON)
122 DrawMinButton(hdc,NULL,TRUE,FALSE);
123 else if (wParam == HTMAXBUTTON)
124 DrawMaxButton(hdc,NULL,TRUE,FALSE);
125 else
126 DrawContextHelpButton(hdc,NULL,TRUE,FALSE);
127 do
128 {
129 BOOL oldstate = pressed;
130
131 GetMessageA(&msg,Win32Hwnd,0,0);
132 pressed = (HandleNCHitTest(msg.pt) == wParam);
133 if (pressed != oldstate)
134 {
135 if (wParam == HTMINBUTTON)
136 DrawMinButton(hdc,NULL,pressed,FALSE);
137 else if (wParam == HTMAXBUTTON)
138 DrawMaxButton(hdc,NULL,pressed,FALSE);
139 else
140 DrawContextHelpButton(hdc,NULL,pressed,FALSE);
141 }
142 } while (msg.message != WM_LBUTTONUP);
143 if (wParam == HTMINBUTTON)
144 DrawMinButton(hdc,NULL,FALSE,FALSE);
145 else if (wParam == HTMAXBUTTON)
146 DrawMaxButton(hdc,NULL,FALSE,FALSE);
147 else
148 DrawContextHelpButton(hdc,NULL,FALSE,FALSE);
149 ReleaseCapture();
150 ReleaseDC(Win32Hwnd,hdc);
151 /* If the item minimize or maximize of the sysmenu are not there */
152 /* or if the style is not present, do nothing */
153 if ((!pressed) || (state == 0xFFFFFFFF))
154 return;
155
156 if (wParam == HTMINBUTTON)
157 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_MINIMIZE,*(LPARAM*)&msg.pt);
158 else if (wParam == HTMAXBUTTON)
159 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,IsZoomed(Win32Hwnd) ? SC_RESTORE:SC_MAXIMIZE,*(LPARAM*)&msg.pt);
160 else
161 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_CONTEXTHELP,*(LPARAM*)&msg.pt);
162}
163//******************************************************************************
164//******************************************************************************
165VOID Win32BaseWindow::TrackCloseButton(WORD wParam)
166{
167 MSG msg;
168 HDC hdc;
169 BOOL pressed = TRUE;
170 UINT state;
171
172 if (hSysMenu == 0)
173 return;
174 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
175 /* If the item close of the sysmenu is disabled or not there do nothing */
176 if((state & MF_DISABLED) || (state & MF_GRAYED) || (state == 0xFFFFFFFF))
177 return;
178 hdc = GetWindowDC(Win32Hwnd);
179 SetCapture(Win32Hwnd);
180 DrawCloseButton(hdc,NULL,TRUE,FALSE);
181 do
182 {
183 BOOL oldstate = pressed;
184
185 GetMessageA(&msg,Win32Hwnd,0,0);
186 pressed = (HandleNCHitTest(msg.pt) == wParam);
187 if (pressed != oldstate)
188 DrawCloseButton(hdc,NULL,pressed,FALSE);
189 } while (msg.message != WM_LBUTTONUP);
190 DrawCloseButton(hdc,NULL,FALSE,FALSE);
191 ReleaseCapture();
192 ReleaseDC(Win32Hwnd,hdc);
193 if (!pressed) return;
194 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_CLOSE,*(LPARAM*)&msg.pt);
195}
196//******************************************************************************
197//******************************************************************************
198VOID Win32BaseWindow::TrackScrollBar(WPARAM wParam,POINT pt)
199{
200 INT scrollbar;
201 MSG msg;
202
203 if ((wParam & 0xfff0) == SC_HSCROLL)
204 {
205 if ((wParam & 0x0f) != HTHSCROLL) return;
206 scrollbar = SB_HORZ;
207 } else /* SC_VSCROLL */
208 {
209 if ((wParam & 0x0f) != HTVSCROLL) return;
210 scrollbar = SB_VERT;
211 }
212
213 ScreenToClient(getWindowHandle(), &pt);
214 pt.x += rectClient.left;
215 pt.y += rectClient.top;
216
217 SCROLL_HandleScrollEvent(getWindowHandle(),0,MAKELONG(pt.x,pt.y),scrollbar,WM_LBUTTONDOWN);
218 if (GetCapture() != Win32Hwnd) return;
219 do
220 {
221 GetMessageA(&msg, 0, 0, 0);
222 if(msg.hwnd == getWindowHandle())
223 {
224 switch(msg.message)
225 {
226 case WM_LBUTTONUP:
227 case WM_MOUSEMOVE:
228 pt.x = msg.pt.x;
229 pt.y = msg.pt.y;
230 ScreenToClient(getWindowHandle(), &pt);
231 pt.x += rectClient.left;
232 pt.y += rectClient.top;
233 msg.lParam = MAKELONG(pt.x,pt.y);
234
235 case WM_SYSTIMER:
236 SCROLL_HandleScrollEvent(Win32Hwnd,msg.wParam,msg.lParam,scrollbar,msg.message);
237 break;
238
239 default:
240 TranslateMessage(&msg);
241 DispatchMessageA(&msg);
242 break;
243 }
244 }
245 else {
246 TranslateMessage(&msg);
247 DispatchMessageA(&msg);
248 }
249 if (!IsWindow())
250 {
251 ReleaseCapture();
252 break;
253 }
254 } while (msg.message != WM_LBUTTONUP);
255}
256//******************************************************************************
257//******************************************************************************
258LONG Win32BaseWindow::HandleNCLButtonDown(WPARAM wParam,LPARAM lParam)
259{
260 switch(wParam) /* Hit test */
261 {
262 case HTCAPTION:
263 {
264 HWND hwndTopParent = GetTopParent();
265
266 if((getStyle() & WS_CHILD) && !(getExStyle() & WS_EX_MDICHILD))
267 {
268 if (GetActiveWindow() != hwndTopParent)
269 {
270 //SvL: Calling topparent->SetActiveWindow() causes focus problems
271 ::SetActiveWindow(hwndTopParent);
272//// SetFocus(topparent->getWindowHandle());
273 }
274 if (GetActiveWindow() == hwndTopParent)
275 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_MOVE+HTCAPTION,lParam);
276 else dprintf(("ACtive window (%x) != toplevel wnd %x", OSLibWinQueryActiveWindow(), hwndTopParent));
277 }
278 else {
279 SetActiveWindow();
280 if (GetActiveWindow() == hwndTopParent)
281 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_MOVE+HTCAPTION,lParam);
282 else dprintf(("ACtive window (%x) != wnd %x", OSLibWinQueryActiveWindow(), getWindowHandle()));
283 }
284 break;
285 }
286
287 case HTSYSMENU:
288 if(dwStyle & WS_SYSMENU )
289 {
290 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_MOUSEMENU+HTSYSMENU,lParam);
291 }
292 break;
293
294 case HTMENU:
295 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_MOUSEMENU,lParam);
296 break;
297
298 case HTHSCROLL:
299 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_HSCROLL+HTHSCROLL,lParam);
300 break;
301
302 case HTVSCROLL:
303 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_VSCROLL+HTVSCROLL,lParam);
304 break;
305
306 case HTMINBUTTON:
307 case HTMAXBUTTON:
308 case HTHELP:
309 TrackMinMaxHelpBox(wParam);
310 break;
311
312 case HTCLOSE:
313 TrackCloseButton(wParam);
314 break;
315
316 case HTLEFT:
317 case HTRIGHT:
318 case HTTOP:
319 case HTTOPLEFT:
320 case HTTOPRIGHT:
321 case HTBOTTOM:
322 case HTBOTTOMLEFT:
323 case HTBOTTOMRIGHT:
324 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
325 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_SIZE+wParam-2,lParam);
326 break;
327 case HTBORDER:
328 break;
329 }
330
331 return 0;
332}
333//******************************************************************************
334//******************************************************************************
335VOID Win32BaseWindow::AdjustMaximizedRect(LPRECT rect)
336{
337 if (HAS_THICKFRAME(dwStyle,dwExStyle ))
338 InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
339 else
340 if (HAS_DLGFRAME( dwStyle, dwExStyle ))
341 InflateRect(rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
342 else
343 if (HAS_THINFRAME( dwStyle ))
344 InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
345}
346//******************************************************************************
347//******************************************************************************
348VOID Win32BaseWindow::AdjustTrackInfo(PPOINT minTrackSize,PPOINT maxTrackSize)
349{
350 if ((dwStyle & WS_THICKFRAME) || !(dwStyle & (WS_POPUP | WS_CHILD)))
351 GetMinMaxInfo(NULL,NULL,minTrackSize,maxTrackSize);
352}
353//******************************************************************************
354//******************************************************************************
355VOID Win32BaseWindow::AdjustRectOuter(LPRECT rect,BOOL menu)
356{
357 int adjust;
358 if(dwStyle & WS_ICONIC) return;
359
360 if ((dwExStyle & (WS_EX_STATICEDGE|WS_EX_DLGMODALFRAME)) ==
361 WS_EX_STATICEDGE)
362 {
363 adjust = 1; /* for the outer frame always present */
364 }
365 else
366 {
367 adjust = 0;
368 if ((dwExStyle & WS_EX_DLGMODALFRAME) ||
369 (dwStyle & (WS_THICKFRAME|WS_DLGFRAME))) adjust = 2; /* outer */
370 }
371 if (dwStyle & WS_THICKFRAME)
372 adjust += ( GetSystemMetrics (SM_CXFRAME)
373 - GetSystemMetrics (SM_CXDLGFRAME)); /* The resize border */
374 if ((dwStyle & (WS_BORDER|WS_DLGFRAME)) ||
375 (dwExStyle & WS_EX_DLGMODALFRAME))
376 adjust++; /* The other border */
377
378 InflateRect (rect, adjust, adjust);
379
380 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
381 {
382 if (dwExStyle & WS_EX_TOOLWINDOW)
383 rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
384 else
385 rect->top -= GetSystemMetrics(SM_CYCAPTION);
386 }
387 if (menu) rect->top -= GetSystemMetrics(SM_CYMENU);
388}
389//******************************************************************************
390//******************************************************************************
391VOID Win32BaseWindow::AdjustRectInner(LPRECT rect)
392{
393 if(dwStyle & WS_ICONIC) return;
394
395 if (dwExStyle & WS_EX_CLIENTEDGE)
396 InflateRect (rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
397
398 //@@PF Wine does not have this but inner rect shrinks when
399 //WS_EX_STATICEDGE is usedd not on a child
400
401 if (dwExStyle & WS_EX_STATICEDGE && (!(dwStyle & WS_CHILD)))
402 InflateRect (rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
403
404 if (dwStyle & WS_VSCROLL) rect->right += GetSystemMetrics(SM_CXVSCROLL);
405 if (dwStyle & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
406}
407//******************************************************************************
408//******************************************************************************
409LONG Win32BaseWindow::HandleNCCalcSize(BOOL calcValidRects,RECT *winRect)
410{
411 RECT tmpRect = { 0, 0, 0, 0 };
412 LONG result = 0;
413 UINT style;
414
415 dprintf(("Default WM_NCCALCSIZE handler"));
416
417 if (!calcValidRects) return 0;
418
419 style = (UINT) GetClassLongA(Win32Hwnd,GCL_STYLE);
420
421 if (style & CS_VREDRAW) result |= WVR_VREDRAW;
422 if (style & CS_HREDRAW) result |= WVR_HREDRAW;
423
424 if(!(dwStyle & WS_MINIMIZE))
425 {
426 AdjustRectOuter(&tmpRect,FALSE);
427
428 winRect->left -= tmpRect.left;
429 winRect->top -= tmpRect.top;
430 winRect->right -= tmpRect.right;
431 winRect->bottom -= tmpRect.bottom;
432
433 if (HAS_MENU())
434 {
435 winRect->top +=
436 MENU_GetMenuBarHeight(Win32Hwnd,
437 winRect->right - winRect->left,
438 -tmpRect.left, -tmpRect.top ) + 1;
439 }
440
441 SetRect (&tmpRect, 0, 0, 0, 0);
442 AdjustRectInner(&tmpRect);
443 winRect->left -= tmpRect.left;
444 winRect->top -= tmpRect.top;
445 winRect->right -= tmpRect.right;
446 winRect->bottom -= tmpRect.bottom;
447
448 if (winRect->top > winRect->bottom)
449 winRect->bottom = winRect->top;
450
451 if (winRect->left > winRect->right)
452 winRect->right = winRect->left;
453 }
454 else {
455 //must return empty rectangle in parent coordinates (converted to
456 //(0,0)(0,0) in NCCALCSIZE handler
457 winRect->right = winRect->left;
458 winRect->bottom = winRect->top;
459 }
460 return result;
461}
462//******************************************************************************
463//******************************************************************************
464LONG Win32BaseWindow::HandleNCHitTest(POINT pt)
465{
466 RECT rect;
467
468 if (dwStyle & WS_MINIMIZE) return HTCAPTION;
469
470 //TODO: is this correct???
471 if (dwStyle & WS_DISABLED) return HTERROR;
472
473 GetWindowRect(getWindowHandle(), &rect);
474
475 if (!PtInRect(&rect,pt)) return HTNOWHERE;
476
477 /* Check borders */
478 if (HAS_THICKFRAME(dwStyle,dwExStyle))
479 {
480 InflateRect(&rect,-GetSystemMetrics(SM_CXFRAME),-GetSystemMetrics(SM_CYFRAME));
481 if (!PtInRect(&rect,pt))
482 {
483 /* Check top sizing border */
484 if (pt.y < rect.top)
485 {
486 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
487 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
488 return HTTOP;
489 }
490 /* Check bottom sizing border */
491 if (pt.y >= rect.bottom)
492 {
493 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
494 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
495 return HTBOTTOM;
496 }
497 /* Check left sizing border */
498 if (pt.x < rect.left)
499 {
500 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
501 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
502 return HTLEFT;
503 }
504 /* Check right sizing border */
505 if (pt.x >= rect.right)
506 {
507 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
508 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
509 return HTRIGHT;
510 }
511 }
512 } else /* No thick frame */
513 {
514 if (HAS_DLGFRAME(dwStyle,dwExStyle))
515 InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
516 else if (HAS_THINFRAME(dwStyle ))
517 InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
518 if (!PtInRect( &rect, pt )) return HTBORDER;
519 }
520
521 /* Check caption */
522
523 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
524 {
525 if (dwExStyle & WS_EX_TOOLWINDOW)
526 rect.top += GetSystemMetrics(SM_CYSMCAPTION)-1;
527 else
528 rect.top += GetSystemMetrics(SM_CYCAPTION)-1;
529 if (!PtInRect(&rect,pt))
530 {
531 /* Check system menu */
532 if(dwStyle & WS_SYSMENU)
533 {
534 /* Check if there is an user icon */
535 if (IconForWindow(ICON_SMALL))
536 rect.left += GetSystemMetrics(SM_CYCAPTION) - 1;
537 }
538 if (pt.x < rect.left) return HTSYSMENU;
539
540 /* Check close button */
541 if (dwStyle & WS_SYSMENU)
542 rect.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
543 if (pt.x > rect.right) return HTCLOSE;
544
545 //Check context help
546 if (dwExStyle & WS_EX_CONTEXTHELP)
547 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
548 if (pt.x > rect.right) return HTHELP;
549
550 /* Check maximize box */
551 /* In win95 there is automatically a Maximize button when there is a minimize one*/
552 if ((dwStyle & WS_MAXIMIZEBOX)|| (dwStyle & WS_MINIMIZEBOX))
553 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
554 if (pt.x > rect.right) return HTMAXBUTTON;
555
556 /* Check minimize box */
557 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
558 if ((dwStyle & WS_MINIMIZEBOX)||(dwStyle & WS_MAXIMIZEBOX))
559 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
560
561 if (pt.x > rect.right) return HTMINBUTTON;
562 return HTCAPTION;
563 }
564 }
565
566 /* Check client area */
567
568 ScreenToClient(Win32Hwnd,&pt);
569 getClientRect(&rect);
570 if (PtInRect(&rect,pt)) return HTCLIENT;
571
572 /* Check vertical scroll bar */
573
574 if (dwStyle & WS_VSCROLL)
575 {
576 rect.right += GetSystemMetrics(SM_CXVSCROLL);
577 if (PtInRect( &rect, pt )) return HTVSCROLL;
578 }
579
580 /* Check horizontal scroll bar */
581
582 if (dwStyle & WS_HSCROLL)
583 {
584 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
585 if (PtInRect( &rect, pt ))
586 {
587 /* Check size box */
588 if ((dwStyle & WS_VSCROLL) &&
589 (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
590 return (dwStyle & WS_CHILD) ? HTSIZE:HTBOTTOMRIGHT;
591 return HTHSCROLL;
592 }
593 }
594
595 /* Check menu bar */
596
597 if (HAS_MENU())
598 {
599 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
600 return HTMENU;
601 }
602
603 /* Has to return HTNOWHERE if nothing was found
604 Could happen when a window has a customized non client area */
605 return HTNOWHERE;
606}
607
608//******************************************************************************
609//******************************************************************************
610VOID Win32BaseWindow::GetInsideRect(RECT *rect)
611{
612 rect->top = rect->left = 0;
613 rect->right = rectWindow.right - rectWindow.left;
614 rect->bottom = rectWindow.bottom - rectWindow.top;
615
616 if (dwStyle & WS_ICONIC) return;
617
618 /* Remove frame from rectangle */
619 if (HAS_THICKFRAME(dwStyle,dwExStyle))
620 {
621 InflateRect( rect, -GetSystemMetrics(SM_CXSIZEFRAME), -GetSystemMetrics(SM_CYSIZEFRAME) );
622 }
623 else if (HAS_DLGFRAME(dwStyle,dwExStyle ))
624 {
625 InflateRect( rect, -GetSystemMetrics(SM_CXFIXEDFRAME), -GetSystemMetrics(SM_CYFIXEDFRAME));
626 }
627 else if (HAS_THINFRAME(dwStyle))
628 {
629 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
630 }
631
632 /* We have additional border information if the window
633 * is a child (but not an MDI child) */
634 if ( (dwStyle & WS_CHILD) &&
635 ( (dwExStyle & WS_EX_MDICHILD) == 0 ) )
636 {
637 if (dwExStyle & WS_EX_CLIENTEDGE)
638 InflateRect (rect, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE));
639
640 if (dwExStyle & WS_EX_STATICEDGE)
641 InflateRect (rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
642 }
643}
644//******************************************************************************
645//******************************************************************************
646VOID Win32BaseWindow::DrawFrame(HDC hdc,RECT *rect,BOOL dlgFrame,BOOL active)
647{
648 INT width, height;
649 HBRUSH oldBrush;
650
651 if (dlgFrame)
652 {
653 width = GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
654 height = GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
655 }
656 else
657 {
658 width = GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXEDGE);
659 height = GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYEDGE);
660 }
661
662 oldBrush = SelectObject(hdc,GetSysColorBrush(active ? COLOR_ACTIVEBORDER:COLOR_INACTIVEBORDER));
663
664 /* Draw frame */
665 PatBlt(hdc,rect->left, rect->top, rect->right-rect->left, height,PATCOPY); //top
666 PatBlt(hdc,rect->left, rect->top, width, rect->bottom-rect->top,PATCOPY); //left
667 PatBlt(hdc,rect->left, rect->bottom-1, rect->right-rect->left,-height,PATCOPY); //bottom
668 PatBlt(hdc,rect->right-1,rect->top, -width, rect->bottom-rect->top,PATCOPY); //right
669 SelectObject(hdc,oldBrush);
670
671 InflateRect(rect,-width,-height);
672}
673//******************************************************************************
674//******************************************************************************
675BOOL Win32BaseWindow::DrawSysButton(HDC hdc,RECT *rect)
676{
677 HICON hSysIcon;
678 RECT r;
679
680 if (!rect) GetInsideRect(&r);
681 else r = *rect;
682
683 hSysIcon = IconForWindow(ICON_SMALL);
684
685//CB: todo: add icons (including Odin icon) to user32.rc
686 if (hSysIcon)
687 DrawIconEx(hdc,r.left+2,r.top+2,hSysIcon,
688 GetSystemMetrics(SM_CXSMICON),
689 GetSystemMetrics(SM_CYSMICON),
690 0, 0, DI_NORMAL);
691
692 return (hSysIcon != 0);
693}
694//******************************************************************************
695//Returns position of system menu in screen coordinates
696//******************************************************************************
697BOOL Win32BaseWindow::GetSysPopupPos(RECT* lpRect)
698{
699 if(hSysMenu)
700 {
701 if(dwStyle & WS_MINIMIZE) {
702 GetWindowRect(getWindowHandle(), lpRect);
703 }
704 else
705 {
706 GetInsideRect(lpRect);
707 OffsetRect(lpRect, rectWindow.left, rectWindow.top);
708 if(getStyle() & WS_CHILD)
709 ClientToScreen(getParent()->getWindowHandle(), (POINT *)lpRect);
710
711 lpRect->right = lpRect->left + GetSystemMetrics(SM_CYCAPTION) - 1;
712 lpRect->bottom = lpRect->top + GetSystemMetrics(SM_CYCAPTION) - 1;
713 }
714 return TRUE;
715 }
716 return FALSE;
717}
718//******************************************************************************
719//******************************************************************************
720BOOL Win32BaseWindow::DrawGrayButton(HDC hdc,int x,int y)
721{
722 HBITMAP hMaskBmp;
723 HDC hdcMask = CreateCompatibleDC (0);
724 HBRUSH hOldBrush;
725 hMaskBmp = CreateBitmap (12, 10, 1, 1, lpGrayMask);
726
727 if(hMaskBmp == 0)
728 return FALSE;
729
730 SelectObject (hdcMask, hMaskBmp);
731
732 /* Draw the grayed bitmap using the mask */
733 hOldBrush = SelectObject (hdc, RGB(128, 128, 128));
734 BitBlt (hdc, x, y, 12, 10,
735 hdcMask, 0, 0, 0xB8074A);
736
737 /* Clean up */
738 SelectObject (hdc, hOldBrush);
739 DeleteObject(hMaskBmp);
740 DeleteDC (hdcMask);
741
742 return TRUE;
743}
744//******************************************************************************
745//******************************************************************************
746VOID Win32BaseWindow::DrawCloseButton(HDC hdc,RECT *rect,BOOL down,BOOL bGrayed)
747{
748 RECT r;
749 HDC hdcMem;
750 BITMAP bmp;
751 HBITMAP hBmp, hOldBmp;
752
753 if (!rect) GetInsideRect(&r);
754 else r = *rect;
755
756 /* A tool window has a smaller Close button */
757 if (dwExStyle & WS_EX_TOOLWINDOW)
758 {
759 RECT toolRect;
760 INT iBmpHeight = 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
761 INT iBmpWidth = 11; /* it uses 11x11 for the close button in tool window */
762 INT iCaptionHeight = GetSystemMetrics(SM_CYSMCAPTION);
763
764
765 toolRect.top = r.top + (iCaptionHeight - 1 - iBmpHeight) / 2;
766 toolRect.left = r.right - (iCaptionHeight + 1 + iBmpWidth) / 2;
767 toolRect.bottom = toolRect.top + iBmpHeight;
768 toolRect.right = toolRect.left + iBmpWidth;
769 DrawFrameControl(hdc,&toolRect,
770 DFC_CAPTION,DFCS_CAPTIONCLOSE |
771 down ? DFCS_PUSHED : 0 |
772 bGrayed ? DFCS_INACTIVE : 0);
773 } else
774 {
775 hdcMem = CreateCompatibleDC( hdc );
776 hBmp = down ? hbitmapCloseD : hbitmapClose;
777 hOldBmp = SelectObject (hdcMem, hBmp);
778 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
779
780 BitBlt (hdc, r.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2,
781 r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
782 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);
783
784 if(bGrayed)
785 DrawGrayButton(hdc,r.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2 + 2,
786 r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
787
788 SelectObject (hdcMem, hOldBmp);
789 DeleteDC (hdcMem);
790 }
791}
792//******************************************************************************
793//******************************************************************************
794VOID Win32BaseWindow::DrawMaxButton(HDC hdc,RECT *rect,BOOL down,BOOL bGrayed)
795{
796 RECT r;
797 HDC hdcMem;
798 BITMAP bmp;
799 HBITMAP hBmp,hOldBmp;
800
801 if (!rect) GetInsideRect(&r);
802 else r = *rect;
803 hdcMem = CreateCompatibleDC( hdc );
804 hBmp = IsZoomed(Win32Hwnd) ?
805 (down ? hbitmapRestoreD : hbitmapRestore ) :
806 (down ? hbitmapMaximizeD: hbitmapMaximize);
807 hOldBmp = SelectObject( hdcMem, hBmp );
808 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
809
810 if (dwStyle & WS_SYSMENU)
811 r.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
812
813 if (dwExStyle & WS_EX_CONTEXTHELP)
814 r.right -= bmp.bmWidth;
815
816 BitBlt( hdc, r.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
817 r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
818 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
819
820 if(bGrayed)
821 DrawGrayButton(hdc, r.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
822 r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
823
824 SelectObject (hdcMem, hOldBmp);
825 DeleteDC( hdcMem );
826}
827//******************************************************************************
828//******************************************************************************
829VOID Win32BaseWindow::DrawMinButton(HDC hdc,RECT *rect,BOOL down,BOOL bGrayed)
830{
831 RECT r;
832 HDC hdcMem;
833 BITMAP bmp;
834 HBITMAP hBmp,hOldBmp;
835
836 if (!rect) GetInsideRect(&r);
837 else r = *rect;
838
839 hdcMem = CreateCompatibleDC( hdc );
840 hBmp = down ? hbitmapMinimizeD : hbitmapMinimize;
841 hOldBmp= SelectObject( hdcMem, hBmp );
842 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
843
844 if (dwStyle & WS_SYSMENU)
845 r.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
846
847 if (dwExStyle & WS_EX_CONTEXTHELP)
848 r.right -= bmp.bmWidth;
849
850 /* In win 95 there is always a Maximize box when there is a Minimize one */
851 if ((dwStyle & WS_MAXIMIZEBOX) || (dwStyle & WS_MINIMIZEBOX))
852 r.right -= bmp.bmWidth;
853
854 BitBlt( hdc, r.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
855 r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
856 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
857
858 if(bGrayed)
859 DrawGrayButton(hdc, r.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
860 r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
861
862
863 SelectObject (hdcMem, hOldBmp);
864 DeleteDC( hdcMem );
865}
866//******************************************************************************
867//******************************************************************************
868VOID Win32BaseWindow::DrawContextHelpButton(HDC hdc,RECT *rect,BOOL down,BOOL bGrayed)
869{
870 RECT r;
871 HDC hdcMem;
872 BITMAP bmp;
873 HBITMAP hBmp,hOldBmp;
874
875 if (!rect) GetInsideRect(&r);
876 else r = *rect;
877
878 hdcMem = CreateCompatibleDC(hdc);
879 hBmp = down ? hbitmapContextHelpD : hbitmapContextHelp;
880 hOldBmp = SelectObject(hdcMem,hBmp);
881 GetObjectA(hBmp,sizeof(BITMAP),&bmp);
882
883 if (dwStyle & WS_SYSMENU)
884 r.right -= GetSystemMetrics(SM_CYCAPTION)+1;
885
886 BitBlt( hdc, r.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
887 r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
888 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
889
890 if(bGrayed)
891 DrawGrayButton(hdc, r.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
892 r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
893
894
895 SelectObject (hdcMem, hOldBmp);
896 DeleteDC( hdcMem );
897}
898//******************************************************************************
899//******************************************************************************
900VOID Win32BaseWindow::DrawCaption(HDC hdc,RECT *rect,BOOL active)
901{
902 RECT r = *rect,r2;
903 char buffer[256];
904 HPEN hPrevPen;
905 HDC memDC;
906 HBITMAP memBmp,oldBmp;
907
908 //WS_EX_TOOLWINDOW is incompatible with the OS2Look (titlebar thinner + smaller font)
909 if(fOS2Look && !(dwExStyle & WS_EX_TOOLWINDOW)) {
910 //Note: If no class icon *and* WS_EX_DLGMODALFRAME -> no system menu
911 if((dwStyle & WS_SYSMENU) && !(dwExStyle & WS_EX_TOOLWINDOW) &&
912 !(!windowClass->getIcon() && (dwExStyle & WS_EX_DLGMODALFRAME)) &&
913 fOS2Look != OS2_APPEARANCE_SYSMENU)
914 {
915 HICON hSysIcon = IconForWindow(ICON_SMALL);
916
917 if (hSysIcon) {
918 int size = GetSystemMetrics(SM_CYCAPTION);
919
920 r2 = r;
921 r2.right = r2.left + size;
922 r2.bottom = r2.top + size;
923 FillRect(hdc, &r2, GetSysColorBrush(COLOR_MENU));
924
925 DrawSysButton(hdc,&r);
926 }
927 }
928 return;
929 }
930
931 memDC = CreateCompatibleDC(hdc);
932 r.right -= r.left;
933 r.bottom -= r.top;
934 r.left = r.top = 0;
935 r2 = r;
936 memBmp = CreateCompatibleBitmap(hdc,r.right,r.bottom);
937 oldBmp = SelectObject(memDC,memBmp);
938
939 hPrevPen = SelectObject(memDC,GetSysColorPen(COLOR_3DFACE));
940 MoveToEx(memDC,r.left,r.bottom-1,NULL);
941 LineTo(memDC,r.right,r.bottom-1);
942 SelectObject(memDC,hPrevPen);
943 r.bottom--;
944
945 if (SYSCOLOR_GetUseWinColors())
946 {
947 COLORREF startColor = GetSysColor(active ? COLOR_ACTIVECAPTION:COLOR_INACTIVECAPTION),endColor = GetSysColor(active ? COLOR_GRADIENTACTIVECAPTION:COLOR_GRADIENTINACTIVECAPTION);
948
949 if (startColor == endColor)
950 FillRect(memDC,&r,GetSysColorBrush(startColor));
951 else
952 {
953 INT rDiff = GetRValue(endColor)-GetRValue(startColor);
954 INT gDiff = GetGValue(endColor)-GetGValue(startColor);
955 INT bDiff = GetBValue(endColor)-GetBValue(startColor);
956 INT steps = MAX(MAX(abs(rDiff),abs(gDiff)),abs(bDiff));
957 INT w = r.right-r.left;
958 RECT r2;
959
960 if (w < steps) steps = w;
961 r2.left = r2.right = r.left;
962 r2.top = r.top;
963 r2.bottom = r.bottom;
964 for (INT x = 0;x <= steps;x++)
965 {
966 COLORREF color = RGB(GetRValue(startColor)+rDiff*x/steps,GetGValue(startColor)+gDiff*x/steps,GetBValue(startColor)+bDiff*x/steps);
967 HBRUSH brush = CreateSolidBrush(color);
968
969 r2.left = r2.right;
970 r2.right = r.left+w*x/steps;
971 FillRect(memDC,&r2,brush);
972 DeleteObject(brush);
973 }
974 }
975 } else FillRect(memDC,&r,GetSysColorBrush(active ? COLOR_ACTIVECAPTION:COLOR_INACTIVECAPTION));
976
977 if (!hbitmapClose)
978 {
979 if (!(hbitmapClose = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CLOSE)))) return;
980 hbitmapCloseD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CLOSED));
981 hbitmapMinimize = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_REDUCE));
982 hbitmapMinimizeD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_REDUCED));
983 hbitmapMaximize = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_ZOOM));
984 hbitmapMaximizeD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_ZOOMD));
985 hbitmapRestore = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_RESTORE));
986 hbitmapRestoreD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_RESTORED));
987 hbitmapContextHelp = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CONTEXTHELP));
988 hbitmapContextHelpD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CONTEXTHELPD));
989 }
990
991 //Note: If no class icon *and* WS_EX_DLGMODALFRAME -> no system menu
992 if((dwStyle & WS_SYSMENU) && !(dwExStyle & WS_EX_TOOLWINDOW) &&
993 !(!windowClass->getIcon() && (dwExStyle & WS_EX_DLGMODALFRAME)))
994 {
995 if (DrawSysButton(memDC,&r))
996 r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
997 }
998
999 if (dwStyle & WS_SYSMENU)
1000 {
1001 UINT state;
1002
1003 /* Go get the sysmenu */
1004 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
1005
1006 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1007 DrawCloseButton(memDC,&r2,FALSE,
1008 ((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
1009 r.right -= GetSystemMetrics(SM_CYCAPTION)-1;
1010
1011 if (dwExStyle & WS_EX_CONTEXTHELP)
1012 {
1013 DrawContextHelpButton(memDC,&r2,FALSE,FALSE);
1014 r.right -= GetSystemMetrics(SM_CXSIZE)+1;
1015 }
1016
1017 //Testing in NT4 shows that tool windows never have a minimize or maximize button!
1018 if (((dwStyle & WS_MAXIMIZEBOX) || (dwStyle & WS_MINIMIZEBOX)) &&
1019 !(dwExStyle & WS_EX_TOOLWINDOW))
1020 {
1021 /* In win95 the two buttons are always there */
1022 /* But if the menu item is not in the menu they're disabled*/
1023
1024 DrawMaxButton(memDC,&r2,FALSE,(!(dwStyle & WS_MAXIMIZEBOX)));
1025 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1026
1027 DrawMinButton(memDC,&r2,FALSE, (!(dwStyle & WS_MINIMIZEBOX)));
1028 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1029 }
1030 }
1031
1032 if (GetWindowTextA(buffer, sizeof(buffer) ))
1033 {
1034 NONCLIENTMETRICSA nclm;
1035 HFONT hFont, hOldFont;
1036
1037 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1038 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1039 if (dwExStyle & WS_EX_TOOLWINDOW)
1040 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
1041 else
1042 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
1043 hOldFont = SelectObject (memDC, hFont);
1044 SetTextColor(memDC,GetSysColor(active ? COLOR_CAPTIONTEXT:COLOR_INACTIVECAPTIONTEXT));
1045 SetBkMode(memDC, TRANSPARENT );
1046 r.left += 2;
1047 DrawTextExA(memDC,buffer,-1,&r,DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT | DT_END_ELLIPSIS,NULL);
1048 DeleteObject (SelectObject (memDC, hOldFont));
1049 IncreaseLogCount();
1050 dprintf(("DrawCaption %s %d", buffer, active));
1051 DecreaseLogCount();
1052 }
1053
1054 BitBlt(hdc,rect->left,rect->top,rect->right-rect->left,rect->bottom-rect->top,memDC,0,0,SRCCOPY);
1055 SelectObject(memDC,oldBmp);
1056 DeleteObject(memBmp);
1057 DeleteDC(memDC);
1058}
1059//******************************************************************************
1060//******************************************************************************
1061VOID Win32BaseWindow::DoNCPaint(HRGN clip,BOOL suppress_menupaint)
1062{
1063 BOOL active = flags & WIN_NCACTIVATED;
1064 HDC hdc;
1065 RECT rect,rectClip,rfuzz;
1066
1067 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1068 the call to GetDCEx implying that it is allowed not to use it either.
1069 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1070 will cause clipRgn to be deleted after ReleaseDC().
1071 Now, how is the "system" supposed to tell what happened?
1072 */
1073
1074 dprintf(("DoNCPaint %x %x %d", getWindowHandle(), clip, suppress_menupaint));
1075
1076 if ( (getStyle() & WS_MINIMIZE) ||
1077 !IsWindowVisible( getWindowHandle() )) {
1078 return; /* Nothing to do */
1079 }
1080
1081 rect.top = rect.left = 0;
1082 rect.right = rectWindow.right - rectWindow.left;
1083 rect.bottom = rectWindow.bottom - rectWindow.top;
1084
1085 if (clip > 1)
1086 {
1087 //only redraw caption
1088 GetRgnBox(clip,&rectClip);
1089#if 1
1090 //SvL: I'm getting paint problems when clipping a dc created in GetDCEx
1091 // with a region that covers the entire window (RealPlayer 7 Update 1)
1092 // As we don't need to clip anything when that occurs, this workaround
1093 // solves the problem.
1094 if(rectClip.right == getWindowWidth() && rectClip.bottom == getWindowHeight())
1095 {
1096 clip = 0;
1097 rectClip = rect;
1098 }
1099#endif
1100 }
1101 else
1102 {
1103 clip = 0;
1104 rectClip = rect;
1105 }
1106
1107 if (!(hdc = GetDCEx( Win32Hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1108 ((clip > 1) ?(DCX_INTERSECTRGN /*| DCX_KEEPCLIPRGN*/) : 0) ))) return;
1109
1110 DecreaseLogCount();
1111 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1112
1113 if (HAS_BIGFRAME( dwStyle, dwExStyle))
1114 {
1115 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1116 }
1117 if (HAS_THICKFRAME( dwStyle, dwExStyle ))
1118 DrawFrame(hdc, &rect, FALSE, active );
1119 else
1120 if (HAS_DLGFRAME( dwStyle, dwExStyle ))
1121 DrawFrame( hdc, &rect, TRUE, active );
1122 else
1123 if (HAS_THINFRAME( dwStyle ))
1124 {
1125 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1126 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1127 }
1128
1129 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
1130 {
1131 RECT r = rect;
1132 if (dwExStyle & WS_EX_TOOLWINDOW)
1133 {
1134 r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
1135 rect.top += GetSystemMetrics(SM_CYSMCAPTION);
1136 }
1137 else
1138 {
1139 r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
1140 rect.top += GetSystemMetrics(SM_CYCAPTION);
1141 }
1142 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
1143 DrawCaption(hdc,&r,active);
1144 }
1145
1146 if (HAS_MENU())
1147 {
1148 RECT r = rect;
1149 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
1150
1151 rect.top += MENU_DrawMenuBar(hdc,&r,Win32Hwnd,suppress_menupaint)+1;
1152 }
1153
1154 if (dwExStyle & WS_EX_CLIENTEDGE)
1155 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1156
1157 if (dwExStyle & WS_EX_STATICEDGE)
1158 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1159
1160 /* Draw the scroll-bars */
1161 if (dwStyle & WS_VSCROLL)
1162 SCROLL_DrawScrollBar(Win32Hwnd,hdc,SB_VERT,TRUE,TRUE);
1163 if (dwStyle & WS_HSCROLL)
1164 SCROLL_DrawScrollBar(Win32Hwnd,hdc,SB_HORZ,TRUE,TRUE);
1165
1166 /* Draw the "size-box" */
1167 if ((dwStyle & WS_VSCROLL) && (dwStyle & WS_HSCROLL))
1168 {
1169 RECT r = rect;
1170 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1171 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1172 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1173 //CB: todo: child windows have sometimes a size grip (i.e. Notepad)
1174 // WS_SIZEBOX isn't set in these cases
1175 if (!(dwStyle & WS_CHILD))
1176 {
1177 POINT p1,p2;
1178 HPEN penDark = GetSysColorPen(COLOR_3DSHADOW);
1179 HPEN penWhite = GetSysColorPen(COLOR_3DHILIGHT);
1180 HPEN oldPen = SelectObject(hdc,penDark);
1181 INT x;
1182
1183 p1.x = r.right-1;
1184 p1.y = r.bottom;
1185 p2.x = r.right;
1186 p2.y = r.bottom-1;
1187 for (x = 0;x < 3;x++)
1188 {
1189 SelectObject(hdc,penDark);
1190 MoveToEx(hdc,p1.x,p1.y,NULL);
1191 LineTo(hdc,p2.x,p2.y);
1192 p1.x--;
1193 p2.y--;
1194 MoveToEx(hdc,p1.x,p1.y,NULL);
1195 LineTo(hdc,p2.x,p2.y);
1196 SelectObject(hdc,penWhite);
1197 p1.x--;
1198 p2.y--;
1199 MoveToEx(hdc,p1.x,p1.y,NULL);
1200 LineTo(hdc,p2.x,p2.y);
1201 p1.x -= 2;
1202 p2.y -= 2;
1203 }
1204
1205 SelectObject(hdc,oldPen);
1206 }
1207 }
1208
1209 IncreaseLogCount();
1210 ReleaseDC(getWindowHandle(),hdc);
1211 dprintf(("**DoNCPaint %x DONE", getWindowHandle()));
1212}
1213//******************************************************************************
1214//******************************************************************************
1215LONG Win32BaseWindow::HandleNCPaint(HRGN clip)
1216{
1217//CB: ignore it for now (SetWindowPos in WM_CREATE)
1218// if (!(dwStyle & WS_VISIBLE)) return 0;
1219
1220 if (dwStyle & WS_MINIMIZE) return 0;
1221
1222 DoNCPaint(clip,FALSE);
1223
1224 return 0;
1225}
1226/***********************************************************************
1227 * NC_HandleNCLButtonDblClk
1228 *
1229 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
1230 */
1231LONG Win32BaseWindow::HandleNCLButtonDblClk(WPARAM wParam,LPARAM lParam)
1232{
1233 /*
1234 * if this is an icon, send a restore since we are handling
1235 * a double click
1236 */
1237 if (dwStyle & WS_MINIMIZE)
1238 {
1239 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_RESTORE,lParam);
1240 return 0;
1241 }
1242
1243 switch(wParam) /* Hit test */
1244 {
1245 case HTCAPTION:
1246 /* stop processing if WS_MAXIMIZEBOX is missing */
1247 if (dwStyle & WS_MAXIMIZEBOX)
1248 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,
1249 (dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
1250 lParam);
1251 break;
1252
1253 case HTSYSMENU:
1254 if (!(GetClassLongA(getWindowHandle(),GCL_STYLE) & CS_NOCLOSE))
1255 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_CLOSE,lParam);
1256 break;
1257
1258 case HTHSCROLL:
1259 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_HSCROLL+HTHSCROLL,lParam);
1260 break;
1261
1262 case HTVSCROLL:
1263 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_VSCROLL+HTVSCROLL,lParam);
1264 break;
1265 }
1266
1267 return 0;
1268}
1269//******************************************************************************
1270//******************************************************************************
1271LONG Win32BaseWindow::HandleNCRButtonUp(WPARAM wParam,LPARAM lParam)
1272{
1273 switch(wParam)
1274 {
1275 case HTCAPTION:
1276 //we receive a HTCAPTION rbuttonup for RMB clicks on icon of minimized mdi windows
1277 if (fOS2Look && ((dwStyle & (WS_SYSMENU | WS_MINIMIZE)) == (WS_SYSMENU | WS_MINIMIZE)) )
1278 {
1279 return HandleNCRButtonUp(HTSYSMENU, lParam);
1280 }
1281
1282 if (GetActiveWindow() != Win32Hwnd)
1283 SetActiveWindow();
1284
1285 if (((GetActiveWindow() == Win32Hwnd) || isMDIChild()) && (dwStyle & WS_SYSMENU))
1286 {
1287 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_MOUSEMENU+HTCAPTION,lParam);
1288 }
1289 break;
1290
1291 case HTSYSMENU:
1292 if (fOS2Look && (dwStyle & WS_SYSMENU))
1293 {
1294 if (fOS2Look == OS2_APPEARANCE)
1295 SendMessageA( getWindowHandle(), WM_SYSCOMMAND,SC_MOUSEMENU+HTSYSMENU,lParam);
1296 else
1297 if (fOS2Look == OS2_APPEARANCE_SYSMENU)
1298 OSLibPostMessageDirect( getOS2FrameWindowHandle(), OSWM_SYSCOMMAND, OSSC_SYSMENU,0);
1299 }
1300 break;
1301
1302 default:
1303 break;
1304 }
1305
1306 return 0;
1307}
1308/***********************************************************************
1309 * NC_HandleSysCommand
1310 *
1311 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
1312 *
1313 */
1314LONG Win32BaseWindow::HandleSysCommand(WPARAM wParam,POINT *pt32)
1315{
1316 UINT uCommand = wParam & 0xFFF0;
1317
1318 switch (uCommand)
1319 {
1320 case SC_SIZE:
1321 {
1322 Frame_SysCommandSizeMove(this, wParam);
1323 break;
1324 }
1325
1326 case SC_MOVE:
1327 Frame_SysCommandSizeMove(this, wParam);
1328 break;
1329
1330 case SC_MINIMIZE:
1331 if(dwStyle & WS_MINIMIZEBOX)
1332 ShowWindow(SW_MINIMIZE);
1333 break;
1334
1335 case SC_MAXIMIZE:
1336 if(dwStyle & WS_MAXIMIZEBOX)
1337 if (fOS2Look && (getOldStyle() & WS_MINIMIZE))
1338 {
1339 //PF Yes this is bad we do things twice - first restore window
1340 //from iconic state and then quickly maximize. What is good is that
1341 //only frame rects are recalculated twice. I checked lots of other
1342 //ways - seems only this one is 100% bug-safe. This happens on every
1343 //minimize from icon to maximum routine so not so often at all.
1344 OSLibWinRestoreWindow(getOS2FrameWindowHandle());
1345 }
1346 ShowWindow(SW_MAXIMIZE);
1347 break;
1348
1349 case SC_RESTORE:
1350
1351 //PF Start PM restoration routine first if we restore from icon
1352 //so all internal PM logic will work - this routine will always
1353 //lead to ShowWindow(SW_RESTORE)
1354
1355 if (getOldStyle() & WS_MINIMIZE)
1356 OSLibWinRestoreWindow(getOS2FrameWindowHandle());
1357 else
1358 ShowWindow(SW_RESTORE);
1359 break;
1360
1361 case SC_CLOSE:
1362 return SendMessageA(getWindowHandle(), WM_CLOSE,0,0);
1363
1364 case SC_CONTEXTHELP:
1365 {
1366 //CB: todo
1367 break;
1368 }
1369
1370 case SC_VSCROLL:
1371 case SC_HSCROLL:
1372 TrackScrollBar(wParam,*pt32);
1373 break;
1374
1375 case SC_MOUSEMENU:
1376 MENU_TrackMouseMenuBar(Win32Hwnd,wParam & 0x000F,*pt32);
1377 break;
1378
1379 case SC_KEYMENU:
1380 MENU_TrackKbdMenuBar(Win32Hwnd,wParam,pt32->x);
1381 break;
1382
1383 case SC_TASKLIST:
1384 OSLibWinShowTaskList(getOS2WindowHandle());
1385 break;
1386
1387 case SC_SCREENSAVE:
1388 if (wParam == SC_ABOUTODIN) {
1389 if(ShellAboutA == 0) {
1390 HINSTANCE hShell32 = LoadLibraryA("SHELL32");
1391 if(hShell32 == 0)
1392 break;
1393 *(VOID **)&ShellAboutA = (VOID *)GetProcAddress(hShell32, "ShellAboutA");
1394 }
1395 ShellAboutA(Win32Hwnd,"Odin","Odin alpha release compiled with IBM VAC++",0);
1396 }
1397#ifdef DEBUG
1398 //SvL: Do NOT turn this into a dprintf.
1399 else
1400 if (wParam == SC_PUTMARK)
1401 WriteLog(("Mark requested by user\n"));
1402 else
1403 if (wParam == SC_DEBUGINT3)
1404 DebugInt3();
1405#endif
1406 break;
1407
1408 case SC_HOTKEY:
1409 case SC_ARRANGE:
1410 case SC_NEXTWINDOW:
1411 case SC_PREVWINDOW:
1412 break;
1413 }
1414 return 0;
1415}
1416/*****************************************************************************
1417 * Name : VOID WIN32API DrawCaption
1418 * Purpose : The DrawCaption function draws a window caption.
1419 * Parameters: HDC hdc handle of device context
1420 * LPRECT lprc address of bounding rectangle coordinates
1421 * HFONT hfont handle of font for caption
1422 * HICON hicon handle of icon in caption
1423 * LPSTR lpszText address of caption string
1424 * WORD wFlags drawing options
1425 * Variables :
1426 * Result :
1427 * Remark :
1428 * Status : UNTESTED STUB
1429 *
1430 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1431 *****************************************************************************/
1432BOOL WIN32API DrawCaption (HWND hwnd,HDC hdc,const RECT *lprc,UINT wFlags)
1433{
1434 dprintf(("USER32: DrawCaption"));
1435
1436 return DrawCaptionTempA(hwnd,hdc,lprc,0,0,NULL,wFlags & 0x1F);
1437}
1438//******************************************************************************
1439// CB: this code is a subset of Win32BaseWindow::DrawCaption
1440// todo: move Win32BaseWindow:DrawCaption to this function
1441//******************************************************************************
1442BOOL WIN32API DrawCaptionTemp(HWND hwnd,HDC hdc,const RECT *rect,HFONT hFont,HICON hIcon,LPWSTR str,UINT uFlags,BOOL unicode)
1443{
1444 RECT rc = *rect;
1445
1446 /* drawing background */
1447 if (uFlags & DC_INBUTTON)
1448 {
1449 FillRect (hdc, &rc, GetSysColorBrush (COLOR_3DFACE));
1450
1451 if (uFlags & DC_ACTIVE)
1452 {
1453 HBRUSH hbr = SelectObject (hdc, GetPattern55AABrush ());
1454 PatBlt (hdc, rc.left, rc.top,
1455 rc.right-rc.left, rc.bottom-rc.top, 0xFA0089);
1456 SelectObject (hdc, hbr);
1457 }
1458 } else
1459 {
1460 FillRect (hdc, &rc, GetSysColorBrush ((uFlags & DC_ACTIVE) ?
1461 COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
1462 }
1463
1464 /* drawing icon */
1465 if ((uFlags & DC_ICON) && !(uFlags & DC_SMALLCAP))
1466 {
1467 POINT pt;
1468
1469 pt.x = rc.left + 2;
1470 pt.y = (rc.bottom + rc.top - GetSystemMetrics(SM_CYSMICON)) / 2;
1471
1472 if (hIcon)
1473 {
1474 DrawIconEx (hdc, pt.x, pt.y, hIcon, GetSystemMetrics(SM_CXSMICON),
1475 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
1476 } else
1477 {
1478 Win32BaseWindow *win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
1479
1480 if (!win32wnd) return 0;
1481
1482 DrawIconEx (hdc, pt.x, pt.y, win32wnd->IconForWindow(ICON_SMALL),
1483 GetSystemMetrics(SM_CXSMICON),
1484 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
1485 }
1486
1487 rc.left += (rc.bottom - rc.top);
1488 }
1489
1490 /* drawing text */
1491 if (uFlags & DC_TEXT)
1492 {
1493 HFONT hOldFont;
1494
1495 if (uFlags & DC_INBUTTON)
1496 SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
1497 else if (uFlags & DC_ACTIVE)
1498 SetTextColor (hdc, GetSysColor (COLOR_CAPTIONTEXT));
1499 else
1500 SetTextColor (hdc, GetSysColor (COLOR_INACTIVECAPTIONTEXT));
1501
1502 SetBkMode (hdc, TRANSPARENT);
1503
1504 if (hFont)
1505 hOldFont = SelectObject (hdc, hFont);
1506 else
1507 {
1508 NONCLIENTMETRICSA nclm;
1509 HFONT hNewFont;
1510
1511 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1512 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1513 hNewFont = CreateFontIndirectA ((uFlags & DC_SMALLCAP) ?
1514 &nclm.lfSmCaptionFont : &nclm.lfCaptionFont);
1515 hOldFont = SelectObject (hdc, hNewFont);
1516 }
1517
1518 if (str)
1519 {
1520 if (unicode)
1521 DrawTextW(hdc,str,-1,&rc,DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
1522 else
1523 DrawTextA(hdc,(LPSTR)str,-1,&rc,DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
1524 } else
1525 {
1526 CHAR szText[128];
1527 INT nLen;
1528
1529 nLen = GetWindowTextA (hwnd, szText, 128);
1530 DrawTextA (hdc, szText, nLen, &rc,
1531 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
1532 }
1533
1534 if (hFont)
1535 SelectObject (hdc, hOldFont);
1536 else
1537 DeleteObject (SelectObject (hdc, hOldFont));
1538 }
1539
1540 /* drawing focus ??? */
1541 //if (uFlags & 0x2000)
1542 // FIXME("undocumented flag (0x2000)!\n");
1543
1544 return 0;
1545}
1546/***********************************************************************
1547 * DrawCaptionTemp32A [USER32.599]
1548 *
1549 * PARAMS
1550 *
1551 * RETURNS
1552 * Success:
1553 * Failure:
1554 */
1555BOOL WIN32API DrawCaptionTempA(HWND hwnd,HDC hdc,const RECT *rect,HFONT hFont,HICON hIcon,LPCSTR str,UINT uFlags)
1556{
1557 dprintf(("USER32: DrawCaptionTempA"));
1558
1559 return DrawCaptionTemp(hwnd,hdc,rect,hFont,hIcon,(LPWSTR)str,uFlags,FALSE);
1560}
1561/***********************************************************************
1562 * DrawCaptionTemp32W [USER32.602]
1563 *
1564 * PARAMS
1565 *
1566 * RETURNS
1567 * Success:
1568 * Failure:
1569 */
1570BOOL WIN32API DrawCaptionTempW (HWND hwnd,HDC hdc,const RECT *rect,HFONT hFont,HICON hIcon,LPCWSTR str,UINT uFlags)
1571{
1572 dprintf(("USER32: DrawCaptionTempA"));
1573
1574 return DrawCaptionTemp(hwnd,hdc,rect,hFont,hIcon,(LPWSTR)str,uFlags,TRUE);
1575}
1576
Note: See TracBrowser for help on using the repository browser.