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

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

System menu commands now work

File size: 32.3 KB
Line 
1/* $Id: win32wbasepaint.cpp,v 1.4 2000-01-09 17:57:50 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 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION) );
713
714 if (!hbitmapClose)
715 {
716 if (!(hbitmapClose = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CLOSE)))) return;
717 hbitmapCloseD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CLOSED));
718 hbitmapMinimize = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_REDUCE));
719 hbitmapMinimizeD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_REDUCED));
720 hbitmapMaximize = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_ZOOM));
721 hbitmapMaximizeD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_ZOOMD));
722 hbitmapRestore = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_RESTORE));
723 hbitmapRestoreD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_RESTORED));
724 }
725
726 if ((dwStyle & WS_SYSMENU) && !(dwExStyle & WS_EX_TOOLWINDOW))
727 {
728 if (DrawSysButton(hdc,FALSE))
729 r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
730 }
731
732 if (dwStyle & WS_SYSMENU)
733 {
734 UINT state;
735 /* Go get the sysmenu */
736 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
737
738 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
739 DrawCloseButton(hdc, FALSE,
740 ((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
741 r.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
742
743 if ((dwStyle & WS_MAXIMIZEBOX) || (dwStyle & WS_MINIMIZEBOX))
744 {
745 /* In win95 the two buttons are always there */
746 /* But if the menu item is not in the menu they're disabled*/
747
748 DrawMaxButton(hdc, FALSE, (!(dwStyle & WS_MAXIMIZEBOX)));
749 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
750
751 DrawMinButton(hdc, FALSE, (!(dwStyle & WS_MINIMIZEBOX)));
752 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
753 }
754 }
755
756 if (GetWindowTextA(buffer, sizeof(buffer) ))
757 {
758 NONCLIENTMETRICSA nclm;
759 HFONT hFont, hOldFont;
760 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
761 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
762 if (dwExStyle & WS_EX_TOOLWINDOW)
763 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
764 else
765 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
766 hOldFont = SelectObject (hdc, hFont);
767 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
768 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
769 SetBkMode( hdc, TRANSPARENT );
770 r.left += 2;
771 DrawTextA( hdc, buffer, -1, &r,
772 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
773 DeleteObject (SelectObject (hdc, hOldFont));
774 }
775}
776//******************************************************************************
777//******************************************************************************
778VOID Win32BaseWindow::HandleNCPaint(HRGN clip, BOOL suppress_menupaint)
779{
780 BOOL active = flags & WIN_NCACTIVATED;
781 HDC hdc;
782 RECT rect,rectClip,rfuzz;
783
784 if (dwStyle & WS_MINIMIZE) return;
785
786 //Load system menu (once)
787 if(!hSysMenu) {
788 hSysMenu = LoadMenuA(hInstanceUser32, (LPCSTR)"SYSMENU");
789 }
790
791 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
792 the call to GetDCEx implying that it is allowed not to use it either.
793 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
794 will cause clipRgn to be deleted after ReleaseDC().
795 Now, how is the "system" supposed to tell what happened?
796 */
797
798 if (!(hdc = GetDCEx( Win32Hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
799 ((clip > 1) ?(DCX_INTERSECTRGN /*| DCX_KEEPCLIPRGN*/) : 0) ))) return;
800
801 rect.top = rect.left = 0;
802 rect.right = getWindowRect()->right - getWindowRect()->left;
803 rect.bottom = getWindowRect()->bottom - getWindowRect()->top;
804
805 if( clip > 1 )
806 GetRgnBox( clip, &rectClip );
807 else
808 {
809 clip = 0;
810 rectClip = rect;
811 }
812
813 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
814
815 if (HAS_BIGFRAME( dwStyle, dwExStyle))
816 {
817 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
818 }
819 if (HAS_THICKFRAME( dwStyle, dwExStyle ))
820 DrawFrame(hdc, &rect, FALSE, active );
821 else if (HAS_DLGFRAME( dwStyle, dwExStyle ))
822 DrawFrame( hdc, &rect, TRUE, active );
823 else if (HAS_THINFRAME( dwStyle ))
824 {
825 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
826 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
827 }
828
829 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
830 {
831 RECT r = rect;
832 if (dwExStyle & WS_EX_TOOLWINDOW)
833 {
834 r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
835 rect.top += GetSystemMetrics(SM_CYSMCAPTION);
836 }
837 else
838 {
839 r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
840 rect.top += GetSystemMetrics(SM_CYCAPTION);
841 }
842 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
843 DrawCaption(hdc, &r, active);
844 }
845
846#if 0 //CB: todo
847 if (HAS_MENU(wndPtr))
848 {
849 RECT r = rect;
850 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
851
852 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ) + 1;
853 }
854
855 if (dwExStyle & WS_EX_CLIENTEDGE)
856 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
857
858 if (dwExStyle & WS_EX_STATICEDGE)
859 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
860
861 /* Draw the scroll-bars */
862#if 0 //CB: todo
863 if (dwStyle & WS_VSCROLL)
864 SCROLL_DrawScrollBar(hwnd,hdc,SB_VERT,TRUE,TRUE);
865 if (wndPtr->dwStyle & WS_HSCROLL)
866 SCROLL_DrawScrollBar(hwnd,hdc,SB_HORZ,TRUE,TRUE);
867#endif
868 /* Draw the "size-box" */
869 if ((dwStyle & WS_VSCROLL) && (dwStyle & WS_HSCROLL))
870 {
871 RECT r = rect;
872 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
873 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
874 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
875 if (!(dwStyle & WS_CHILD))
876 {
877 POINT p1,p2;
878 HPEN penDark = GetSysColorPen(COLOR_3DSHADOW);
879 HPEN penWhite = GetSysColorPen(COLOR_3DHILIGHT);
880 HPEN oldPen = SelectObject(hdc,penDark);
881 INT x;
882
883 p1.x = r.right-1;
884 p1.y = r.bottom;
885 p2.x = r.right;
886 p2.y = r.bottom-1;
887 for (x = 0;x < 3;x++)
888 {
889 SelectObject(hdc,penDark);
890 MoveToEx(hdc,p1.x,p1.y,NULL);
891 LineTo(hdc,p2.x,p2.y);
892 p1.x--;
893 p2.y--;
894 MoveToEx(hdc,p1.x,p1.y,NULL);
895 LineTo(hdc,p2.x,p2.y);
896 SelectObject(hdc,penWhite);
897 p1.x--;
898 p2.y--;
899 MoveToEx(hdc,p1.x,p1.y,NULL);
900 LineTo(hdc,p2.x,p2.y);
901 p1.x -= 2;
902 p2.y -= 2;
903 }
904
905 SelectObject(hdc,oldPen);
906 }
907 }
908#endif
909
910 ReleaseDC(Win32Hwnd,hdc);
911}
912//******************************************************************************
913//******************************************************************************
914LONG Win32BaseWindow::HandleNCActivate(WPARAM wParam)
915{
916 WORD wStateChange;
917
918 if( wParam ) {
919 wStateChange = !(flags & WIN_NCACTIVATED);
920 }
921 else wStateChange = flags & WIN_NCACTIVATED;
922
923 if( wStateChange )
924 {
925 if (wParam)
926 flags |= WIN_NCACTIVATED;
927 else flags &= ~WIN_NCACTIVATED;
928
929 if(!(dwStyle & WS_MINIMIZE))
930 HandleNCPaint((HRGN)1,FALSE);
931 }
932 return TRUE;
933}
934//******************************************************************************
935//******************************************************************************
936/***********************************************************************
937 * NC_HandleSysCommand
938 *
939 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
940 *
941 * TODO: Not done (see #if 0)
942 */
943LONG Win32BaseWindow::HandleSysCommand(WPARAM wParam, POINT *pt32)
944{
945 UINT uCommand = wParam & 0xFFF0;
946
947 if ((getStyle() & WS_CHILD) && (uCommand != SC_KEYMENU))
948 ScreenToClient(getParent()->getWindowHandle(), pt32 );
949
950 switch (uCommand)
951 {
952
953 case SC_SIZE:
954 {
955 DWORD flags = 0;
956
957 switch ((wParam & 0xF)+2)
958 {
959 case HTLEFT:
960 flags = TFOS_LEFT;
961 break;
962
963 case HTRIGHT:
964 flags = TFOS_RIGHT;
965 break;
966
967 case HTTOP:
968 flags = TFOS_TOP;
969 break;
970
971 case HTTOPLEFT:
972 flags = TFOS_TOP | TFOS_LEFT;
973 break;
974
975 case HTTOPRIGHT:
976 flags = TFOS_TOP | TFOS_RIGHT;
977 break;
978
979 case HTBOTTOM:
980 flags = TFOS_BOTTOM;
981 break;
982
983 case HTBOTTOMLEFT:
984 flags = TFOS_BOTTOM | TFOS_LEFT;
985 break;
986
987 case HTBOTTOMRIGHT:
988 flags = TFOS_BOTTOM | TFOS_RIGHT;
989 break;
990 }
991 if (flags) FrameTrackFrame(this,flags);
992 break;
993 }
994
995 case SC_MOVE:
996 FrameTrackFrame(this,TFOS_MOVE);
997 break;
998
999 case SC_MINIMIZE:
1000 ShowWindow(SW_MINIMIZE);
1001 break;
1002
1003 case SC_MAXIMIZE:
1004 ShowWindow(SW_MAXIMIZE);
1005 break;
1006
1007 case SC_RESTORE:
1008 ShowWindow(SW_RESTORE);
1009 break;
1010
1011 case SC_CLOSE:
1012 return SendInternalMessageA(WM_CLOSE, 0, 0);
1013
1014 case SC_MOUSEMENU:
1015 if((wParam & 0x000F) == HTSYSMENU)
1016 {
1017 RECT rect;
1018 HWND hwndTitleBar;
1019
1020 hwndTitleBar = OSLibWinGetFrameControlHandle(getOS2FrameWindowHandle(), OSLIB_FID_TITLEBAR);
1021 OSLibWinQueryWindowRect(hwndTitleBar, &rect, RELATIVE_TO_SCREEN);
1022 //Need to use Open32 api directly, as we want the msgs to go to the frame window
1023 O32_TrackPopupMenu((OS2SysMenu) ? OS2SysMenu : hSysMenu, TPM_LEFTALIGN|TPM_LEFTBUTTON,
1024 rect.left, rect.bottom+1,
1025 0, getOS2FrameWindowHandle(), NULL);
1026 }
1027 //MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt32 );
1028 break;
1029
1030 case SC_SCREENSAVE:
1031 if (wParam == SC_ABOUTODIN) {
1032 if(ShellAboutA == 0) {
1033 HINSTANCE hShell32 = LoadLibraryA("SHELL32");
1034 if(hShell32 == 0)
1035 break;
1036 *(VOID **)&ShellAboutA = (VOID *)GetProcAddress(hShell32, "ShellAboutA");
1037 }
1038 ShellAboutA(Win32Hwnd,"Odin","Odin alpha release compiled with IBM VAC++",0);
1039 }
1040 else
1041 if (wParam == SC_PUTMARK)
1042 dprintf(("Mark requested by user\n"));
1043 break;
1044
1045#if 0
1046 case SC_VSCROLL:
1047 case SC_HSCROLL:
1048 NC_TrackScrollBar( hwnd, wParam, pt32 );
1049 break;
1050
1051 case SC_MOUSEMENU:
1052 MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt32 );
1053 break;
1054
1055 case SC_KEYMENU:
1056 MENU_TrackKbdMenuBar( wndPtr , wParam , pt.x );
1057 break;
1058
1059 case SC_TASKLIST:
1060 WinExec( "taskman.exe", SW_SHOWNORMAL );
1061 break;
1062
1063 case SC_HOTKEY:
1064 case SC_ARRANGE:
1065 case SC_NEXTWINDOW:
1066 case SC_PREVWINDOW:
1067 break;
1068#endif
1069 }
1070 return 0;
1071}
1072//******************************************************************************
1073//******************************************************************************
1074HMENU Win32BaseWindow::getSystemMenu()
1075{
1076 if(!fOS2Look) {
1077 return (OS2SysMenu) ? OS2SysMenu : hSysMenu;
1078 }
1079 return 0;
1080}
1081//******************************************************************************
1082//******************************************************************************
1083
Note: See TracBrowser for help on using the repository browser.