1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/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" 
  30     #include "wx/cursor.h" 
  34 #include "wx/apptrait.h" 
  36 #include "wx/os2/private.h"     // includes <windows.h> 
  38 // ============================================================================ 
  40 // ============================================================================ 
  42 // ---------------------------------------------------------------------------- 
  43 // functions to work with .INI files 
  44 // ---------------------------------------------------------------------------- 
  46 // Sleep for nSecs seconds. Attempt a Windows implementation using timers. 
  47 static bool inTimer 
= false; 
  49 class wxSleepTimer
: public wxTimer
 
  59 // Reading and writing resources (eg WIN.INI, .Xdefaults) 
  61 bool wxWriteResource( const wxString
& rSection
, 
  62                       const wxString
& rEntry
, 
  63                       const wxString
& rValue
, 
  64                       const wxString
& rFile 
) 
  71         hIni 
= ::PrfOpenProfile(hab
, (PSZ
)WXSTRINGCAST rFile
); 
  74             return (::PrfWriteProfileString( hIni
 
  75                                             ,(PSZ
)WXSTRINGCAST rSection
 
  76                                             ,(PSZ
)WXSTRINGCAST rEntry
 
  77                                             ,(PSZ
)WXSTRINGCAST rValue
 
  82         return (::PrfWriteProfileString( HINI_PROFILE
 
  83                                         ,(PSZ
)WXSTRINGCAST rSection
 
  84                                         ,(PSZ
)WXSTRINGCAST rEntry
 
  85                                         ,(PSZ
)WXSTRINGCAST rValue
 
  91   const wxString
&                   rSection
 
  92 , const wxString
&                   rEntry
 
  94 , const wxString
&                   rFile
 
  99     wxSprintf(zBuf
, "%.4f", fValue
); 
 100     return wxWriteResource( rSection
 
 107 bool wxWriteResource( 
 108   const wxString
&                   rSection
 
 109 , const wxString
&                   rEntry
 
 111 , const wxString
&                   rFile
 
 116     wxSprintf(zBuf
, "%ld", lValue
); 
 117     return wxWriteResource( rSection
 
 124 bool wxWriteResource( const wxString
& rSection
, 
 125                       const wxString
& rEntry
, 
 127                       const wxString
& rFile 
) 
 131     wxSprintf(zBuf
, "%d", lValue
); 
 132     return wxWriteResource( rSection
, rEntry
, zBuf
, rFile 
); 
 135 bool wxGetResource( const wxString
& rSection
, 
 136                     const wxString
& rEntry
, 
 138                     const wxString
& rFile 
) 
 142     wxChar zDefunkt
[] = _T("$$default"); 
 147         hIni 
= ::PrfOpenProfile(hab
, (PSZ
)WXSTRINGCAST rFile
); 
 150             ULONG n 
= ::PrfQueryProfileString( hIni
 
 151                                               ,(PSZ
)WXSTRINGCAST rSection
 
 152                                               ,(PSZ
)WXSTRINGCAST rEntry
 
 159             if (n 
== 0L || wxStrcmp(zBuf
, zDefunkt
) == 0) 
 168         ULONG n 
= ::PrfQueryProfileString( HINI_PROFILE
 
 169                                           ,(PSZ
)WXSTRINGCAST rSection
 
 170                                           ,(PSZ
)WXSTRINGCAST rEntry
 
 177         if (n 
== 0L || wxStrcmp(zBuf
, zDefunkt
) == 0) 
 181     strcpy((char*)*ppValue
, zBuf
); 
 185 bool wxGetResource( const wxString
& rSection
, 
 186                     const wxString
& rEntry
, 
 188                     const wxString
& rFile 
) 
 192     zStr 
= new wxChar
[1000]; 
 193     bool bSucc 
= wxGetResource( rSection
, rEntry
, (wxChar 
**)&zStr
, rFile 
); 
 197         *pValue 
= (float)wxStrtod(zStr
, NULL
); 
 204 bool wxGetResource( const wxString
& rSection
, 
 205                     const wxString
& rEntry
, 
 207                     const wxString
& rFile 
) 
 211     zStr 
= new wxChar
[1000]; 
 212     bool bSucc 
= wxGetResource( rSection
, rEntry
, (wxChar 
**)&zStr
, rFile 
); 
 216         *pValue 
= wxStrtol(zStr
, NULL
, 10); 
 223 bool wxGetResource( const wxString
& rSection
, 
 224                     const wxString
& rEntry
, 
 226                     const wxString
& rFile 
) 
 230     zStr 
= new wxChar
[1000]; 
 231     bool bSucc 
= wxGetResource( rSection
, rEntry
, (wxChar 
**)&zStr
, rFile 
); 
 235         *pValue 
= (int)wxStrtol(zStr
, NULL
, 10); 
 241 #endif // wxUSE_RESOURCES 
 243 // --------------------------------------------------------------------------- 
 244 // helper functions for showing a "busy" cursor 
 245 // --------------------------------------------------------------------------- 
 247 HCURSOR gs_wxBusyCursor 
= 0;     // new, busy cursor 
 248 HCURSOR gs_wxBusyCursorOld 
= 0;  // old cursor 
 249 static int gs_wxBusyCursorCount 
= 0; 
 251 // Set the cursor to the busy cursor for all windows 
 252 void wxBeginBusyCursor(const wxCursor
* pCursor
) 
 254     if ( gs_wxBusyCursorCount
++ == 0 ) 
 256         gs_wxBusyCursor 
= (HCURSOR
)pCursor
->GetHCURSOR(); 
 257         ::WinSetPointer(HWND_DESKTOP
, (HPOINTER
)gs_wxBusyCursor
); 
 259     //else: nothing to do, already set 
 262 // Restore cursor to normal 
 263 void wxEndBusyCursor() 
 265     wxCHECK_RET( gs_wxBusyCursorCount 
> 0 
 266                 ,_T("no matching wxBeginBusyCursor() for wxEndBusyCursor()") 
 269     if (--gs_wxBusyCursorCount 
== 0) 
 271         ::WinSetPointer(HWND_DESKTOP
, (HPOINTER
)gs_wxBusyCursorOld
); 
 272         gs_wxBusyCursorOld 
= 0; 
 276 // true if we're between the above two calls 
 279     return (gs_wxBusyCursorCount 
> 0); 
 282 // Check whether this window wants to process messages, e.g. Stop button 
 283 // in long calculations. 
 284 bool wxCheckForInterrupt( wxWindow
* pWnd 
) 
 290         HWND hwndFilter 
= NULLHANDLE
; 
 292         while(::WinPeekMsg(hab
, &vMsg
, hwndFilter
, 0, 0, PM_REMOVE
)) 
 294             ::WinDispatchMsg(hab
, &vMsg
); 
 296         return true;//*** temporary? 
 300         wxFAIL_MSG(_T("pWnd==NULL !!!")); 
 301         return false;//*** temporary? 
 305 // ---------------------------------------------------------------------------- 
 307 // ---------------------------------------------------------------------------- 
 309 // See also the wxGetMousePosition in window.cpp 
 310 // Deprecated: use wxPoint wxGetMousePosition() instead 
 311 void wxGetMousePosition( 
 318     ::WinQueryPointerPos(HWND_DESKTOP
, &vPt
); 
 323 // Return true if we have a colour display 
 324 bool wxColourDisplay() 
 331     hpsScreen 
= ::WinGetScreenPS(HWND_DESKTOP
); 
 332     hdcScreen 
= ::GpiQueryDevice(hpsScreen
); 
 333     ::DevQueryCaps(hdcScreen
, CAPS_COLORS
, 1L, &lColors
); 
 334     return(lColors 
> 1L); 
 336     // I don't see how the PM display could not be color. Besides, this 
 337     // was leaking DCs and PSs!!!  MN 
 342 // Returns depth of screen 
 349     static LONG                     nDepth 
= 0; 
 351     // The screen colordepth ain't gonna change. No reason to query 
 354         hpsScreen 
= ::WinGetScreenPS(HWND_DESKTOP
); 
 355         hdcScreen 
= ::GpiQueryDevice(hpsScreen
); 
 356         ::DevQueryCaps(hdcScreen
, CAPS_COLOR_PLANES
, 1L, &lPlanes
); 
 357         ::DevQueryCaps(hdcScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitsPerPixel
); 
 359         nDepth 
= (int)(lPlanes 
* lBitsPerPixel
); 
 360         ::DevCloseDC(hdcScreen
); 
 361         ::WinReleasePS(hpsScreen
); 
 366 // Get size of display 
 374     static LONG                     lWidth  
= 0; 
 375     static LONG                     lHeight 
= 0; 
 377     // The screen size ain't gonna change either so just cache the values 
 379         hpsScreen 
= ::WinGetScreenPS(HWND_DESKTOP
); 
 380         hdcScreen 
= ::GpiQueryDevice(hpsScreen
); 
 381         ::DevQueryCaps(hdcScreen
, CAPS_WIDTH
, 1L, &lWidth
); 
 382         ::DevQueryCaps(hdcScreen
, CAPS_HEIGHT
, 1L, &lHeight
); 
 383         ::DevCloseDC(hdcScreen
); 
 384         ::WinReleasePS(hpsScreen
); 
 387         *pWidth 
= (int)lWidth
; 
 389         *pHeight 
= (int)lHeight
; 
 392 void wxDisplaySizeMM( 
 400     hpsScreen 
= ::WinGetScreenPS(HWND_DESKTOP
); 
 401     hdcScreen 
= ::GpiQueryDevice(hpsScreen
); 
 404         ::DevQueryCaps( hdcScreen
 
 405                        ,CAPS_HORIZONTAL_RESOLUTION
 
 410         ::DevQueryCaps( hdcScreen
 
 411                        ,CAPS_VERTICAL_RESOLUTION
 
 415     ::DevCloseDC(hdcScreen
); 
 416     ::WinReleasePS(hpsScreen
); 
 419 void wxClientDisplayRect(int *x
, int *y
, int *width
, int *height
) 
 421     // This is supposed to return desktop dimensions minus any window 
 422     // manager panels, menus, taskbars, etc.  If there is a way to do that 
 423     // for this platform please fix this function, otherwise it defaults 
 424     // to the entire desktop. 
 427     wxDisplaySize(width
, height
); 
 430 void wxGUIAppTraits::InitializeGui(unsigned long &ulHab
) 
 432     ulHab 
= ::WinInitialize(0); 
 435 void wxGUIAppTraits::TerminateGui(unsigned long ulHab
) 
 437     ::WinTerminate(ulHab
); 
 440 wxPortId 
wxGUIAppTraits::GetToolkitVersion(int *verMaj
, int *verMin
) const 
 442     // How to get version of PM ? I guess, just reusing the OS version is OK. 
 443     (void) wxGetOsVersion(verMaj
, verMin
); 
 448 // --------------------------------------------------------------------------- 
 449 // window information functions 
 450 // --------------------------------------------------------------------------- 
 452 wxString WXDLLEXPORT 
wxGetWindowText( WXHWND hWnd 
) 
 458         long lLen 
= ::WinQueryWindowTextLength((HWND
)hWnd
) + 1; 
 459         ::WinQueryWindowText((HWND
)hWnd
, lLen
, (PSZ
)(wxChar
*)wxStringBuffer(vStr
, lLen
)); 
 465 wxString WXDLLEXPORT 
wxGetWindowClass( WXHWND hWnd 
) 
 470         int nLen 
= 256; // some starting value 
 474         int                     nCount 
= ::WinQueryClassName((HWND
)hWnd
, nLen
, (PSZ
)(wxChar
*)wxStringBuffer(vStr
, nLen
)); 
 478             // the class name might have been truncated, retry with larger 
 491 WXWORD WXDLLEXPORT 
wxGetWindowId( 
 495     return ::WinQueryWindowUShort((HWND
)hWnd
, QWS_ID
); 
 506     vPoint
[0].x 
= rRect
.xLeft
; 
 507     vPoint
[0].y 
= rRect
.yBottom
; 
 508     ::GpiMove(hPS
, &vPoint
[0]); 
 509     if (dwStyle 
& wxSIMPLE_BORDER 
|| 
 510         dwStyle 
& wxSTATIC_BORDER
) 
 512         vPoint
[1].x 
= rRect
.xRight 
- 1; 
 513         vPoint
[1].y 
= rRect
.yTop 
- 1; 
 521     if (dwStyle 
& wxSUNKEN_BORDER
) 
 523         LINEBUNDLE                      vLineBundle
; 
 525         vLineBundle
.lColor     
= 0x00FFFFFF; // WHITE 
 526         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 527         vLineBundle
.fxWidth    
= 2; 
 528         vLineBundle
.lGeomWidth 
= 2; 
 529         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 530         vLineBundle
.usEnd      
= 0; 
 531         vLineBundle
.usJoin     
= 0; 
 534                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 538         vPoint
[1].x 
= rRect
.xRight 
- 1; 
 539         vPoint
[1].y 
= rRect
.yTop 
- 1; 
 546        vPoint
[0].x 
= rRect
.xLeft 
+ 1; 
 547        vPoint
[0].y 
= rRect
.yBottom 
+ 1; 
 548        ::GpiMove(hPS
, &vPoint
[0]); 
 549         vPoint
[1].x 
= rRect
.xRight 
- 2; 
 550         vPoint
[1].y 
= rRect
.yTop 
- 2; 
 558         vLineBundle
.lColor     
= 0x00000000; // BLACK 
 559         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 560         vLineBundle
.fxWidth    
= 2; 
 561         vLineBundle
.lGeomWidth 
= 2; 
 562         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 563         vLineBundle
.usEnd      
= 0; 
 564         vLineBundle
.usJoin     
= 0; 
 567                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 571         vPoint
[0].x 
= rRect
.xLeft 
+ 2; 
 572         vPoint
[0].y 
= rRect
.yBottom 
+ 2; 
 573         ::GpiMove(hPS
, &vPoint
[0]); 
 574         vPoint
[1].x 
= rRect
.xLeft 
+ 2; 
 575         vPoint
[1].y 
= rRect
.yTop 
- 3; 
 576         ::GpiLine(hPS
, &vPoint
[1]); 
 577         vPoint
[1].x 
= rRect
.xRight 
- 3; 
 578         vPoint
[1].y 
= rRect
.yTop 
- 3; 
 579         ::GpiLine(hPS
, &vPoint
[1]); 
 581         vPoint
[0].x 
= rRect
.xLeft 
+ 3; 
 582         vPoint
[0].y 
= rRect
.yBottom 
+ 3; 
 583         ::GpiMove(hPS
, &vPoint
[0]); 
 584         vPoint
[1].x 
= rRect
.xLeft 
+ 3; 
 585         vPoint
[1].y 
= rRect
.yTop 
- 4; 
 586         ::GpiLine(hPS
, &vPoint
[1]); 
 587         vPoint
[1].x 
= rRect
.xRight 
- 4; 
 588         vPoint
[1].y 
= rRect
.yTop 
- 4; 
 589         ::GpiLine(hPS
, &vPoint
[1]); 
 591     if (dwStyle 
& wxDOUBLE_BORDER
) 
 593         LINEBUNDLE                      vLineBundle
; 
 595         vLineBundle
.lColor     
= 0x00FFFFFF; // WHITE 
 596         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 597         vLineBundle
.fxWidth    
= 2; 
 598         vLineBundle
.lGeomWidth 
= 2; 
 599         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 600         vLineBundle
.usEnd      
= 0; 
 601         vLineBundle
.usJoin     
= 0; 
 604                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 608         vPoint
[1].x 
= rRect
.xRight 
- 1; 
 609         vPoint
[1].y 
= rRect
.yTop 
- 1; 
 616         vLineBundle
.lColor     
= 0x00000000; // WHITE 
 617         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 618         vLineBundle
.fxWidth    
= 2; 
 619         vLineBundle
.lGeomWidth 
= 2; 
 620         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 621         vLineBundle
.usEnd      
= 0; 
 622         vLineBundle
.usJoin     
= 0; 
 625                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 629         vPoint
[0].x 
= rRect
.xLeft 
+ 2; 
 630         vPoint
[0].y 
= rRect
.yBottom 
+ 2; 
 631         ::GpiMove(hPS
, &vPoint
[0]); 
 632         vPoint
[1].x 
= rRect
.xRight 
- 2; 
 633         vPoint
[1].y 
= rRect
.yTop 
- 2; 
 640         vLineBundle
.lColor     
= 0x00FFFFFF; // BLACK 
 641         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 642         vLineBundle
.fxWidth    
= 2; 
 643         vLineBundle
.lGeomWidth 
= 2; 
 644         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 645         vLineBundle
.usEnd      
= 0; 
 646         vLineBundle
.usJoin     
= 0; 
 649                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 653         vPoint
[0].x 
= rRect
.xLeft 
+ 3; 
 654         vPoint
[0].y 
= rRect
.yBottom 
+ 3; 
 655         ::GpiMove(hPS
, &vPoint
[0]); 
 656         vPoint
[1].x 
= rRect
.xRight 
- 3; 
 657         vPoint
[1].y 
= rRect
.yTop 
- 3; 
 665     if (dwStyle 
& wxRAISED_BORDER
) 
 667         LINEBUNDLE                      vLineBundle
; 
 669         vLineBundle
.lColor     
= 0x00000000; // BLACK 
 670         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 671         vLineBundle
.fxWidth    
= 2; 
 672         vLineBundle
.lGeomWidth 
= 2; 
 673         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 674         vLineBundle
.usEnd      
= 0; 
 675         vLineBundle
.usJoin     
= 0; 
 678                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 682         vPoint
[1].x 
= rRect
.xRight 
- 1; 
 683         vPoint
[1].y 
= rRect
.yTop 
- 1; 
 690        vPoint
[0].x 
= rRect
.xLeft 
+ 1; 
 691        vPoint
[0].y 
= rRect
.yBottom 
+ 1; 
 692        ::GpiMove(hPS
, &vPoint
[0]); 
 693         vPoint
[1].x 
= rRect
.xRight 
- 2; 
 694         vPoint
[1].y 
= rRect
.yTop 
- 2; 
 702         vLineBundle
.lColor     
= 0x00FFFFFF; // WHITE 
 703         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 704         vLineBundle
.fxWidth    
= 2; 
 705         vLineBundle
.lGeomWidth 
= 2; 
 706         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 707         vLineBundle
.usEnd      
= 0; 
 708         vLineBundle
.usJoin     
= 0; 
 711                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 715         vPoint
[0].x 
= rRect
.xLeft 
+ 2; 
 716         vPoint
[0].y 
= rRect
.yBottom 
+ 2; 
 717         ::GpiMove(hPS
, &vPoint
[0]); 
 718         vPoint
[1].x 
= rRect
.xLeft 
+ 2; 
 719         vPoint
[1].y 
= rRect
.yTop 
- 3; 
 720         ::GpiLine(hPS
, &vPoint
[1]); 
 721         vPoint
[1].x 
= rRect
.xRight 
- 3; 
 722         vPoint
[1].y 
= rRect
.yTop 
- 3; 
 723         ::GpiLine(hPS
, &vPoint
[1]); 
 725         vPoint
[0].x 
= rRect
.xLeft 
+ 3; 
 726         vPoint
[0].y 
= rRect
.yBottom 
+ 3; 
 727         ::GpiMove(hPS
, &vPoint
[0]); 
 728         vPoint
[1].x 
= rRect
.xLeft 
+ 3; 
 729         vPoint
[1].y 
= rRect
.yTop 
- 4; 
 730         ::GpiLine(hPS
, &vPoint
[1]); 
 731         vPoint
[1].x 
= rRect
.xRight 
- 4; 
 732         vPoint
[1].y 
= rRect
.yTop 
- 4; 
 733         ::GpiLine(hPS
, &vPoint
[1]); 
 735 } // end of wxDrawBorder 
 739 , const wxFont
&                     rFont
 
 747     if (hWnd 
== NULLHANDLE
) 
 751     // The fonts available for Presentation Params are just a few 
 752     // outline fonts, the rest are available to the GPI, so we must 
 753     // map the families to one of these three 
 755     switch(rFont
.GetFamily()) 
 758             strcpy(zFacename
, "Script"); 
 762             strcpy(zFacename
, "WarpSans"); 
 766             strcpy(zFacename
,"Times New Roman"); 
 770             strcpy(zFacename
, "Courier New"); 
 774             strcpy(zFacename
, "Courier New"); 
 780             strcpy(zFacename
, "Helvetica"); 
 784     switch(rFont
.GetWeight()) 
 793         case wxFONTWEIGHT_MAX
: 
 794             strcpy(zWeight
, "Bold"); 
 798     switch(rFont
.GetStyle()) 
 802             strcpy(zStyle
, "Italic"); 
 809     sprintf(zFont
, "%d.%s", rFont
.GetPointSize(), zFacename
); 
 810     if (zWeight
[0] != '\0') 
 813         strcat(zFont
, zWeight
); 
 815     if (zStyle
[0] != '\0') 
 818         strcat(zFont
, zStyle
); 
 820     ::WinSetPresParam(hWnd
, PP_FONTNAMESIZE
, strlen(zFont
) + 1, (PVOID
)zFont
); 
 821 } // end of wxOS2SetFont 
 823 // --------------------------------------------------------------------------- 
 824 // Helper for taking a regular bitmap and giving it a disabled look 
 825 // --------------------------------------------------------------------------- 
 826 wxBitmap 
wxDisableBitmap( 
 831     wxMask
*                         pMask 
= rBmp
.GetMask(); 
 834         return(wxNullBitmap
); 
 836     DEVOPENSTRUC                    vDop  
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
 837     SIZEL                           vSize 
= {0, 0}; 
 838     HDC                             hDC   
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
 839     HPS                             hPS   
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
 840     BITMAPINFOHEADER2               vHeader
; 
 844     HBITMAP                         hBitmap 
=  (HBITMAP
)rBmp
.GetHBITMAP(); 
 845     HBITMAP                         hOldBitmap 
= NULLHANDLE
; 
 846     HBITMAP                         hOldMask   
= NULLHANDLE
; 
 847     HBITMAP                         hMask 
= (HBITMAP
)rBmp
.GetMask()->GetMaskBitmap(); 
 848     unsigned char*                  pucBits
;     // buffer that will contain the bitmap data 
 849     unsigned char*                  pucData
;     // pointer to use to traverse bitmap data 
 850     unsigned char*                  pucBitsMask
; // buffer that will contain the mask data 
 851     unsigned char*                  pucDataMask
; // pointer to use to traverse mask data 
 854     bool                            bpp16 
= (wxDisplayDepth() == 16); 
 856     memset(&vHeader
, '\0', 16); 
 859     memset(&vInfo
, '\0', 16); 
 861     vInfo
.cx              
= (ULONG
)rBmp
.GetWidth(); 
 862     vInfo
.cy              
= (ULONG
)rBmp
.GetHeight(); 
 864     vInfo
.cBitCount       
= 24; // Set to desired count going in 
 867     // Create the buffers for data....all wxBitmaps are 24 bit internally 
 869     int                             nBytesPerLine 
= rBmp
.GetWidth() * 3; 
 870     int                             nSizeDWORD    
= sizeof(DWORD
); 
 871     int                             nLineBoundary 
= nBytesPerLine 
% nSizeDWORD
; 
 877     // Bitmap must be in a double-word aligned address so we may 
 878     // have some padding to worry about 
 880     if (nLineBoundary 
> 0) 
 882         nPadding     
= nSizeDWORD 
- nLineBoundary
; 
 883         nBytesPerLine 
+= nPadding
; 
 885     pucBits 
= (unsigned char *)malloc(nBytesPerLine 
* rBmp
.GetHeight()); 
 886     memset(pucBits
, '\0', (nBytesPerLine 
* rBmp
.GetHeight())); 
 887     pucBitsMask 
= (unsigned char *)malloc(nBytesPerLine 
* rBmp
.GetHeight()); 
 888     memset(pucBitsMask
, '\0', (nBytesPerLine 
* rBmp
.GetHeight())); 
 891     // Extract the bitmap and mask data 
 893     if ((hOldBitmap 
= ::GpiSetBitmap(hPS
, hBitmap
)) == HBM_ERROR
) 
 895         vError 
= ::WinGetLastError(vHabmain
); 
 896         sError 
= wxPMErrorToStr(vError
); 
 898     ::GpiQueryBitmapInfoHeader(hBitmap
, &vHeader
); 
 899     vInfo
.cBitCount 
= 24; 
 900     if ((lScans 
= ::GpiQueryBitmapBits( hPS
 
 902                                        ,(LONG
)rBmp
.GetHeight() 
 907         vError 
= ::WinGetLastError(vHabmain
); 
 908         sError 
= wxPMErrorToStr(vError
); 
 910     if ((hOldMask 
= ::GpiSetBitmap(hPS
, hMask
)) == HBM_ERROR
) 
 912         vError 
= ::WinGetLastError(vHabmain
); 
 913         sError 
= wxPMErrorToStr(vError
); 
 915     ::GpiQueryBitmapInfoHeader(hMask
, &vHeader
); 
 916     vInfo
.cBitCount 
= 24; 
 917     if ((lScans 
= ::GpiQueryBitmapBits( hPS
 
 919                                        ,(LONG
)rBmp
.GetHeight() 
 924         vError 
= ::WinGetLastError(vHabmain
); 
 925         sError 
= wxPMErrorToStr(vError
); 
 927     if (( hMask 
= ::GpiSetBitmap(hPS
, hOldMask
)) == HBM_ERROR
) 
 929         vError 
= ::WinGetLastError(vHabmain
); 
 930         sError 
= wxPMErrorToStr(vError
); 
 933     pucDataMask 
= pucBitsMask
; 
 936     // Get the mask value 
 938     for (i 
= 0; i 
< rBmp
.GetHeight(); i
++) 
 940         for (j 
= 0; j 
< rBmp
.GetWidth(); j
++) 
 943             if (bpp16 
&& *pucDataMask 
== 0xF8) // 16 bit display gobblygook 
 948             else if (*pucDataMask 
== 0xFF) // set to grey 
 955                 *pucData 
= ((unsigned char)(lColor 
>> 16)); 
 960             if (bpp16 
&& *(pucDataMask 
+ 1) == 0xFC) // 16 bit display gobblygook 
 965             else if (*(pucDataMask 
+ 1) == 0xFF) // set to grey 
 972                 *pucData 
= ((unsigned char)(lColor 
>> 8)); 
 977             if (bpp16 
&& *(pucDataMask 
+ 2) == 0xF8) // 16 bit display gobblygook 
 982             else if (*(pucDataMask 
+ 2) == 0xFF) // set to grey 
 989                 *pucData 
= ((unsigned char)lColor
); 
 994         for (j 
= 0; j 
< nPadding
; j
++) 
1002     // Create a new bitmap and set the modified bits 
1004     wxBitmap                        
vNewBmp( rBmp
.GetWidth() 
1008     HBITMAP                         hNewBmp 
= (HBITMAP
)vNewBmp
.GetHBITMAP(); 
1010     if ((hOldBitmap 
= ::GpiSetBitmap(hPS
, hNewBmp
)) == HBM_ERROR
) 
1012         vError 
= ::WinGetLastError(vHabmain
); 
1013         sError 
= wxPMErrorToStr(vError
); 
1015     if ((lScansSet 
= ::GpiSetBitmapBits( hPS
 
1017                                         ,(LONG
)rBmp
.GetHeight() 
1023         vError 
= ::WinGetLastError(vHabmain
); 
1024         sError 
= wxPMErrorToStr(vError
); 
1028     pNewMask 
= new wxMask(pMask
->GetMaskBitmap()); 
1029     vNewBmp
.SetMask(pNewMask
); 
1031     ::GpiSetBitmap(hPS
, NULLHANDLE
); 
1032     ::GpiDestroyPS(hPS
); 
1036     return(wxNullBitmap
); 
1037 } // end of wxDisableBitmap 
1039 COLORREF 
wxColourToRGB( 
1040   const wxColour
&                   rColor
 
1043     return(OS2RGB(rColor
.Red(), rColor
.Green(), rColor
.Blue())); 
1044 } // end of wxColourToRGB