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

Last change on this file since 5215 was 5215, checked in by sandervl, 25 years ago

ScrollWindow, maximized window + system menu fixes

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