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

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

win32 look update

File size: 31.5 KB
Line 
1/* $Id: win32wbasepaint.cpp,v 1.2 2000-01-09 15:56:05 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(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 (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(Win32Hwnd);
182 SetCapture(Win32Hwnd);
183 DrawCloseButton(hdc,TRUE,FALSE);
184 do
185 {
186 BOOL oldstate = pressed;
187
188 GetMessageA(&msg,Win32Hwnd,0,0);
189 pressed = (HandleNCHitTest(msg.pt) == wParam);
190 if (pressed != oldstate)
191 DrawCloseButton(hdc, pressed, FALSE);
192 } while (msg.message != WM_LBUTTONUP);
193 DrawCloseButton(hdc,FALSE,FALSE);
194 ReleaseCapture();
195 ReleaseDC(Win32Hwnd,hdc);
196 if (!pressed) return;
197 SendInternalMessageA(WM_SYSCOMMAND,SC_CLOSE,*(LPARAM*)&msg.pt);
198}
199//******************************************************************************
200//******************************************************************************
201LONG Win32BaseWindow::HandleNCLButtonUp(WPARAM wParam,LPARAM lParam)
202{
203 switch(wParam) /* Hit test */
204 {
205 case HTMINBUTTON:
206 SendInternalMessageA(WM_SYSCOMMAND,SC_MINIMIZE,lParam);
207 break;
208
209 case HTMAXBUTTON:
210 SendInternalMessageA(WM_SYSCOMMAND,SC_MAXIMIZE,lParam);
211 break;
212
213 case HTCLOSE:
214 SendInternalMessageA(WM_SYSCOMMAND,SC_CLOSE,lParam);
215 break;
216 }
217
218 return 0;
219}
220/***********************************************************************
221 * NC_HandleNCLButtonDblClk
222 *
223 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
224 */
225LONG Win32BaseWindow::HandleNCLButtonDblClk(WPARAM wParam,LPARAM lParam)
226{
227 /*
228 * if this is an icon, send a restore since we are handling
229 * a double click
230 */
231 if (dwStyle & WS_MINIMIZE)
232 {
233 SendInternalMessageA(WM_SYSCOMMAND,SC_RESTORE,lParam);
234 return 0;
235 }
236
237 switch(wParam) /* Hit test */
238 {
239 case HTCAPTION:
240 /* stop processing if WS_MAXIMIZEBOX is missing */
241 if (dwStyle & WS_MAXIMIZEBOX)
242 SendInternalMessageA(WM_SYSCOMMAND,
243 (dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
244 lParam);
245 break;
246
247 case HTSYSMENU:
248 if (!(GetClassWord(Win32Hwnd,GCW_STYLE) & CS_NOCLOSE))
249 SendInternalMessageA(WM_SYSCOMMAND,SC_CLOSE,lParam);
250 break;
251
252 case HTHSCROLL:
253 SendInternalMessageA(WM_SYSCOMMAND,SC_HSCROLL+HTHSCROLL,lParam);
254 break;
255
256 case HTVSCROLL:
257 SendInternalMessageA(WM_SYSCOMMAND,SC_VSCROLL+HTVSCROLL,lParam);
258 break;
259 }
260
261 return 0;
262}
263//******************************************************************************
264//******************************************************************************
265LONG Win32BaseWindow::HandleNCLButtonDown(WPARAM wParam,LPARAM lParam)
266{
267 switch(wParam) /* Hit test */
268 {
269 case HTCAPTION:
270 SetActiveWindow();
271 if (GetActiveWindow() == Win32Hwnd)
272 SendInternalMessageA(WM_SYSCOMMAND,SC_MOVE+HTCAPTION,lParam);
273 break;
274
275 case HTSYSMENU:
276 if(dwStyle & WS_SYSMENU )
277 {
278 if( !(dwStyle & WS_MINIMIZE) )
279 {
280 HDC hDC = GetWindowDC(Win32Hwnd);
281 DrawSysButton(hDC,TRUE);
282 ReleaseDC(Win32Hwnd,hDC);
283 }
284 SendInternalMessageA(WM_SYSCOMMAND,SC_MOUSEMENU+HTSYSMENU,lParam);
285 }
286 break;
287
288 case HTMENU:
289 SendInternalMessageA(WM_SYSCOMMAND,SC_MOUSEMENU,lParam);
290 break;
291
292 case HTHSCROLL:
293 SendInternalMessageA(WM_SYSCOMMAND,SC_HSCROLL+HTHSCROLL,lParam);
294 break;
295
296 case HTVSCROLL:
297 SendInternalMessageA(WM_SYSCOMMAND,SC_VSCROLL+HTVSCROLL,lParam);
298 break;
299
300 case HTMINBUTTON:
301 case HTMAXBUTTON:
302 TrackMinMaxBox(wParam);
303 break;
304
305 case HTCLOSE:
306 TrackCloseButton(wParam);
307 break;
308
309 case HTLEFT:
310 case HTRIGHT:
311 case HTTOP:
312 case HTTOPLEFT:
313 case HTTOPRIGHT:
314 case HTBOTTOM:
315 case HTBOTTOMLEFT:
316 case HTBOTTOMRIGHT:
317 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
318 SendInternalMessageA(WM_SYSCOMMAND,SC_SIZE+wParam-2,lParam);
319 break;
320 case HTBORDER:
321 break;
322 }
323
324 return 0;
325}
326//******************************************************************************
327//******************************************************************************
328LONG Win32BaseWindow::HandleNCHitTest(POINT pt)
329{
330 RECT rect;
331
332 rect = *getWindowRect();
333 if (!PtInRect(&rect,pt)) return HTNOWHERE;
334
335 if (dwStyle & WS_MINIMIZE) return HTCAPTION;
336
337 if (!(flags & WIN_MANAGED))
338 {
339 /* Check borders */
340 if (HAS_THICKFRAME(dwStyle,dwExStyle))
341 {
342 InflateRect(&rect,-GetSystemMetrics(SM_CXFRAME),-GetSystemMetrics(SM_CYFRAME));
343 if (!PtInRect(&rect,pt))
344 {
345 /* Check top sizing border */
346 if (pt.y < rect.top)
347 {
348 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
349 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
350 return HTTOP;
351 }
352 /* Check bottom sizing border */
353 if (pt.y >= rect.bottom)
354 {
355 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
356 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
357 return HTBOTTOM;
358 }
359 /* Check left sizing border */
360 if (pt.x < rect.left)
361 {
362 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
363 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
364 return HTLEFT;
365 }
366 /* Check right sizing border */
367 if (pt.x >= rect.right)
368 {
369 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
370 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
371 return HTRIGHT;
372 }
373 }
374 } else /* No thick frame */
375 {
376 if (HAS_DLGFRAME(dwStyle,dwExStyle))
377 InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
378 else if (HAS_THINFRAME(dwStyle ))
379 InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
380 if (!PtInRect( &rect, pt )) return HTBORDER;
381 }
382
383 /* Check caption */
384
385 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
386 {
387 if (dwExStyle & WS_EX_TOOLWINDOW)
388 rect.top += GetSystemMetrics(SM_CYSMCAPTION)-1;
389 else
390 rect.top += GetSystemMetrics(SM_CYCAPTION)-1;
391 if (!PtInRect(&rect,pt))
392 {
393 /* Check system menu */
394 if(dwStyle & WS_SYSMENU)
395 {
396 /* Check if there is an user icon */
397 HICON hIcon = (HICON) GetClassLongA(Win32Hwnd, GCL_HICONSM);
398 if(!hIcon) hIcon = (HICON) GetClassLongA(Win32Hwnd, GCL_HICON);
399
400 /* If there is an icon associated with the window OR */
401 /* If there is no hIcon specified and this is not a modal dialog, */
402 /* there is a system menu icon. */
403 if((hIcon != 0) || (!(dwStyle & DS_MODALFRAME)))
404 rect.left += GetSystemMetrics(SM_CYCAPTION) - 1;
405 }
406 if (pt.x < rect.left) return HTSYSMENU;
407
408 /* Check close button */
409 if (dwStyle & WS_SYSMENU)
410 rect.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
411 if (pt.x > rect.right) return HTCLOSE;
412
413 /* Check maximize box */
414 /* In win95 there is automatically a Maximize button when there is a minimize one*/
415 if ((dwStyle & WS_MAXIMIZEBOX)|| (dwStyle & WS_MINIMIZEBOX))
416 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
417 if (pt.x > rect.right) return HTMAXBUTTON;
418
419 /* Check minimize box */
420 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
421 if ((dwStyle & WS_MINIMIZEBOX)||(dwStyle & WS_MAXIMIZEBOX))
422 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
423
424 if (pt.x > rect.right) return HTMINBUTTON;
425 return HTCAPTION;
426 }
427 }
428 }
429
430 /* Check client area */
431
432 ScreenToClient(Win32Hwnd,&pt);
433 rect = *getClientRect();
434 if (PtInRect(&rect,pt)) return HTCLIENT;
435
436 /* Check vertical scroll bar */
437
438 if (dwStyle & WS_VSCROLL)
439 {
440 rect.right += GetSystemMetrics(SM_CXVSCROLL);
441 if (PtInRect( &rect, pt )) return HTVSCROLL;
442 }
443
444 /* Check horizontal scroll bar */
445
446 if (dwStyle & WS_HSCROLL)
447 {
448 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
449 if (PtInRect( &rect, pt ))
450 {
451 /* Check size box */
452 if ((dwStyle & WS_VSCROLL) &&
453 (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
454 return (dwStyle & WS_CHILD) ? HTSIZE:HTBOTTOMRIGHT;
455 return HTHSCROLL;
456 }
457 }
458
459 /* Check menu bar */
460
461 if (HAS_MENU(this))
462 {
463 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
464 return HTMENU;
465 }
466
467 /* Should never get here */
468 return HTERROR;
469}
470
471//******************************************************************************
472//******************************************************************************
473VOID Win32BaseWindow::GetInsideRect(RECT *rect)
474{
475 rect->top = rect->left = 0;
476 rect->right = getWindowRect()->right - getWindowRect()->left;
477 rect->bottom = getWindowRect()->bottom - getWindowRect()->top;
478
479 if ((dwStyle & WS_ICONIC) || (flags & WIN_MANAGED)) return;
480
481 /* Remove frame from rectangle */
482 if (HAS_THICKFRAME(dwStyle,dwExStyle))
483 {
484 InflateRect( rect, -GetSystemMetrics(SM_CXSIZEFRAME), -GetSystemMetrics(SM_CYSIZEFRAME) );
485 }
486 else if (HAS_DLGFRAME(dwStyle,dwExStyle ))
487 {
488 InflateRect( rect, -GetSystemMetrics(SM_CXFIXEDFRAME), -GetSystemMetrics(SM_CYFIXEDFRAME));
489 }
490 else if (HAS_THINFRAME(dwStyle))
491 {
492 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
493 }
494
495 /* We have additional border information if the window
496 * is a child (but not an MDI child) */
497 if ( (dwStyle & WS_CHILD) &&
498 ( (dwExStyle & WS_EX_MDICHILD) == 0 ) )
499 {
500 if (dwExStyle & WS_EX_CLIENTEDGE)
501 InflateRect (rect, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE));
502
503 if (dwExStyle & WS_EX_STATICEDGE)
504 InflateRect (rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
505 }
506}
507//******************************************************************************
508//******************************************************************************
509VOID Win32BaseWindow::DrawFrame(HDC hdc,RECT *rect,BOOL dlgFrame,BOOL active)
510{
511 INT width, height;
512 HBRUSH oldBrush;
513
514 if (dlgFrame)
515 {
516 width = GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
517 height = GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
518 }
519 else
520 {
521 width = GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXEDGE);
522 height = GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYEDGE);
523 }
524
525 oldBrush = SelectObject(hdc,GetSysColorBrush(active ? COLOR_ACTIVEBORDER:COLOR_INACTIVEBORDER));
526
527 /* Draw frame */
528
529 PatBlt(hdc,rect->left,rect->top,rect->right-rect->left,height,PATCOPY);
530 PatBlt(hdc,rect->left,rect->top,width,rect->bottom-rect->top,PATCOPY);
531 PatBlt(hdc,rect->left,rect->bottom-1,rect->right-rect->left,-height,PATCOPY);
532 PatBlt(hdc,rect->right-1,rect->top,-width,rect->bottom-rect->top,PATCOPY);
533 SelectObject(hdc,oldBrush);
534
535 InflateRect(rect,-width,-height);
536}
537//******************************************************************************
538//******************************************************************************
539BOOL Win32BaseWindow::DrawSysButton(HDC hdc,BOOL down)
540{
541 HICON hIcon;
542 RECT rect;
543
544 GetInsideRect(&rect);
545
546 hIcon = (HICON) GetClassLongA(Win32Hwnd, GCL_HICONSM);
547 if(!hIcon) hIcon = (HICON) GetClassLongA(Win32Hwnd, GCL_HICON);
548
549 /* If there is no hIcon specified or this is not a modal dialog, */
550 /* get the default one. */
551 if(hIcon == 0)
552 if (!(dwStyle & DS_MODALFRAME))
553 hIcon = LoadImageA(0, MAKEINTRESOURCEA(OIC_WINEICON), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
554
555 if (hIcon)
556 DrawIconEx (hdc, rect.left + 2, rect.top + 2, hIcon,
557 GetSystemMetrics(SM_CXSMICON),
558 GetSystemMetrics(SM_CYSMICON),
559 0, 0, DI_NORMAL);
560
561 return (hIcon != 0);
562}
563//******************************************************************************
564//******************************************************************************
565BOOL Win32BaseWindow::DrawGrayButton(HDC hdc,int x,int y)
566{
567 HBITMAP hMaskBmp;
568 HDC hdcMask = CreateCompatibleDC (0);
569 HBRUSH hOldBrush;
570 hMaskBmp = CreateBitmap (12, 10, 1, 1, lpGrayMask);
571
572 if(hMaskBmp == 0)
573 return FALSE;
574
575 SelectObject (hdcMask, hMaskBmp);
576
577 /* Draw the grayed bitmap using the mask */
578 hOldBrush = SelectObject (hdc, RGB(128, 128, 128));
579 BitBlt (hdc, x, y, 12, 10,
580 hdcMask, 0, 0, 0xB8074A);
581
582 /* Clean up */
583 SelectObject (hdc, hOldBrush);
584 DeleteObject(hMaskBmp);
585 DeleteDC (hdcMask);
586
587 return TRUE;
588}
589//******************************************************************************
590//******************************************************************************
591VOID Win32BaseWindow::DrawCloseButton(HDC hdc,BOOL down,BOOL bGrayed)
592{
593 RECT rect;
594 HDC hdcMem;
595
596 if( !(flags & WIN_MANAGED) )
597 {
598 BITMAP bmp;
599 HBITMAP hBmp, hOldBmp;
600
601 GetInsideRect(&rect);
602
603 hdcMem = CreateCompatibleDC( hdc );
604 hBmp = down ? hbitmapCloseD : hbitmapClose;
605 hOldBmp = SelectObject (hdcMem, hBmp);
606 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
607
608 BitBlt (hdc, rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2,
609 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
610 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);
611
612 if(bGrayed)
613 DrawGrayButton(hdc,rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2 + 2,
614 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
615
616 SelectObject (hdcMem, hOldBmp);
617 DeleteDC (hdcMem);
618 }
619}
620//******************************************************************************
621//******************************************************************************
622VOID Win32BaseWindow::DrawMaxButton(HDC hdc,BOOL down,BOOL bGrayed)
623{
624 RECT rect;
625 HDC hdcMem;
626
627 if( !(flags & WIN_MANAGED))
628 {
629 BITMAP bmp;
630 HBITMAP hBmp,hOldBmp;
631
632 GetInsideRect(&rect);
633 hdcMem = CreateCompatibleDC( hdc );
634 hBmp = IsZoomed(Win32Hwnd) ?
635 (down ? hbitmapRestoreD : hbitmapRestore ) :
636 (down ? hbitmapMaximizeD: hbitmapMaximize);
637 hOldBmp=SelectObject( hdcMem, hBmp );
638 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
639
640 if (dwStyle & WS_SYSMENU)
641 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
642
643 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
644 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
645 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
646
647 if(bGrayed)
648 DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
649 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
650
651
652 SelectObject (hdcMem, hOldBmp);
653 DeleteDC( hdcMem );
654 }
655}
656//******************************************************************************
657//******************************************************************************
658VOID Win32BaseWindow::DrawMinButton(HDC hdc,BOOL down,BOOL bGrayed)
659{
660 RECT rect;
661 HDC hdcMem;
662
663 if( !(flags & WIN_MANAGED))
664
665 {
666 BITMAP bmp;
667 HBITMAP hBmp,hOldBmp;
668
669 GetInsideRect(&rect);
670
671 hdcMem = CreateCompatibleDC( hdc );
672 hBmp = down ? hbitmapMinimizeD : hbitmapMinimize;
673 hOldBmp= SelectObject( hdcMem, hBmp );
674 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
675
676 if (dwStyle & WS_SYSMENU)
677 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
678
679 /* In win 95 there is always a Maximize box when there is a Minimize one */
680 if ((dwStyle & WS_MAXIMIZEBOX) || (dwStyle & WS_MINIMIZEBOX))
681 rect.right += -1 - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2;
682
683 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
684 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
685 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
686
687 if(bGrayed)
688 DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
689 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
690
691
692 SelectObject (hdcMem, hOldBmp);
693 DeleteDC( hdcMem );
694 }
695}
696//******************************************************************************
697//******************************************************************************
698VOID Win32BaseWindow::DrawCaption(HDC hdc,RECT *rect,BOOL active)
699{
700 RECT r = *rect;
701 char buffer[256];
702 HPEN hPrevPen;
703 HMENU hSysMenu;
704
705 hPrevPen = SelectObject( hdc, GetSysColorPen(COLOR_3DFACE) );
706 MoveToEx( hdc, r.left, r.bottom - 1, NULL );
707 LineTo( hdc, r.right, r.bottom - 1 );
708 SelectObject( hdc, hPrevPen );
709 r.bottom--;
710
711 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION) );
712
713 if (!hbitmapClose)
714 {
715 if (!(hbitmapClose = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CLOSE)))) return;
716 hbitmapCloseD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CLOSED));
717 hbitmapMinimize = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_REDUCE));
718 hbitmapMinimizeD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_REDUCED));
719 hbitmapMaximize = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_ZOOM));
720 hbitmapMaximizeD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_ZOOMD));
721 hbitmapRestore = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_RESTORE));
722 hbitmapRestoreD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_RESTORED));
723 }
724
725 if ((dwStyle & WS_SYSMENU) && !(dwExStyle & WS_EX_TOOLWINDOW))
726 {
727 if (DrawSysButton(hdc,FALSE))
728 r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
729 }
730
731 if (dwStyle & WS_SYSMENU)
732 {
733 UINT state;
734 /* Go get the sysmenu */
735 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
736
737 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
738 DrawCloseButton(hdc, FALSE,
739 ((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
740 r.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
741
742 if ((dwStyle & WS_MAXIMIZEBOX) || (dwStyle & WS_MINIMIZEBOX))
743 {
744 /* In win95 the two buttons are always there */
745 /* But if the menu item is not in the menu they're disabled*/
746
747 DrawMaxButton(hdc, FALSE, (!(dwStyle & WS_MAXIMIZEBOX)));
748 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
749
750 DrawMinButton(hdc, FALSE, (!(dwStyle & WS_MINIMIZEBOX)));
751 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
752 }
753 }
754
755 if (GetWindowTextA(buffer, sizeof(buffer) ))
756 {
757 NONCLIENTMETRICSA nclm;
758 HFONT hFont, hOldFont;
759 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
760 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
761 if (dwExStyle & WS_EX_TOOLWINDOW)
762 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
763 else
764 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
765 hOldFont = SelectObject (hdc, hFont);
766 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
767 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
768 SetBkMode( hdc, TRANSPARENT );
769 r.left += 2;
770 DrawTextA( hdc, buffer, -1, &r,
771 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
772 DeleteObject (SelectObject (hdc, hOldFont));
773 }
774}
775//******************************************************************************
776//******************************************************************************
777VOID Win32BaseWindow::HandleNCPaint(HRGN clip, BOOL suppress_menupaint)
778{
779 BOOL active = flags & WIN_NCACTIVATED;
780 HDC hdc;
781 RECT rect,rectClip,rfuzz;
782
783 if (dwStyle & WS_MINIMIZE) return;
784
785 //Load system menu (once)
786 if(!hSysMenu) {
787 hSysMenu = LoadMenuA(hInstanceUser32, (LPCSTR)"SYSMENU");
788 }
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/***********************************************************************
936 * NC_HandleSysCommand
937 *
938 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
939 *
940 * TODO: Not done (see #if 0)
941 */
942LONG Win32BaseWindow::HandleSysCommand(WPARAM wParam, POINT *pt32)
943{
944 UINT uCommand = wParam & 0xFFF0;
945
946 if ((getStyle() & WS_CHILD) && (uCommand != SC_KEYMENU))
947 ScreenToClient(getParent()->getWindowHandle(), pt32 );
948
949 switch (uCommand)
950 {
951
952 case SC_SIZE:
953 {
954 DWORD flags = 0;
955
956 switch ((wParam & 0xF)+2)
957 {
958 case HTLEFT:
959 flags = TFOS_LEFT;
960 break;
961
962 case HTRIGHT:
963 flags = TFOS_RIGHT;
964 break;
965
966 case HTTOP:
967 flags = TFOS_TOP;
968 break;
969
970 case HTTOPLEFT:
971 flags = TFOS_TOP | TFOS_LEFT;
972 break;
973
974 case HTTOPRIGHT:
975 flags = TFOS_TOP | TFOS_RIGHT;
976 break;
977
978 case HTBOTTOM:
979 flags = TFOS_BOTTOM;
980 break;
981
982 case HTBOTTOMLEFT:
983 flags = TFOS_BOTTOM | TFOS_LEFT;
984 break;
985
986 case HTBOTTOMRIGHT:
987 flags = TFOS_BOTTOM | TFOS_RIGHT;
988 break;
989 }
990 if (flags) FrameTrackFrame(this,flags);
991 break;
992 }
993
994 case SC_MOVE:
995 FrameTrackFrame(this,TFOS_MOVE);
996 break;
997
998 case SC_MINIMIZE:
999 ShowWindow(SW_MINIMIZE);
1000 break;
1001
1002 case SC_MAXIMIZE:
1003 ShowWindow(SW_MAXIMIZE);
1004 break;
1005
1006 case SC_RESTORE:
1007 ShowWindow(SW_RESTORE);
1008 break;
1009
1010 case SC_CLOSE:
1011 return SendInternalMessageA(WM_CLOSE, 0, 0);
1012
1013 case SC_MOUSEMENU:
1014 if((wParam & 0x000F) == HTSYSMENU)
1015 {
1016 RECT rect;
1017 HWND hwndTitleBar;
1018
1019 hwndTitleBar = OSLibWinGetFrameControlHandle(getOS2FrameWindowHandle(), OSLIB_FID_TITLEBAR);
1020 OSLibWinQueryWindowRect(hwndTitleBar, &rect, RELATIVE_TO_SCREEN);
1021 TrackPopupMenu((OS2SysMenu) ? OS2SysMenu : hSysMenu, TPM_LEFTALIGN|TPM_LEFTBUTTON,
1022 rect.left, rect.bottom+1,
1023 0, getWindowHandle(), NULL);
1024 }
1025 //MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt32 );
1026 break;
1027
1028#if 0
1029 case SC_VSCROLL:
1030 case SC_HSCROLL:
1031 NC_TrackScrollBar( hwnd, wParam, pt32 );
1032 break;
1033
1034 case SC_MOUSEMENU:
1035 MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt32 );
1036 break;
1037
1038 case SC_KEYMENU:
1039 MENU_TrackKbdMenuBar( wndPtr , wParam , pt.x );
1040 break;
1041
1042 case SC_TASKLIST:
1043 WinExec( "taskman.exe", SW_SHOWNORMAL );
1044 break;
1045
1046 case SC_SCREENSAVE:
1047 if (wParam == SC_ABOUTWINE)
1048 ShellAboutA(hwnd, "Odin", WINE_RELEASE_INFO, 0);
1049 else
1050 if (wParam == SC_PUTMARK)
1051 dprintf(("Mark requested by user\n"));
1052 break;
1053
1054 case SC_HOTKEY:
1055 case SC_ARRANGE:
1056 case SC_NEXTWINDOW:
1057 case SC_PREVWINDOW:
1058 break;
1059#endif
1060 }
1061 return 0;
1062}
1063//******************************************************************************
1064//******************************************************************************
1065
Note: See TracBrowser for help on using the repository browser.