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

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

PF: Wrong checks on restoration point remembering. Maximizing window from PM icon using keyboard or menu produced wrong controls

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