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

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

fixes for minimizing frame windows + WM_BUTTONxMOTIONSTART/END handling

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