Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

win32wbasenonclient.cpp

Go to the documentation of this file.
00001 /* $Id: win32wbasenonclient.cpp,v 1.37 2001/10/15 17:09:04 sandervl Exp $ */
00002 /*
00003  * Win32 Window Base Class for OS/2 (non-client methods)
00004  *
00005  * Copyright 2000 Christoph Bratschi (cbratschi@datacomm.ch)
00006  *
00007  * Based on Wine code (windows\nonclient.c)
00008  *  Corel Version 20000212
00009  *
00010  * Copyright 1994 Alexandre Julliard
00011  *
00012  * TODO: Not thread/process safe
00013  *
00014  * Project Odin Software License can be found in LICENSE.TXT
00015  *
00016  */
00017 #include <os2win.h>
00018 #include <win.h>
00019 #include <stdlib.h>
00020 #include <string.h>
00021 #include <stdarg.h>
00022 #include <assert.h>
00023 #include <misc.h>
00024 #include <heapstring.h>
00025 #include <win32wbase.h>
00026 #include "wndmsg.h"
00027 #include "oslibwin.h"
00028 #include "oslibmsg.h"
00029 #include "oslibutil.h"
00030 #include "oslibgdi.h"
00031 #include "oslibres.h"
00032 #include "oslibdos.h"
00033 #include "syscolor.h"
00034 #include "win32wndhandle.h"
00035 #include "dc.h"
00036 #include "win32wdesktop.h"
00037 #include "controls.h"
00038 #include "pmwindow.h"
00039 #include <menu.h>
00040 
00041 #define DBG_LOCALLOG    DBG_win32wbasenonclient
00042 #include "dbglocal.h"
00043 
00044 /* bits in the dwKeyData */
00045 #define KEYDATA_ALT         0x2000
00046 #define KEYDATA_PREVSTATE   0x4000
00047 
00048 static INT bitmapW = 16,bitmapH = 14;
00049 static HBITMAP hbitmapClose        = 0;
00050 static HBITMAP hbitmapCloseD       = 0;
00051 static HBITMAP hbitmapMinimize     = 0;
00052 static HBITMAP hbitmapMinimizeD    = 0;
00053 static HBITMAP hbitmapMaximize     = 0;
00054 static HBITMAP hbitmapMaximizeD    = 0;
00055 static HBITMAP hbitmapRestore      = 0;
00056 static HBITMAP hbitmapRestoreD     = 0;
00057 static HBITMAP hbitmapContextHelp  = 0;
00058 static HBITMAP hbitmapContextHelpD = 0;
00059 
00060 BYTE lpGrayMask[] = { 0xAA, 0xA0,
00061                       0x55, 0x50,
00062                       0xAA, 0xA0,
00063                       0x55, 0x50,
00064                       0xAA, 0xA0,
00065                       0x55, 0x50,
00066                       0xAA, 0xA0,
00067                       0x55, 0x50,
00068                       0xAA, 0xA0,
00069                       0x55, 0x50};
00070 
00071 static INT (* WINAPI ShellAboutA)(HWND,LPCSTR,LPCSTR,HICON) = 0;
00072 
00073 //******************************************************************************
00074 //******************************************************************************
00075 LONG Win32BaseWindow::HandleNCActivate(WPARAM wParam)
00076 {
00077   WORD wStateChange;
00078 
00079   if( wParam ) wStateChange = !(flags & WIN_NCACTIVATED);
00080   else wStateChange = flags & WIN_NCACTIVATED;
00081 
00082   if( wStateChange )
00083   {
00084     if (wParam) flags |= WIN_NCACTIVATED;
00085     else flags &= ~WIN_NCACTIVATED;
00086 
00087     if (!(dwStyle & WS_CAPTION)) return TRUE;
00088 
00089     if(!(dwStyle & WS_MINIMIZE))
00090       DoNCPaint((HRGN)1,FALSE);
00091   }
00092 
00093   return TRUE;
00094 }
00095 //******************************************************************************
00096 //******************************************************************************
00097 VOID Win32BaseWindow::TrackMinMaxHelpBox(WORD wParam)
00098 {
00099   MSG msg;
00100   HDC hdc;
00101   BOOL pressed = TRUE;
00102   UINT state;
00103 
00104   if (wParam == HTMINBUTTON)
00105   {
00106     /* If the style is not present, do nothing */
00107     if (!(dwStyle & WS_MINIMIZEBOX))
00108       return;
00109     /* Check if the sysmenu item for minimize is there  */
00110     state = GetMenuState(hSysMenu,SC_MINIMIZE,MF_BYCOMMAND);
00111   } else if (wParam == HTMAXBUTTON)
00112   {
00113     /* If the style is not present, do nothing */
00114     if (!(dwStyle & WS_MAXIMIZEBOX))
00115       return;
00116     /* Check if the sysmenu item for maximize is there  */
00117     state = GetMenuState(hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
00118   } else state = 0;
00119   SetCapture(Win32Hwnd);
00120   hdc = GetWindowDC(Win32Hwnd);
00121   if (wParam == HTMINBUTTON)
00122     DrawMinButton(hdc,NULL,TRUE,FALSE);
00123   else if (wParam == HTMAXBUTTON)
00124     DrawMaxButton(hdc,NULL,TRUE,FALSE);
00125   else
00126     DrawContextHelpButton(hdc,NULL,TRUE,FALSE);
00127   do
00128   {
00129     BOOL oldstate = pressed;
00130 
00131     GetMessageA(&msg,Win32Hwnd,0,0);
00132     pressed = (HandleNCHitTest(msg.pt) == wParam);
00133     if (pressed != oldstate)
00134     {
00135       if (wParam == HTMINBUTTON)
00136         DrawMinButton(hdc,NULL,pressed,FALSE);
00137       else if (wParam == HTMAXBUTTON)
00138         DrawMaxButton(hdc,NULL,pressed,FALSE);
00139       else
00140         DrawContextHelpButton(hdc,NULL,pressed,FALSE);
00141     }
00142   } while (msg.message != WM_LBUTTONUP);
00143   if (wParam == HTMINBUTTON)
00144     DrawMinButton(hdc,NULL,FALSE,FALSE);
00145   else if (wParam == HTMAXBUTTON)
00146     DrawMaxButton(hdc,NULL,FALSE,FALSE);
00147   else
00148     DrawContextHelpButton(hdc,NULL,FALSE,FALSE);
00149   ReleaseCapture();
00150   ReleaseDC(Win32Hwnd,hdc);
00151   /* If the item minimize or maximize of the sysmenu are not there */
00152   /* or if the style is not present, do nothing */
00153   if ((!pressed) || (state == 0xFFFFFFFF))
00154     return;
00155 
00156   if (wParam == HTMINBUTTON)
00157     SendInternalMessageA(WM_SYSCOMMAND,SC_MINIMIZE,*(LPARAM*)&msg.pt);
00158   else if (wParam == HTMAXBUTTON)
00159     SendInternalMessageA(WM_SYSCOMMAND,IsZoomed(Win32Hwnd) ? SC_RESTORE:SC_MAXIMIZE,*(LPARAM*)&msg.pt);
00160   else
00161     SendInternalMessageA(WM_SYSCOMMAND,SC_CONTEXTHELP,*(LPARAM*)&msg.pt);
00162 }
00163 //******************************************************************************
00164 //******************************************************************************
00165 VOID Win32BaseWindow::TrackCloseButton(WORD wParam)
00166 {
00167   MSG msg;
00168   HDC hdc;
00169   BOOL pressed = TRUE;
00170   UINT state;
00171 
00172   if (hSysMenu == 0)
00173     return;
00174   state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
00175   /* If the item close of the sysmenu is disabled or not there do nothing */
00176   if((state & MF_DISABLED) || (state & MF_GRAYED) || (state == 0xFFFFFFFF))
00177     return;
00178   hdc = GetWindowDC(Win32Hwnd);
00179   SetCapture(Win32Hwnd);
00180   DrawCloseButton(hdc,NULL,TRUE,FALSE);
00181   do
00182   {
00183     BOOL oldstate = pressed;
00184 
00185     GetMessageA(&msg,Win32Hwnd,0,0);
00186     pressed = (HandleNCHitTest(msg.pt) == wParam);
00187     if (pressed != oldstate)
00188       DrawCloseButton(hdc,NULL,pressed,FALSE);
00189   } while (msg.message != WM_LBUTTONUP);
00190   DrawCloseButton(hdc,NULL,FALSE,FALSE);
00191   ReleaseCapture();
00192   ReleaseDC(Win32Hwnd,hdc);
00193   if (!pressed) return;
00194   SendInternalMessageA(WM_SYSCOMMAND,SC_CLOSE,*(LPARAM*)&msg.pt);
00195 }
00196 //******************************************************************************
00197 //******************************************************************************
00198 VOID Win32BaseWindow::TrackScrollBar(WPARAM wParam,POINT pt)
00199 {
00200   INT scrollbar;
00201   MSG msg;
00202 
00203   if ((wParam & 0xfff0) == SC_HSCROLL)
00204   {
00205     if ((wParam & 0x0f) != HTHSCROLL) return;
00206     scrollbar = SB_HORZ;
00207   } else  /* SC_VSCROLL */
00208   {
00209     if ((wParam & 0x0f) != HTVSCROLL) return;
00210     scrollbar = SB_VERT;
00211   }
00212 
00213   ScreenToClient(getWindowHandle(), &pt);
00214   pt.x += rectClient.left;
00215   pt.y += rectClient.top;
00216 
00217   SCROLL_HandleScrollEvent(getWindowHandle(),0,MAKELONG(pt.x,pt.y),scrollbar,WM_LBUTTONDOWN);
00218   if (GetCapture() != Win32Hwnd) return;
00219   do
00220   {
00221     GetMessageA(&msg, 0, 0, 0);
00222     if(msg.hwnd == getWindowHandle())
00223     {
00224         switch(msg.message)
00225         {
00226         case WM_LBUTTONUP:
00227         case WM_MOUSEMOVE:
00228             pt.x = msg.pt.x;
00229             pt.y = msg.pt.y;
00230             ScreenToClient(getWindowHandle(), &pt);
00231         pt.x += rectClient.left;
00232         pt.y += rectClient.top;
00233             msg.lParam = MAKELONG(pt.x,pt.y);
00234 
00235         case WM_SYSTIMER:
00236             SCROLL_HandleScrollEvent(Win32Hwnd,msg.wParam,msg.lParam,scrollbar,msg.message);
00237             break;
00238 
00239         default:
00240             TranslateMessage(&msg);
00241             DispatchMessageA(&msg);
00242             break;
00243         }
00244     }
00245     else {
00246         TranslateMessage(&msg);
00247         DispatchMessageA(&msg);
00248     }
00249     if (!IsWindow())
00250     {
00251       ReleaseCapture();
00252       break;
00253     }
00254   } while (msg.message != WM_LBUTTONUP);
00255 }
00256 //******************************************************************************
00257 //******************************************************************************
00258 LONG Win32BaseWindow::HandleNCLButtonDown(WPARAM wParam,LPARAM lParam)
00259 {
00260   switch(wParam)  /* Hit test */
00261   {
00262     case HTCAPTION:
00263     {
00264       HWND hwndTopParent = GetTopParent();
00265 
00266         if((getStyle() & WS_CHILD) && !(getExStyle() & WS_EX_MDICHILD))
00267         {
00268             if (GetActiveWindow() != hwndTopParent)
00269             {
00270                 //SvL: Calling topparent->SetActiveWindow() causes focus problems
00271                 ::SetActiveWindow(hwndTopParent);
00272 ////            OSLibWinSetFocus(topparent->getOS2WindowHandle());
00273             }
00274             if (GetActiveWindow() == hwndTopParent)
00275                  SendInternalMessageA(WM_SYSCOMMAND,SC_MOVE+HTCAPTION,lParam);
00276             else dprintf(("ACtive window (%x) != toplevel wnd %x", OSLibWinQueryActiveWindow(), hwndTopParent));
00277         }
00278         else {
00279             SetActiveWindow();
00280             if (GetActiveWindow() == hwndTopParent)
00281                  SendInternalMessageA(WM_SYSCOMMAND,SC_MOVE+HTCAPTION,lParam);
00282             else dprintf(("ACtive window (%x) != wnd %x", OSLibWinQueryActiveWindow(), getWindowHandle()));
00283         }
00284         break;
00285     }
00286 
00287     case HTSYSMENU:
00288         if(dwStyle & WS_SYSMENU )
00289         {
00290             SendInternalMessageA(WM_SYSCOMMAND,SC_MOUSEMENU+HTSYSMENU,lParam);
00291         }
00292         break;
00293 
00294     case HTMENU:
00295         SendInternalMessageA(WM_SYSCOMMAND,SC_MOUSEMENU,lParam);
00296         break;
00297 
00298     case HTHSCROLL:
00299         SendInternalMessageA(WM_SYSCOMMAND,SC_HSCROLL+HTHSCROLL,lParam);
00300         break;
00301 
00302     case HTVSCROLL:
00303         SendInternalMessageA(WM_SYSCOMMAND,SC_VSCROLL+HTVSCROLL,lParam);
00304         break;
00305 
00306     case HTMINBUTTON:
00307     case HTMAXBUTTON:
00308     case HTHELP:
00309         TrackMinMaxHelpBox(wParam);
00310         break;
00311 
00312     case HTCLOSE:
00313         TrackCloseButton(wParam);
00314         break;
00315 
00316     case HTLEFT:
00317     case HTRIGHT:
00318     case HTTOP:
00319     case HTTOPLEFT:
00320     case HTTOPRIGHT:
00321     case HTBOTTOM:
00322     case HTBOTTOMLEFT:
00323     case HTBOTTOMRIGHT:
00324         /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
00325         SendInternalMessageA(WM_SYSCOMMAND,SC_SIZE+wParam-2,lParam);
00326         break;
00327     case HTBORDER:
00328         break;
00329   }
00330 
00331   return 0;
00332 }
00333 //******************************************************************************
00334 //******************************************************************************
00335 VOID Win32BaseWindow::AdjustMaximizedRect(LPRECT rect)
00336 {
00337     if (HAS_THICKFRAME(dwStyle,dwExStyle ))
00338         InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
00339     else
00340     if (HAS_DLGFRAME( dwStyle, dwExStyle ))
00341         InflateRect(rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
00342     else
00343     if (HAS_THINFRAME( dwStyle ))
00344         InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
00345 }
00346 //******************************************************************************
00347 //******************************************************************************
00348 VOID Win32BaseWindow::AdjustTrackInfo(PPOINT minTrackSize,PPOINT maxTrackSize)
00349 {
00350     if ((dwStyle & WS_THICKFRAME) || !(dwStyle & (WS_POPUP | WS_CHILD)))
00351         GetMinMaxInfo(NULL,NULL,minTrackSize,maxTrackSize);
00352 }
00353 //******************************************************************************
00354 //******************************************************************************
00355 VOID Win32BaseWindow::AdjustRectOuter(LPRECT rect,BOOL menu)
00356 {
00357     if(dwStyle & WS_ICONIC) return;
00358 
00359     if (HAS_THICKFRAME(dwStyle,dwExStyle ))
00360         InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
00361     else
00362     if (HAS_DLGFRAME( dwStyle, dwExStyle ))
00363         InflateRect(rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
00364     else
00365     if (HAS_THINFRAME( dwStyle ))
00366         InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
00367 
00368     if ((dwStyle & WS_CAPTION) == WS_CAPTION)
00369     {
00370         if (dwExStyle & WS_EX_TOOLWINDOW)
00371             rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
00372         else
00373             rect->top -= GetSystemMetrics(SM_CYCAPTION);
00374     }
00375 
00376     if (menu)
00377         rect->top -= GetSystemMetrics(SM_CYMENU);
00378 }
00379 //******************************************************************************
00380 //******************************************************************************
00381 VOID Win32BaseWindow::AdjustRectInner(LPRECT rect)
00382 {
00383   if(dwStyle & WS_ICONIC) return;
00384 
00385   if (dwExStyle & WS_EX_CLIENTEDGE)
00386     InflateRect (rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
00387 
00388   if (dwExStyle & WS_EX_STATICEDGE)
00389     InflateRect (rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
00390 
00391   if (dwStyle & WS_VSCROLL) rect->right  += GetSystemMetrics(SM_CXVSCROLL);
00392   if (dwStyle & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
00393 }
00394 //******************************************************************************
00395 //******************************************************************************
00396 LONG Win32BaseWindow::HandleNCCalcSize(BOOL calcValidRects,RECT *winRect)
00397 {
00398   RECT tmpRect = { 0, 0, 0, 0 };
00399   LONG result = 0;
00400   UINT style;
00401 
00402     dprintf(("Default WM_NCCALCSIZE handler"));
00403 
00404     if (!calcValidRects) return 0;
00405 
00406     style = (UINT) GetClassLongA(Win32Hwnd,GCL_STYLE);
00407 
00408     if (style & CS_VREDRAW) result |= WVR_VREDRAW;
00409     if (style & CS_HREDRAW) result |= WVR_HREDRAW;
00410 
00411     if(!(dwStyle & WS_MINIMIZE))
00412     {
00413         AdjustRectOuter(&tmpRect,FALSE);
00414 
00415         winRect->left   -= tmpRect.left;
00416         winRect->top    -= tmpRect.top;
00417         winRect->right  -= tmpRect.right;
00418         winRect->bottom -= tmpRect.bottom;
00419 
00420         if (HAS_MENU())
00421         {
00422             winRect->top +=
00423                 MENU_GetMenuBarHeight(Win32Hwnd,
00424                                       winRect->right - winRect->left,
00425                                       -tmpRect.left, -tmpRect.top ) + 1;
00426         }
00427 
00428         SetRect (&tmpRect, 0, 0, 0, 0);
00429         AdjustRectInner(&tmpRect);
00430         winRect->left   -= tmpRect.left;
00431         winRect->top    -= tmpRect.top;
00432         winRect->right  -= tmpRect.right;
00433         winRect->bottom -= tmpRect.bottom;
00434 
00435         if (winRect->top > winRect->bottom)
00436             winRect->bottom = winRect->top;
00437 
00438         if (winRect->left > winRect->right)
00439             winRect->right = winRect->left;
00440     }
00441 
00442     return result;
00443 }
00444 //******************************************************************************
00445 //******************************************************************************
00446 LONG Win32BaseWindow::HandleNCHitTest(POINT pt)
00447 {
00448   RECT rect;
00449 
00450   if (dwStyle & WS_MINIMIZE) return HTCAPTION;
00451 
00452   //TODO: is this correct???
00453   if (dwStyle & WS_DISABLED) return HTERROR;
00454 
00455   GetWindowRect(getWindowHandle(), &rect);
00456 
00457   if (!PtInRect(&rect,pt)) return HTNOWHERE;
00458 
00459   /* Check borders */
00460   if (HAS_THICKFRAME(dwStyle,dwExStyle))
00461   {
00462     InflateRect(&rect,-GetSystemMetrics(SM_CXFRAME),-GetSystemMetrics(SM_CYFRAME));
00463     if (!PtInRect(&rect,pt))
00464     {
00465       /* Check top sizing border */
00466       if (pt.y < rect.top)
00467       {
00468         if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
00469         if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
00470         return HTTOP;
00471       }
00472       /* Check bottom sizing border */
00473       if (pt.y >= rect.bottom)
00474       {
00475         if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
00476         if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
00477         return HTBOTTOM;
00478       }
00479       /* Check left sizing border */
00480       if (pt.x < rect.left)
00481       {
00482         if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
00483         if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
00484         return HTLEFT;
00485       }
00486       /* Check right sizing border */
00487       if (pt.x >= rect.right)
00488       {
00489         if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
00490         if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
00491         return HTRIGHT;
00492       }
00493     }
00494   } else  /* No thick frame */
00495   {
00496     if (HAS_DLGFRAME(dwStyle,dwExStyle))
00497       InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
00498     else if (HAS_THINFRAME(dwStyle ))
00499       InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
00500     if (!PtInRect( &rect, pt )) return HTBORDER;
00501   }
00502 
00503   /* Check caption */
00504 
00505   if ((dwStyle & WS_CAPTION) == WS_CAPTION)
00506   {
00507     if (dwExStyle & WS_EX_TOOLWINDOW)
00508       rect.top += GetSystemMetrics(SM_CYSMCAPTION)-1;
00509     else
00510       rect.top += GetSystemMetrics(SM_CYCAPTION)-1;
00511     if (!PtInRect(&rect,pt))
00512     {
00513       /* Check system menu */
00514       if(dwStyle & WS_SYSMENU)
00515       {
00516         /* Check if there is an user icon */
00517         if (IconForWindow(ICON_SMALL))
00518           rect.left += GetSystemMetrics(SM_CYCAPTION) - 1;
00519       }
00520       if (pt.x < rect.left) return HTSYSMENU;
00521 
00522       /* Check close button */
00523       if (dwStyle & WS_SYSMENU)
00524         rect.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
00525       if (pt.x > rect.right) return HTCLOSE;
00526 
00527       //Check context help
00528       if (dwExStyle & WS_EX_CONTEXTHELP)
00529           rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
00530       if (pt.x > rect.right) return HTHELP;
00531 
00532       /* Check maximize box */
00533       /* In win95 there is automatically a Maximize button when there is a minimize one*/
00534       if ((dwStyle & WS_MAXIMIZEBOX)|| (dwStyle & WS_MINIMIZEBOX))
00535           rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
00536       if (pt.x > rect.right) return HTMAXBUTTON;
00537 
00538       /* Check minimize box */
00539       /* In win95 there is automatically a Maximize button when there is a Maximize one*/
00540       if ((dwStyle & WS_MINIMIZEBOX)||(dwStyle & WS_MAXIMIZEBOX))
00541           rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
00542 
00543       if (pt.x > rect.right) return HTMINBUTTON;
00544       return HTCAPTION;
00545     }
00546   }
00547 
00548   /* Check client area */
00549 
00550   ScreenToClient(Win32Hwnd,&pt);
00551   getClientRect(&rect);
00552   if (PtInRect(&rect,pt)) return HTCLIENT;
00553 
00554   /* Check vertical scroll bar */
00555 
00556   if (dwStyle & WS_VSCROLL)
00557   {
00558     rect.right += GetSystemMetrics(SM_CXVSCROLL);
00559     if (PtInRect( &rect, pt )) return HTVSCROLL;
00560   }
00561 
00562   /* Check horizontal scroll bar */
00563 
00564   if (dwStyle & WS_HSCROLL)
00565   {
00566     rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
00567     if (PtInRect( &rect, pt ))
00568     {
00569       /* Check size box */
00570       if ((dwStyle & WS_VSCROLL) &&
00571           (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
00572         return (dwStyle & WS_CHILD) ? HTSIZE:HTBOTTOMRIGHT;
00573       return HTHSCROLL;
00574     }
00575   }
00576 
00577   /* Check menu bar */
00578 
00579   if (HAS_MENU())
00580   {
00581     if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
00582       return HTMENU;
00583   }
00584 
00585   /* Has to return HTNOWHERE if nothing was found
00586      Could happen when a window has a customized non client area */
00587   return HTNOWHERE;
00588 }
00589 
00590 //******************************************************************************
00591 //******************************************************************************
00592 VOID Win32BaseWindow::GetInsideRect(RECT *rect)
00593 {
00594   rect->top    = rect->left = 0;
00595   rect->right  = rectWindow.right - rectWindow.left;
00596   rect->bottom = rectWindow.bottom - rectWindow.top;
00597 
00598   if (dwStyle & WS_ICONIC) return;
00599 
00600   /* Remove frame from rectangle */
00601   if (HAS_THICKFRAME(dwStyle,dwExStyle))
00602   {
00603     InflateRect( rect, -GetSystemMetrics(SM_CXSIZEFRAME), -GetSystemMetrics(SM_CYSIZEFRAME) );
00604   }
00605   else if (HAS_DLGFRAME(dwStyle,dwExStyle ))
00606   {
00607     InflateRect( rect, -GetSystemMetrics(SM_CXFIXEDFRAME), -GetSystemMetrics(SM_CYFIXEDFRAME));
00608   }
00609   else if (HAS_THINFRAME(dwStyle))
00610   {
00611     InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
00612   }
00613 
00614   /* We have additional border information if the window
00615    * is a child (but not an MDI child) */
00616   if ( (dwStyle & WS_CHILD)  &&
00617        ( (dwExStyle & WS_EX_MDICHILD) == 0 ) )
00618   {
00619     if (dwExStyle & WS_EX_CLIENTEDGE)
00620       InflateRect (rect, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE));
00621 
00622     if (dwExStyle & WS_EX_STATICEDGE)
00623       InflateRect (rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
00624   }
00625 }
00626 //******************************************************************************
00627 //******************************************************************************
00628 VOID Win32BaseWindow::DrawFrame(HDC hdc,RECT *rect,BOOL dlgFrame,BOOL active)
00629 {
00630   INT width, height;
00631   HBRUSH oldBrush;
00632 
00633   if (dlgFrame)
00634   {
00635     width = GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
00636     height = GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
00637   }
00638   else
00639   {
00640     width = GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXEDGE);
00641     height = GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYEDGE);
00642   }
00643 
00644   oldBrush = SelectObject(hdc,GetSysColorBrush(active ? COLOR_ACTIVEBORDER:COLOR_INACTIVEBORDER));
00645 
00646   /* Draw frame */
00647   PatBlt(hdc,rect->left,   rect->top,      rect->right-rect->left, height,PATCOPY); //top
00648   PatBlt(hdc,rect->left,   rect->top,      width,                  rect->bottom-rect->top,PATCOPY); //left
00649   PatBlt(hdc,rect->left,   rect->bottom-1, rect->right-rect->left,-height,PATCOPY); //bottom
00650   PatBlt(hdc,rect->right-1,rect->top,     -width,                  rect->bottom-rect->top,PATCOPY); //right
00651   SelectObject(hdc,oldBrush);
00652 
00653   InflateRect(rect,-width,-height);
00654 }
00655 //******************************************************************************
00656 //******************************************************************************
00657 BOOL Win32BaseWindow::DrawSysButton(HDC hdc,RECT *rect)
00658 {
00659   HICON  hSysIcon;
00660   RECT r;
00661 
00662   if (!rect) GetInsideRect(&r);
00663   else r = *rect;
00664 
00665   hSysIcon = IconForWindow(ICON_SMALL);
00666 
00667 //CB: todo: add icons (including Odin icon) to user32.rc
00668   if (hSysIcon)
00669     DrawIconEx(hdc,r.left+2,r.top+2,hSysIcon,
00670                GetSystemMetrics(SM_CXSMICON),
00671                GetSystemMetrics(SM_CYSMICON),
00672                0, 0, DI_NORMAL);
00673 
00674   return (hSysIcon != 0);
00675 }
00676 //******************************************************************************
00677 //Returns position of system menu in screen coordinates
00678 //******************************************************************************
00679 BOOL Win32BaseWindow::GetSysPopupPos(RECT* rect)
00680 {
00681     if(hSysMenu)
00682     {
00683         if(dwStyle & WS_MINIMIZE) {
00684             *rect = rectWindow;
00685         }
00686         else
00687         {
00688             GetInsideRect(rect );
00689             OffsetRect( rect, rectWindow.left, rectWindow.top);
00690             if(getStyle() & WS_CHILD)
00691                 ClientToScreen(getParent()->getWindowHandle(), (POINT *)rect);
00692 
00693             rect->right = rect->left + GetSystemMetrics(SM_CYCAPTION) - 1;
00694             rect->bottom = rect->top + GetSystemMetrics(SM_CYCAPTION) - 1;
00695         }
00696         return TRUE;
00697     }
00698     return FALSE;
00699 }
00700 //******************************************************************************
00701 //******************************************************************************
00702 BOOL Win32BaseWindow::DrawGrayButton(HDC hdc,int x,int y)
00703 {
00704   HBITMAP hMaskBmp;
00705   HDC hdcMask = CreateCompatibleDC (0);
00706   HBRUSH hOldBrush;
00707   hMaskBmp = CreateBitmap (12, 10, 1, 1, lpGrayMask);
00708 
00709   if(hMaskBmp == 0)
00710     return FALSE;
00711 
00712   SelectObject (hdcMask, hMaskBmp);
00713 
00714   /* Draw the grayed bitmap using the mask */
00715   hOldBrush = SelectObject (hdc, RGB(128, 128, 128));
00716   BitBlt (hdc, x, y, 12, 10,
00717           hdcMask, 0, 0, 0xB8074A);
00718 
00719   /* Clean up */
00720   SelectObject (hdc, hOldBrush);
00721   DeleteObject(hMaskBmp);
00722   DeleteDC (hdcMask);
00723 
00724   return TRUE;
00725 }
00726 //******************************************************************************
00727 //******************************************************************************
00728 VOID Win32BaseWindow::DrawCloseButton(HDC hdc,RECT *rect,BOOL down,BOOL bGrayed)
00729 {
00730   RECT r;
00731   HDC hdcMem;
00732   BITMAP bmp;
00733   HBITMAP hBmp, hOldBmp;
00734 
00735   if (!rect) GetInsideRect(&r);
00736   else r = *rect;
00737 
00738   /* A tool window has a smaller Close button */
00739   if (dwExStyle & WS_EX_TOOLWINDOW)
00740   {
00741     RECT toolRect;
00742     INT iBmpHeight = 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE   */
00743     INT iBmpWidth = 11;  /* it uses 11x11 for  the close button in tool window */
00744     INT iCaptionHeight = GetSystemMetrics(SM_CYSMCAPTION);
00745 
00746 
00747     toolRect.top = r.top + (iCaptionHeight - 1 - iBmpHeight) / 2;
00748     toolRect.left = r.right - (iCaptionHeight + 1 + iBmpWidth) / 2;
00749     toolRect.bottom = toolRect.top + iBmpHeight;
00750     toolRect.right = toolRect.left + iBmpWidth;
00751     DrawFrameControl(hdc,&toolRect,
00752                      DFC_CAPTION,DFCS_CAPTIONCLOSE |
00753                      down ? DFCS_PUSHED : 0 |
00754                      bGrayed ? DFCS_INACTIVE : 0);
00755   } else
00756   {
00757     hdcMem = CreateCompatibleDC( hdc );
00758     hBmp = down ? hbitmapCloseD : hbitmapClose;
00759     hOldBmp = SelectObject (hdcMem, hBmp);
00760     GetObjectA (hBmp, sizeof(BITMAP), &bmp);
00761 
00762     BitBlt (hdc, r.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2,
00763             r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
00764             bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);
00765 
00766     if(bGrayed)
00767       DrawGrayButton(hdc,r.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2 + 2,
00768                      r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
00769 
00770     SelectObject (hdcMem, hOldBmp);
00771     DeleteDC (hdcMem);
00772   }
00773 }
00774 //******************************************************************************
00775 //******************************************************************************
00776 VOID Win32BaseWindow::DrawMaxButton(HDC hdc,RECT *rect,BOOL down,BOOL bGrayed)
00777 {
00778   RECT r;
00779   HDC hdcMem;
00780   BITMAP  bmp;
00781   HBITMAP  hBmp,hOldBmp;
00782 
00783   if (!rect) GetInsideRect(&r);
00784   else r = *rect;
00785   hdcMem = CreateCompatibleDC( hdc );
00786   hBmp = IsZoomed(Win32Hwnd) ?
00787           (down ? hbitmapRestoreD : hbitmapRestore ) :
00788           (down ? hbitmapMaximizeD: hbitmapMaximize);
00789   hOldBmp = SelectObject( hdcMem, hBmp );
00790   GetObjectA (hBmp, sizeof(BITMAP), &bmp);
00791 
00792   if (dwStyle & WS_SYSMENU)
00793     r.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
00794 
00795   if (dwExStyle & WS_EX_CONTEXTHELP)
00796     r.right -= bmp.bmWidth;
00797 
00798   BitBlt( hdc, r.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
00799         r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
00800         bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
00801 
00802   if(bGrayed)
00803     DrawGrayButton(hdc, r.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
00804                    r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
00805 
00806   SelectObject (hdcMem, hOldBmp);
00807   DeleteDC( hdcMem );
00808 }
00809 //******************************************************************************
00810 //******************************************************************************
00811 VOID Win32BaseWindow::DrawMinButton(HDC hdc,RECT *rect,BOOL down,BOOL bGrayed)
00812 {
00813   RECT r;
00814   HDC hdcMem;
00815   BITMAP  bmp;
00816   HBITMAP  hBmp,hOldBmp;
00817 
00818   if (!rect) GetInsideRect(&r);
00819   else r = *rect;
00820 
00821   hdcMem = CreateCompatibleDC( hdc );
00822   hBmp = down ? hbitmapMinimizeD : hbitmapMinimize;
00823   hOldBmp= SelectObject( hdcMem, hBmp );
00824   GetObjectA (hBmp, sizeof(BITMAP), &bmp);
00825 
00826   if (dwStyle & WS_SYSMENU)
00827     r.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
00828 
00829   if (dwExStyle & WS_EX_CONTEXTHELP)
00830     r.right -= bmp.bmWidth;
00831 
00832   /* In win 95 there is always a Maximize box when there is a Minimize one */
00833   if ((dwStyle & WS_MAXIMIZEBOX) || (dwStyle & WS_MINIMIZEBOX))
00834     r.right -= bmp.bmWidth;
00835 
00836   BitBlt( hdc, r.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
00837           r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
00838           bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
00839 
00840   if(bGrayed)
00841     DrawGrayButton(hdc, r.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
00842                    r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
00843 
00844 
00845   SelectObject (hdcMem, hOldBmp);
00846   DeleteDC( hdcMem );
00847 }
00848 //******************************************************************************
00849 //******************************************************************************
00850 VOID Win32BaseWindow::DrawContextHelpButton(HDC hdc,RECT *rect,BOOL down,BOOL bGrayed)
00851 {
00852   RECT r;
00853   HDC hdcMem;
00854   BITMAP  bmp;
00855   HBITMAP  hBmp,hOldBmp;
00856 
00857   if (!rect) GetInsideRect(&r);
00858   else r = *rect;
00859 
00860   hdcMem = CreateCompatibleDC(hdc);
00861   hBmp = down ? hbitmapContextHelpD : hbitmapContextHelp;
00862   hOldBmp = SelectObject(hdcMem,hBmp);
00863   GetObjectA(hBmp,sizeof(BITMAP),&bmp);
00864 
00865   if (dwStyle & WS_SYSMENU)
00866     r.right -= GetSystemMetrics(SM_CYCAPTION)+1;
00867 
00868   BitBlt( hdc, r.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
00869           r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
00870           bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
00871 
00872   if(bGrayed)
00873     DrawGrayButton(hdc, r.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
00874                    r.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
00875 
00876 
00877   SelectObject (hdcMem, hOldBmp);
00878   DeleteDC( hdcMem );
00879 }
00880 //******************************************************************************
00881 //******************************************************************************
00882 VOID Win32BaseWindow::DrawCaption(HDC hdc,RECT *rect,BOOL active)
00883 {
00884   RECT  r = *rect,r2;
00885   char  buffer[256];
00886   HPEN  hPrevPen;
00887   HDC memDC;
00888   HBITMAP memBmp,oldBmp;
00889 
00890   if(fOS2Look) {
00891       if ((dwStyle & WS_SYSMENU) && !(dwExStyle & WS_EX_TOOLWINDOW) &&
00892            fOS2Look != OS2_APPEARANCE_SYSMENU)
00893       {
00894          HICON hSysIcon = IconForWindow(ICON_SMALL);
00895 
00896          if (hSysIcon) {
00897              int size = GetSystemMetrics(SM_CYCAPTION);
00898    
00899              r2 = r;
00900              r2.right  = r2.left + size;
00901              r2.bottom = r2.top + size;
00902              FillRect(hdc, &r2, GetSysColorBrush(COLOR_MENU));
00903 
00904              DrawSysButton(hdc,&r);
00905          }
00906       }
00907       return;
00908   }
00909 
00910   memDC = CreateCompatibleDC(hdc);
00911   r.right -= r.left;
00912   r.bottom -= r.top;
00913   r.left = r.top = 0;
00914   r2 = r;
00915   memBmp = CreateCompatibleBitmap(hdc,r.right,r.bottom);
00916   oldBmp = SelectObject(memDC,memBmp);
00917 
00918   hPrevPen = SelectObject(memDC,GetSysColorPen(COLOR_3DFACE));
00919   MoveToEx(memDC,r.left,r.bottom-1,NULL);
00920   LineTo(memDC,r.right,r.bottom-1);
00921   SelectObject(memDC,hPrevPen);
00922   r.bottom--;
00923 
00924   if (SYSCOLOR_GetUseWinColors())
00925   {
00926     COLORREF startColor = GetSysColor(active ? COLOR_ACTIVECAPTION:COLOR_INACTIVECAPTION),endColor = GetSysColor(active ? COLOR_GRADIENTACTIVECAPTION:COLOR_GRADIENTINACTIVECAPTION);
00927 
00928     if (startColor == endColor)
00929       FillRect(memDC,&r,GetSysColorBrush(startColor));
00930     else
00931     {
00932       INT rDiff = GetRValue(endColor)-GetRValue(startColor);
00933       INT gDiff = GetGValue(endColor)-GetGValue(startColor);
00934       INT bDiff = GetBValue(endColor)-GetBValue(startColor);
00935       INT steps = MAX(MAX(abs(rDiff),abs(gDiff)),abs(bDiff));
00936       INT w = r.right-r.left;
00937       RECT r2;
00938 
00939       if (w < steps) steps = w;
00940       r2.left = r2.right = r.left;
00941       r2.top = r.top;
00942       r2.bottom = r.bottom;
00943       for (INT x = 0;x <= steps;x++)
00944       {
00945         COLORREF color = RGB(GetRValue(startColor)+rDiff*x/steps,GetGValue(startColor)+gDiff*x/steps,GetBValue(startColor)+bDiff*x/steps);
00946         HBRUSH brush = CreateSolidBrush(color);
00947 
00948         r2.left = r2.right;
00949         r2.right = r.left+w*x/steps;
00950         FillRect(memDC,&r2,brush);
00951         DeleteObject(brush);
00952       }
00953     }
00954   } else FillRect(memDC,&r,GetSysColorBrush(active ? COLOR_ACTIVECAPTION:COLOR_INACTIVECAPTION));
00955 
00956   if (!hbitmapClose)
00957   {
00958     if (!(hbitmapClose = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CLOSE)))) return;
00959     hbitmapCloseD       = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CLOSED));
00960     hbitmapMinimize     = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_REDUCE));
00961     hbitmapMinimizeD    = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_REDUCED));
00962     hbitmapMaximize     = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_ZOOM));
00963     hbitmapMaximizeD    = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_ZOOMD));
00964     hbitmapRestore      = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_RESTORE));
00965     hbitmapRestoreD     = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_RESTORED));
00966     hbitmapContextHelp  = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CONTEXTHELP));
00967     hbitmapContextHelpD = LoadBitmapA(0,MAKEINTRESOURCEA(OBM_CONTEXTHELPD));
00968   }
00969 
00970   if ((dwStyle & WS_SYSMENU) && !(dwExStyle & WS_EX_TOOLWINDOW))
00971   {
00972     if (DrawSysButton(memDC,&r))
00973       r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
00974   }
00975 
00976   if (dwStyle & WS_SYSMENU)
00977   {
00978     UINT state;
00979 
00980     /* Go get the sysmenu */
00981     state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
00982 
00983     /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
00984     DrawCloseButton(memDC,&r2,FALSE,
00985                     ((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
00986     r.right -= GetSystemMetrics(SM_CYCAPTION)-1;
00987 
00988     if (dwExStyle & WS_EX_CONTEXTHELP)
00989     {
00990       DrawContextHelpButton(memDC,&r2,FALSE,FALSE);
00991       r.right -= GetSystemMetrics(SM_CXSIZE)+1;
00992     }
00993 
00994     if ((dwStyle & WS_MAXIMIZEBOX) || (dwStyle & WS_MINIMIZEBOX))
00995     {
00996       /* In win95 the two buttons are always there */
00997       /* But if the menu item is not in the menu they're disabled*/
00998 
00999       DrawMaxButton(memDC,&r2,FALSE,(!(dwStyle & WS_MAXIMIZEBOX)));
01000       r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
01001 
01002       DrawMinButton(memDC,&r2,FALSE,  (!(dwStyle & WS_MINIMIZEBOX)));
01003       r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
01004     }
01005   }
01006 
01007   if (GetWindowTextA(buffer, sizeof(buffer) ))
01008   {
01009     NONCLIENTMETRICSA nclm;
01010     HFONT hFont, hOldFont;
01011 
01012     nclm.cbSize = sizeof(NONCLIENTMETRICSA);
01013     SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
01014     if (dwExStyle & WS_EX_TOOLWINDOW)
01015       hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
01016     else
01017       hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
01018     hOldFont = SelectObject (memDC, hFont);
01019     SetTextColor(memDC,GetSysColor(active ? COLOR_CAPTIONTEXT:COLOR_INACTIVECAPTIONTEXT));
01020     SetBkMode(memDC, TRANSPARENT );
01021     r.left += 2;
01022     DrawTextExA(memDC,buffer,-1,&r,DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT | DT_END_ELLIPSIS,NULL);
01023     DeleteObject (SelectObject (memDC, hOldFont));
01024     IncreaseLogCount();
01025     dprintf(("DrawCaption %s %d", buffer, active));
01026     DecreaseLogCount();
01027   }
01028 
01029   BitBlt(hdc,rect->left,rect->top,rect->right-rect->left,rect->bottom-rect->top,memDC,0,0,SRCCOPY);
01030   SelectObject(memDC,oldBmp);
01031   DeleteObject(memBmp);
01032   DeleteDC(memDC);
01033 }
01034 //******************************************************************************
01035 //******************************************************************************
01036 VOID Win32BaseWindow::DoNCPaint(HRGN clip,BOOL suppress_menupaint)
01037 {
01038     BOOL active  = flags & WIN_NCACTIVATED;
01039     HDC hdc;
01040     RECT rect,rectClip,rfuzz;
01041 
01042     /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
01043        the call to GetDCEx implying that it is allowed not to use it either.
01044        However, the suggested GetDCEx(    , DCX_WINDOW | DCX_INTERSECTRGN)
01045        will cause clipRgn to be deleted after ReleaseDC().
01046        Now, how is the "system" supposed to tell what happened?
01047     */
01048 
01049     dprintf(("DoNCPaint %x %x %d", getWindowHandle(), clip, suppress_menupaint));
01050 
01051     rect.top    = rect.left = 0;
01052     rect.right  = rectWindow.right - rectWindow.left;
01053     rect.bottom = rectWindow.bottom - rectWindow.top;
01054 
01055     if (clip > 1)
01056     {
01057         //only redraw caption
01058         GetRgnBox(clip,&rectClip);
01059 #if 1
01060         //SvL: I'm getting paint problems when clipping a dc created in GetDCEx
01061         //     with a region that covers the entire window (RealPlayer 7 Update 1)
01062         //     As we don't need to clip anything when that occurs, this workaround
01063         //     solves the problem.
01064         if(rectClip.right == getWindowWidth() && rectClip.bottom == getWindowHeight())
01065         {
01066             clip = 0;
01067             rectClip = rect;
01068         }
01069 #endif
01070     }
01071     else
01072     {
01073         clip = 0;
01074         rectClip = rect;
01075     }
01076 
01077     if (!(hdc = GetDCEx( Win32Hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
01078                          ((clip > 1) ?(DCX_INTERSECTRGN /*| DCX_KEEPCLIPRGN*/) : 0) ))) return;
01079 
01080     DecreaseLogCount();
01081     SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
01082 
01083     if (HAS_BIGFRAME( dwStyle, dwExStyle))
01084     {
01085         DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
01086     }
01087     if (HAS_THICKFRAME( dwStyle, dwExStyle ))
01088         DrawFrame(hdc, &rect, FALSE, active );
01089     else
01090     if (HAS_DLGFRAME( dwStyle, dwExStyle ))
01091         DrawFrame( hdc, &rect, TRUE, active );
01092     else
01093     if (HAS_THINFRAME( dwStyle ))
01094     {
01095         SelectObject( hdc, GetStockObject(NULL_BRUSH) );
01096         Rectangle( hdc, 0, 0, rect.right, rect.bottom );
01097     }
01098 
01099     if ((dwStyle & WS_CAPTION) == WS_CAPTION)
01100     {
01101         RECT  r = rect;
01102         if (dwExStyle & WS_EX_TOOLWINDOW)
01103         {
01104             r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
01105             rect.top += GetSystemMetrics(SM_CYSMCAPTION);
01106         }
01107         else
01108         {
01109             r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
01110             rect.top += GetSystemMetrics(SM_CYCAPTION);
01111         }
01112         if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
01113             DrawCaption(hdc,&r,active);
01114     }
01115 
01116     if (HAS_MENU())
01117     {
01118         RECT r = rect;
01119         r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
01120 
01121         rect.top += MENU_DrawMenuBar(hdc,&r,Win32Hwnd,suppress_menupaint)+1;
01122     }
01123 
01124     if (dwExStyle & WS_EX_CLIENTEDGE)
01125         DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
01126 
01127     if (dwExStyle & WS_EX_STATICEDGE)
01128         DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
01129 
01130     /* Draw the scroll-bars */
01131     if (dwStyle & WS_VSCROLL)
01132         SCROLL_DrawScrollBar(Win32Hwnd,hdc,SB_VERT,TRUE,TRUE);
01133     if (dwStyle & WS_HSCROLL)
01134         SCROLL_DrawScrollBar(Win32Hwnd,hdc,SB_HORZ,TRUE,TRUE);
01135 
01136     /* Draw the "size-box" */
01137     if ((dwStyle & WS_VSCROLL) && (dwStyle & WS_HSCROLL))
01138     {
01139         RECT r = rect;
01140         r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
01141         r.top  = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
01142         FillRect( hdc, &r,  GetSysColorBrush(COLOR_SCROLLBAR) );
01143         //CB: todo: child windows have sometimes a size grip (i.e. Notepad)
01144         //    WS_SIZEBOX isn't set in these cases
01145         if (!(dwStyle & WS_CHILD))
01146         {
01147             POINT p1,p2;
01148             HPEN penDark = GetSysColorPen(COLOR_3DSHADOW);
01149             HPEN penWhite = GetSysColorPen(COLOR_3DHILIGHT);
01150             HPEN oldPen = SelectObject(hdc,penDark);
01151             INT x;
01152 
01153             p1.x = r.right-1;
01154             p1.y = r.bottom;
01155             p2.x = r.right;
01156             p2.y = r.bottom-1;
01157             for (x = 0;x < 3;x++)
01158             {
01159                 SelectObject(hdc,penDark);
01160                 MoveToEx(hdc,p1.x,p1.y,NULL);
01161                 LineTo(hdc,p2.x,p2.y);
01162                 p1.x--;
01163                 p2.y--;
01164                 MoveToEx(hdc,p1.x,p1.y,NULL);
01165                 LineTo(hdc,p2.x,p2.y);
01166                 SelectObject(hdc,penWhite);
01167                 p1.x--;
01168                 p2.y--;
01169                 MoveToEx(hdc,p1.x,p1.y,NULL);
01170                 LineTo(hdc,p2.x,p2.y);
01171                 p1.x -= 2;
01172                 p2.y -= 2;
01173             }
01174 
01175             SelectObject(hdc,oldPen);
01176         }
01177     }
01178 
01179     IncreaseLogCount();
01180     ReleaseDC(getWindowHandle(),hdc);
01181     dprintf(("**DoNCPaint %x DONE", getWindowHandle()));
01182 }
01183 //******************************************************************************
01184 //******************************************************************************
01185 LONG Win32BaseWindow::HandleNCPaint(HRGN clip)
01186 {
01187 //CB: ignore it for now (SetWindowPos in WM_CREATE)
01188 //  if (!(dwStyle & WS_VISIBLE)) return 0;
01189 
01190   if (dwStyle & WS_MINIMIZE) return 0;
01191 
01192   DoNCPaint(clip,FALSE);
01193 
01194   return 0;
01195 }
01196 /***********************************************************************
01197  *           NC_HandleNCLButtonDblClk
01198  *
01199  * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
01200  */
01201 LONG Win32BaseWindow::HandleNCLButtonDblClk(WPARAM wParam,LPARAM lParam)
01202 {
01203   /*
01204    * if this is an icon, send a restore since we are handling
01205    * a double click
01206    */
01207   if (dwStyle & WS_MINIMIZE)
01208   {
01209     SendInternalMessageA(WM_SYSCOMMAND,SC_RESTORE,lParam);
01210     return 0;
01211   }
01212 
01213   switch(wParam)  /* Hit test */
01214   {
01215     case HTCAPTION:
01216       /* stop processing if WS_MAXIMIZEBOX is missing */
01217       if (dwStyle & WS_MAXIMIZEBOX)
01218         SendInternalMessageA(WM_SYSCOMMAND,
01219                       (dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
01220                       lParam);
01221       break;
01222 
01223     case HTSYSMENU:
01224       if (!(GetClassWord(Win32Hwnd,GCW_STYLE) & CS_NOCLOSE))
01225         SendInternalMessageA(WM_SYSCOMMAND,SC_CLOSE,lParam);
01226       break;
01227 
01228     case HTHSCROLL:
01229       SendInternalMessageA(WM_SYSCOMMAND,SC_HSCROLL+HTHSCROLL,lParam);
01230       break;
01231 
01232     case HTVSCROLL:
01233       SendInternalMessageA(WM_SYSCOMMAND,SC_VSCROLL+HTVSCROLL,lParam);
01234       break;
01235   }
01236 
01237   return 0;
01238 }
01239 //******************************************************************************
01240 //******************************************************************************
01241 LONG Win32BaseWindow::HandleNCRButtonUp(WPARAM wParam,LPARAM lParam)
01242 {
01243   switch(wParam)
01244   {
01245     case HTCAPTION:
01246       if (GetActiveWindow() != Win32Hwnd)
01247         SetActiveWindow();
01248 
01249       if (((GetActiveWindow() == Win32Hwnd) || isMDIChild()) && (dwStyle & WS_SYSMENU))
01250       {
01251         SendInternalMessageA(WM_SYSCOMMAND,SC_MOUSEMENU+HTCAPTION,lParam);
01252       }
01253       break;
01254 
01255     default:
01256       break;
01257   }
01258 
01259   return 0;
01260 }
01261 /***********************************************************************
01262  *           NC_HandleSysCommand
01263  *
01264  * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
01265  *
01266  */
01267 LONG Win32BaseWindow::HandleSysCommand(WPARAM wParam,POINT *pt32)
01268 {
01269     UINT uCommand = wParam & 0xFFF0;
01270 
01271     switch (uCommand)
01272     {
01273     case SC_SIZE:
01274     {
01275 #ifdef CUSTOM_TRACKFRAME
01276       Frame_SysCommandSizeMove(this, wParam);
01277 #else
01278       DWORD flags;
01279 
01280       if (dwStyle & WS_MAXIMIZE) break;
01281 
01282       switch ((wParam & 0xF)+2)
01283       {
01284         case HTLEFT:
01285           flags = TFOS_LEFT;
01286           break;
01287 
01288         case HTRIGHT:
01289           flags = TFOS_RIGHT;
01290           break;
01291 
01292         case HTTOP:
01293           flags = TFOS_TOP;
01294           break;
01295 
01296         case HTTOPLEFT:
01297           flags = TFOS_TOP | TFOS_LEFT;
01298           break;
01299 
01300         case HTTOPRIGHT:
01301           flags = TFOS_TOP | TFOS_RIGHT;
01302           break;
01303 
01304         case HTBOTTOM:
01305           flags = TFOS_BOTTOM;
01306           break;
01307 
01308         case HTBOTTOMLEFT:
01309           flags = TFOS_BOTTOM | TFOS_LEFT;
01310           break;
01311 
01312         case HTBOTTOMRIGHT:
01313           flags = TFOS_BOTTOM | TFOS_RIGHT;
01314           break;
01315 
01316         default:
01317           flags = TFOS_BOTTOM | TFOS_RIGHT;
01318           break;
01319       }
01320       if (flags) FrameTrackFrame(this,flags);
01321 #endif
01322       break;
01323     }
01324 
01325     case SC_MOVE:
01326 #ifdef CUSTOM_TRACKFRAME
01327         Frame_SysCommandSizeMove(this, wParam);
01328 #else
01329         if (dwStyle & WS_MAXIMIZE) break;
01330         FrameTrackFrame(this,TFOS_MOVE);
01331 #endif
01332         break;
01333 
01334     case SC_MINIMIZE:
01335         ShowWindow(SW_MINIMIZE);
01336         break;
01337 
01338     case SC_MAXIMIZE:
01339         ShowWindow(SW_MAXIMIZE);
01340         break;
01341 
01342     case SC_RESTORE:
01343         ShowWindow(SW_RESTORE);
01344         break;
01345 
01346     case SC_CLOSE:
01347         return SendInternalMessageA(WM_CLOSE,0,0);
01348 
01349     case SC_CONTEXTHELP:
01350         {
01351           //CB: todo
01352           break;
01353         }
01354 
01355     case SC_VSCROLL:
01356     case SC_HSCROLL:
01357         TrackScrollBar(wParam,*pt32);
01358         break;
01359 
01360     case SC_MOUSEMENU:
01361         MENU_TrackMouseMenuBar(Win32Hwnd,wParam & 0x000F,*pt32);
01362         break;
01363 
01364     case SC_KEYMENU:
01365         MENU_TrackKbdMenuBar(Win32Hwnd,wParam,pt32->x);
01366         break;
01367 
01368     case SC_TASKLIST:
01369         OSLibWinShowTaskList(getOS2WindowHandle());
01370         break;
01371 
01372     case SC_SCREENSAVE:
01373         if (wParam == SC_ABOUTODIN) {
01374             if(ShellAboutA == 0) {
01375                 HINSTANCE hShell32 = LoadLibraryA("SHELL32");
01376                 if(hShell32 == 0)
01377                     break;
01378                 *(VOID **)&ShellAboutA = (VOID *)GetProcAddress(hShell32, "ShellAboutA");
01379             }
01380             ShellAboutA(Win32Hwnd,"Odin","Odin alpha release compiled with IBM VAC++",0);
01381         }
01382 #ifdef DEBUG
01383         //SvL: Do NOT turn this into a dprintf.
01384         else
01385         if (wParam == SC_PUTMARK)
01386             WriteLog(("Mark requested by user\n"));
01387     else
01388         if (wParam == SC_DEBUGINT3)
01389             DebugInt3();
01390 #endif
01391         break;
01392 
01393     case SC_HOTKEY:
01394     case SC_ARRANGE:
01395     case SC_NEXTWINDOW:
01396     case SC_PREVWINDOW:
01397         break;
01398     }
01399     return 0;
01400 }
01401 /*****************************************************************************
01402  * Name      : VOID WIN32API DrawCaption
01403  * Purpose   : The DrawCaption function draws a window caption.
01404  * Parameters: HDC hdc        handle of device context
01405  *             LPRECT lprc    address of bounding rectangle coordinates
01406  *             HFONT hfont    handle of font for caption
01407  *             HICON hicon    handle of icon in caption
01408  *             LPSTR lpszText address of caption string
01409  *             WORD wFlags    drawing options
01410  * Variables :
01411  * Result    :
01412  * Remark    :
01413  * Status    : UNTESTED STUB
01414  *
01415  * Author    : Patrick Haller [Thu, 1998/02/26 11:55]
01416  *****************************************************************************/
01417 BOOL WIN32API DrawCaption (HWND hwnd,HDC  hdc,const RECT *lprc,UINT wFlags)
01418 {
01419   dprintf(("USER32: DrawCaption"));
01420 
01421   return DrawCaptionTempA(hwnd,hdc,lprc,0,0,NULL,wFlags & 0x1F);
01422 }
01423 //******************************************************************************
01424 // CB: this code is a subset of Win32BaseWindow::DrawCaption
01425 //     todo: move Win32BaseWindow:DrawCaption to this function
01426 //******************************************************************************
01427 BOOL WIN32API DrawCaptionTemp(HWND hwnd,HDC hdc,const RECT *rect,HFONT hFont,HICON hIcon,LPWSTR str,UINT uFlags,BOOL unicode)
01428 {
01429   RECT rc = *rect;
01430 
01431   /* drawing background */
01432   if (uFlags & DC_INBUTTON)
01433   {
01434     FillRect (hdc, &rc, GetSysColorBrush (COLOR_3DFACE));
01435 
01436     if (uFlags & DC_ACTIVE)
01437     {
01438       HBRUSH hbr = SelectObject (hdc, GetPattern55AABrush ());
01439       PatBlt (hdc, rc.left, rc.top,
01440               rc.right-rc.left, rc.bottom-rc.top, 0xFA0089);
01441       SelectObject (hdc, hbr);
01442     }
01443   } else
01444   {
01445     FillRect (hdc, &rc, GetSysColorBrush ((uFlags & DC_ACTIVE) ?
01446               COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
01447   }
01448 
01449   /* drawing icon */
01450   if ((uFlags & DC_ICON) && !(uFlags & DC_SMALLCAP))
01451   {
01452     POINT pt;
01453 
01454     pt.x = rc.left + 2;
01455     pt.y = (rc.bottom + rc.top - GetSystemMetrics(SM_CYSMICON)) / 2;
01456 
01457     if (hIcon)
01458     {
01459       DrawIconEx (hdc, pt.x, pt.y, hIcon, GetSystemMetrics(SM_CXSMICON),
01460                   GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
01461     } else
01462     {
01463       Win32BaseWindow *win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
01464 
01465       if (!win32wnd) return 0;
01466 
01467       DrawIconEx (hdc, pt.x, pt.y, win32wnd->IconForWindow(ICON_SMALL),
01468                   GetSystemMetrics(SM_CXSMICON),
01469                   GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
01470     }
01471 
01472     rc.left += (rc.bottom - rc.top);
01473   }
01474 
01475   /* drawing text */
01476   if (uFlags & DC_TEXT)
01477   {
01478     HFONT hOldFont;
01479 
01480     if (uFlags & DC_INBUTTON)
01481       SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
01482     else if (uFlags & DC_ACTIVE)
01483       SetTextColor (hdc, GetSysColor (COLOR_CAPTIONTEXT));
01484     else
01485       SetTextColor (hdc, GetSysColor (COLOR_INACTIVECAPTIONTEXT));
01486 
01487     SetBkMode (hdc, TRANSPARENT);
01488 
01489     if (hFont)
01490       hOldFont = SelectObject (hdc, hFont);
01491     else
01492     {
01493       NONCLIENTMETRICSA nclm;
01494       HFONT hNewFont;
01495 
01496       nclm.cbSize = sizeof(NONCLIENTMETRICSA);
01497       SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
01498       hNewFont = CreateFontIndirectA ((uFlags & DC_SMALLCAP) ?
01499         &nclm.lfSmCaptionFont : &nclm.lfCaptionFont);
01500       hOldFont = SelectObject (hdc, hNewFont);
01501     }
01502 
01503     if (str)
01504     {
01505       if (unicode)
01506         DrawTextW(hdc,str,-1,&rc,DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
01507       else
01508         DrawTextA(hdc,(LPSTR)str,-1,&rc,DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
01509     } else
01510     {
01511       CHAR szText[128];
01512       INT nLen;
01513 
01514       nLen = GetWindowTextA (hwnd, szText, 128);
01515       DrawTextA (hdc, szText, nLen, &rc,
01516                  DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
01517     }
01518 
01519     if (hFont)
01520       SelectObject (hdc, hOldFont);
01521     else
01522       DeleteObject (SelectObject (hdc, hOldFont));
01523   }
01524 
01525   /* drawing focus ??? */
01526   //if (uFlags & 0x2000)
01527   //  FIXME("undocumented flag (0x2000)!\n");
01528 
01529   return 0;
01530 }
01531 /***********************************************************************
01532  * DrawCaptionTemp32A [USER32.599]
01533  *
01534  * PARAMS
01535  *
01536  * RETURNS
01537  *     Success:
01538  *     Failure:
01539  */
01540 BOOL WIN32API DrawCaptionTempA(HWND hwnd,HDC hdc,const RECT *rect,HFONT hFont,HICON hIcon,LPCSTR str,UINT uFlags)
01541 {
01542   dprintf(("USER32: DrawCaptionTempA"));
01543 
01544   return DrawCaptionTemp(hwnd,hdc,rect,hFont,hIcon,(LPWSTR)str,uFlags,FALSE);
01545 }
01546 /***********************************************************************
01547  * DrawCaptionTemp32W [USER32.602]
01548  *
01549  * PARAMS
01550  *
01551  * RETURNS
01552  *     Success:
01553  *     Failure:
01554  */
01555 BOOL WIN32API DrawCaptionTempW (HWND hwnd,HDC hdc,const RECT *rect,HFONT hFont,HICON hIcon,LPCWSTR str,UINT uFlags)
01556 {
01557   dprintf(("USER32: DrawCaptionTempA"));
01558 
01559   return DrawCaptionTemp(hwnd,hdc,rect,hFont,hIcon,(LPWSTR)str,uFlags,TRUE);
01560 }
01561 

Generated on Wed Jan 23 23:17:48 2002 for ODIN-user32 by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001