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

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

titlebar/sysmenu fixes + LoadBitmap fix for system bitmaps

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