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" 
  35 #include "wx/apptrait.h" 
  36 #include "wx/os2/private/timer.h" 
  37 #include "wx/evtloop.h" 
  39 #include "wx/os2/private.h"     // includes <windows.h> 
  41 // ============================================================================ 
  43 // ============================================================================ 
  45 // ---------------------------------------------------------------------------- 
  46 // functions to work with .INI files 
  47 // ---------------------------------------------------------------------------- 
  49 // Sleep for nSecs seconds. Attempt a Windows implementation using timers. 
  50 static bool inTimer 
= false; 
  52 class wxSleepTimer
: public wxTimer
 
  62 // --------------------------------------------------------------------------- 
  63 // helper functions for showing a "busy" cursor 
  64 // --------------------------------------------------------------------------- 
  66 HCURSOR gs_wxBusyCursor 
= 0;     // new, busy cursor 
  67 HCURSOR gs_wxBusyCursorOld 
= 0;  // old cursor 
  68 static int gs_wxBusyCursorCount 
= 0; 
  70 // Set the cursor to the busy cursor for all windows 
  71 void wxBeginBusyCursor(const wxCursor
* pCursor
) 
  73     if ( gs_wxBusyCursorCount
++ == 0 ) 
  75         gs_wxBusyCursor 
= (HCURSOR
)pCursor
->GetHCURSOR(); 
  76         ::WinSetPointer(HWND_DESKTOP
, (HPOINTER
)gs_wxBusyCursor
); 
  78     //else: nothing to do, already set 
  81 // Restore cursor to normal 
  82 void wxEndBusyCursor() 
  84     wxCHECK_RET( gs_wxBusyCursorCount 
> 0 
  85                 ,_T("no matching wxBeginBusyCursor() for wxEndBusyCursor()") 
  88     if (--gs_wxBusyCursorCount 
== 0) 
  90         ::WinSetPointer(HWND_DESKTOP
, (HPOINTER
)gs_wxBusyCursorOld
); 
  91         gs_wxBusyCursorOld 
= 0; 
  95 // true if we're between the above two calls 
  98     return (gs_wxBusyCursorCount 
> 0); 
 101 // Check whether this window wants to process messages, e.g. Stop button 
 102 // in long calculations. 
 103 bool wxCheckForInterrupt( wxWindow
* pWnd 
) 
 109         HWND hwndFilter 
= NULLHANDLE
; 
 111         while(::WinPeekMsg(hab
, &vMsg
, hwndFilter
, 0, 0, PM_REMOVE
)) 
 113             ::WinDispatchMsg(hab
, &vMsg
); 
 115         return true;//*** temporary? 
 119         wxFAIL_MSG(_T("pWnd==NULL !!!")); 
 120         return false;//*** temporary? 
 124 // ---------------------------------------------------------------------------- 
 126 // ---------------------------------------------------------------------------- 
 128 // See also the wxGetMousePosition in window.cpp 
 129 // Deprecated: use wxPoint wxGetMousePosition() instead 
 130 void wxGetMousePosition( 
 137     ::WinQueryPointerPos(HWND_DESKTOP
, &vPt
); 
 142 // Return true if we have a colour display 
 143 bool wxColourDisplay() 
 150     hpsScreen 
= ::WinGetScreenPS(HWND_DESKTOP
); 
 151     hdcScreen 
= ::GpiQueryDevice(hpsScreen
); 
 152     ::DevQueryCaps(hdcScreen
, CAPS_COLORS
, 1L, &lColors
); 
 153     return(lColors 
> 1L); 
 155     // I don't see how the PM display could not be color. Besides, this 
 156     // was leaking DCs and PSs!!!  MN 
 161 // Returns depth of screen 
 168     static LONG                     nDepth 
= 0; 
 170     // The screen colordepth ain't gonna change. No reason to query 
 173         hpsScreen 
= ::WinGetScreenPS(HWND_DESKTOP
); 
 174         hdcScreen 
= ::GpiQueryDevice(hpsScreen
); 
 175         ::DevQueryCaps(hdcScreen
, CAPS_COLOR_PLANES
, 1L, &lPlanes
); 
 176         ::DevQueryCaps(hdcScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitsPerPixel
); 
 178         nDepth 
= (int)(lPlanes 
* lBitsPerPixel
); 
 179         ::DevCloseDC(hdcScreen
); 
 180         ::WinReleasePS(hpsScreen
); 
 185 // Get size of display 
 193     static LONG                     lWidth  
= 0; 
 194     static LONG                     lHeight 
= 0; 
 196     // The screen size ain't gonna change either so just cache the values 
 198         hpsScreen 
= ::WinGetScreenPS(HWND_DESKTOP
); 
 199         hdcScreen 
= ::GpiQueryDevice(hpsScreen
); 
 200         ::DevQueryCaps(hdcScreen
, CAPS_WIDTH
, 1L, &lWidth
); 
 201         ::DevQueryCaps(hdcScreen
, CAPS_HEIGHT
, 1L, &lHeight
); 
 202         ::DevCloseDC(hdcScreen
); 
 203         ::WinReleasePS(hpsScreen
); 
 206         *pWidth 
= (int)lWidth
; 
 208         *pHeight 
= (int)lHeight
; 
 211 void wxDisplaySizeMM( 
 219     hpsScreen 
= ::WinGetScreenPS(HWND_DESKTOP
); 
 220     hdcScreen 
= ::GpiQueryDevice(hpsScreen
); 
 223         ::DevQueryCaps( hdcScreen
 
 224                        ,CAPS_HORIZONTAL_RESOLUTION
 
 229         ::DevQueryCaps( hdcScreen
 
 230                        ,CAPS_VERTICAL_RESOLUTION
 
 234     ::DevCloseDC(hdcScreen
); 
 235     ::WinReleasePS(hpsScreen
); 
 238 void wxClientDisplayRect(int *x
, int *y
, int *width
, int *height
) 
 240     // This is supposed to return desktop dimensions minus any window 
 241     // manager panels, menus, taskbars, etc.  If there is a way to do that 
 242     // for this platform please fix this function, otherwise it defaults 
 243     // to the entire desktop. 
 246     wxDisplaySize(width
, height
); 
 249 void wxGUIAppTraits::InitializeGui(unsigned long &ulHab
) 
 251     ulHab 
= ::WinInitialize(0); 
 254 void wxGUIAppTraits::TerminateGui(unsigned long ulHab
) 
 256     ::WinTerminate(ulHab
); 
 259 wxPortId 
wxGUIAppTraits::GetToolkitVersion(int *verMaj
, int *verMin
) const 
 261     // How to get version of PM ? I guess, just reusing the OS version is OK. 
 262     (void) wxGetOsVersion(verMaj
, verMin
); 
 266 wxTimerImpl
* wxGUIAppTraits::CreateTimerImpl(wxTimer 
*timer
) 
 268     return new wxOS2TimerImpl(timer
); 
 271 wxEventLoopBase
* wxGUIAppTraits::CreateEventLoop() 
 273     return new wxEventLoop
; 
 276 // --------------------------------------------------------------------------- 
 277 // window information functions 
 278 // --------------------------------------------------------------------------- 
 280 wxString WXDLLEXPORT 
wxGetWindowText( WXHWND hWnd 
) 
 286         long lLen 
= ::WinQueryWindowTextLength((HWND
)hWnd
) + 1; 
 287         ::WinQueryWindowText((HWND
)hWnd
, lLen
, (PSZ
)(wxChar
*)wxStringBuffer(vStr
, lLen
)); 
 293 wxString WXDLLEXPORT 
wxGetWindowClass( WXHWND hWnd 
) 
 298         int nLen 
= 256; // some starting value 
 302         int                     nCount 
= ::WinQueryClassName((HWND
)hWnd
, nLen
, (PSZ
)(wxChar
*)wxStringBuffer(vStr
, nLen
)); 
 306             // the class name might have been truncated, retry with larger 
 319 WXWORD WXDLLEXPORT 
wxGetWindowId( 
 323     return ::WinQueryWindowUShort((HWND
)hWnd
, QWS_ID
); 
 334     vPoint
[0].x 
= rRect
.xLeft
; 
 335     vPoint
[0].y 
= rRect
.yBottom
; 
 336     ::GpiMove(hPS
, &vPoint
[0]); 
 337     if (dwStyle 
& wxSIMPLE_BORDER 
|| 
 338         dwStyle 
& wxSTATIC_BORDER
) 
 340         vPoint
[1].x 
= rRect
.xRight 
- 1; 
 341         vPoint
[1].y 
= rRect
.yTop 
- 1; 
 349     if (dwStyle 
& wxSUNKEN_BORDER
) 
 351         LINEBUNDLE                      vLineBundle
; 
 353         vLineBundle
.lColor     
= 0x00FFFFFF; // WHITE 
 354         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 355         vLineBundle
.fxWidth    
= 2; 
 356         vLineBundle
.lGeomWidth 
= 2; 
 357         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 358         vLineBundle
.usEnd      
= 0; 
 359         vLineBundle
.usJoin     
= 0; 
 362                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 366         vPoint
[1].x 
= rRect
.xRight 
- 1; 
 367         vPoint
[1].y 
= rRect
.yTop 
- 1; 
 374        vPoint
[0].x 
= rRect
.xLeft 
+ 1; 
 375        vPoint
[0].y 
= rRect
.yBottom 
+ 1; 
 376        ::GpiMove(hPS
, &vPoint
[0]); 
 377         vPoint
[1].x 
= rRect
.xRight 
- 2; 
 378         vPoint
[1].y 
= rRect
.yTop 
- 2; 
 386         vLineBundle
.lColor     
= 0x00000000; // BLACK 
 387         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 388         vLineBundle
.fxWidth    
= 2; 
 389         vLineBundle
.lGeomWidth 
= 2; 
 390         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 391         vLineBundle
.usEnd      
= 0; 
 392         vLineBundle
.usJoin     
= 0; 
 395                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 399         vPoint
[0].x 
= rRect
.xLeft 
+ 2; 
 400         vPoint
[0].y 
= rRect
.yBottom 
+ 2; 
 401         ::GpiMove(hPS
, &vPoint
[0]); 
 402         vPoint
[1].x 
= rRect
.xLeft 
+ 2; 
 403         vPoint
[1].y 
= rRect
.yTop 
- 3; 
 404         ::GpiLine(hPS
, &vPoint
[1]); 
 405         vPoint
[1].x 
= rRect
.xRight 
- 3; 
 406         vPoint
[1].y 
= rRect
.yTop 
- 3; 
 407         ::GpiLine(hPS
, &vPoint
[1]); 
 409         vPoint
[0].x 
= rRect
.xLeft 
+ 3; 
 410         vPoint
[0].y 
= rRect
.yBottom 
+ 3; 
 411         ::GpiMove(hPS
, &vPoint
[0]); 
 412         vPoint
[1].x 
= rRect
.xLeft 
+ 3; 
 413         vPoint
[1].y 
= rRect
.yTop 
- 4; 
 414         ::GpiLine(hPS
, &vPoint
[1]); 
 415         vPoint
[1].x 
= rRect
.xRight 
- 4; 
 416         vPoint
[1].y 
= rRect
.yTop 
- 4; 
 417         ::GpiLine(hPS
, &vPoint
[1]); 
 419     if (dwStyle 
& wxDOUBLE_BORDER
) 
 421         LINEBUNDLE                      vLineBundle
; 
 423         vLineBundle
.lColor     
= 0x00FFFFFF; // WHITE 
 424         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 425         vLineBundle
.fxWidth    
= 2; 
 426         vLineBundle
.lGeomWidth 
= 2; 
 427         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 428         vLineBundle
.usEnd      
= 0; 
 429         vLineBundle
.usJoin     
= 0; 
 432                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 436         vPoint
[1].x 
= rRect
.xRight 
- 1; 
 437         vPoint
[1].y 
= rRect
.yTop 
- 1; 
 444         vLineBundle
.lColor     
= 0x00000000; // WHITE 
 445         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 446         vLineBundle
.fxWidth    
= 2; 
 447         vLineBundle
.lGeomWidth 
= 2; 
 448         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 449         vLineBundle
.usEnd      
= 0; 
 450         vLineBundle
.usJoin     
= 0; 
 453                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 457         vPoint
[0].x 
= rRect
.xLeft 
+ 2; 
 458         vPoint
[0].y 
= rRect
.yBottom 
+ 2; 
 459         ::GpiMove(hPS
, &vPoint
[0]); 
 460         vPoint
[1].x 
= rRect
.xRight 
- 2; 
 461         vPoint
[1].y 
= rRect
.yTop 
- 2; 
 468         vLineBundle
.lColor     
= 0x00FFFFFF; // BLACK 
 469         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 470         vLineBundle
.fxWidth    
= 2; 
 471         vLineBundle
.lGeomWidth 
= 2; 
 472         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 473         vLineBundle
.usEnd      
= 0; 
 474         vLineBundle
.usJoin     
= 0; 
 477                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 481         vPoint
[0].x 
= rRect
.xLeft 
+ 3; 
 482         vPoint
[0].y 
= rRect
.yBottom 
+ 3; 
 483         ::GpiMove(hPS
, &vPoint
[0]); 
 484         vPoint
[1].x 
= rRect
.xRight 
- 3; 
 485         vPoint
[1].y 
= rRect
.yTop 
- 3; 
 493     if (dwStyle 
& wxRAISED_BORDER
) 
 495         LINEBUNDLE                      vLineBundle
; 
 497         vLineBundle
.lColor     
= 0x00000000; // BLACK 
 498         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 499         vLineBundle
.fxWidth    
= 2; 
 500         vLineBundle
.lGeomWidth 
= 2; 
 501         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 502         vLineBundle
.usEnd      
= 0; 
 503         vLineBundle
.usJoin     
= 0; 
 506                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 510         vPoint
[1].x 
= rRect
.xRight 
- 1; 
 511         vPoint
[1].y 
= rRect
.yTop 
- 1; 
 518        vPoint
[0].x 
= rRect
.xLeft 
+ 1; 
 519        vPoint
[0].y 
= rRect
.yBottom 
+ 1; 
 520        ::GpiMove(hPS
, &vPoint
[0]); 
 521         vPoint
[1].x 
= rRect
.xRight 
- 2; 
 522         vPoint
[1].y 
= rRect
.yTop 
- 2; 
 530         vLineBundle
.lColor     
= 0x00FFFFFF; // WHITE 
 531         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 532         vLineBundle
.fxWidth    
= 2; 
 533         vLineBundle
.lGeomWidth 
= 2; 
 534         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 535         vLineBundle
.usEnd      
= 0; 
 536         vLineBundle
.usJoin     
= 0; 
 539                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 543         vPoint
[0].x 
= rRect
.xLeft 
+ 2; 
 544         vPoint
[0].y 
= rRect
.yBottom 
+ 2; 
 545         ::GpiMove(hPS
, &vPoint
[0]); 
 546         vPoint
[1].x 
= rRect
.xLeft 
+ 2; 
 547         vPoint
[1].y 
= rRect
.yTop 
- 3; 
 548         ::GpiLine(hPS
, &vPoint
[1]); 
 549         vPoint
[1].x 
= rRect
.xRight 
- 3; 
 550         vPoint
[1].y 
= rRect
.yTop 
- 3; 
 551         ::GpiLine(hPS
, &vPoint
[1]); 
 553         vPoint
[0].x 
= rRect
.xLeft 
+ 3; 
 554         vPoint
[0].y 
= rRect
.yBottom 
+ 3; 
 555         ::GpiMove(hPS
, &vPoint
[0]); 
 556         vPoint
[1].x 
= rRect
.xLeft 
+ 3; 
 557         vPoint
[1].y 
= rRect
.yTop 
- 4; 
 558         ::GpiLine(hPS
, &vPoint
[1]); 
 559         vPoint
[1].x 
= rRect
.xRight 
- 4; 
 560         vPoint
[1].y 
= rRect
.yTop 
- 4; 
 561         ::GpiLine(hPS
, &vPoint
[1]); 
 563 } // end of wxDrawBorder 
 567 , const wxFont
&                     rFont
 
 575     if (hWnd 
== NULLHANDLE
) 
 579     // The fonts available for Presentation Params are just a few 
 580     // outline fonts, the rest are available to the GPI, so we must 
 581     // map the families to one of these three 
 583     switch(rFont
.GetFamily()) 
 586             strcpy(zFacename
, "Script"); 
 590             strcpy(zFacename
, "WarpSans"); 
 594             strcpy(zFacename
,"Times New Roman"); 
 598             strcpy(zFacename
, "Courier New"); 
 602             strcpy(zFacename
, "Courier New"); 
 608             strcpy(zFacename
, "Helvetica"); 
 612     switch(rFont
.GetWeight()) 
 621         case wxFONTWEIGHT_MAX
: 
 622             strcpy(zWeight
, "Bold"); 
 626     switch(rFont
.GetStyle()) 
 630             strcpy(zStyle
, "Italic"); 
 637     sprintf(zFont
, "%d.%s", rFont
.GetPointSize(), zFacename
); 
 638     if (zWeight
[0] != '\0') 
 641         strcat(zFont
, zWeight
); 
 643     if (zStyle
[0] != '\0') 
 646         strcat(zFont
, zStyle
); 
 648     ::WinSetPresParam(hWnd
, PP_FONTNAMESIZE
, strlen(zFont
) + 1, (PVOID
)zFont
); 
 649 } // end of wxOS2SetFont 
 651 // --------------------------------------------------------------------------- 
 652 // Helper for taking a regular bitmap and giving it a disabled look 
 653 // --------------------------------------------------------------------------- 
 654 wxBitmap 
wxDisableBitmap( 
 659     wxMask
*                         pMask 
= rBmp
.GetMask(); 
 662         return(wxNullBitmap
); 
 664     DEVOPENSTRUC                    vDop  
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
 665     SIZEL                           vSize 
= {0, 0}; 
 666     HDC                             hDC   
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
 667     HPS                             hPS   
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
 668     BITMAPINFOHEADER2               vHeader
; 
 672     HBITMAP                         hBitmap 
=  (HBITMAP
)rBmp
.GetHBITMAP(); 
 673     HBITMAP                         hOldBitmap 
= NULLHANDLE
; 
 674     HBITMAP                         hOldMask   
= NULLHANDLE
; 
 675     HBITMAP                         hMask 
= (HBITMAP
)rBmp
.GetMask()->GetMaskBitmap(); 
 676     unsigned char*                  pucBits
;     // buffer that will contain the bitmap data 
 677     unsigned char*                  pucData
;     // pointer to use to traverse bitmap data 
 678     unsigned char*                  pucBitsMask
; // buffer that will contain the mask data 
 679     unsigned char*                  pucDataMask
; // pointer to use to traverse mask data 
 682     bool                            bpp16 
= (wxDisplayDepth() == 16); 
 684     memset(&vHeader
, '\0', 16); 
 687     memset(&vInfo
, '\0', 16); 
 689     vInfo
.cx              
= (ULONG
)rBmp
.GetWidth(); 
 690     vInfo
.cy              
= (ULONG
)rBmp
.GetHeight(); 
 692     vInfo
.cBitCount       
= 24; // Set to desired count going in 
 695     // Create the buffers for data....all wxBitmaps are 24 bit internally 
 697     int                             nBytesPerLine 
= rBmp
.GetWidth() * 3; 
 698     int                             nSizeDWORD    
= sizeof(DWORD
); 
 699     int                             nLineBoundary 
= nBytesPerLine 
% nSizeDWORD
; 
 705     // Bitmap must be in a double-word aligned address so we may 
 706     // have some padding to worry about 
 708     if (nLineBoundary 
> 0) 
 710         nPadding     
= nSizeDWORD 
- nLineBoundary
; 
 711         nBytesPerLine 
+= nPadding
; 
 713     pucBits 
= (unsigned char *)malloc(nBytesPerLine 
* rBmp
.GetHeight()); 
 714     memset(pucBits
, '\0', (nBytesPerLine 
* rBmp
.GetHeight())); 
 715     pucBitsMask 
= (unsigned char *)malloc(nBytesPerLine 
* rBmp
.GetHeight()); 
 716     memset(pucBitsMask
, '\0', (nBytesPerLine 
* rBmp
.GetHeight())); 
 719     // Extract the bitmap and mask data 
 721     if ((hOldBitmap 
= ::GpiSetBitmap(hPS
, hBitmap
)) == HBM_ERROR
) 
 723         vError 
= ::WinGetLastError(vHabmain
); 
 724         sError 
= wxPMErrorToStr(vError
); 
 726     ::GpiQueryBitmapInfoHeader(hBitmap
, &vHeader
); 
 727     vInfo
.cBitCount 
= 24; 
 728     if ((lScans 
= ::GpiQueryBitmapBits( hPS
 
 730                                        ,(LONG
)rBmp
.GetHeight() 
 735         vError 
= ::WinGetLastError(vHabmain
); 
 736         sError 
= wxPMErrorToStr(vError
); 
 738     if ((hOldMask 
= ::GpiSetBitmap(hPS
, hMask
)) == HBM_ERROR
) 
 740         vError 
= ::WinGetLastError(vHabmain
); 
 741         sError 
= wxPMErrorToStr(vError
); 
 743     ::GpiQueryBitmapInfoHeader(hMask
, &vHeader
); 
 744     vInfo
.cBitCount 
= 24; 
 745     if ((lScans 
= ::GpiQueryBitmapBits( hPS
 
 747                                        ,(LONG
)rBmp
.GetHeight() 
 752         vError 
= ::WinGetLastError(vHabmain
); 
 753         sError 
= wxPMErrorToStr(vError
); 
 755     if (( hMask 
= ::GpiSetBitmap(hPS
, hOldMask
)) == HBM_ERROR
) 
 757         vError 
= ::WinGetLastError(vHabmain
); 
 758         sError 
= wxPMErrorToStr(vError
); 
 761     pucDataMask 
= pucBitsMask
; 
 764     // Get the mask value 
 766     for (i 
= 0; i 
< rBmp
.GetHeight(); i
++) 
 768         for (j 
= 0; j 
< rBmp
.GetWidth(); j
++) 
 771             if (bpp16 
&& *pucDataMask 
== 0xF8) // 16 bit display gobblygook 
 776             else if (*pucDataMask 
== 0xFF) // set to grey 
 783                 *pucData 
= ((unsigned char)(lColor 
>> 16)); 
 788             if (bpp16 
&& *(pucDataMask 
+ 1) == 0xFC) // 16 bit display gobblygook 
 793             else if (*(pucDataMask 
+ 1) == 0xFF) // set to grey 
 800                 *pucData 
= ((unsigned char)(lColor 
>> 8)); 
 805             if (bpp16 
&& *(pucDataMask 
+ 2) == 0xF8) // 16 bit display gobblygook 
 810             else if (*(pucDataMask 
+ 2) == 0xFF) // set to grey 
 817                 *pucData 
= ((unsigned char)lColor
); 
 822         for (j 
= 0; j 
< nPadding
; j
++) 
 830     // Create a new bitmap and set the modified bits 
 832     wxBitmap                        
vNewBmp( rBmp
.GetWidth() 
 836     HBITMAP                         hNewBmp 
= (HBITMAP
)vNewBmp
.GetHBITMAP(); 
 838     if ((hOldBitmap 
= ::GpiSetBitmap(hPS
, hNewBmp
)) == HBM_ERROR
) 
 840         vError 
= ::WinGetLastError(vHabmain
); 
 841         sError 
= wxPMErrorToStr(vError
); 
 843     if ((lScansSet 
= ::GpiSetBitmapBits( hPS
 
 845                                         ,(LONG
)rBmp
.GetHeight() 
 851         vError 
= ::WinGetLastError(vHabmain
); 
 852         sError 
= wxPMErrorToStr(vError
); 
 856     pNewMask 
= new wxMask(pMask
->GetMaskBitmap()); 
 857     vNewBmp
.SetMask(pNewMask
); 
 859     ::GpiSetBitmap(hPS
, NULLHANDLE
); 
 864     return(wxNullBitmap
); 
 865 } // end of wxDisableBitmap 
 867 COLORREF 
wxColourToRGB( 
 868   const wxColour
&                   rColor
 
 871     return(OS2RGB(rColor
.Red(), rColor
.Green(), rColor
.Blue())); 
 872 } // end of wxColourToRGB