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

Last change on this file since 2912 was 2873, checked in by cbratschi, 26 years ago

export 55AA pattern for COMCTL32, edit EN_CHANGED fix

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