source: trunk/src/user32/win32wbasepaint.cpp@ 2394

Last change on this file since 2394 was 2394, checked in by sandervl, 26 years ago

titlebar fix + gradient titlebar look

File size: 33.5 KB
Line 
1/* $Id: win32wbasepaint.cpp,v 1.5 2000-01-09 19:46:27 sandervl Exp $ */
2/*
3 * Win32 Window Base Class for OS/2
4 *
5 * Copyright 2000 Sander van Leeuwen (sandervl@xs4all.nl)
6 * Copyright 2000 Christoph Bratschi (cbratschi@datacomm.ch)
7 *
8 * Based on Wine code (windows\nonclient.c)
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 "oslibwin.h"
29#include "oslibmsg.h"
30#include "oslibutil.h"
31#include "oslibgdi.h"
32#include "oslibres.h"
33#include "oslibmenu.h"
34#include "oslibdos.h"
35#include "syscolor.h"
36#include "win32wndhandle.h"
37#include "dc.h"
38#include "pmframe.h"
39#include "pmtitlebar.h"
40#include "win32wdesktop.h"
41#include "pmwindow.h"
42#include "controls.h"
43#include "initterm.h"
44
45#define SC_ABOUTODIN (SC_SCREENSAVE+1)
46#define SC_PUTMARK (SC_SCREENSAVE+2)
47
48#define HAS_DLGFRAME(style,exStyle) \
49 (((exStyle) & WS_EX_DLGMODALFRAME) || \
50 (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
51
52#define HAS_THICKFRAME(style,exStyle) \
53 (((style) & WS_THICKFRAME) && \
54 !((exStyle) & WS_EX_DLGMODALFRAME))
55
56#define HAS_THINFRAME(style) \
57 (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
58
59#define HAS_BIGFRAME(style,exStyle) \
60 (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
61 ((exStyle) & WS_EX_DLGMODALFRAME))
62
63#define HAS_ANYFRAME(style,exStyle) \
64 (((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
65 ((exStyle) & WS_EX_DLGMODALFRAME) || \
66 !((style) & (WS_CHILD | WS_POPUP)))
67
68#define HAS_3DFRAME(exStyle) \
69 ((exStyle & WS_EX_CLIENTEDGE) || (exStyle & WS_EX_STATICEDGE) || (exStyle & WS_EX_WINDOWEDGE))
70
71#define HAS_BORDER(style, exStyle) \
72 ((style & WS_BORDER) || HAS_THICKFRAME(style) || HAS_DLGFRAME(style,exStyle))
73
74#define IS_OVERLAPPED(style) \
75 !(style & (WS_CHILD | WS_POPUP))
76
77#define HAS_MENU(w) (!((w)->getStyle() & WS_CHILD) && ((w)->getWindowId() != 0))
78
79static HBITMAP hbitmapClose = 0;
80static HBITMAP hbitmapCloseD = 0;
81static HBITMAP hbitmapMinimize = 0;
82static HBITMAP hbitmapMinimizeD = 0;
83static HBITMAP hbitmapMaximize = 0;
84static HBITMAP hbitmapMaximizeD = 0;
85static HBITMAP hbitmapRestore = 0;
86static HBITMAP hbitmapRestoreD = 0;
87static HMENU hSysMenu = 0;
88
89static INT (* WINAPI ShellAboutA)(HWND,LPCSTR,LPCSTR,HICON) = 0;
90
91BYTE lpGrayMask[] = { 0xAA, 0xA0,
92 0x55, 0x50,
93 0xAA, 0xA0,
94 0x55, 0x50,
95 0xAA, 0xA0,
96 0x55, 0x50,
97 0xAA, 0xA0,
98 0x55, 0x50,
99 0xAA, 0xA0,
100 0x55, 0x50};
101
102//******************************************************************************
103//******************************************************************************
104VOID Win32BaseWindow::TrackMinMaxBox(WORD wParam)
105{
106 MSG msg;
107 HDC hdc;
108 BOOL pressed = TRUE;
109 UINT state;
110
111 if (wParam == HTMINBUTTON)
112 {
113 /* If the style is not present, do nothing */
114 if (!(dwStyle & WS_MINIMIZEBOX))
115 return;
116 /* Check if the sysmenu item for minimize is there */
117 state = GetMenuState(hSysMenu,SC_MINIMIZE,MF_BYCOMMAND);
118 }
119 else
120 {
121 /* If the style is not present, do nothing */
122 if (!(dwStyle & WS_MAXIMIZEBOX))
123 return;
124
125 /* Check if the sysmenu item for maximize is there */
126 state = GetMenuState(hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
127 }
128 SetCapture(getWindowHandle());
129 hdc = GetWindowDC(getWindowHandle());
130 if (wParam == HTMINBUTTON)
131 DrawMinButton(hdc,TRUE,FALSE);
132 else
133 DrawMaxButton(hdc,TRUE,FALSE);
134
135 do
136 {
137 BOOL oldstate = pressed;
138
139 GetMessageA(&msg, getWindowHandle(), 0, 0);
140 pressed = (HandleNCHitTest(msg.pt) == wParam);
141 if (pressed != oldstate)
142 {
143 if (wParam == HTMINBUTTON)
144 DrawMinButton(hdc,pressed,FALSE);
145 else
146 DrawMaxButton(hdc,pressed,FALSE);
147 }
148 }
149
150 while (msg.message != WM_NCLBUTTONUP);
151
152 if (wParam == HTMINBUTTON)
153 DrawMinButton(hdc,FALSE,FALSE);
154 else
155 DrawMaxButton(hdc,FALSE,FALSE);
156
157 ReleaseCapture();
158 ReleaseDC(getWindowHandle(), hdc);
159 /* If the item minimize or maximize of the sysmenu are not there */
160 /* or if the style is not present, do nothing */
161 if ((!pressed) || (state == 0xFFFFFFFF))
162 return;
163
164 if (wParam == HTMINBUTTON)
165 SendInternalMessageA(WM_SYSCOMMAND,SC_MINIMIZE,*(LPARAM*)&msg.pt);
166 else
167 SendInternalMessageA(WM_SYSCOMMAND,IsZoomed(Win32Hwnd) ? SC_RESTORE:SC_MAXIMIZE,*(LPARAM*)&msg.pt);
168}
169//******************************************************************************
170//******************************************************************************
171VOID Win32BaseWindow::TrackCloseButton(WORD wParam)
172{
173 MSG msg;
174 HDC hdc;
175 BOOL pressed = TRUE;
176 UINT state;
177
178 if (hSysMenu == 0)
179 return;
180
181 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
182
183 /* If the item close of the sysmenu is disabled or not there do nothing */
184 if((state & MF_DISABLED) || (state & MF_GRAYED) || (state == 0xFFFFFFFF))
185 return;
186 hdc = GetWindowDC(getWindowHandle());
187 SetCapture(getWindowHandle());
188 DrawCloseButton(hdc,TRUE,FALSE);
189 do
190 {
191 BOOL oldstate = pressed;
192
193 GetMessageA(&msg, getWindowHandle(), 0, 0);
194 pressed = (HandleNCHitTest(msg.pt) == wParam);
195
196 if (pressed != oldstate)
197 DrawCloseButton(hdc, pressed, FALSE);
198 }
199 while (msg.message != WM_NCLBUTTONUP);
200
201 DrawCloseButton(hdc,FALSE,FALSE);
202 ReleaseCapture();
203 ReleaseDC(getWindowHandle(), hdc);
204
205 if (!pressed)
206 return;
207
208 SendInternalMessageA(WM_SYSCOMMAND,SC_CLOSE,*(LPARAM*)&msg.pt);
209}
210//******************************************************************************
211//******************************************************************************
212LONG Win32BaseWindow::HandleNCLButtonUp(WPARAM wParam,LPARAM lParam)
213{
214 switch(wParam) /* Hit test */
215 {
216 case HTMINBUTTON:
217 SendInternalMessageA(WM_SYSCOMMAND,SC_MINIMIZE,lParam);
218 break;
219
220 case HTMAXBUTTON:
221 SendInternalMessageA(WM_SYSCOMMAND,SC_MAXIMIZE,lParam);
222 break;
223
224 case HTCLOSE:
225 SendInternalMessageA(WM_SYSCOMMAND,SC_CLOSE,lParam);
226 break;
227 }
228
229 return 0;
230}
231/***********************************************************************
232 * NC_HandleNCLButtonDblClk
233 *
234 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
235 */
236LONG Win32BaseWindow::HandleNCLButtonDblClk(WPARAM wParam,LPARAM lParam)
237{
238 /*
239 * if this is an icon, send a restore since we are handling
240 * a double click
241 */
242 if (dwStyle & WS_MINIMIZE)
243 {
244 SendInternalMessageA(WM_SYSCOMMAND,SC_RESTORE,lParam);
245 return 0;
246 }
247
248 switch(wParam) /* Hit test */
249 {
250 case HTCAPTION:
251 /* stop processing if WS_MAXIMIZEBOX is missing */
252 if (dwStyle & WS_MAXIMIZEBOX)
253 SendInternalMessageA(WM_SYSCOMMAND,
254 (dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
255 lParam);
256 break;
257
258 case HTSYSMENU:
259 if (!(GetClassWord(Win32Hwnd,GCW_STYLE) & CS_NOCLOSE))
260 SendInternalMessageA(WM_SYSCOMMAND,SC_CLOSE,lParam);
261 break;
262
263 case HTHSCROLL:
264 SendInternalMessageA(WM_SYSCOMMAND,SC_HSCROLL+HTHSCROLL,lParam);
265 break;
266
267 case HTVSCROLL:
268 SendInternalMessageA(WM_SYSCOMMAND,SC_VSCROLL+HTVSCROLL,lParam);
269 break;
270 }
271
272 return 0;
273}
274//******************************************************************************
275//******************************************************************************
276LONG Win32BaseWindow::HandleNCLButtonDown(WPARAM wParam,LPARAM lParam)
277{
278 switch(wParam) /* Hit test */
279 {
280 case HTCAPTION:
281 SetActiveWindow();
282 if (GetActiveWindow() == Win32Hwnd)
283 SendInternalMessageA(WM_SYSCOMMAND,SC_MOVE+HTCAPTION,lParam);
284 break;
285
286 case HTSYSMENU:
287 if(dwStyle & WS_SYSMENU )
288 {
289 if( !(dwStyle & WS_MINIMIZE) )
290 {
291 HDC hDC = GetWindowDC(Win32Hwnd);
292 DrawSysButton(hDC,TRUE);
293 ReleaseDC(Win32Hwnd,hDC);
294 }
295 SendInternalMessageA(WM_SYSCOMMAND,SC_MOUSEMENU+HTSYSMENU,lParam);
296 }
297 break;
298
299 case HTMENU:
300 SendInternalMessageA(WM_SYSCOMMAND,SC_MOUSEMENU,lParam);
301 break;
302
303 case HTHSCROLL:
304 SendInternalMessageA(WM_SYSCOMMAND,SC_HSCROLL+HTHSCROLL,lParam);
305 break;
306
307 case HTVSCROLL:
308 SendInternalMessageA(WM_SYSCOMMAND,SC_VSCROLL+HTVSCROLL,lParam);
309 break;
310
311 case HTMINBUTTON:
312 case HTMAXBUTTON:
313 TrackMinMaxBox(wParam);
314 break;
315
316 case HTCLOSE:
317 TrackCloseButton(wParam);
318 break;
319
320 case HTLEFT:
321 case HTRIGHT:
322 case HTTOP:
323 case HTTOPLEFT:
324 case HTTOPRIGHT:
325 case HTBOTTOM:
326 case HTBOTTOMLEFT:
327 case HTBOTTOMRIGHT:
328 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
329 SendInternalMessageA(WM_SYSCOMMAND,SC_SIZE+wParam-2,lParam);
330 break;
331 case HTBORDER:
332 break;
333 }
334
335 return 0;
336}
337//******************************************************************************
338//******************************************************************************
339LONG Win32BaseWindow::HandleNCHitTest(POINT pt)
340{
341 RECT rect;
342
343 rect = *getWindowRect();
344 if (!PtInRect(&rect,pt)) return HTNOWHERE;
345
346 if (dwStyle & WS_MINIMIZE) return HTCAPTION;
347
348 if (!(flags & WIN_MANAGED))
349 {
350 /* Check borders */
351 if (HAS_THICKFRAME(dwStyle,dwExStyle))
352 {
353 InflateRect(&rect,-GetSystemMetrics(SM_CXFRAME),-GetSystemMetrics(SM_CYFRAME));
354 if (!PtInRect(&rect,pt))
355 {
356 /* Check top sizing border */
357 if (pt.y < rect.top)
358 {
359 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
360 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
361 return HTTOP;
362 }
363 /* Check bottom sizing border */
364 if (pt.y >= rect.bottom)
365 {
366 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
367 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
368 return HTBOTTOM;
369 }
370 /* Check left sizing border */
371 if (pt.x < rect.left)
372 {
373 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
374 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
375 return HTLEFT;
376 }
377 /* Check right sizing border */
378 if (pt.x >= rect.right)
379 {
380 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
381 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
382 return HTRIGHT;
383 }
384 }
385 } else /* No thick frame */
386 {
387 if (HAS_DLGFRAME(dwStyle,dwExStyle))
388 InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
389 else if (HAS_THINFRAME(dwStyle ))
390 InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
391 if (!PtInRect( &rect, pt )) return HTBORDER;
392 }
393
394 /* Check caption */
395
396 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
397 {
398 if (dwExStyle & WS_EX_TOOLWINDOW)
399 rect.top += GetSystemMetrics(SM_CYSMCAPTION)-1;
400 else
401 rect.top += GetSystemMetrics(SM_CYCAPTION)-1;
402 if (!PtInRect(&rect,pt))
403 {
404 /* Check system menu */
405 if(dwStyle & WS_SYSMENU)
406 {
407 /* Check if there is an user icon */
408 HICON hIcon = (HICON) GetClassLongA(Win32Hwnd, GCL_HICONSM);
409 if(!hIcon) hIcon = (HICON) GetClassLongA(Win32Hwnd, GCL_HICON);
410
411 /* If there is an icon associated with the window OR */
412 /* If there is no hIcon specified and this is not a modal dialog, */
413 /* there is a system menu icon. */
414 if((hIcon != 0) || (!(dwStyle & DS_MODALFRAME)))
415 rect.left += GetSystemMetrics(SM_CYCAPTION) - 1;
416 }
417 if (pt.x < rect.left) return HTSYSMENU;
418
419 /* Check close button */
420 if (dwStyle & WS_SYSMENU)
421 rect.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
422 if (pt.x > rect.right) return HTCLOSE;
423
424 /* Check maximize box */
425 /* In win95 there is automatically a Maximize button when there is a minimize one*/
426 if ((dwStyle & WS_MAXIMIZEBOX)|| (dwStyle & WS_MINIMIZEBOX))
427 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
428 if (pt.x > rect.right) return HTMAXBUTTON;
429
430 /* Check minimize box */
431 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
432 if ((dwStyle & WS_MINIMIZEBOX)||(dwStyle & WS_MAXIMIZEBOX))
433 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
434
435 if (pt.x > rect.right) return HTMINBUTTON;
436 return HTCAPTION;
437 }
438 }
439 }
440
441 /* Check client area */
442
443 ScreenToClient(Win32Hwnd,&pt);
444 rect = *getClientRect();
445 if (PtInRect(&rect,pt)) return HTCLIENT;
446
447 /* Check vertical scroll bar */
448
449 if (dwStyle & WS_VSCROLL)
450 {
451 rect.right += GetSystemMetrics(SM_CXVSCROLL);
452 if (PtInRect( &rect, pt )) return HTVSCROLL;
453 }
454
455 /* Check horizontal scroll bar */
456
457 if (dwStyle & WS_HSCROLL)
458 {
459 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
460 if (PtInRect( &rect, pt ))
461 {
462 /* Check size box */
463 if ((dwStyle & WS_VSCROLL) &&
464 (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
465 return (dwStyle & WS_CHILD) ? HTSIZE:HTBOTTOMRIGHT;
466 return HTHSCROLL;
467 }
468 }
469
470 /* Check menu bar */
471
472 if (HAS_MENU(this))
473 {
474 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
475 return HTMENU;
476 }
477
478 /* Should never get here */
479 return HTERROR;
480}
481
482//******************************************************************************
483//******************************************************************************
484VOID Win32BaseWindow::GetInsideRect(RECT *rect)
485{
486 rect->top = rect->left = 0;
487 rect->right = getWindowRect()->right - getWindowRect()->left;
488 rect->bottom = getWindowRect()->bottom - getWindowRect()->top;
489
490 if ((dwStyle & WS_ICONIC) || (flags & WIN_MANAGED)) return;
491
492 /* Remove frame from rectangle */
493 if (HAS_THICKFRAME(dwStyle,dwExStyle))
494 {
495 InflateRect( rect, -GetSystemMetrics(SM_CXSIZEFRAME), -GetSystemMetrics(SM_CYSIZEFRAME) );
496 }
497 else if (HAS_DLGFRAME(dwStyle,dwExStyle ))
498 {
499 InflateRect( rect, -GetSystemMetrics(SM_CXFIXEDFRAME), -GetSystemMetrics(SM_CYFIXEDFRAME));
500 }
501 else if (HAS_THINFRAME(dwStyle))
502 {
503 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
504 }
505
506 /* We have additional border information if the window
507 * is a child (but not an MDI child) */
508 if ( (dwStyle & WS_CHILD) &&
509 ( (dwExStyle & WS_EX_MDICHILD) == 0 ) )
510 {
511 if (dwExStyle & WS_EX_CLIENTEDGE)
512 InflateRect (rect, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE));
513
514 if (dwExStyle & WS_EX_STATICEDGE)
515 InflateRect (rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
516 }
517}
518//******************************************************************************
519//******************************************************************************
520VOID Win32BaseWindow::DrawFrame(HDC hdc,RECT *rect,BOOL dlgFrame,BOOL active)
521{
522 INT width, height;
523 HBRUSH oldBrush;
524
525 if (dlgFrame)
526 {
527 width = GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
528 height = GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
529 }
530 else
531 {
532 width = GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXEDGE);
533 height = GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYEDGE);
534 }
535
536 oldBrush = SelectObject(hdc,GetSysColorBrush(active ? COLOR_ACTIVEBORDER:COLOR_INACTIVEBORDER));
537
538 /* Draw frame */
539
540 PatBlt(hdc,rect->left,rect->top,rect->right-rect->left,height,PATCOPY);
541 PatBlt(hdc,rect->left,rect->top,width,rect->bottom-rect->top,PATCOPY);
542 PatBlt(hdc,rect->left,rect->bottom-1,rect->right-rect->left,-height,PATCOPY);
543 PatBlt(hdc,rect->right-1,rect->top,-width,rect->bottom-rect->top,PATCOPY);
544 SelectObject(hdc,oldBrush);
545
546 InflateRect(rect,-width,-height);
547}
548//******************************************************************************
549//******************************************************************************
550BOOL Win32BaseWindow::DrawSysButton(HDC hdc,BOOL down)
551{
552 HICON hIcon;
553 RECT rect;
554
555 GetInsideRect(&rect);
556
557 hIcon = (HICON) GetClassLongA(Win32Hwnd, GCL_HICONSM);
558 if(!hIcon) hIcon = (HICON) GetClassLongA(Win32Hwnd, GCL_HICON);
559
560 /* If there is no hIcon specified or this is not a modal dialog, */
561 /* get the default one. */
562 if(hIcon == 0)
563 if (!(dwStyle & DS_MODALFRAME))
564 hIcon = LoadImageA(0, MAKEINTRESOURCEA(OIC_ODINICON), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
565
566 if (hIcon)
567 DrawIconEx (hdc, rect.left + 2, rect.top + 2, hIcon,
568 GetSystemMetrics(SM_CXSMICON),
569 GetSystemMetrics(SM_CYSMICON),
570 0, 0, DI_NORMAL);
571
572 return (hIcon != 0);
573}
574//******************************************************************************
575//******************************************************************************
576BOOL Win32BaseWindow::DrawGrayButton(HDC hdc,int x,int y)
577{
578 HBITMAP hMaskBmp;
579 HDC hdcMask = CreateCompatibleDC (0);
580 HBRUSH hOldBrush;
581 hMaskBmp = CreateBitmap (12, 10, 1, 1, lpGrayMask);
582
583 if(hMaskBmp == 0)
584 return FALSE;
585
586 SelectObject (hdcMask, hMaskBmp);
587
588 /* Draw the grayed bitmap using the mask */
589 hOldBrush = SelectObject (hdc, RGB(128, 128, 128));
590 BitBlt (hdc, x, y, 12, 10,
591 hdcMask, 0, 0, 0xB8074A);
592
593 /* Clean up */
594 SelectObject (hdc, hOldBrush);
595 DeleteObject(hMaskBmp);
596 DeleteDC (hdcMask);
597
598 return TRUE;
599}
600//******************************************************************************
601//******************************************************************************
602VOID Win32BaseWindow::DrawCloseButton(HDC hdc,BOOL down,BOOL bGrayed)
603{
604 RECT rect;
605 HDC hdcMem;
606
607 BITMAP bmp;
608 HBITMAP hBmp, hOldBmp;
609
610 GetInsideRect(&rect);
611
612 hdcMem = CreateCompatibleDC( hdc );
613 hBmp = down ? hbitmapCloseD : hbitmapClose;
614 hOldBmp = SelectObject (hdcMem, hBmp);
615 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
616
617 BitBlt (hdc, rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2,
618 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
619 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);
620
621 if(bGrayed)
622 DrawGrayButton(hdc,rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2 + 2,
623 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
624
625 SelectObject (hdcMem, hOldBmp);
626 DeleteDC (hdcMem);
627}
628//******************************************************************************
629//******************************************************************************
630VOID Win32BaseWindow::DrawMaxButton(HDC hdc,BOOL down,BOOL bGrayed)
631{
632 RECT rect;
633 HDC hdcMem;
634
635 BITMAP bmp;
636 HBITMAP hBmp,hOldBmp;
637
638 GetInsideRect(&rect);
639 hdcMem = CreateCompatibleDC( hdc );
640 hBmp = IsZoomed(Win32Hwnd) ?
641 (down ? hbitmapRestoreD : hbitmapRestore ) :
642 (down ? hbitmapMaximizeD: hbitmapMaximize);
643 hOldBmp=SelectObject( hdcMem, hBmp );
644 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
645
646 if (dwStyle & WS_SYSMENU)
647 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
648
649 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
650 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
651 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
652
653 if(bGrayed)
654 DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
655 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
656
657
658 SelectObject (hdcMem, hOldBmp);
659 DeleteDC( hdcMem );
660}
661//******************************************************************************
662//******************************************************************************
663VOID Win32BaseWindow::DrawMinButton(HDC hdc,BOOL down,BOOL bGrayed)
664{
665 RECT rect;
666 HDC hdcMem;
667
668 BITMAP bmp;
669 HBITMAP hBmp,hOldBmp;
670
671 GetInsideRect(&rect);
672
673 hdcMem = CreateCompatibleDC( hdc );
674 hBmp = down ? hbitmapMinimizeD : hbitmapMinimize;
675 hOldBmp= SelectObject( hdcMem, hBmp );
676 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
677
678 if (dwStyle & WS_SYSMENU)
679 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
680
681 /* In win 95 there is always a Maximize box when there is a Minimize one */
682 if ((dwStyle & WS_MAXIMIZEBOX) || (dwStyle & WS_MINIMIZEBOX))
683 rect.right += -1 - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2;
684
685 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
686 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
687 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
688
689 if(bGrayed)
690 DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
691 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
692
693
694 SelectObject (hdcMem, hOldBmp);
695 DeleteDC( hdcMem );
696}
697//******************************************************************************
698//******************************************************************************
699VOID Win32BaseWindow::DrawCaption(HDC hdc,RECT *rect,BOOL active)
700{
701 RECT r = *rect;
702 char buffer[256];
703 HPEN hPrevPen;
704 HMENU hSysMenu;
705
706 hPrevPen = SelectObject( hdc, GetSysColorPen(COLOR_3DFACE) );
707 MoveToEx( hdc, r.left, r.bottom - 1, NULL );
708 LineTo( hdc, r.right, r.bottom - 1 );
709 SelectObject( hdc, hPrevPen );
710 r.bottom--;
711
712 //CB: todo:
713 //COLOR_GRADIENTACTIVECAPTION
714 //COLOR_GRADIENTINACTIVECAPTION
715 //-> end color
716
717 if (SYSCOLOR_GetUseWinColors())
718 {
719 COLORREF startColor = GetSysColor(active ? COLOR_ACTIVECAPTION:COLOR_INACTIVECAPTION),endColor = GetSysColor(active ? COLOR_GRADIENTACTIVECAPTION:COLOR_GRADIENTINACTIVECAPTION);
720
721 if (startColor == endColor)
722 FillRect(hdc,&r,GetSysColorBrush(startColor));
723 else
724 {
725 INT rDiff = GetRValue(endColor)-GetRValue(startColor);
726 INT gDiff = GetGValue(endColor)-GetGValue(startColor);
727 INT bDiff = GetBValue(endColor)-GetBValue(startColor);
728 INT steps = MAX(MAX(abs(rDiff),abs(gDiff)),abs(bDiff));
729 INT w = r.right-r.left;
730 RECT r2;
731
732 if (w < steps) steps = w;
733 r2.left = r2.right = r.left;
734 r2.top = r.top;
735 r2.bottom = r.bottom;
736 for (INT x = 0;x <= steps;x++)
737 {
738 COLORREF color = RGB(GetRValue(startColor)+rDiff*x/steps,GetGValue(startColor)+gDiff*x/steps,GetBValue(startColor)+bDiff*x/steps);
739 HBRUSH brush = CreateSolidBrush(color);
740
741 r2.left = r2.right;
742 r2.right = r.left+w*x/steps;
743 FillRect(hdc,&r2,brush);
744 DeleteObject(brush);
745 }
746 }
747 }
748 else FillRect(hdc,&r,GetSysColorBrush(active ? COLOR_ACTIVECAPTION:COLOR_INACTIVECAPTION));
749
750 if (!hbitmapClose)
751 {
752 if (!(hbitmapClose = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CLOSE)))) return;
753 hbitmapCloseD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CLOSED));
754 hbitmapMinimize = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_REDUCE));
755 hbitmapMinimizeD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_REDUCED));
756 hbitmapMaximize = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_ZOOM));
757 hbitmapMaximizeD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_ZOOMD));
758 hbitmapRestore = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_RESTORE));
759 hbitmapRestoreD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_RESTORED));
760 }
761
762 if ((dwStyle & WS_SYSMENU) && !(dwExStyle & WS_EX_TOOLWINDOW))
763 {
764 if (DrawSysButton(hdc,FALSE))
765 r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
766 }
767
768 if (dwStyle & WS_SYSMENU)
769 {
770 UINT state;
771 /* Go get the sysmenu */
772 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
773
774 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
775 DrawCloseButton(hdc, FALSE,
776 ((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
777 r.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
778
779 if ((dwStyle & WS_MAXIMIZEBOX) || (dwStyle & WS_MINIMIZEBOX))
780 {
781 /* In win95 the two buttons are always there */
782 /* But if the menu item is not in the menu they're disabled*/
783
784 DrawMaxButton(hdc, FALSE, (!(dwStyle & WS_MAXIMIZEBOX)));
785 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
786
787 DrawMinButton(hdc, FALSE, (!(dwStyle & WS_MINIMIZEBOX)));
788 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
789 }
790 }
791
792 if (GetWindowTextA(buffer, sizeof(buffer) ))
793 {
794 NONCLIENTMETRICSA nclm;
795 HFONT hFont, hOldFont;
796 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
797 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
798 if (dwExStyle & WS_EX_TOOLWINDOW)
799 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
800 else
801 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
802 hOldFont = SelectObject (hdc, hFont);
803 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
804 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
805 SetBkMode( hdc, TRANSPARENT );
806 r.left += 2;
807 DrawTextA( hdc, buffer, -1, &r,
808 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
809 DeleteObject (SelectObject (hdc, hOldFont));
810 }
811}
812//******************************************************************************
813//******************************************************************************
814VOID Win32BaseWindow::HandleNCPaint(HRGN clip, BOOL suppress_menupaint)
815{
816 BOOL active = flags & WIN_NCACTIVATED;
817 HDC hdc;
818 RECT rect,rectClip,rfuzz;
819
820 if (dwStyle & WS_MINIMIZE) return;
821
822 //Load system menu (once)
823 if(!hSysMenu) {
824 hSysMenu = LoadMenuA(hInstanceUser32, (LPCSTR)"SYSMENU");
825 }
826
827 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
828 the call to GetDCEx implying that it is allowed not to use it either.
829 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
830 will cause clipRgn to be deleted after ReleaseDC().
831 Now, how is the "system" supposed to tell what happened?
832 */
833
834 if (!(hdc = GetDCEx( Win32Hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
835 ((clip > 1) ?(DCX_INTERSECTRGN /*| DCX_KEEPCLIPRGN*/) : 0) ))) return;
836
837 rect.top = rect.left = 0;
838 rect.right = getWindowRect()->right - getWindowRect()->left;
839 rect.bottom = getWindowRect()->bottom - getWindowRect()->top;
840
841 if( clip > 1 )
842 GetRgnBox( clip, &rectClip );
843 else
844 {
845 clip = 0;
846 rectClip = rect;
847 }
848
849 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
850
851 if (HAS_BIGFRAME( dwStyle, dwExStyle))
852 {
853 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
854 }
855 if (HAS_THICKFRAME( dwStyle, dwExStyle ))
856 DrawFrame(hdc, &rect, FALSE, active );
857 else if (HAS_DLGFRAME( dwStyle, dwExStyle ))
858 DrawFrame( hdc, &rect, TRUE, active );
859 else if (HAS_THINFRAME( dwStyle ))
860 {
861 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
862 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
863 }
864
865 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
866 {
867 RECT r = rect;
868 if (dwExStyle & WS_EX_TOOLWINDOW)
869 {
870 r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
871 rect.top += GetSystemMetrics(SM_CYSMCAPTION);
872 }
873 else
874 {
875 r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
876 rect.top += GetSystemMetrics(SM_CYCAPTION);
877 }
878 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
879 DrawCaption(hdc, &r, active);
880 }
881
882#if 0 //CB: todo
883 if (HAS_MENU(wndPtr))
884 {
885 RECT r = rect;
886 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
887
888 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ) + 1;
889 }
890
891 if (dwExStyle & WS_EX_CLIENTEDGE)
892 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
893
894 if (dwExStyle & WS_EX_STATICEDGE)
895 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
896
897 /* Draw the scroll-bars */
898#if 0 //CB: todo
899 if (dwStyle & WS_VSCROLL)
900 SCROLL_DrawScrollBar(hwnd,hdc,SB_VERT,TRUE,TRUE);
901 if (wndPtr->dwStyle & WS_HSCROLL)
902 SCROLL_DrawScrollBar(hwnd,hdc,SB_HORZ,TRUE,TRUE);
903#endif
904 /* Draw the "size-box" */
905 if ((dwStyle & WS_VSCROLL) && (dwStyle & WS_HSCROLL))
906 {
907 RECT r = rect;
908 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
909 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
910 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
911 if (!(dwStyle & WS_CHILD))
912 {
913 POINT p1,p2;
914 HPEN penDark = GetSysColorPen(COLOR_3DSHADOW);
915 HPEN penWhite = GetSysColorPen(COLOR_3DHILIGHT);
916 HPEN oldPen = SelectObject(hdc,penDark);
917 INT x;
918
919 p1.x = r.right-1;
920 p1.y = r.bottom;
921 p2.x = r.right;
922 p2.y = r.bottom-1;
923 for (x = 0;x < 3;x++)
924 {
925 SelectObject(hdc,penDark);
926 MoveToEx(hdc,p1.x,p1.y,NULL);
927 LineTo(hdc,p2.x,p2.y);
928 p1.x--;
929 p2.y--;
930 MoveToEx(hdc,p1.x,p1.y,NULL);
931 LineTo(hdc,p2.x,p2.y);
932 SelectObject(hdc,penWhite);
933 p1.x--;
934 p2.y--;
935 MoveToEx(hdc,p1.x,p1.y,NULL);
936 LineTo(hdc,p2.x,p2.y);
937 p1.x -= 2;
938 p2.y -= 2;
939 }
940
941 SelectObject(hdc,oldPen);
942 }
943 }
944#endif
945
946 ReleaseDC(Win32Hwnd,hdc);
947}
948//******************************************************************************
949//******************************************************************************
950LONG Win32BaseWindow::HandleNCActivate(WPARAM wParam)
951{
952 WORD wStateChange;
953
954 if( wParam ) {
955 wStateChange = !(flags & WIN_NCACTIVATED);
956 }
957 else wStateChange = flags & WIN_NCACTIVATED;
958
959 if( wStateChange )
960 {
961 if (wParam)
962 flags |= WIN_NCACTIVATED;
963 else flags &= ~WIN_NCACTIVATED;
964
965 if(!(dwStyle & WS_MINIMIZE))
966 HandleNCPaint((HRGN)1,FALSE);
967 }
968 return TRUE;
969}
970//******************************************************************************
971//******************************************************************************
972/***********************************************************************
973 * NC_HandleSysCommand
974 *
975 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
976 *
977 * TODO: Not done (see #if 0)
978 */
979LONG Win32BaseWindow::HandleSysCommand(WPARAM wParam, POINT *pt32)
980{
981 UINT uCommand = wParam & 0xFFF0;
982
983 if ((getStyle() & WS_CHILD) && (uCommand != SC_KEYMENU))
984 ScreenToClient(getParent()->getWindowHandle(), pt32 );
985
986 switch (uCommand)
987 {
988
989 case SC_SIZE:
990 {
991 DWORD flags = 0;
992
993 switch ((wParam & 0xF)+2)
994 {
995 case HTLEFT:
996 flags = TFOS_LEFT;
997 break;
998
999 case HTRIGHT:
1000 flags = TFOS_RIGHT;
1001 break;
1002
1003 case HTTOP:
1004 flags = TFOS_TOP;
1005 break;
1006
1007 case HTTOPLEFT:
1008 flags = TFOS_TOP | TFOS_LEFT;
1009 break;
1010
1011 case HTTOPRIGHT:
1012 flags = TFOS_TOP | TFOS_RIGHT;
1013 break;
1014
1015 case HTBOTTOM:
1016 flags = TFOS_BOTTOM;
1017 break;
1018
1019 case HTBOTTOMLEFT:
1020 flags = TFOS_BOTTOM | TFOS_LEFT;
1021 break;
1022
1023 case HTBOTTOMRIGHT:
1024 flags = TFOS_BOTTOM | TFOS_RIGHT;
1025 break;
1026 }
1027 if (flags) FrameTrackFrame(this,flags);
1028 break;
1029 }
1030
1031 case SC_MOVE:
1032 FrameTrackFrame(this,TFOS_MOVE);
1033 break;
1034
1035 case SC_MINIMIZE:
1036 ShowWindow(SW_MINIMIZE);
1037 break;
1038
1039 case SC_MAXIMIZE:
1040 ShowWindow(SW_MAXIMIZE);
1041 break;
1042
1043 case SC_RESTORE:
1044 ShowWindow(SW_RESTORE);
1045 break;
1046
1047 case SC_CLOSE:
1048 return SendInternalMessageA(WM_CLOSE, 0, 0);
1049
1050 case SC_MOUSEMENU:
1051 if((wParam & 0x000F) == HTSYSMENU)
1052 {
1053 RECT rect;
1054 HWND hwndTitleBar;
1055
1056 hwndTitleBar = OSLibWinGetFrameControlHandle(getOS2FrameWindowHandle(), OSLIB_FID_TITLEBAR);
1057 OSLibWinQueryWindowRect(hwndTitleBar, &rect, RELATIVE_TO_SCREEN);
1058 //Need to use Open32 api directly, as we want the msgs to go to the frame window
1059 O32_TrackPopupMenu((OS2SysMenu) ? OS2SysMenu : hSysMenu, TPM_LEFTALIGN|TPM_LEFTBUTTON,
1060 rect.left, rect.bottom+1,
1061 0, getOS2FrameWindowHandle(), NULL);
1062 }
1063 //MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt32 );
1064 break;
1065
1066 case SC_SCREENSAVE:
1067 if (wParam == SC_ABOUTODIN) {
1068 if(ShellAboutA == 0) {
1069 HINSTANCE hShell32 = LoadLibraryA("SHELL32");
1070 if(hShell32 == 0)
1071 break;
1072 *(VOID **)&ShellAboutA = (VOID *)GetProcAddress(hShell32, "ShellAboutA");
1073 }
1074 ShellAboutA(Win32Hwnd,"Odin","Odin alpha release compiled with IBM VAC++",0);
1075 }
1076 else
1077 if (wParam == SC_PUTMARK)
1078 dprintf(("Mark requested by user\n"));
1079 break;
1080
1081#if 0
1082 case SC_VSCROLL:
1083 case SC_HSCROLL:
1084 NC_TrackScrollBar( hwnd, wParam, pt32 );
1085 break;
1086
1087 case SC_MOUSEMENU:
1088 MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt32 );
1089 break;
1090
1091 case SC_KEYMENU:
1092 MENU_TrackKbdMenuBar( wndPtr , wParam , pt.x );
1093 break;
1094
1095 case SC_TASKLIST:
1096 WinExec( "taskman.exe", SW_SHOWNORMAL );
1097 break;
1098
1099 case SC_HOTKEY:
1100 case SC_ARRANGE:
1101 case SC_NEXTWINDOW:
1102 case SC_PREVWINDOW:
1103 break;
1104#endif
1105 }
1106 return 0;
1107}
1108//******************************************************************************
1109//******************************************************************************
1110HMENU Win32BaseWindow::getSystemMenu()
1111{
1112 if(!fOS2Look) {
1113 return (OS2SysMenu) ? OS2SysMenu : hSysMenu;
1114 }
1115 return 0;
1116}
1117//******************************************************************************
1118//******************************************************************************
1119
Note: See TracBrowser for help on using the repository browser.