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

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

focus fixes + changes for dinput

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