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

Last change on this file since 21356 was 21356, checked in by rlwalsh, 16 years ago

eliminate VACPP warning & info msgs - see Ticket #1

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