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

Last change on this file since 7788 was 7063, checked in by sandervl, 24 years ago

custom build update

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