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

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

SPI_GETNONCLIENTMETRICS size check extended & Fixed RMB on icon of minimized mdi window

File size: 48.1 KB
Line 
1/* $Id: win32wbasenonclient.cpp,v 1.43 2002-08-15 15:45:46 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 rect.top = rect.left = 0;
1070 rect.right = rectWindow.right - rectWindow.left;
1071 rect.bottom = rectWindow.bottom - rectWindow.top;
1072
1073 if (clip > 1)
1074 {
1075 //only redraw caption
1076 GetRgnBox(clip,&rectClip);
1077#if 1
1078 //SvL: I'm getting paint problems when clipping a dc created in GetDCEx
1079 // with a region that covers the entire window (RealPlayer 7 Update 1)
1080 // As we don't need to clip anything when that occurs, this workaround
1081 // solves the problem.
1082 if(rectClip.right == getWindowWidth() && rectClip.bottom == getWindowHeight())
1083 {
1084 clip = 0;
1085 rectClip = rect;
1086 }
1087#endif
1088 }
1089 else
1090 {
1091 clip = 0;
1092 rectClip = rect;
1093 }
1094
1095 if (!(hdc = GetDCEx( Win32Hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1096 ((clip > 1) ?(DCX_INTERSECTRGN /*| DCX_KEEPCLIPRGN*/) : 0) ))) return;
1097
1098 DecreaseLogCount();
1099 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1100
1101 if (HAS_BIGFRAME( dwStyle, dwExStyle))
1102 {
1103 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1104 }
1105 if (HAS_THICKFRAME( dwStyle, dwExStyle ))
1106 DrawFrame(hdc, &rect, FALSE, active );
1107 else
1108 if (HAS_DLGFRAME( dwStyle, dwExStyle ))
1109 DrawFrame( hdc, &rect, TRUE, active );
1110 else
1111 if (HAS_THINFRAME( dwStyle ))
1112 {
1113 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1114 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1115 }
1116
1117 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
1118 {
1119 RECT r = rect;
1120 if (dwExStyle & WS_EX_TOOLWINDOW)
1121 {
1122 r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
1123 rect.top += GetSystemMetrics(SM_CYSMCAPTION);
1124 }
1125 else
1126 {
1127 r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
1128 rect.top += GetSystemMetrics(SM_CYCAPTION);
1129 }
1130 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
1131 DrawCaption(hdc,&r,active);
1132 }
1133
1134 if (HAS_MENU())
1135 {
1136 RECT r = rect;
1137 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
1138
1139 rect.top += MENU_DrawMenuBar(hdc,&r,Win32Hwnd,suppress_menupaint)+1;
1140 }
1141
1142 if (dwExStyle & WS_EX_CLIENTEDGE)
1143 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1144
1145 if (dwExStyle & WS_EX_STATICEDGE)
1146 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1147
1148 /* Draw the scroll-bars */
1149 if (dwStyle & WS_VSCROLL)
1150 SCROLL_DrawScrollBar(Win32Hwnd,hdc,SB_VERT,TRUE,TRUE);
1151 if (dwStyle & WS_HSCROLL)
1152 SCROLL_DrawScrollBar(Win32Hwnd,hdc,SB_HORZ,TRUE,TRUE);
1153
1154 /* Draw the "size-box" */
1155 if ((dwStyle & WS_VSCROLL) && (dwStyle & WS_HSCROLL))
1156 {
1157 RECT r = rect;
1158 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1159 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1160 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1161 //CB: todo: child windows have sometimes a size grip (i.e. Notepad)
1162 // WS_SIZEBOX isn't set in these cases
1163 if (!(dwStyle & WS_CHILD))
1164 {
1165 POINT p1,p2;
1166 HPEN penDark = GetSysColorPen(COLOR_3DSHADOW);
1167 HPEN penWhite = GetSysColorPen(COLOR_3DHILIGHT);
1168 HPEN oldPen = SelectObject(hdc,penDark);
1169 INT x;
1170
1171 p1.x = r.right-1;
1172 p1.y = r.bottom;
1173 p2.x = r.right;
1174 p2.y = r.bottom-1;
1175 for (x = 0;x < 3;x++)
1176 {
1177 SelectObject(hdc,penDark);
1178 MoveToEx(hdc,p1.x,p1.y,NULL);
1179 LineTo(hdc,p2.x,p2.y);
1180 p1.x--;
1181 p2.y--;
1182 MoveToEx(hdc,p1.x,p1.y,NULL);
1183 LineTo(hdc,p2.x,p2.y);
1184 SelectObject(hdc,penWhite);
1185 p1.x--;
1186 p2.y--;
1187 MoveToEx(hdc,p1.x,p1.y,NULL);
1188 LineTo(hdc,p2.x,p2.y);
1189 p1.x -= 2;
1190 p2.y -= 2;
1191 }
1192
1193 SelectObject(hdc,oldPen);
1194 }
1195 }
1196
1197 IncreaseLogCount();
1198 ReleaseDC(getWindowHandle(),hdc);
1199 dprintf(("**DoNCPaint %x DONE", getWindowHandle()));
1200}
1201//******************************************************************************
1202//******************************************************************************
1203LONG Win32BaseWindow::HandleNCPaint(HRGN clip)
1204{
1205//CB: ignore it for now (SetWindowPos in WM_CREATE)
1206// if (!(dwStyle & WS_VISIBLE)) return 0;
1207
1208 if (dwStyle & WS_MINIMIZE) return 0;
1209
1210 DoNCPaint(clip,FALSE);
1211
1212 return 0;
1213}
1214/***********************************************************************
1215 * NC_HandleNCLButtonDblClk
1216 *
1217 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
1218 */
1219LONG Win32BaseWindow::HandleNCLButtonDblClk(WPARAM wParam,LPARAM lParam)
1220{
1221 /*
1222 * if this is an icon, send a restore since we are handling
1223 * a double click
1224 */
1225 if (dwStyle & WS_MINIMIZE)
1226 {
1227 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_RESTORE,lParam);
1228 return 0;
1229 }
1230
1231 switch(wParam) /* Hit test */
1232 {
1233 case HTCAPTION:
1234 /* stop processing if WS_MAXIMIZEBOX is missing */
1235 if (dwStyle & WS_MAXIMIZEBOX)
1236 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,
1237 (dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
1238 lParam);
1239 break;
1240
1241 case HTSYSMENU:
1242 if (!(GetClassWord(Win32Hwnd,GCW_STYLE) & CS_NOCLOSE))
1243 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_CLOSE,lParam);
1244 break;
1245
1246 case HTHSCROLL:
1247 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_HSCROLL+HTHSCROLL,lParam);
1248 break;
1249
1250 case HTVSCROLL:
1251 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_VSCROLL+HTVSCROLL,lParam);
1252 break;
1253 }
1254
1255 return 0;
1256}
1257//******************************************************************************
1258//******************************************************************************
1259LONG Win32BaseWindow::HandleNCRButtonUp(WPARAM wParam,LPARAM lParam)
1260{
1261 switch(wParam)
1262 {
1263 case HTCAPTION:
1264 //we receive a HTCAPTION rbuttonup for RMB clicks on icon of minimized mdi windows
1265 if (fOS2Look && ((dwStyle & (WS_SYSMENU | WS_MINIMIZE)) == (WS_SYSMENU | WS_MINIMIZE)) )
1266 {
1267 return HandleNCRButtonUp(HTSYSMENU, lParam);
1268 }
1269
1270 if (GetActiveWindow() != Win32Hwnd)
1271 SetActiveWindow();
1272
1273 if (((GetActiveWindow() == Win32Hwnd) || isMDIChild()) && (dwStyle & WS_SYSMENU))
1274 {
1275 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_MOUSEMENU+HTCAPTION,lParam);
1276 }
1277 break;
1278
1279 case HTSYSMENU:
1280 if (fOS2Look && (dwStyle & WS_SYSMENU))
1281 {
1282 if (fOS2Look == OS2_APPEARANCE)
1283 SendMessageA( getWindowHandle(), WM_SYSCOMMAND,SC_MOUSEMENU+HTSYSMENU,lParam);
1284 else
1285 if (fOS2Look == OS2_APPEARANCE_SYSMENU)
1286 OSLibPostMessageDirect( getOS2FrameWindowHandle(), OSWM_SYSCOMMAND, OSSC_SYSMENU,0);
1287 }
1288 break;
1289
1290 default:
1291 break;
1292 }
1293
1294 return 0;
1295}
1296/***********************************************************************
1297 * NC_HandleSysCommand
1298 *
1299 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
1300 *
1301 */
1302LONG Win32BaseWindow::HandleSysCommand(WPARAM wParam,POINT *pt32)
1303{
1304 UINT uCommand = wParam & 0xFFF0;
1305
1306 switch (uCommand)
1307 {
1308 case SC_SIZE:
1309 {
1310 Frame_SysCommandSizeMove(this, wParam);
1311 break;
1312 }
1313
1314 case SC_MOVE:
1315 Frame_SysCommandSizeMove(this, wParam);
1316 break;
1317
1318 case SC_MINIMIZE:
1319 if(dwStyle & WS_MINIMIZEBOX)
1320 ShowWindow(SW_MINIMIZE);
1321 break;
1322
1323 case SC_MAXIMIZE:
1324 if(dwStyle & WS_MAXIMIZEBOX)
1325 ShowWindow(SW_MAXIMIZE);
1326 break;
1327
1328 case SC_RESTORE:
1329 ShowWindow(SW_RESTORE);
1330 break;
1331
1332 case SC_CLOSE:
1333 return SendMessageA(getWindowHandle(), WM_CLOSE,0,0);
1334
1335 case SC_CONTEXTHELP:
1336 {
1337 //CB: todo
1338 break;
1339 }
1340
1341 case SC_VSCROLL:
1342 case SC_HSCROLL:
1343 TrackScrollBar(wParam,*pt32);
1344 break;
1345
1346 case SC_MOUSEMENU:
1347 MENU_TrackMouseMenuBar(Win32Hwnd,wParam & 0x000F,*pt32);
1348 break;
1349
1350 case SC_KEYMENU:
1351 MENU_TrackKbdMenuBar(Win32Hwnd,wParam,pt32->x);
1352 break;
1353
1354 case SC_TASKLIST:
1355 OSLibWinShowTaskList(getOS2WindowHandle());
1356 break;
1357
1358 case SC_SCREENSAVE:
1359 if (wParam == SC_ABOUTODIN) {
1360 if(ShellAboutA == 0) {
1361 HINSTANCE hShell32 = LoadLibraryA("SHELL32");
1362 if(hShell32 == 0)
1363 break;
1364 *(VOID **)&ShellAboutA = (VOID *)GetProcAddress(hShell32, "ShellAboutA");
1365 }
1366 ShellAboutA(Win32Hwnd,"Odin","Odin alpha release compiled with IBM VAC++",0);
1367 }
1368#ifdef DEBUG
1369 //SvL: Do NOT turn this into a dprintf.
1370 else
1371 if (wParam == SC_PUTMARK)
1372 WriteLog(("Mark requested by user\n"));
1373 else
1374 if (wParam == SC_DEBUGINT3)
1375 DebugInt3();
1376#endif
1377 break;
1378
1379 case SC_HOTKEY:
1380 case SC_ARRANGE:
1381 case SC_NEXTWINDOW:
1382 case SC_PREVWINDOW:
1383 break;
1384 }
1385 return 0;
1386}
1387/*****************************************************************************
1388 * Name : VOID WIN32API DrawCaption
1389 * Purpose : The DrawCaption function draws a window caption.
1390 * Parameters: HDC hdc handle of device context
1391 * LPRECT lprc address of bounding rectangle coordinates
1392 * HFONT hfont handle of font for caption
1393 * HICON hicon handle of icon in caption
1394 * LPSTR lpszText address of caption string
1395 * WORD wFlags drawing options
1396 * Variables :
1397 * Result :
1398 * Remark :
1399 * Status : UNTESTED STUB
1400 *
1401 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1402 *****************************************************************************/
1403BOOL WIN32API DrawCaption (HWND hwnd,HDC hdc,const RECT *lprc,UINT wFlags)
1404{
1405 dprintf(("USER32: DrawCaption"));
1406
1407 return DrawCaptionTempA(hwnd,hdc,lprc,0,0,NULL,wFlags & 0x1F);
1408}
1409//******************************************************************************
1410// CB: this code is a subset of Win32BaseWindow::DrawCaption
1411// todo: move Win32BaseWindow:DrawCaption to this function
1412//******************************************************************************
1413BOOL WIN32API DrawCaptionTemp(HWND hwnd,HDC hdc,const RECT *rect,HFONT hFont,HICON hIcon,LPWSTR str,UINT uFlags,BOOL unicode)
1414{
1415 RECT rc = *rect;
1416
1417 /* drawing background */
1418 if (uFlags & DC_INBUTTON)
1419 {
1420 FillRect (hdc, &rc, GetSysColorBrush (COLOR_3DFACE));
1421
1422 if (uFlags & DC_ACTIVE)
1423 {
1424 HBRUSH hbr = SelectObject (hdc, GetPattern55AABrush ());
1425 PatBlt (hdc, rc.left, rc.top,
1426 rc.right-rc.left, rc.bottom-rc.top, 0xFA0089);
1427 SelectObject (hdc, hbr);
1428 }
1429 } else
1430 {
1431 FillRect (hdc, &rc, GetSysColorBrush ((uFlags & DC_ACTIVE) ?
1432 COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
1433 }
1434
1435 /* drawing icon */
1436 if ((uFlags & DC_ICON) && !(uFlags & DC_SMALLCAP))
1437 {
1438 POINT pt;
1439
1440 pt.x = rc.left + 2;
1441 pt.y = (rc.bottom + rc.top - GetSystemMetrics(SM_CYSMICON)) / 2;
1442
1443 if (hIcon)
1444 {
1445 DrawIconEx (hdc, pt.x, pt.y, hIcon, GetSystemMetrics(SM_CXSMICON),
1446 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
1447 } else
1448 {
1449 Win32BaseWindow *win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
1450
1451 if (!win32wnd) return 0;
1452
1453 DrawIconEx (hdc, pt.x, pt.y, win32wnd->IconForWindow(ICON_SMALL),
1454 GetSystemMetrics(SM_CXSMICON),
1455 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
1456 }
1457
1458 rc.left += (rc.bottom - rc.top);
1459 }
1460
1461 /* drawing text */
1462 if (uFlags & DC_TEXT)
1463 {
1464 HFONT hOldFont;
1465
1466 if (uFlags & DC_INBUTTON)
1467 SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
1468 else if (uFlags & DC_ACTIVE)
1469 SetTextColor (hdc, GetSysColor (COLOR_CAPTIONTEXT));
1470 else
1471 SetTextColor (hdc, GetSysColor (COLOR_INACTIVECAPTIONTEXT));
1472
1473 SetBkMode (hdc, TRANSPARENT);
1474
1475 if (hFont)
1476 hOldFont = SelectObject (hdc, hFont);
1477 else
1478 {
1479 NONCLIENTMETRICSA nclm;
1480 HFONT hNewFont;
1481
1482 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1483 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1484 hNewFont = CreateFontIndirectA ((uFlags & DC_SMALLCAP) ?
1485 &nclm.lfSmCaptionFont : &nclm.lfCaptionFont);
1486 hOldFont = SelectObject (hdc, hNewFont);
1487 }
1488
1489 if (str)
1490 {
1491 if (unicode)
1492 DrawTextW(hdc,str,-1,&rc,DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
1493 else
1494 DrawTextA(hdc,(LPSTR)str,-1,&rc,DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
1495 } else
1496 {
1497 CHAR szText[128];
1498 INT nLen;
1499
1500 nLen = GetWindowTextA (hwnd, szText, 128);
1501 DrawTextA (hdc, szText, nLen, &rc,
1502 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
1503 }
1504
1505 if (hFont)
1506 SelectObject (hdc, hOldFont);
1507 else
1508 DeleteObject (SelectObject (hdc, hOldFont));
1509 }
1510
1511 /* drawing focus ??? */
1512 //if (uFlags & 0x2000)
1513 // FIXME("undocumented flag (0x2000)!\n");
1514
1515 return 0;
1516}
1517/***********************************************************************
1518 * DrawCaptionTemp32A [USER32.599]
1519 *
1520 * PARAMS
1521 *
1522 * RETURNS
1523 * Success:
1524 * Failure:
1525 */
1526BOOL WIN32API DrawCaptionTempA(HWND hwnd,HDC hdc,const RECT *rect,HFONT hFont,HICON hIcon,LPCSTR str,UINT uFlags)
1527{
1528 dprintf(("USER32: DrawCaptionTempA"));
1529
1530 return DrawCaptionTemp(hwnd,hdc,rect,hFont,hIcon,(LPWSTR)str,uFlags,FALSE);
1531}
1532/***********************************************************************
1533 * DrawCaptionTemp32W [USER32.602]
1534 *
1535 * PARAMS
1536 *
1537 * RETURNS
1538 * Success:
1539 * Failure:
1540 */
1541BOOL WIN32API DrawCaptionTempW (HWND hwnd,HDC hdc,const RECT *rect,HFONT hFont,HICON hIcon,LPCWSTR str,UINT uFlags)
1542{
1543 dprintf(("USER32: DrawCaptionTempA"));
1544
1545 return DrawCaptionTemp(hwnd,hdc,rect,hFont,hIcon,(LPWSTR)str,uFlags,TRUE);
1546}
1547
Note: See TracBrowser for help on using the repository browser.