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

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

Changes & fixes for minimized windows

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