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

Last change on this file since 9563 was 9563, checked in by sandervl, 23 years ago

Fix for painting a completely ownerdrawn menu (owner window was wrong); don't do anything in DoNCPaint if window is invisible

File size: 48.3 KB
Line 
1/* $Id: win32wbasenonclient.cpp,v 1.45 2002-12-29 17:17:16 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//// OSLibWinSetFocus(topparent->getOS2WindowHandle());
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 if(fOS2Look) {
909 if ((dwStyle & WS_SYSMENU) && !(dwExStyle & WS_EX_TOOLWINDOW) &&
910 fOS2Look != OS2_APPEARANCE_SYSMENU)
911 {
912 HICON hSysIcon = IconForWindow(ICON_SMALL);
913
914 if (hSysIcon) {
915 int size = GetSystemMetrics(SM_CYCAPTION);
916
917 r2 = r;
918 r2.right = r2.left + size;
919 r2.bottom = r2.top + size;
920 FillRect(hdc, &r2, GetSysColorBrush(COLOR_MENU));
921
922 DrawSysButton(hdc,&r);
923 }
924 }
925 return;
926 }
927
928 memDC = CreateCompatibleDC(hdc);
929 r.right -= r.left;
930 r.bottom -= r.top;
931 r.left = r.top = 0;
932 r2 = r;
933 memBmp = CreateCompatibleBitmap(hdc,r.right,r.bottom);
934 oldBmp = SelectObject(memDC,memBmp);
935
936 hPrevPen = SelectObject(memDC,GetSysColorPen(COLOR_3DFACE));
937 MoveToEx(memDC,r.left,r.bottom-1,NULL);
938 LineTo(memDC,r.right,r.bottom-1);
939 SelectObject(memDC,hPrevPen);
940 r.bottom--;
941
942 if (SYSCOLOR_GetUseWinColors())
943 {
944 COLORREF startColor = GetSysColor(active ? COLOR_ACTIVECAPTION:COLOR_INACTIVECAPTION),endColor = GetSysColor(active ? COLOR_GRADIENTACTIVECAPTION:COLOR_GRADIENTINACTIVECAPTION);
945
946 if (startColor == endColor)
947 FillRect(memDC,&r,GetSysColorBrush(startColor));
948 else
949 {
950 INT rDiff = GetRValue(endColor)-GetRValue(startColor);
951 INT gDiff = GetGValue(endColor)-GetGValue(startColor);
952 INT bDiff = GetBValue(endColor)-GetBValue(startColor);
953 INT steps = MAX(MAX(abs(rDiff),abs(gDiff)),abs(bDiff));
954 INT w = r.right-r.left;
955 RECT r2;
956
957 if (w < steps) steps = w;
958 r2.left = r2.right = r.left;
959 r2.top = r.top;
960 r2.bottom = r.bottom;
961 for (INT x = 0;x <= steps;x++)
962 {
963 COLORREF color = RGB(GetRValue(startColor)+rDiff*x/steps,GetGValue(startColor)+gDiff*x/steps,GetBValue(startColor)+bDiff*x/steps);
964 HBRUSH brush = CreateSolidBrush(color);
965
966 r2.left = r2.right;
967 r2.right = r.left+w*x/steps;
968 FillRect(memDC,&r2,brush);
969 DeleteObject(brush);
970 }
971 }
972 } else FillRect(memDC,&r,GetSysColorBrush(active ? COLOR_ACTIVECAPTION:COLOR_INACTIVECAPTION));
973
974 if (!hbitmapClose)
975 {
976 if (!(hbitmapClose = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CLOSE)))) return;
977 hbitmapCloseD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CLOSED));
978 hbitmapMinimize = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_REDUCE));
979 hbitmapMinimizeD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_REDUCED));
980 hbitmapMaximize = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_ZOOM));
981 hbitmapMaximizeD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_ZOOMD));
982 hbitmapRestore = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_RESTORE));
983 hbitmapRestoreD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_RESTORED));
984 hbitmapContextHelp = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CONTEXTHELP));
985 hbitmapContextHelpD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CONTEXTHELPD));
986 }
987
988 if ((dwStyle & WS_SYSMENU) && !(dwExStyle & WS_EX_TOOLWINDOW))
989 {
990 if (DrawSysButton(memDC,&r))
991 r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
992 }
993
994 if (dwStyle & WS_SYSMENU)
995 {
996 UINT state;
997
998 /* Go get the sysmenu */
999 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
1000
1001 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1002 DrawCloseButton(memDC,&r2,FALSE,
1003 ((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
1004 r.right -= GetSystemMetrics(SM_CYCAPTION)-1;
1005
1006 if (dwExStyle & WS_EX_CONTEXTHELP)
1007 {
1008 DrawContextHelpButton(memDC,&r2,FALSE,FALSE);
1009 r.right -= GetSystemMetrics(SM_CXSIZE)+1;
1010 }
1011
1012 if ((dwStyle & WS_MAXIMIZEBOX) || (dwStyle & WS_MINIMIZEBOX))
1013 {
1014 /* In win95 the two buttons are always there */
1015 /* But if the menu item is not in the menu they're disabled*/
1016
1017 DrawMaxButton(memDC,&r2,FALSE,(!(dwStyle & WS_MAXIMIZEBOX)));
1018 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1019
1020 DrawMinButton(memDC,&r2,FALSE, (!(dwStyle & WS_MINIMIZEBOX)));
1021 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1022 }
1023 }
1024
1025 if (GetWindowTextA(buffer, sizeof(buffer) ))
1026 {
1027 NONCLIENTMETRICSA nclm;
1028 HFONT hFont, hOldFont;
1029
1030 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1031 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1032 if (dwExStyle & WS_EX_TOOLWINDOW)
1033 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
1034 else
1035 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
1036 hOldFont = SelectObject (memDC, hFont);
1037 SetTextColor(memDC,GetSysColor(active ? COLOR_CAPTIONTEXT:COLOR_INACTIVECAPTIONTEXT));
1038 SetBkMode(memDC, TRANSPARENT );
1039 r.left += 2;
1040 DrawTextExA(memDC,buffer,-1,&r,DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT | DT_END_ELLIPSIS,NULL);
1041 DeleteObject (SelectObject (memDC, hOldFont));
1042 IncreaseLogCount();
1043 dprintf(("DrawCaption %s %d", buffer, active));
1044 DecreaseLogCount();
1045 }
1046
1047 BitBlt(hdc,rect->left,rect->top,rect->right-rect->left,rect->bottom-rect->top,memDC,0,0,SRCCOPY);
1048 SelectObject(memDC,oldBmp);
1049 DeleteObject(memBmp);
1050 DeleteDC(memDC);
1051}
1052//******************************************************************************
1053//******************************************************************************
1054VOID Win32BaseWindow::DoNCPaint(HRGN clip,BOOL suppress_menupaint)
1055{
1056 BOOL active = flags & WIN_NCACTIVATED;
1057 HDC hdc;
1058 RECT rect,rectClip,rfuzz;
1059
1060 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1061 the call to GetDCEx implying that it is allowed not to use it either.
1062 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1063 will cause clipRgn to be deleted after ReleaseDC().
1064 Now, how is the "system" supposed to tell what happened?
1065 */
1066
1067 dprintf(("DoNCPaint %x %x %d", getWindowHandle(), clip, suppress_menupaint));
1068
1069 if ( getStyle() & WS_MINIMIZE ||
1070 !IsWindowVisible( getWindowHandle() )) {
1071 return; /* Nothing to do */
1072 }
1073
1074 rect.top = rect.left = 0;
1075 rect.right = rectWindow.right - rectWindow.left;
1076 rect.bottom = rectWindow.bottom - rectWindow.top;
1077
1078 if (clip > 1)
1079 {
1080 //only redraw caption
1081 GetRgnBox(clip,&rectClip);
1082#if 1
1083 //SvL: I'm getting paint problems when clipping a dc created in GetDCEx
1084 // with a region that covers the entire window (RealPlayer 7 Update 1)
1085 // As we don't need to clip anything when that occurs, this workaround
1086 // solves the problem.
1087 if(rectClip.right == getWindowWidth() && rectClip.bottom == getWindowHeight())
1088 {
1089 clip = 0;
1090 rectClip = rect;
1091 }
1092#endif
1093 }
1094 else
1095 {
1096 clip = 0;
1097 rectClip = rect;
1098 }
1099
1100 if (!(hdc = GetDCEx( Win32Hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1101 ((clip > 1) ?(DCX_INTERSECTRGN /*| DCX_KEEPCLIPRGN*/) : 0) ))) return;
1102
1103 DecreaseLogCount();
1104 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1105
1106 if (HAS_BIGFRAME( dwStyle, dwExStyle))
1107 {
1108 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1109 }
1110 if (HAS_THICKFRAME( dwStyle, dwExStyle ))
1111 DrawFrame(hdc, &rect, FALSE, active );
1112 else
1113 if (HAS_DLGFRAME( dwStyle, dwExStyle ))
1114 DrawFrame( hdc, &rect, TRUE, active );
1115 else
1116 if (HAS_THINFRAME( dwStyle ))
1117 {
1118 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1119 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1120 }
1121
1122 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
1123 {
1124 RECT r = rect;
1125 if (dwExStyle & WS_EX_TOOLWINDOW)
1126 {
1127 r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
1128 rect.top += GetSystemMetrics(SM_CYSMCAPTION);
1129 }
1130 else
1131 {
1132 r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
1133 rect.top += GetSystemMetrics(SM_CYCAPTION);
1134 }
1135 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
1136 DrawCaption(hdc,&r,active);
1137 }
1138
1139 if (HAS_MENU())
1140 {
1141 RECT r = rect;
1142 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
1143
1144 rect.top += MENU_DrawMenuBar(hdc,&r,Win32Hwnd,suppress_menupaint)+1;
1145 }
1146
1147 if (dwExStyle & WS_EX_CLIENTEDGE)
1148 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1149
1150 if (dwExStyle & WS_EX_STATICEDGE)
1151 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1152
1153 /* Draw the scroll-bars */
1154 if (dwStyle & WS_VSCROLL)
1155 SCROLL_DrawScrollBar(Win32Hwnd,hdc,SB_VERT,TRUE,TRUE);
1156 if (dwStyle & WS_HSCROLL)
1157 SCROLL_DrawScrollBar(Win32Hwnd,hdc,SB_HORZ,TRUE,TRUE);
1158
1159 /* Draw the "size-box" */
1160 if ((dwStyle & WS_VSCROLL) && (dwStyle & WS_HSCROLL))
1161 {
1162 RECT r = rect;
1163 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1164 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1165 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1166 //CB: todo: child windows have sometimes a size grip (i.e. Notepad)
1167 // WS_SIZEBOX isn't set in these cases
1168 if (!(dwStyle & WS_CHILD))
1169 {
1170 POINT p1,p2;
1171 HPEN penDark = GetSysColorPen(COLOR_3DSHADOW);
1172 HPEN penWhite = GetSysColorPen(COLOR_3DHILIGHT);
1173 HPEN oldPen = SelectObject(hdc,penDark);
1174 INT x;
1175
1176 p1.x = r.right-1;
1177 p1.y = r.bottom;
1178 p2.x = r.right;
1179 p2.y = r.bottom-1;
1180 for (x = 0;x < 3;x++)
1181 {
1182 SelectObject(hdc,penDark);
1183 MoveToEx(hdc,p1.x,p1.y,NULL);
1184 LineTo(hdc,p2.x,p2.y);
1185 p1.x--;
1186 p2.y--;
1187 MoveToEx(hdc,p1.x,p1.y,NULL);
1188 LineTo(hdc,p2.x,p2.y);
1189 SelectObject(hdc,penWhite);
1190 p1.x--;
1191 p2.y--;
1192 MoveToEx(hdc,p1.x,p1.y,NULL);
1193 LineTo(hdc,p2.x,p2.y);
1194 p1.x -= 2;
1195 p2.y -= 2;
1196 }
1197
1198 SelectObject(hdc,oldPen);
1199 }
1200 }
1201
1202 IncreaseLogCount();
1203 ReleaseDC(getWindowHandle(),hdc);
1204 dprintf(("**DoNCPaint %x DONE", getWindowHandle()));
1205}
1206//******************************************************************************
1207//******************************************************************************
1208LONG Win32BaseWindow::HandleNCPaint(HRGN clip)
1209{
1210//CB: ignore it for now (SetWindowPos in WM_CREATE)
1211// if (!(dwStyle & WS_VISIBLE)) return 0;
1212
1213 if (dwStyle & WS_MINIMIZE) return 0;
1214
1215 DoNCPaint(clip,FALSE);
1216
1217 return 0;
1218}
1219/***********************************************************************
1220 * NC_HandleNCLButtonDblClk
1221 *
1222 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
1223 */
1224LONG Win32BaseWindow::HandleNCLButtonDblClk(WPARAM wParam,LPARAM lParam)
1225{
1226 /*
1227 * if this is an icon, send a restore since we are handling
1228 * a double click
1229 */
1230 if (dwStyle & WS_MINIMIZE)
1231 {
1232 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_RESTORE,lParam);
1233 return 0;
1234 }
1235
1236 switch(wParam) /* Hit test */
1237 {
1238 case HTCAPTION:
1239 /* stop processing if WS_MAXIMIZEBOX is missing */
1240 if (dwStyle & WS_MAXIMIZEBOX)
1241 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,
1242 (dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
1243 lParam);
1244 break;
1245
1246 case HTSYSMENU:
1247 if (!(GetClassLongA(getWindowHandle(),GCL_STYLE) & CS_NOCLOSE))
1248 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_CLOSE,lParam);
1249 break;
1250
1251 case HTHSCROLL:
1252 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_HSCROLL+HTHSCROLL,lParam);
1253 break;
1254
1255 case HTVSCROLL:
1256 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_VSCROLL+HTVSCROLL,lParam);
1257 break;
1258 }
1259
1260 return 0;
1261}
1262//******************************************************************************
1263//******************************************************************************
1264LONG Win32BaseWindow::HandleNCRButtonUp(WPARAM wParam,LPARAM lParam)
1265{
1266 switch(wParam)
1267 {
1268 case HTCAPTION:
1269 //we receive a HTCAPTION rbuttonup for RMB clicks on icon of minimized mdi windows
1270 if (fOS2Look && ((dwStyle & (WS_SYSMENU | WS_MINIMIZE)) == (WS_SYSMENU | WS_MINIMIZE)) )
1271 {
1272 return HandleNCRButtonUp(HTSYSMENU, lParam);
1273 }
1274
1275 if (GetActiveWindow() != Win32Hwnd)
1276 SetActiveWindow();
1277
1278 if (((GetActiveWindow() == Win32Hwnd) || isMDIChild()) && (dwStyle & WS_SYSMENU))
1279 {
1280 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_MOUSEMENU+HTCAPTION,lParam);
1281 }
1282 break;
1283
1284 case HTSYSMENU:
1285 if (fOS2Look && (dwStyle & WS_SYSMENU))
1286 {
1287 if (fOS2Look == OS2_APPEARANCE)
1288 SendMessageA( getWindowHandle(), WM_SYSCOMMAND,SC_MOUSEMENU+HTSYSMENU,lParam);
1289 else
1290 if (fOS2Look == OS2_APPEARANCE_SYSMENU)
1291 OSLibPostMessageDirect( getOS2FrameWindowHandle(), OSWM_SYSCOMMAND, OSSC_SYSMENU,0);
1292 }
1293 break;
1294
1295 default:
1296 break;
1297 }
1298
1299 return 0;
1300}
1301/***********************************************************************
1302 * NC_HandleSysCommand
1303 *
1304 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
1305 *
1306 */
1307LONG Win32BaseWindow::HandleSysCommand(WPARAM wParam,POINT *pt32)
1308{
1309 UINT uCommand = wParam & 0xFFF0;
1310
1311 switch (uCommand)
1312 {
1313 case SC_SIZE:
1314 {
1315 Frame_SysCommandSizeMove(this, wParam);
1316 break;
1317 }
1318
1319 case SC_MOVE:
1320 Frame_SysCommandSizeMove(this, wParam);
1321 break;
1322
1323 case SC_MINIMIZE:
1324 if(dwStyle & WS_MINIMIZEBOX)
1325 ShowWindow(SW_MINIMIZE);
1326 break;
1327
1328 case SC_MAXIMIZE:
1329 if(dwStyle & WS_MAXIMIZEBOX)
1330 ShowWindow(SW_MAXIMIZE);
1331 break;
1332
1333 case SC_RESTORE:
1334 ShowWindow(SW_RESTORE);
1335 break;
1336
1337 case SC_CLOSE:
1338 return SendMessageA(getWindowHandle(), WM_CLOSE,0,0);
1339
1340 case SC_CONTEXTHELP:
1341 {
1342 //CB: todo
1343 break;
1344 }
1345
1346 case SC_VSCROLL:
1347 case SC_HSCROLL:
1348 TrackScrollBar(wParam,*pt32);
1349 break;
1350
1351 case SC_MOUSEMENU:
1352 MENU_TrackMouseMenuBar(Win32Hwnd,wParam & 0x000F,*pt32);
1353 break;
1354
1355 case SC_KEYMENU:
1356 MENU_TrackKbdMenuBar(Win32Hwnd,wParam,pt32->x);
1357 break;
1358
1359 case SC_TASKLIST:
1360 OSLibWinShowTaskList(getOS2WindowHandle());
1361 break;
1362
1363 case SC_SCREENSAVE:
1364 if (wParam == SC_ABOUTODIN) {
1365 if(ShellAboutA == 0) {
1366 HINSTANCE hShell32 = LoadLibraryA("SHELL32");
1367 if(hShell32 == 0)
1368 break;
1369 *(VOID **)&ShellAboutA = (VOID *)GetProcAddress(hShell32, "ShellAboutA");
1370 }
1371 ShellAboutA(Win32Hwnd,"Odin","Odin alpha release compiled with IBM VAC++",0);
1372 }
1373#ifdef DEBUG
1374 //SvL: Do NOT turn this into a dprintf.
1375 else
1376 if (wParam == SC_PUTMARK)
1377 WriteLog(("Mark requested by user\n"));
1378 else
1379 if (wParam == SC_DEBUGINT3)
1380 DebugInt3();
1381#endif
1382 break;
1383
1384 case SC_HOTKEY:
1385 case SC_ARRANGE:
1386 case SC_NEXTWINDOW:
1387 case SC_PREVWINDOW:
1388 break;
1389 }
1390 return 0;
1391}
1392/*****************************************************************************
1393 * Name : VOID WIN32API DrawCaption
1394 * Purpose : The DrawCaption function draws a window caption.
1395 * Parameters: HDC hdc handle of device context
1396 * LPRECT lprc address of bounding rectangle coordinates
1397 * HFONT hfont handle of font for caption
1398 * HICON hicon handle of icon in caption
1399 * LPSTR lpszText address of caption string
1400 * WORD wFlags drawing options
1401 * Variables :
1402 * Result :
1403 * Remark :
1404 * Status : UNTESTED STUB
1405 *
1406 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1407 *****************************************************************************/
1408BOOL WIN32API DrawCaption (HWND hwnd,HDC hdc,const RECT *lprc,UINT wFlags)
1409{
1410 dprintf(("USER32: DrawCaption"));
1411
1412 return DrawCaptionTempA(hwnd,hdc,lprc,0,0,NULL,wFlags & 0x1F);
1413}
1414//******************************************************************************
1415// CB: this code is a subset of Win32BaseWindow::DrawCaption
1416// todo: move Win32BaseWindow:DrawCaption to this function
1417//******************************************************************************
1418BOOL WIN32API DrawCaptionTemp(HWND hwnd,HDC hdc,const RECT *rect,HFONT hFont,HICON hIcon,LPWSTR str,UINT uFlags,BOOL unicode)
1419{
1420 RECT rc = *rect;
1421
1422 /* drawing background */
1423 if (uFlags & DC_INBUTTON)
1424 {
1425 FillRect (hdc, &rc, GetSysColorBrush (COLOR_3DFACE));
1426
1427 if (uFlags & DC_ACTIVE)
1428 {
1429 HBRUSH hbr = SelectObject (hdc, GetPattern55AABrush ());
1430 PatBlt (hdc, rc.left, rc.top,
1431 rc.right-rc.left, rc.bottom-rc.top, 0xFA0089);
1432 SelectObject (hdc, hbr);
1433 }
1434 } else
1435 {
1436 FillRect (hdc, &rc, GetSysColorBrush ((uFlags & DC_ACTIVE) ?
1437 COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
1438 }
1439
1440 /* drawing icon */
1441 if ((uFlags & DC_ICON) && !(uFlags & DC_SMALLCAP))
1442 {
1443 POINT pt;
1444
1445 pt.x = rc.left + 2;
1446 pt.y = (rc.bottom + rc.top - GetSystemMetrics(SM_CYSMICON)) / 2;
1447
1448 if (hIcon)
1449 {
1450 DrawIconEx (hdc, pt.x, pt.y, hIcon, GetSystemMetrics(SM_CXSMICON),
1451 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
1452 } else
1453 {
1454 Win32BaseWindow *win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
1455
1456 if (!win32wnd) return 0;
1457
1458 DrawIconEx (hdc, pt.x, pt.y, win32wnd->IconForWindow(ICON_SMALL),
1459 GetSystemMetrics(SM_CXSMICON),
1460 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
1461 }
1462
1463 rc.left += (rc.bottom - rc.top);
1464 }
1465
1466 /* drawing text */
1467 if (uFlags & DC_TEXT)
1468 {
1469 HFONT hOldFont;
1470
1471 if (uFlags & DC_INBUTTON)
1472 SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
1473 else if (uFlags & DC_ACTIVE)
1474 SetTextColor (hdc, GetSysColor (COLOR_CAPTIONTEXT));
1475 else
1476 SetTextColor (hdc, GetSysColor (COLOR_INACTIVECAPTIONTEXT));
1477
1478 SetBkMode (hdc, TRANSPARENT);
1479
1480 if (hFont)
1481 hOldFont = SelectObject (hdc, hFont);
1482 else
1483 {
1484 NONCLIENTMETRICSA nclm;
1485 HFONT hNewFont;
1486
1487 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1488 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1489 hNewFont = CreateFontIndirectA ((uFlags & DC_SMALLCAP) ?
1490 &nclm.lfSmCaptionFont : &nclm.lfCaptionFont);
1491 hOldFont = SelectObject (hdc, hNewFont);
1492 }
1493
1494 if (str)
1495 {
1496 if (unicode)
1497 DrawTextW(hdc,str,-1,&rc,DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
1498 else
1499 DrawTextA(hdc,(LPSTR)str,-1,&rc,DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
1500 } else
1501 {
1502 CHAR szText[128];
1503 INT nLen;
1504
1505 nLen = GetWindowTextA (hwnd, szText, 128);
1506 DrawTextA (hdc, szText, nLen, &rc,
1507 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
1508 }
1509
1510 if (hFont)
1511 SelectObject (hdc, hOldFont);
1512 else
1513 DeleteObject (SelectObject (hdc, hOldFont));
1514 }
1515
1516 /* drawing focus ??? */
1517 //if (uFlags & 0x2000)
1518 // FIXME("undocumented flag (0x2000)!\n");
1519
1520 return 0;
1521}
1522/***********************************************************************
1523 * DrawCaptionTemp32A [USER32.599]
1524 *
1525 * PARAMS
1526 *
1527 * RETURNS
1528 * Success:
1529 * Failure:
1530 */
1531BOOL WIN32API DrawCaptionTempA(HWND hwnd,HDC hdc,const RECT *rect,HFONT hFont,HICON hIcon,LPCSTR str,UINT uFlags)
1532{
1533 dprintf(("USER32: DrawCaptionTempA"));
1534
1535 return DrawCaptionTemp(hwnd,hdc,rect,hFont,hIcon,(LPWSTR)str,uFlags,FALSE);
1536}
1537/***********************************************************************
1538 * DrawCaptionTemp32W [USER32.602]
1539 *
1540 * PARAMS
1541 *
1542 * RETURNS
1543 * Success:
1544 * Failure:
1545 */
1546BOOL WIN32API DrawCaptionTempW (HWND hwnd,HDC hdc,const RECT *rect,HFONT hFont,HICON hIcon,LPCWSTR str,UINT uFlags)
1547{
1548 dprintf(("USER32: DrawCaptionTempA"));
1549
1550 return DrawCaptionTemp(hwnd,hdc,rect,hFont,hIcon,(LPWSTR)str,uFlags,TRUE);
1551}
1552
Note: See TracBrowser for help on using the repository browser.