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

Last change on this file since 21916 was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

File size: 50.3 KB
Line 
1/* $Id: win32wbasenonclient.cpp,v 1.53 2004-03-09 10:06:15 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() != getWindowHandle()) 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(getWindowHandle(),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) && !(dwExStyle & WS_EX_TOOLWINDOW))
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 //Testing in NT4 shows that tool windows never have a minimize or maximize button!
553 if (((dwStyle & WS_MAXIMIZEBOX) || (dwStyle & WS_MINIMIZEBOX)) &&
554 !(dwExStyle & WS_EX_TOOLWINDOW))
555 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
556 if (pt.x > rect.right) return HTMAXBUTTON;
557
558 /* Check minimize box */
559 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
560 //Testing in NT4 shows that tool windows never have a minimize or maximize button!
561 if (((dwStyle & WS_MINIMIZEBOX) || (dwStyle & WS_MAXIMIZEBOX)) &&
562 !(dwExStyle & WS_EX_TOOLWINDOW))
563 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
564
565 if (pt.x > rect.right) return HTMINBUTTON;
566 return HTCAPTION;
567 }
568 }
569
570 /* Check client area */
571
572 ScreenToClient(Win32Hwnd,&pt);
573 getClientRect(&rect);
574 if (PtInRect(&rect,pt)) return HTCLIENT;
575
576 /* Check vertical scroll bar */
577
578 if (dwStyle & WS_VSCROLL)
579 {
580 rect.right += GetSystemMetrics(SM_CXVSCROLL);
581 if (PtInRect( &rect, pt )) return HTVSCROLL;
582 }
583
584 /* Check horizontal scroll bar */
585
586 if (dwStyle & WS_HSCROLL)
587 {
588 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
589 if (PtInRect( &rect, pt ))
590 {
591 /* Check size box */
592 if ((dwStyle & WS_VSCROLL) &&
593 (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
594 return (dwStyle & WS_CHILD) ? HTSIZE:HTBOTTOMRIGHT;
595 return HTHSCROLL;
596 }
597 }
598
599 /* Check menu bar */
600
601 if (HAS_MENU())
602 {
603 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
604 return HTMENU;
605 }
606
607 /* Has to return HTNOWHERE if nothing was found
608 Could happen when a window has a customized non client area */
609 return HTNOWHERE;
610}
611
612//******************************************************************************
613//******************************************************************************
614VOID Win32BaseWindow::GetInsideRect(RECT *rect)
615{
616 rect->top = rect->left = 0;
617 rect->right = rectWindow.right - rectWindow.left;
618 rect->bottom = rectWindow.bottom - rectWindow.top;
619
620 if (dwStyle & WS_ICONIC) return;
621
622 /* Remove frame from rectangle */
623 if (HAS_THICKFRAME(dwStyle,dwExStyle))
624 {
625 InflateRect( rect, -GetSystemMetrics(SM_CXSIZEFRAME), -GetSystemMetrics(SM_CYSIZEFRAME) );
626 }
627 else if (HAS_DLGFRAME(dwStyle,dwExStyle ))
628 {
629 InflateRect( rect, -GetSystemMetrics(SM_CXFIXEDFRAME), -GetSystemMetrics(SM_CYFIXEDFRAME));
630 }
631 else if (HAS_THINFRAME(dwStyle))
632 {
633 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
634 }
635
636 /* We have additional border information if the window
637 * is a child (but not an MDI child) */
638 if ( (dwStyle & WS_CHILD) &&
639 ( (dwExStyle & WS_EX_MDICHILD) == 0 ) )
640 {
641 if (dwExStyle & WS_EX_CLIENTEDGE)
642 InflateRect (rect, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE));
643
644 if (dwExStyle & WS_EX_STATICEDGE)
645 InflateRect (rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
646 }
647}
648//******************************************************************************
649//******************************************************************************
650VOID Win32BaseWindow::DrawFrame(HDC hdc,RECT *rect,BOOL dlgFrame,BOOL active)
651{
652 INT width, height;
653 HBRUSH oldBrush;
654
655 if (dlgFrame)
656 {
657 width = GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
658 height = GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
659 }
660 else
661 {
662 width = GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXEDGE);
663 height = GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYEDGE);
664 }
665
666 oldBrush = SelectObject(hdc,GetSysColorBrush(active ? COLOR_ACTIVEBORDER:COLOR_INACTIVEBORDER));
667
668 /* Draw frame */
669 PatBlt(hdc,rect->left, rect->top, rect->right-rect->left, height,PATCOPY); //top
670 PatBlt(hdc,rect->left, rect->top, width, rect->bottom-rect->top,PATCOPY); //left
671 PatBlt(hdc,rect->left, rect->bottom-1, rect->right-rect->left,-height,PATCOPY); //bottom
672 PatBlt(hdc,rect->right-1,rect->top, -width, rect->bottom-rect->top,PATCOPY); //right
673 SelectObject(hdc,oldBrush);
674
675 InflateRect(rect,-width,-height);
676}
677//******************************************************************************
678//******************************************************************************
679BOOL Win32BaseWindow::DrawSysButton(HDC hdc,RECT *rect)
680{
681 HICON hSysIcon;
682 RECT r;
683
684 if (!rect) GetInsideRect(&r);
685 else r = *rect;
686
687 hSysIcon = IconForWindow(ICON_SMALL);
688
689//CB: todo: add icons (including Odin icon) to user32.rc
690 if (hSysIcon)
691 DrawIconEx(hdc,r.left+2,r.top+2,hSysIcon,
692 GetSystemMetrics(SM_CXSMICON),
693 GetSystemMetrics(SM_CYSMICON),
694 0, 0, DI_NORMAL);
695
696 return (hSysIcon != 0);
697}
698//******************************************************************************
699//Returns position of system menu in screen coordinates
700//******************************************************************************
701BOOL Win32BaseWindow::GetSysPopupPos(RECT* lpRect)
702{
703 if(hSysMenu)
704 {
705 if(dwStyle & WS_MINIMIZE) {
706 GetWindowRect(getWindowHandle(), lpRect);
707 }
708 else
709 {
710 GetInsideRect(lpRect);
711 OffsetRect(lpRect, rectWindow.left, rectWindow.top);
712 if(getStyle() & WS_CHILD)
713 ClientToScreen(getParent()->getWindowHandle(), (POINT *)lpRect);
714
715 lpRect->right = lpRect->left + GetSystemMetrics(SM_CYCAPTION) - 1;
716 lpRect->bottom = lpRect->top + GetSystemMetrics(SM_CYCAPTION) - 1;
717 }
718 return TRUE;
719 }
720 return FALSE;
721}
722//******************************************************************************
723//******************************************************************************
724BOOL Win32BaseWindow::DrawGrayButton(HDC hdc,int x,int y)
725{
726 HBITMAP hMaskBmp;
727 HDC hdcMask = CreateCompatibleDC (0);
728 HBRUSH hOldBrush;
729 hMaskBmp = CreateBitmap (12, 10, 1, 1, lpGrayMask);
730
731 if(hMaskBmp == 0)
732 return FALSE;
733
734 SelectObject (hdcMask, hMaskBmp);
735
736 /* Draw the grayed bitmap using the mask */
737 hOldBrush = SelectObject (hdc, RGB(128, 128, 128));
738 BitBlt (hdc, x, y, 12, 10,
739 hdcMask, 0, 0, 0xB8074A);
740
741 /* Clean up */
742 SelectObject (hdc, hOldBrush);
743 DeleteObject(hMaskBmp);
744 DeleteDC (hdcMask);
745
746 return TRUE;
747}
748//******************************************************************************
749//******************************************************************************
750VOID Win32BaseWindow::DrawCloseButton(HDC hdc,RECT *rect,BOOL down,BOOL bGrayed)
751{
752 RECT r;
753 HDC hdcMem;
754 BITMAP bmp;
755 HBITMAP hBmp, hOldBmp;
756
757 if (!rect) GetInsideRect(&r);
758 else r = *rect;
759
760 /* A tool window has a smaller Close button */
761 if (dwExStyle & WS_EX_TOOLWINDOW)
762 {
763 RECT toolRect;
764 INT iBmpHeight = 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
765 INT iBmpWidth = 11; /* it uses 11x11 for the close button in tool window */
766 INT iCaptionHeight = GetSystemMetrics(SM_CYSMCAPTION);
767
768
769 toolRect.top = r.top + (iCaptionHeight - 1 - iBmpHeight) / 2;
770 toolRect.left = r.right - (iCaptionHeight + 1 + iBmpWidth) / 2;
771 toolRect.bottom = toolRect.top + iBmpHeight;
772 toolRect.right = toolRect.left + iBmpWidth;
773 DrawFrameControl(hdc,&toolRect,
774 DFC_CAPTION,DFCS_CAPTIONCLOSE |
775 down ? DFCS_PUSHED : 0 |
776 bGrayed ? DFCS_INACTIVE : 0);
777 } else
778 {
779 hdcMem = CreateCompatibleDC( hdc );
780 hBmp = down ? hbitmapCloseD : hbitmapClose;
781 hOldBmp = SelectObject (hdcMem, hBmp);
782 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
783
784 BitBlt (hdc, r.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2,
785 r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
786 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);
787
788 if(bGrayed)
789 DrawGrayButton(hdc,r.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2 + 2,
790 r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
791
792 SelectObject (hdcMem, hOldBmp);
793 DeleteDC (hdcMem);
794 }
795}
796//******************************************************************************
797//******************************************************************************
798VOID Win32BaseWindow::DrawMaxButton(HDC hdc,RECT *rect,BOOL down,BOOL bGrayed)
799{
800 RECT r;
801 HDC hdcMem;
802 BITMAP bmp;
803 HBITMAP hBmp,hOldBmp;
804
805 if (!rect) GetInsideRect(&r);
806 else r = *rect;
807 hdcMem = CreateCompatibleDC( hdc );
808 hBmp = IsZoomed(Win32Hwnd) ?
809 (down ? hbitmapRestoreD : hbitmapRestore ) :
810 (down ? hbitmapMaximizeD: hbitmapMaximize);
811 hOldBmp = SelectObject( hdcMem, hBmp );
812 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
813
814 if (dwStyle & WS_SYSMENU)
815 r.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
816
817 if (dwExStyle & WS_EX_CONTEXTHELP)
818 r.right -= bmp.bmWidth;
819
820 BitBlt( hdc, r.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
821 r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
822 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
823
824 if(bGrayed)
825 DrawGrayButton(hdc, r.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
826 r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
827
828 SelectObject (hdcMem, hOldBmp);
829 DeleteDC( hdcMem );
830}
831//******************************************************************************
832//******************************************************************************
833VOID Win32BaseWindow::DrawMinButton(HDC hdc,RECT *rect,BOOL down,BOOL bGrayed)
834{
835 RECT r;
836 HDC hdcMem;
837 BITMAP bmp;
838 HBITMAP hBmp,hOldBmp;
839
840 if (!rect) GetInsideRect(&r);
841 else r = *rect;
842
843 hdcMem = CreateCompatibleDC( hdc );
844 hBmp = down ? hbitmapMinimizeD : hbitmapMinimize;
845 hOldBmp= SelectObject( hdcMem, hBmp );
846 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
847
848 if (dwStyle & WS_SYSMENU)
849 r.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
850
851 if (dwExStyle & WS_EX_CONTEXTHELP)
852 r.right -= bmp.bmWidth;
853
854 /* In win 95 there is always a Maximize box when there is a Minimize one */
855 if ((dwStyle & WS_MAXIMIZEBOX) || (dwStyle & WS_MINIMIZEBOX))
856 r.right -= bmp.bmWidth;
857
858 BitBlt( hdc, r.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
859 r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
860 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
861
862 if(bGrayed)
863 DrawGrayButton(hdc, r.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
864 r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
865
866
867 SelectObject (hdcMem, hOldBmp);
868 DeleteDC( hdcMem );
869}
870//******************************************************************************
871//******************************************************************************
872VOID Win32BaseWindow::DrawContextHelpButton(HDC hdc,RECT *rect,BOOL down,BOOL bGrayed)
873{
874 RECT r;
875 HDC hdcMem;
876 BITMAP bmp;
877 HBITMAP hBmp,hOldBmp;
878
879 if (!rect) GetInsideRect(&r);
880 else r = *rect;
881
882 hdcMem = CreateCompatibleDC(hdc);
883 hBmp = down ? hbitmapContextHelpD : hbitmapContextHelp;
884 hOldBmp = SelectObject(hdcMem,hBmp);
885 GetObjectA(hBmp,sizeof(BITMAP),&bmp);
886
887 if (dwStyle & WS_SYSMENU)
888 r.right -= GetSystemMetrics(SM_CYCAPTION)+1;
889
890 BitBlt( hdc, r.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
891 r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
892 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
893
894 if(bGrayed)
895 DrawGrayButton(hdc, r.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
896 r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
897
898
899 SelectObject (hdcMem, hOldBmp);
900 DeleteDC( hdcMem );
901}
902//******************************************************************************
903//******************************************************************************
904VOID Win32BaseWindow::DrawCaption(HDC hdc,RECT *rect,BOOL active)
905{
906 RECT r = *rect,r2;
907 char buffer[256];
908 HPEN hPrevPen;
909 HDC memDC;
910 HBITMAP memBmp,oldBmp;
911
912 //WS_EX_TOOLWINDOW is incompatible with the OS2Look (titlebar thinner + smaller font)
913 if(fOS2Look && !(dwExStyle & WS_EX_TOOLWINDOW)) {
914 //Note: If no class icon *and* WS_EX_DLGMODALFRAME -> no system menu
915 if((dwStyle & WS_SYSMENU) && !(dwExStyle & WS_EX_TOOLWINDOW) &&
916 !(!windowClass->getIcon() && (dwExStyle & WS_EX_DLGMODALFRAME)) &&
917 fOS2Look != OS2_APPEARANCE_SYSMENU)
918 {
919 HICON hSysIcon = IconForWindow(ICON_SMALL);
920
921 if (hSysIcon) {
922 int size = GetSystemMetrics(SM_CYCAPTION);
923
924 r2 = r;
925 r2.right = r2.left + size;
926 r2.bottom = r2.top + size;
927 FillRect(hdc, &r2, GetSysColorBrush(COLOR_MENU));
928
929 DrawSysButton(hdc,&r);
930 }
931 }
932 return;
933 }
934
935 memDC = CreateCompatibleDC(hdc);
936 r.right -= r.left;
937 r.bottom -= r.top;
938 r.left = r.top = 0;
939 r2 = r;
940 memBmp = CreateCompatibleBitmap(hdc,r.right,r.bottom);
941 oldBmp = SelectObject(memDC,memBmp);
942
943 hPrevPen = SelectObject(memDC,GetSysColorPen(COLOR_3DFACE));
944 MoveToEx(memDC,r.left,r.bottom-1,NULL);
945 LineTo(memDC,r.right,r.bottom-1);
946 SelectObject(memDC,hPrevPen);
947 r.bottom--;
948
949 if (SYSCOLOR_GetUseWinColors())
950 {
951 COLORREF startColor = GetSysColor(active ? COLOR_ACTIVECAPTION:COLOR_INACTIVECAPTION),endColor = GetSysColor(active ? COLOR_GRADIENTACTIVECAPTION:COLOR_GRADIENTINACTIVECAPTION);
952
953 if (startColor == endColor)
954 FillRect(memDC,&r,GetSysColorBrush(startColor));
955 else
956 {
957 INT rDiff = GetRValue(endColor)-GetRValue(startColor);
958 INT gDiff = GetGValue(endColor)-GetGValue(startColor);
959 INT bDiff = GetBValue(endColor)-GetBValue(startColor);
960 INT steps = MAX(MAX(abs(rDiff),abs(gDiff)),abs(bDiff));
961 INT w = r.right-r.left;
962 RECT r2;
963
964 if (w < steps) steps = w;
965 r2.left = r2.right = r.left;
966 r2.top = r.top;
967 r2.bottom = r.bottom;
968 for (INT x = 0;x <= steps;x++)
969 {
970 COLORREF color = RGB(GetRValue(startColor)+rDiff*x/steps,GetGValue(startColor)+gDiff*x/steps,GetBValue(startColor)+bDiff*x/steps);
971 HBRUSH brush = CreateSolidBrush(color);
972
973 r2.left = r2.right;
974 r2.right = r.left+w*x/steps;
975 FillRect(memDC,&r2,brush);
976 DeleteObject(brush);
977 }
978 }
979 } else FillRect(memDC,&r,GetSysColorBrush(active ? COLOR_ACTIVECAPTION:COLOR_INACTIVECAPTION));
980
981 if (!hbitmapClose)
982 {
983 if (!(hbitmapClose = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CLOSE)))) return;
984 hbitmapCloseD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CLOSED));
985 hbitmapMinimize = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_REDUCE));
986 hbitmapMinimizeD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_REDUCED));
987 hbitmapMaximize = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_ZOOM));
988 hbitmapMaximizeD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_ZOOMD));
989 hbitmapRestore = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_RESTORE));
990 hbitmapRestoreD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_RESTORED));
991 hbitmapContextHelp = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CONTEXTHELP));
992 hbitmapContextHelpD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CONTEXTHELPD));
993 }
994
995 //Note: If no class icon *and* WS_EX_DLGMODALFRAME -> no system menu
996 if((dwStyle & WS_SYSMENU) && !(dwExStyle & WS_EX_TOOLWINDOW) &&
997 !(!windowClass->getIcon() && (dwExStyle & WS_EX_DLGMODALFRAME)))
998 {
999 if (DrawSysButton(memDC,&r))
1000 r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
1001 }
1002
1003 if (dwStyle & WS_SYSMENU)
1004 {
1005 UINT state;
1006
1007 /* Go get the sysmenu */
1008 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
1009
1010 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1011 DrawCloseButton(memDC,&r2,FALSE,
1012 ((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
1013 r.right -= GetSystemMetrics(SM_CYCAPTION)-1;
1014
1015 if (dwExStyle & WS_EX_CONTEXTHELP)
1016 {
1017 DrawContextHelpButton(memDC,&r2,FALSE,FALSE);
1018 r.right -= GetSystemMetrics(SM_CXSIZE)+1;
1019 }
1020
1021 //Testing in NT4 shows that tool windows never have a minimize or maximize button!
1022 if (((dwStyle & WS_MAXIMIZEBOX) || (dwStyle & WS_MINIMIZEBOX)) &&
1023 !(dwExStyle & WS_EX_TOOLWINDOW))
1024 {
1025 /* In win95 the two buttons are always there */
1026 /* But if the menu item is not in the menu they're disabled*/
1027
1028 DrawMaxButton(memDC,&r2,FALSE,(!(dwStyle & WS_MAXIMIZEBOX)));
1029 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1030
1031 DrawMinButton(memDC,&r2,FALSE, (!(dwStyle & WS_MINIMIZEBOX)));
1032 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1033 }
1034 }
1035
1036 if (GetWindowTextA(buffer, sizeof(buffer) ))
1037 {
1038 NONCLIENTMETRICSA nclm;
1039 HFONT hFont, hOldFont;
1040
1041 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1042 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1043 if (dwExStyle & WS_EX_TOOLWINDOW)
1044 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
1045 else
1046 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
1047 hOldFont = SelectObject (memDC, hFont);
1048 SetTextColor(memDC,GetSysColor(active ? COLOR_CAPTIONTEXT:COLOR_INACTIVECAPTIONTEXT));
1049 SetBkMode(memDC, TRANSPARENT );
1050 r.left += 2;
1051 DrawTextExA(memDC,buffer,-1,&r,DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT | DT_END_ELLIPSIS,NULL);
1052 DeleteObject (SelectObject (memDC, hOldFont));
1053 IncreaseLogCount();
1054 dprintf(("DrawCaption %s %d", buffer, active));
1055 DecreaseLogCount();
1056 }
1057
1058 BitBlt(hdc,rect->left,rect->top,rect->right-rect->left,rect->bottom-rect->top,memDC,0,0,SRCCOPY);
1059 SelectObject(memDC,oldBmp);
1060 DeleteObject(memBmp);
1061 DeleteDC(memDC);
1062}
1063//******************************************************************************
1064//******************************************************************************
1065VOID Win32BaseWindow::DoNCPaint(HRGN clip,BOOL suppress_menupaint)
1066{
1067 BOOL active = flags & WIN_NCACTIVATED;
1068 HDC hdc;
1069 RECT rect,rectClip,rfuzz;
1070
1071 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1072 the call to GetDCEx implying that it is allowed not to use it either.
1073 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1074 will cause clipRgn to be deleted after ReleaseDC().
1075 Now, how is the "system" supposed to tell what happened?
1076 */
1077
1078 dprintf(("DoNCPaint %x %x %d", getWindowHandle(), clip, suppress_menupaint));
1079
1080 if ( (getStyle() & WS_MINIMIZE) ||
1081 !IsWindowVisible( getWindowHandle() )) {
1082 return; /* Nothing to do */
1083 }
1084
1085 rect.top = rect.left = 0;
1086 rect.right = rectWindow.right - rectWindow.left;
1087 rect.bottom = rectWindow.bottom - rectWindow.top;
1088
1089 if (clip > 1)
1090 {
1091 //only redraw caption
1092 GetRgnBox(clip,&rectClip);
1093#if 1
1094 //SvL: I'm getting paint problems when clipping a dc created in GetDCEx
1095 // with a region that covers the entire window (RealPlayer 7 Update 1)
1096 // As we don't need to clip anything when that occurs, this workaround
1097 // solves the problem.
1098 if(rectClip.right == getWindowWidth() && rectClip.bottom == getWindowHeight())
1099 {
1100 clip = 0;
1101 rectClip = rect;
1102 }
1103#endif
1104 }
1105 else
1106 {
1107 clip = 0;
1108 rectClip = rect;
1109 }
1110
1111 if (!(hdc = GetDCEx( Win32Hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1112 ((clip > 1) ?(DCX_INTERSECTRGN /*| DCX_KEEPCLIPRGN*/) : 0) ))) return;
1113
1114 DecreaseLogCount();
1115 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1116
1117 if (HAS_BIGFRAME( dwStyle, dwExStyle))
1118 {
1119 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1120 }
1121 if (HAS_THICKFRAME( dwStyle, dwExStyle ))
1122 DrawFrame(hdc, &rect, FALSE, active );
1123 else
1124 if (HAS_DLGFRAME( dwStyle, dwExStyle ))
1125 DrawFrame( hdc, &rect, TRUE, active );
1126 else
1127 if (HAS_THINFRAME( dwStyle ))
1128 {
1129 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1130 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1131 }
1132
1133 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
1134 {
1135 RECT r = rect;
1136 if (dwExStyle & WS_EX_TOOLWINDOW)
1137 {
1138 r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
1139 rect.top += GetSystemMetrics(SM_CYSMCAPTION);
1140 }
1141 else
1142 {
1143 r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
1144 rect.top += GetSystemMetrics(SM_CYCAPTION);
1145 }
1146 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
1147 DrawCaption(hdc,&r,active);
1148 }
1149
1150 if (HAS_MENU())
1151 {
1152 RECT r = rect;
1153 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
1154
1155 rect.top += MENU_DrawMenuBar(hdc,&r,Win32Hwnd,suppress_menupaint)+1;
1156 }
1157
1158 if (dwExStyle & WS_EX_CLIENTEDGE)
1159 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1160
1161 if (dwExStyle & WS_EX_STATICEDGE)
1162 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1163
1164 /* Draw the scroll-bars */
1165 if (dwStyle & WS_VSCROLL)
1166 SCROLL_DrawScrollBar(Win32Hwnd,hdc,SB_VERT,TRUE,TRUE);
1167 if (dwStyle & WS_HSCROLL)
1168 SCROLL_DrawScrollBar(Win32Hwnd,hdc,SB_HORZ,TRUE,TRUE);
1169
1170 /* Draw the "size-box" */
1171 if ((dwStyle & WS_VSCROLL) && (dwStyle & WS_HSCROLL))
1172 {
1173 RECT r = rect;
1174 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1175 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1176 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1177 //CB: todo: child windows have sometimes a size grip (i.e. Notepad)
1178 // WS_SIZEBOX isn't set in these cases
1179 if (!(dwStyle & WS_CHILD))
1180 {
1181 POINT p1,p2;
1182 HPEN penDark = GetSysColorPen(COLOR_3DSHADOW);
1183 HPEN penWhite = GetSysColorPen(COLOR_3DHILIGHT);
1184 HPEN oldPen = SelectObject(hdc,penDark);
1185 INT x;
1186
1187 p1.x = r.right-1;
1188 p1.y = r.bottom;
1189 p2.x = r.right;
1190 p2.y = r.bottom-1;
1191 for (x = 0;x < 3;x++)
1192 {
1193 SelectObject(hdc,penDark);
1194 MoveToEx(hdc,p1.x,p1.y,NULL);
1195 LineTo(hdc,p2.x,p2.y);
1196 p1.x--;
1197 p2.y--;
1198 MoveToEx(hdc,p1.x,p1.y,NULL);
1199 LineTo(hdc,p2.x,p2.y);
1200 SelectObject(hdc,penWhite);
1201 p1.x--;
1202 p2.y--;
1203 MoveToEx(hdc,p1.x,p1.y,NULL);
1204 LineTo(hdc,p2.x,p2.y);
1205 p1.x -= 2;
1206 p2.y -= 2;
1207 }
1208
1209 SelectObject(hdc,oldPen);
1210 }
1211 }
1212
1213 IncreaseLogCount();
1214 ReleaseDC(getWindowHandle(),hdc);
1215 dprintf(("**DoNCPaint %x DONE", getWindowHandle()));
1216}
1217//******************************************************************************
1218//******************************************************************************
1219LONG Win32BaseWindow::HandleNCPaint(HRGN clip)
1220{
1221//CB: ignore it for now (SetWindowPos in WM_CREATE)
1222// if (!(dwStyle & WS_VISIBLE)) return 0;
1223
1224 if (dwStyle & WS_MINIMIZE) return 0;
1225
1226 DoNCPaint(clip,FALSE);
1227
1228 return 0;
1229}
1230/***********************************************************************
1231 * NC_HandleNCLButtonDblClk
1232 *
1233 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
1234 */
1235LONG Win32BaseWindow::HandleNCLButtonDblClk(WPARAM wParam,LPARAM lParam)
1236{
1237 /*
1238 * if this is an icon, send a restore since we are handling
1239 * a double click
1240 */
1241 if (dwStyle & WS_MINIMIZE)
1242 {
1243 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_RESTORE,lParam);
1244 return 0;
1245 }
1246
1247 switch(wParam) /* Hit test */
1248 {
1249 case HTCAPTION:
1250 /* stop processing if WS_MAXIMIZEBOX is missing */
1251 if (dwStyle & WS_MAXIMIZEBOX)
1252 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,
1253 (dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
1254 lParam);
1255 break;
1256
1257 case HTSYSMENU:
1258 if (!(GetClassLongA(getWindowHandle(),GCL_STYLE) & CS_NOCLOSE))
1259 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_CLOSE,lParam);
1260 break;
1261
1262 case HTHSCROLL:
1263 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_HSCROLL+HTHSCROLL,lParam);
1264 break;
1265
1266 case HTVSCROLL:
1267 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_VSCROLL+HTVSCROLL,lParam);
1268 break;
1269 }
1270
1271 return 0;
1272}
1273//******************************************************************************
1274//******************************************************************************
1275LONG Win32BaseWindow::HandleNCRButtonUp(WPARAM wParam,LPARAM lParam)
1276{
1277 switch(wParam)
1278 {
1279 case HTCAPTION:
1280 //we receive a HTCAPTION rbuttonup for RMB clicks on icon of minimized mdi windows
1281 if (fOS2Look && ((dwStyle & (WS_SYSMENU | WS_MINIMIZE)) == (WS_SYSMENU | WS_MINIMIZE)) )
1282 {
1283 return HandleNCRButtonUp(HTSYSMENU, lParam);
1284 }
1285
1286 if (GetActiveWindow() != Win32Hwnd)
1287 SetActiveWindow();
1288
1289 if (((GetActiveWindow() == Win32Hwnd) || isMDIChild()) && (dwStyle & WS_SYSMENU))
1290 {
1291 SendMessageA(getWindowHandle(), WM_SYSCOMMAND,SC_MOUSEMENU+HTCAPTION,lParam);
1292 }
1293 break;
1294
1295 case HTSYSMENU:
1296 if (fOS2Look && (dwStyle & WS_SYSMENU))
1297 {
1298 if (fOS2Look == OS2_APPEARANCE)
1299 SendMessageA( getWindowHandle(), WM_SYSCOMMAND,SC_MOUSEMENU+HTSYSMENU,lParam);
1300 else
1301 if (fOS2Look == OS2_APPEARANCE_SYSMENU)
1302 OSLibPostMessageDirect( getOS2FrameWindowHandle(), OSWM_SYSCOMMAND, OSSC_SYSMENU,0);
1303 }
1304 break;
1305
1306 default:
1307 break;
1308 }
1309
1310 return 0;
1311}
1312/***********************************************************************
1313 * NC_HandleSysCommand
1314 *
1315 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
1316 *
1317 */
1318LONG Win32BaseWindow::HandleSysCommand(WPARAM wParam,POINT *pt32)
1319{
1320 UINT uCommand = wParam & 0xFFF0;
1321
1322 switch (uCommand)
1323 {
1324 case SC_SIZE:
1325 {
1326 Frame_SysCommandSizeMove(this, wParam);
1327 break;
1328 }
1329
1330 case SC_MOVE:
1331 Frame_SysCommandSizeMove(this, wParam);
1332 break;
1333
1334 case SC_MINIMIZE:
1335 if(dwStyle & WS_MINIMIZEBOX)
1336 ShowWindow(SW_MINIMIZE);
1337 break;
1338
1339 case SC_MAXIMIZE:
1340 if(dwStyle & WS_MAXIMIZEBOX)
1341 if (fOS2Look && (getOldStyle() & WS_MINIMIZE))
1342 {
1343 //PF Yes this is bad we do things twice - first restore window
1344 //from iconic state and then quickly maximize. What is good is that
1345 //only frame rects are recalculated twice. I checked lots of other
1346 //ways - seems only this one is 100% bug-safe. This happens on every
1347 //minimize from icon to maximum routine so not so often at all.
1348 OSLibWinRestoreWindow(getOS2FrameWindowHandle());
1349 }
1350 ShowWindow(SW_MAXIMIZE);
1351 break;
1352
1353 case SC_RESTORE:
1354
1355 //PF Start PM restoration routine first if we restore from icon
1356 //so all internal PM logic will work - this routine will always
1357 //lead to ShowWindow(SW_RESTORE)
1358
1359 if (getOldStyle() & WS_MINIMIZE)
1360 OSLibWinRestoreWindow(getOS2FrameWindowHandle());
1361 else
1362 ShowWindow(SW_RESTORE);
1363 break;
1364
1365 case SC_CLOSE:
1366 return SendMessageA(getWindowHandle(), WM_CLOSE,0,0);
1367
1368 case SC_CONTEXTHELP:
1369 {
1370 //CB: todo
1371 break;
1372 }
1373
1374 case SC_VSCROLL:
1375 case SC_HSCROLL:
1376 TrackScrollBar(wParam,*pt32);
1377 break;
1378
1379 case SC_MOUSEMENU:
1380 MENU_TrackMouseMenuBar(Win32Hwnd,wParam & 0x000F,*pt32);
1381 break;
1382
1383 case SC_KEYMENU:
1384 MENU_TrackKbdMenuBar(Win32Hwnd,wParam,pt32->x);
1385 break;
1386
1387 case SC_TASKLIST:
1388// Stress case for drawing
1389#if 0
1390 {
1391 for(int i=0;i<25000;i++)
1392 {
1393 MSG msg;
1394
1395 InvalidateRect(Win32Hwnd, 0, 1);
1396 while(PeekMessageA(&msg, 0, 0, 0, TRUE) == TRUE)
1397 {
1398 DispatchMessageA(&msg);
1399 }
1400 }
1401 }
1402#else
1403 OSLibWinShowTaskList(getOS2WindowHandle());
1404#endif
1405 break;
1406
1407 case SC_SCREENSAVE:
1408 if (wParam == SC_ABOUTODIN) {
1409 if(ShellAboutA == 0) {
1410 HINSTANCE hShell32 = LoadLibraryA("SHELL32");
1411 if(hShell32 == 0)
1412 break;
1413 *(VOID **)&ShellAboutA = (VOID *)GetProcAddress(hShell32, "ShellAboutA");
1414 }
1415 ShellAboutA(Win32Hwnd,"Odin","Odin alpha release compiled with IBM VAC++",0);
1416 }
1417#ifdef DEBUG
1418 //SvL: Do NOT turn this into a dprintf.
1419 else
1420 if (wParam == SC_PUTMARK)
1421 WriteLog(("Mark requested by user\n"));
1422 else
1423 if (wParam == SC_DEBUGINT3)
1424 DebugInt3();
1425#endif
1426 break;
1427
1428 case SC_HOTKEY:
1429 case SC_ARRANGE:
1430 case SC_NEXTWINDOW:
1431 case SC_PREVWINDOW:
1432 break;
1433 }
1434 return 0;
1435}
1436/*****************************************************************************
1437 * Name : VOID WIN32API DrawCaption
1438 * Purpose : The DrawCaption function draws a window caption.
1439 * Parameters: HDC hdc handle of device context
1440 * LPRECT lprc address of bounding rectangle coordinates
1441 * HFONT hfont handle of font for caption
1442 * HICON hicon handle of icon in caption
1443 * LPSTR lpszText address of caption string
1444 * WORD wFlags drawing options
1445 * Variables :
1446 * Result :
1447 * Remark :
1448 * Status : UNTESTED STUB
1449 *
1450 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
1451 *****************************************************************************/
1452BOOL WIN32API DrawCaption (HWND hwnd,HDC hdc,const RECT *lprc,UINT wFlags)
1453{
1454 dprintf(("USER32: DrawCaption"));
1455
1456 return DrawCaptionTempA(hwnd,hdc,lprc,0,0,NULL,wFlags & 0x1F);
1457}
1458//******************************************************************************
1459// CB: this code is a subset of Win32BaseWindow::DrawCaption
1460// todo: move Win32BaseWindow:DrawCaption to this function
1461//******************************************************************************
1462BOOL WIN32API DrawCaptionTemp(HWND hwnd,HDC hdc,const RECT *rect,HFONT hFont,HICON hIcon,LPWSTR str,UINT uFlags,BOOL unicode)
1463{
1464 RECT rc = *rect;
1465
1466 /* drawing background */
1467 if (uFlags & DC_INBUTTON)
1468 {
1469 FillRect (hdc, &rc, GetSysColorBrush (COLOR_3DFACE));
1470
1471 if (uFlags & DC_ACTIVE)
1472 {
1473 HBRUSH hbr = SelectObject (hdc, GetPattern55AABrush ());
1474 PatBlt (hdc, rc.left, rc.top,
1475 rc.right-rc.left, rc.bottom-rc.top, 0xFA0089);
1476 SelectObject (hdc, hbr);
1477 }
1478 } else
1479 {
1480 FillRect (hdc, &rc, GetSysColorBrush ((uFlags & DC_ACTIVE) ?
1481 COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
1482 }
1483
1484 /* drawing icon */
1485 if ((uFlags & DC_ICON) && !(uFlags & DC_SMALLCAP))
1486 {
1487 POINT pt;
1488
1489 pt.x = rc.left + 2;
1490 pt.y = (rc.bottom + rc.top - GetSystemMetrics(SM_CYSMICON)) / 2;
1491
1492 if (hIcon)
1493 {
1494 DrawIconEx (hdc, pt.x, pt.y, hIcon, GetSystemMetrics(SM_CXSMICON),
1495 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
1496 } else
1497 {
1498 Win32BaseWindow *win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
1499
1500 if (!win32wnd) return 0;
1501
1502 DrawIconEx (hdc, pt.x, pt.y, win32wnd->IconForWindow(ICON_SMALL),
1503 GetSystemMetrics(SM_CXSMICON),
1504 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
1505 }
1506
1507 rc.left += (rc.bottom - rc.top);
1508 }
1509
1510 /* drawing text */
1511 if (uFlags & DC_TEXT)
1512 {
1513 HFONT hOldFont;
1514
1515 if (uFlags & DC_INBUTTON)
1516 SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
1517 else if (uFlags & DC_ACTIVE)
1518 SetTextColor (hdc, GetSysColor (COLOR_CAPTIONTEXT));
1519 else
1520 SetTextColor (hdc, GetSysColor (COLOR_INACTIVECAPTIONTEXT));
1521
1522 SetBkMode (hdc, TRANSPARENT);
1523
1524 if (hFont)
1525 hOldFont = SelectObject (hdc, hFont);
1526 else
1527 {
1528 NONCLIENTMETRICSA nclm;
1529 HFONT hNewFont;
1530
1531 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1532 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1533 hNewFont = CreateFontIndirectA ((uFlags & DC_SMALLCAP) ?
1534 &nclm.lfSmCaptionFont : &nclm.lfCaptionFont);
1535 hOldFont = SelectObject (hdc, hNewFont);
1536 }
1537
1538 if (str)
1539 {
1540 if (unicode)
1541 DrawTextW(hdc,str,-1,&rc,DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
1542 else
1543 DrawTextA(hdc,(LPSTR)str,-1,&rc,DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
1544 } else
1545 {
1546 CHAR szText[128];
1547 INT nLen;
1548
1549 nLen = GetWindowTextA (hwnd, szText, 128);
1550 DrawTextA (hdc, szText, nLen, &rc,
1551 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
1552 }
1553
1554 if (hFont)
1555 SelectObject (hdc, hOldFont);
1556 else
1557 DeleteObject (SelectObject (hdc, hOldFont));
1558 }
1559
1560 /* drawing focus ??? */
1561 //if (uFlags & 0x2000)
1562 // FIXME("undocumented flag (0x2000)!\n");
1563
1564 return 0;
1565}
1566/***********************************************************************
1567 * DrawCaptionTemp32A [USER32.599]
1568 *
1569 * PARAMS
1570 *
1571 * RETURNS
1572 * Success:
1573 * Failure:
1574 */
1575BOOL WIN32API DrawCaptionTempA(HWND hwnd,HDC hdc,const RECT *rect,HFONT hFont,HICON hIcon,LPCSTR str,UINT uFlags)
1576{
1577 dprintf(("USER32: DrawCaptionTempA"));
1578
1579 return DrawCaptionTemp(hwnd,hdc,rect,hFont,hIcon,(LPWSTR)str,uFlags,FALSE);
1580}
1581/***********************************************************************
1582 * DrawCaptionTemp32W [USER32.602]
1583 *
1584 * PARAMS
1585 *
1586 * RETURNS
1587 * Success:
1588 * Failure:
1589 */
1590BOOL WIN32API DrawCaptionTempW (HWND hwnd,HDC hdc,const RECT *rect,HFONT hFont,HICON hIcon,LPCWSTR str,UINT uFlags)
1591{
1592 dprintf(("USER32: DrawCaptionTempA"));
1593
1594 return DrawCaptionTemp(hwnd,hdc,rect,hFont,hIcon,(LPWSTR)str,uFlags,TRUE);
1595}
1596
Note: See TracBrowser for help on using the repository browser.