1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        os2/utilsgui.cpp 
   3 // Purpose:     Various utility functions only available in GUI 
   4 // Author:      David Webster 
   6 // Created:     20.08.2003 (extracted from os2/utils.cpp) 
   8 // Copyright:   (c) David Webster 
   9 // License:     wxWindows licence 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 // for compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  31     #include "wx/cursor.h" 
  34 #include "wx/apptrait.h" 
  37 #include "wx/os2/private.h"     // includes <windows.h> 
  39 // ============================================================================ 
  41 // ============================================================================ 
  43 // ---------------------------------------------------------------------------- 
  44 // functions to work with .INI files 
  45 // ---------------------------------------------------------------------------- 
  47 // Sleep for nSecs seconds. Attempt a Windows implementation using timers. 
  48 static bool inTimer 
= FALSE
; 
  50 class wxSleepTimer
: public wxTimer
 
  60 // Reading and writing resources (eg WIN.INI, .Xdefaults) 
  63   const wxString
&                   rSection
 
  64 , const wxString
&                   rEntry
 
  65 , const wxString
&                   rValue
 
  66 , const wxString
&                   rFile
 
  74         hIni 
= ::PrfOpenProfile(hab
, (PSZ
)WXSTRINGCAST rFile
); 
  77             return (::PrfWriteProfileString( hIni
 
  78                                             ,(PSZ
)WXSTRINGCAST rSection
 
  79                                             ,(PSZ
)WXSTRINGCAST rEntry
 
  80                                             ,(PSZ
)WXSTRINGCAST rValue
 
  85         return (::PrfWriteProfileString( HINI_PROFILE
 
  86                                         ,(PSZ
)WXSTRINGCAST rSection
 
  87                                         ,(PSZ
)WXSTRINGCAST rEntry
 
  88                                         ,(PSZ
)WXSTRINGCAST rValue
 
  94   const wxString
&                   rSection
 
  95 , const wxString
&                   rEntry
 
  97 , const wxString
&                   rFile
 
 102     wxSprintf(zBuf
, "%.4f", fValue
); 
 103     return wxWriteResource( rSection
 
 110 bool wxWriteResource( 
 111   const wxString
&                   rSection
 
 112 , const wxString
&                   rEntry
 
 114 , const wxString
&                   rFile
 
 119     wxSprintf(zBuf
, "%ld", lValue
); 
 120     return wxWriteResource( rSection
 
 127 bool wxWriteResource( 
 128   const wxString
&                   rSection
 
 129 , const wxString
&                   rEntry
 
 131 , const wxString
&                   rFile
 
 136     wxSprintf(zBuf
, "%d", lValue
); 
 137     return wxWriteResource( rSection
 
 145   const wxString
&                   rSection
 
 146 , const wxString
&                   rEntry
 
 148 , const wxString
&                   rFile
 
 153     wxChar                          zDefunkt
[] = _T("$$default"); 
 158         hIni 
= ::PrfOpenProfile(hab
, (PSZ
)WXSTRINGCAST rFile
); 
 161             ULONG n 
= ::PrfQueryProfileString( hIni
 
 162                                               ,(PSZ
)WXSTRINGCAST rSection
 
 163                                               ,(PSZ
)WXSTRINGCAST rEntry
 
 170             if (n 
== 0L || wxStrcmp(zBuf
, zDefunkt
) == 0) 
 179         ULONG n 
= ::PrfQueryProfileString( HINI_PROFILE
 
 180                                           ,(PSZ
)WXSTRINGCAST rSection
 
 181                                           ,(PSZ
)WXSTRINGCAST rEntry
 
 188         if (n 
== 0L || wxStrcmp(zBuf
, zDefunkt
) == 0) 
 192     strcpy((char*)*ppValue
, zBuf
); 
 197   const wxString
&                   rSection
 
 198 , const wxString
&                   rEntry
 
 200 , const wxString
&                   rFile
 
 205     zStr 
= new wxChar
[1000]; 
 206     bool                            bSucc 
= wxGetResource( rSection
 
 214         *pValue 
= (float)wxStrtod(zStr
, NULL
); 
 226   const wxString
&                   rSection
 
 227 , const wxString
&                   rEntry
 
 229 , const wxString
&                   rFile
 
 234     zStr 
= new wxChar
[1000]; 
 235     bool                              bSucc 
= wxGetResource( rSection
 
 243         *pValue 
= wxStrtol(zStr
, NULL
, 10); 
 255   const wxString
&                   rSection
 
 256 , const wxString
&                   rEntry
 
 258 , const wxString
&                   rFile
 
 263     zStr 
= new wxChar
[1000]; 
 264     bool                            bSucc 
= wxGetResource( rSection
 
 272         *pValue 
= (int)wxStrtol(zStr
, NULL
, 10); 
 282 #endif // wxUSE_RESOURCES 
 284 // --------------------------------------------------------------------------- 
 285 // helper functions for showing a "busy" cursor 
 286 // --------------------------------------------------------------------------- 
 288 HCURSOR gs_wxBusyCursor 
= 0;     // new, busy cursor 
 289 HCURSOR gs_wxBusyCursorOld 
= 0;  // old cursor 
 290 static int gs_wxBusyCursorCount 
= 0; 
 292 // Set the cursor to the busy cursor for all windows 
 293 void wxBeginBusyCursor( 
 297     if ( gs_wxBusyCursorCount
++ == 0 ) 
 299         gs_wxBusyCursor 
= (HCURSOR
)pCursor
->GetHCURSOR(); 
 300         ::WinSetPointer(HWND_DESKTOP
, (HPOINTER
)gs_wxBusyCursor
); 
 302     //else: nothing to do, already set 
 305 // Restore cursor to normal 
 306 void wxEndBusyCursor() 
 308     wxCHECK_RET( gs_wxBusyCursorCount 
> 0 
 309                 ,_T("no matching wxBeginBusyCursor() for wxEndBusyCursor()") 
 312     if (--gs_wxBusyCursorCount 
== 0) 
 314         ::WinSetPointer(HWND_DESKTOP
, (HPOINTER
)gs_wxBusyCursorOld
); 
 315         gs_wxBusyCursorOld 
= 0; 
 319 // TRUE if we're between the above two calls 
 322     return (gs_wxBusyCursorCount 
> 0); 
 325 // Check whether this window wants to process messages, e.g. Stop button 
 326 // in long calculations. 
 327 bool wxCheckForInterrupt( 
 335         HWND                        hwndFilter 
= NULLHANDLE
; 
 337         while(::WinPeekMsg(hab
, &vMsg
, hwndFilter
, 0, 0, PM_REMOVE
)) 
 339             ::WinDispatchMsg(hab
, &vMsg
); 
 341         return TRUE
;//*** temporary? 
 345         wxFAIL_MSG(_T("pWnd==NULL !!!")); 
 346         return FALSE
;//*** temporary? 
 350 // ---------------------------------------------------------------------------- 
 352 // ---------------------------------------------------------------------------- 
 354 // See also the wxGetMousePosition in window.cpp 
 355 // Deprecated: use wxPoint wxGetMousePosition() instead 
 356 void wxGetMousePosition( 
 363     ::WinQueryPointerPos(HWND_DESKTOP
, &vPt
); 
 368 // Return TRUE if we have a colour display 
 369 bool wxColourDisplay() 
 376     hpsScreen 
= ::WinGetScreenPS(HWND_DESKTOP
); 
 377     hdcScreen 
= ::GpiQueryDevice(hpsScreen
); 
 378     ::DevQueryCaps(hdcScreen
, CAPS_COLORS
, 1L, &lColors
); 
 379     return(lColors 
> 1L); 
 381     // I don't see how the PM display could not be color. Besides, this 
 382     // was leaking DCs and PSs!!!  MN 
 387 // Returns depth of screen 
 394     static LONG                     nDepth 
= 0; 
 396     // The screen colordepth ain't gonna change. No reason to query 
 399         hpsScreen 
= ::WinGetScreenPS(HWND_DESKTOP
); 
 400         hdcScreen 
= ::GpiQueryDevice(hpsScreen
); 
 401         ::DevQueryCaps(hdcScreen
, CAPS_COLOR_PLANES
, 1L, &lPlanes
); 
 402         ::DevQueryCaps(hdcScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitsPerPixel
); 
 404         nDepth 
= (int)(lPlanes 
* lBitsPerPixel
); 
 405         ::DevCloseDC(hdcScreen
); 
 406         ::WinReleasePS(hpsScreen
); 
 411 // Get size of display 
 419     static LONG                     lWidth  
= 0; 
 420     static LONG                     lHeight 
= 0; 
 422     // The screen size ain't gonna change either so just cache the values 
 424         hpsScreen 
= ::WinGetScreenPS(HWND_DESKTOP
); 
 425         hdcScreen 
= ::GpiQueryDevice(hpsScreen
); 
 426         ::DevQueryCaps(hdcScreen
, CAPS_WIDTH
, 1L, &lWidth
); 
 427         ::DevQueryCaps(hdcScreen
, CAPS_HEIGHT
, 1L, &lHeight
); 
 428         ::DevCloseDC(hdcScreen
); 
 429         ::WinReleasePS(hpsScreen
); 
 431     *pWidth 
= (int)lWidth
; 
 432     *pHeight 
= (int)lHeight
; 
 435 void wxDisplaySizeMM( 
 443     hpsScreen 
= ::WinGetScreenPS(HWND_DESKTOP
); 
 444     hdcScreen 
= ::GpiQueryDevice(hpsScreen
); 
 447         ::DevQueryCaps( hdcScreen
 
 448                        ,CAPS_HORIZONTAL_RESOLUTION
 
 453         ::DevQueryCaps( hdcScreen
 
 454                        ,CAPS_VERTICAL_RESOLUTION
 
 458     ::DevCloseDC(hdcScreen
); 
 459     ::WinReleasePS(hpsScreen
); 
 462 void wxClientDisplayRect(int *x
, int *y
, int *width
, int *height
) 
 464     // This is supposed to return desktop dimensions minus any window 
 465     // manager panels, menus, taskbars, etc.  If there is a way to do that 
 466     // for this platform please fix this function, otherwise it defaults 
 467     // to the entire desktop. 
 470     wxDisplaySize(width
, height
); 
 473 void wxGUIAppTraits::InitializeGui(unsigned long &ulHab
) 
 475     ulHab 
= ::WinInitialize(0); 
 478 void wxGUIAppTraits::TerminateGui(unsigned long ulHab
) 
 480     ::WinTerminate(ulHab
); 
 483 wxToolkitInfo 
& wxGUIAppTraits::GetToolkitInfo() 
 485     static wxToolkitInfo            vInfo
; 
 486     ULONG                           ulSysInfo
[QSV_MAX
] = {0}; 
 489     vInfo
.shortName 
= _T("PM"); 
 490     vInfo
.name 
= _T("wxOS2"); 
 491 #ifdef __WXUNIVERSAL__ 
 492     vInfo
.shortName 
<< _T("univ"); 
 493     vInfo
.name 
<< _T("/wxUniversal"); 
 495     ulrc 
= ::DosQuerySysInfo( 1L 
 498                              ,sizeof(ULONG
) * QSV_MAX
 
 502         vInfo
.versionMajor 
= ulSysInfo
[QSV_VERSION_MAJOR
] / 10; 
 503         vInfo
.versionMinor 
= ulSysInfo
[QSV_VERSION_MINOR
]; 
 509 // --------------------------------------------------------------------------- 
 510 // window information functions 
 511 // --------------------------------------------------------------------------- 
 513 wxString WXDLLEXPORT 
wxGetWindowText( 
 521         long                lLen 
= ::WinQueryWindowTextLength((HWND
)hWnd
) + 1; 
 522         ::WinQueryWindowText((HWND
)hWnd
, lLen
, wxStringBuffer(vStr
, lLen
)); 
 528 wxString WXDLLEXPORT 
wxGetWindowClass( 
 535         int                         nLen 
= 256; // some starting value 
 539             int                     nCount 
= ::WinQueryClassName((HWND
)hWnd
, nLen
, wxStringBuffer(vStr
, nLen
)); 
 543                 // the class name might have been truncated, retry with larger 
 556 WXWORD WXDLLEXPORT 
wxGetWindowId( 
 560     return ::WinQueryWindowUShort((HWND
)hWnd
, QWS_ID
); 
 571     vPoint
[0].x 
= rRect
.xLeft
; 
 572     vPoint
[0].y 
= rRect
.yBottom
; 
 573     ::GpiMove(hPS
, &vPoint
[0]); 
 574     if (dwStyle 
& wxSIMPLE_BORDER 
|| 
 575         dwStyle 
& wxSTATIC_BORDER
) 
 577         vPoint
[1].x 
= rRect
.xRight 
- 1; 
 578         vPoint
[1].y 
= rRect
.yTop 
- 1; 
 586     if (dwStyle 
& wxSUNKEN_BORDER
) 
 588         LINEBUNDLE                      vLineBundle
; 
 590         vLineBundle
.lColor     
= 0x00FFFFFF; // WHITE 
 591         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 592         vLineBundle
.fxWidth    
= 2; 
 593         vLineBundle
.lGeomWidth 
= 2; 
 594         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 595         vLineBundle
.usEnd      
= 0; 
 596         vLineBundle
.usJoin     
= 0; 
 599                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 603         vPoint
[1].x 
= rRect
.xRight 
- 1; 
 604         vPoint
[1].y 
= rRect
.yTop 
- 1; 
 611        vPoint
[0].x 
= rRect
.xLeft 
+ 1; 
 612        vPoint
[0].y 
= rRect
.yBottom 
+ 1; 
 613        ::GpiMove(hPS
, &vPoint
[0]); 
 614         vPoint
[1].x 
= rRect
.xRight 
- 2; 
 615         vPoint
[1].y 
= rRect
.yTop 
- 2; 
 623         vLineBundle
.lColor     
= 0x00000000; // BLACK 
 624         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 625         vLineBundle
.fxWidth    
= 2; 
 626         vLineBundle
.lGeomWidth 
= 2; 
 627         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 628         vLineBundle
.usEnd      
= 0; 
 629         vLineBundle
.usJoin     
= 0; 
 632                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 636         vPoint
[0].x 
= rRect
.xLeft 
+ 2; 
 637         vPoint
[0].y 
= rRect
.yBottom 
+ 2; 
 638         ::GpiMove(hPS
, &vPoint
[0]); 
 639         vPoint
[1].x 
= rRect
.xLeft 
+ 2; 
 640         vPoint
[1].y 
= rRect
.yTop 
- 3; 
 641         ::GpiLine(hPS
, &vPoint
[1]); 
 642         vPoint
[1].x 
= rRect
.xRight 
- 3; 
 643         vPoint
[1].y 
= rRect
.yTop 
- 3; 
 644         ::GpiLine(hPS
, &vPoint
[1]); 
 646         vPoint
[0].x 
= rRect
.xLeft 
+ 3; 
 647         vPoint
[0].y 
= rRect
.yBottom 
+ 3; 
 648         ::GpiMove(hPS
, &vPoint
[0]); 
 649         vPoint
[1].x 
= rRect
.xLeft 
+ 3; 
 650         vPoint
[1].y 
= rRect
.yTop 
- 4; 
 651         ::GpiLine(hPS
, &vPoint
[1]); 
 652         vPoint
[1].x 
= rRect
.xRight 
- 4; 
 653         vPoint
[1].y 
= rRect
.yTop 
- 4; 
 654         ::GpiLine(hPS
, &vPoint
[1]); 
 656     if (dwStyle 
& wxDOUBLE_BORDER
) 
 658         LINEBUNDLE                      vLineBundle
; 
 660         vLineBundle
.lColor     
= 0x00FFFFFF; // WHITE 
 661         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 662         vLineBundle
.fxWidth    
= 2; 
 663         vLineBundle
.lGeomWidth 
= 2; 
 664         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 665         vLineBundle
.usEnd      
= 0; 
 666         vLineBundle
.usJoin     
= 0; 
 669                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 673         vPoint
[1].x 
= rRect
.xRight 
- 1; 
 674         vPoint
[1].y 
= rRect
.yTop 
- 1; 
 681         vLineBundle
.lColor     
= 0x00000000; // WHITE 
 682         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 683         vLineBundle
.fxWidth    
= 2; 
 684         vLineBundle
.lGeomWidth 
= 2; 
 685         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 686         vLineBundle
.usEnd      
= 0; 
 687         vLineBundle
.usJoin     
= 0; 
 690                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 694         vPoint
[0].x 
= rRect
.xLeft 
+ 2; 
 695         vPoint
[0].y 
= rRect
.yBottom 
+ 2; 
 696         ::GpiMove(hPS
, &vPoint
[0]); 
 697         vPoint
[1].x 
= rRect
.xRight 
- 2; 
 698         vPoint
[1].y 
= rRect
.yTop 
- 2; 
 705         vLineBundle
.lColor     
= 0x00FFFFFF; // BLACK 
 706         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 707         vLineBundle
.fxWidth    
= 2; 
 708         vLineBundle
.lGeomWidth 
= 2; 
 709         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 710         vLineBundle
.usEnd      
= 0; 
 711         vLineBundle
.usJoin     
= 0; 
 714                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 718         vPoint
[0].x 
= rRect
.xLeft 
+ 3; 
 719         vPoint
[0].y 
= rRect
.yBottom 
+ 3; 
 720         ::GpiMove(hPS
, &vPoint
[0]); 
 721         vPoint
[1].x 
= rRect
.xRight 
- 3; 
 722         vPoint
[1].y 
= rRect
.yTop 
- 3; 
 730     if (dwStyle 
& wxRAISED_BORDER
) 
 732         LINEBUNDLE                      vLineBundle
; 
 734         vLineBundle
.lColor     
= 0x00000000; // BLACK 
 735         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 736         vLineBundle
.fxWidth    
= 2; 
 737         vLineBundle
.lGeomWidth 
= 2; 
 738         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 739         vLineBundle
.usEnd      
= 0; 
 740         vLineBundle
.usJoin     
= 0; 
 743                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 747         vPoint
[1].x 
= rRect
.xRight 
- 1; 
 748         vPoint
[1].y 
= rRect
.yTop 
- 1; 
 755        vPoint
[0].x 
= rRect
.xLeft 
+ 1; 
 756        vPoint
[0].y 
= rRect
.yBottom 
+ 1; 
 757        ::GpiMove(hPS
, &vPoint
[0]); 
 758         vPoint
[1].x 
= rRect
.xRight 
- 2; 
 759         vPoint
[1].y 
= rRect
.yTop 
- 2; 
 767         vLineBundle
.lColor     
= 0x00FFFFFF; // WHITE 
 768         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 769         vLineBundle
.fxWidth    
= 2; 
 770         vLineBundle
.lGeomWidth 
= 2; 
 771         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 772         vLineBundle
.usEnd      
= 0; 
 773         vLineBundle
.usJoin     
= 0; 
 776                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 780         vPoint
[0].x 
= rRect
.xLeft 
+ 2; 
 781         vPoint
[0].y 
= rRect
.yBottom 
+ 2; 
 782         ::GpiMove(hPS
, &vPoint
[0]); 
 783         vPoint
[1].x 
= rRect
.xLeft 
+ 2; 
 784         vPoint
[1].y 
= rRect
.yTop 
- 3; 
 785         ::GpiLine(hPS
, &vPoint
[1]); 
 786         vPoint
[1].x 
= rRect
.xRight 
- 3; 
 787         vPoint
[1].y 
= rRect
.yTop 
- 3; 
 788         ::GpiLine(hPS
, &vPoint
[1]); 
 790         vPoint
[0].x 
= rRect
.xLeft 
+ 3; 
 791         vPoint
[0].y 
= rRect
.yBottom 
+ 3; 
 792         ::GpiMove(hPS
, &vPoint
[0]); 
 793         vPoint
[1].x 
= rRect
.xLeft 
+ 3; 
 794         vPoint
[1].y 
= rRect
.yTop 
- 4; 
 795         ::GpiLine(hPS
, &vPoint
[1]); 
 796         vPoint
[1].x 
= rRect
.xRight 
- 4; 
 797         vPoint
[1].y 
= rRect
.yTop 
- 4; 
 798         ::GpiLine(hPS
, &vPoint
[1]); 
 800 } // end of wxDrawBorder 
 804 , const wxFont
&                     rFont
 
 812     if (hWnd 
== NULLHANDLE
) 
 816     // The fonts available for Presentation Params are just a few 
 817     // outline fonts, the rest are available to the GPI, so we must 
 818     // map the families to one of these three 
 820     switch(rFont
.GetFamily()) 
 823             strcpy(zFacename
, "Script"); 
 827             strcpy(zFacename
, "WarpSans"); 
 831             strcpy(zFacename
,"Times New Roman"); 
 835             strcpy(zFacename
, "Courier New"); 
 839             strcpy(zFacename
, "Courier New"); 
 845             strcpy(zFacename
, "Helvetica"); 
 849     switch(rFont
.GetWeight()) 
 858         case wxFONTWEIGHT_MAX
: 
 859             strcpy(zWeight
, "Bold"); 
 863     switch(rFont
.GetStyle()) 
 867             strcpy(zStyle
, "Italic"); 
 874     sprintf(zFont
, "%d.%s", rFont
.GetPointSize(), zFacename
); 
 875     if (zWeight
[0] != '\0') 
 878         strcat(zFont
, zWeight
); 
 880     if (zStyle
[0] != '\0') 
 883         strcat(zFont
, zStyle
); 
 885     ::WinSetPresParam(hWnd
, PP_FONTNAMESIZE
, strlen(zFont
) + 1, (PVOID
)zFont
); 
 886 } // end of wxOS2SetFont 
 888 // --------------------------------------------------------------------------- 
 889 // Helper for taking a regular bitmap and giving it a disabled look 
 890 // --------------------------------------------------------------------------- 
 891 wxBitmap 
wxDisableBitmap( 
 896     wxMask
*                         pMask 
= rBmp
.GetMask(); 
 899         return(wxNullBitmap
); 
 901     DEVOPENSTRUC                    vDop  
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
 902     SIZEL                           vSize 
= {0, 0}; 
 903     HDC                             hDC   
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
 904     HPS                             hPS   
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
 905     BITMAPINFOHEADER2               vHeader
; 
 909     HBITMAP                         hBitmap 
=  (HBITMAP
)rBmp
.GetHBITMAP(); 
 910     HBITMAP                         hOldBitmap 
= NULLHANDLE
; 
 911     HBITMAP                         hOldMask   
= NULLHANDLE
; 
 912     HBITMAP                         hMask 
= (HBITMAP
)rBmp
.GetMask()->GetMaskBitmap(); 
 913     unsigned char*                  pucBits
;     // buffer that will contain the bitmap data 
 914     unsigned char*                  pucData
;     // pointer to use to traverse bitmap data 
 915     unsigned char*                  pucBitsMask
; // buffer that will contain the mask data 
 916     unsigned char*                  pucDataMask
; // pointer to use to traverse mask data 
 919     bool                            bpp16 
= (wxDisplayDepth() == 16); 
 921     memset(&vHeader
, '\0', 16); 
 924     memset(&vInfo
, '\0', 16); 
 926     vInfo
.cx              
= (ULONG
)rBmp
.GetWidth(); 
 927     vInfo
.cy              
= (ULONG
)rBmp
.GetHeight(); 
 929     vInfo
.cBitCount       
= 24; // Set to desired count going in 
 932     // Create the buffers for data....all wxBitmaps are 24 bit internally 
 934     int                             nBytesPerLine 
= rBmp
.GetWidth() * 3; 
 935     int                             nSizeDWORD    
= sizeof(DWORD
); 
 936     int                             nLineBoundary 
= nBytesPerLine 
% nSizeDWORD
; 
 942     // Bitmap must be ina double-word alligned address so we may 
 943     // have some padding to worry about 
 945     if (nLineBoundary 
> 0) 
 947         nPadding     
= nSizeDWORD 
- nLineBoundary
; 
 948         nBytesPerLine 
+= nPadding
; 
 950     pucBits 
= (unsigned char *)malloc(nBytesPerLine 
* rBmp
.GetHeight()); 
 951     memset(pucBits
, '\0', (nBytesPerLine 
* rBmp
.GetHeight())); 
 952     pucBitsMask 
= (unsigned char *)malloc(nBytesPerLine 
* rBmp
.GetHeight()); 
 953     memset(pucBitsMask
, '\0', (nBytesPerLine 
* rBmp
.GetHeight())); 
 956     // Extract the bitmap and mask data 
 958     if ((hOldBitmap 
= ::GpiSetBitmap(hPS
, hBitmap
)) == HBM_ERROR
) 
 960         vError 
= ::WinGetLastError(vHabmain
); 
 961         sError 
= wxPMErrorToStr(vError
); 
 963     ::GpiQueryBitmapInfoHeader(hBitmap
, &vHeader
); 
 964     vInfo
.cBitCount 
= 24; 
 965     if ((lScans 
= ::GpiQueryBitmapBits( hPS
 
 967                                        ,(LONG
)rBmp
.GetHeight() 
 972         vError 
= ::WinGetLastError(vHabmain
); 
 973         sError 
= wxPMErrorToStr(vError
); 
 975     if ((hOldMask 
= ::GpiSetBitmap(hPS
, hMask
)) == HBM_ERROR
) 
 977         vError 
= ::WinGetLastError(vHabmain
); 
 978         sError 
= wxPMErrorToStr(vError
); 
 980     ::GpiQueryBitmapInfoHeader(hMask
, &vHeader
); 
 981     vInfo
.cBitCount 
= 24; 
 982     if ((lScans 
= ::GpiQueryBitmapBits( hPS
 
 984                                        ,(LONG
)rBmp
.GetHeight() 
 989         vError 
= ::WinGetLastError(vHabmain
); 
 990         sError 
= wxPMErrorToStr(vError
); 
 992     if (( hMask 
= ::GpiSetBitmap(hPS
, hOldMask
)) == HBM_ERROR
) 
 994         vError 
= ::WinGetLastError(vHabmain
); 
 995         sError 
= wxPMErrorToStr(vError
); 
 998     pucDataMask 
= pucBitsMask
; 
1001     // Get the mask value 
1003     for (i 
= 0; i 
< rBmp
.GetHeight(); i
++) 
1005         for (j 
= 0; j 
< rBmp
.GetWidth(); j
++) 
1008             if (bpp16 
&& *pucDataMask 
== 0xF8) // 16 bit display gobblygook 
1013             else if (*pucDataMask 
== 0xFF) // set to grey 
1020                 *pucData 
= ((unsigned char)(lColor 
>> 16)); 
1025             if (bpp16 
&& *(pucDataMask 
+ 1) == 0xFC) // 16 bit display gobblygook 
1030             else if (*(pucDataMask 
+ 1) == 0xFF) // set to grey 
1037                 *pucData 
= ((unsigned char)(lColor 
>> 8)); 
1042             if (bpp16 
&& *(pucDataMask 
+ 2) == 0xF8) // 16 bit display gobblygook 
1047             else if (*(pucDataMask 
+ 2) == 0xFF) // set to grey 
1054                 *pucData 
= ((unsigned char)lColor
); 
1059         for (j 
= 0; j 
< nPadding
; j
++) 
1067     // Create a new bitmap and set the modified bits 
1069     wxBitmap                        
vNewBmp( rBmp
.GetWidth() 
1073     HBITMAP                         hNewBmp 
= (HBITMAP
)vNewBmp
.GetHBITMAP(); 
1075     if ((hOldBitmap 
= ::GpiSetBitmap(hPS
, hNewBmp
)) == HBM_ERROR
) 
1077         vError 
= ::WinGetLastError(vHabmain
); 
1078         sError 
= wxPMErrorToStr(vError
); 
1080     if ((lScansSet 
= ::GpiSetBitmapBits( hPS
 
1082                                         ,(LONG
)rBmp
.GetHeight() 
1088         vError 
= ::WinGetLastError(vHabmain
); 
1089         sError 
= wxPMErrorToStr(vError
); 
1093     pNewMask 
= new wxMask(pMask
->GetMaskBitmap()); 
1094     vNewBmp
.SetMask(pNewMask
); 
1096     ::GpiSetBitmap(hPS
, NULLHANDLE
); 
1097     ::GpiDestroyPS(hPS
); 
1101     return(wxNullBitmap
); 
1102 } // end of wxDisableBitmap 
1104 COLORREF 
wxColourToRGB( 
1105   const wxColour
&                   rColor
 
1108     return(OS2RGB(rColor
.Red(), rColor
.Green(), rColor
.Blue())); 
1109 } // end of wxColourToRGB