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

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

Several updates/bug fixes

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