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( 
 518     long                            lLen 
= ::WinQueryWindowTextLength((HWND
)hWnd
) + 1; 
 520     ::WinQueryWindowText((HWND
)hWnd
, lLen
, vStr
.GetWriteBuf((int)lLen
)); 
 521     vStr
.UngetWriteBuf(); 
 526 wxString WXDLLEXPORT 
wxGetWindowClass( 
 531     int                             nLen 
= 256; // some starting value 
 535         int                         nCount 
= ::WinQueryClassName((HWND
)hWnd
, nLen
, vStr
.GetWriteBuf(nLen
)); 
 537         vStr
.UngetWriteBuf(); 
 540             // the class name might have been truncated, retry with larger 
 552 WXWORD WXDLLEXPORT 
wxGetWindowId( 
 556     return ::WinQueryWindowUShort((HWND
)hWnd
, QWS_ID
); 
 567     vPoint
[0].x 
= rRect
.xLeft
; 
 568     vPoint
[0].y 
= rRect
.yBottom
; 
 569     ::GpiMove(hPS
, &vPoint
[0]); 
 570     if (dwStyle 
& wxSIMPLE_BORDER 
|| 
 571         dwStyle 
& wxSTATIC_BORDER
) 
 573         vPoint
[1].x 
= rRect
.xRight 
- 1; 
 574         vPoint
[1].y 
= rRect
.yTop 
- 1; 
 582     if (dwStyle 
& wxSUNKEN_BORDER
) 
 584         LINEBUNDLE                      vLineBundle
; 
 586         vLineBundle
.lColor     
= 0x00FFFFFF; // WHITE 
 587         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 588         vLineBundle
.fxWidth    
= 2; 
 589         vLineBundle
.lGeomWidth 
= 2; 
 590         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 591         vLineBundle
.usEnd      
= 0; 
 592         vLineBundle
.usJoin     
= 0; 
 595                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 599         vPoint
[1].x 
= rRect
.xRight 
- 1; 
 600         vPoint
[1].y 
= rRect
.yTop 
- 1; 
 607        vPoint
[0].x 
= rRect
.xLeft 
+ 1; 
 608        vPoint
[0].y 
= rRect
.yBottom 
+ 1; 
 609        ::GpiMove(hPS
, &vPoint
[0]); 
 610         vPoint
[1].x 
= rRect
.xRight 
- 2; 
 611         vPoint
[1].y 
= rRect
.yTop 
- 2; 
 619         vLineBundle
.lColor     
= 0x00000000; // BLACK 
 620         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 621         vLineBundle
.fxWidth    
= 2; 
 622         vLineBundle
.lGeomWidth 
= 2; 
 623         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 624         vLineBundle
.usEnd      
= 0; 
 625         vLineBundle
.usJoin     
= 0; 
 628                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 632         vPoint
[0].x 
= rRect
.xLeft 
+ 2; 
 633         vPoint
[0].y 
= rRect
.yBottom 
+ 2; 
 634         ::GpiMove(hPS
, &vPoint
[0]); 
 635         vPoint
[1].x 
= rRect
.xLeft 
+ 2; 
 636         vPoint
[1].y 
= rRect
.yTop 
- 3; 
 637         ::GpiLine(hPS
, &vPoint
[1]); 
 638         vPoint
[1].x 
= rRect
.xRight 
- 3; 
 639         vPoint
[1].y 
= rRect
.yTop 
- 3; 
 640         ::GpiLine(hPS
, &vPoint
[1]); 
 642         vPoint
[0].x 
= rRect
.xLeft 
+ 3; 
 643         vPoint
[0].y 
= rRect
.yBottom 
+ 3; 
 644         ::GpiMove(hPS
, &vPoint
[0]); 
 645         vPoint
[1].x 
= rRect
.xLeft 
+ 3; 
 646         vPoint
[1].y 
= rRect
.yTop 
- 4; 
 647         ::GpiLine(hPS
, &vPoint
[1]); 
 648         vPoint
[1].x 
= rRect
.xRight 
- 4; 
 649         vPoint
[1].y 
= rRect
.yTop 
- 4; 
 650         ::GpiLine(hPS
, &vPoint
[1]); 
 652     if (dwStyle 
& wxDOUBLE_BORDER
) 
 654         LINEBUNDLE                      vLineBundle
; 
 656         vLineBundle
.lColor     
= 0x00FFFFFF; // WHITE 
 657         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 658         vLineBundle
.fxWidth    
= 2; 
 659         vLineBundle
.lGeomWidth 
= 2; 
 660         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 661         vLineBundle
.usEnd      
= 0; 
 662         vLineBundle
.usJoin     
= 0; 
 665                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 669         vPoint
[1].x 
= rRect
.xRight 
- 1; 
 670         vPoint
[1].y 
= rRect
.yTop 
- 1; 
 677         vLineBundle
.lColor     
= 0x00000000; // WHITE 
 678         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 679         vLineBundle
.fxWidth    
= 2; 
 680         vLineBundle
.lGeomWidth 
= 2; 
 681         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 682         vLineBundle
.usEnd      
= 0; 
 683         vLineBundle
.usJoin     
= 0; 
 686                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 690         vPoint
[0].x 
= rRect
.xLeft 
+ 2; 
 691         vPoint
[0].y 
= rRect
.yBottom 
+ 2; 
 692         ::GpiMove(hPS
, &vPoint
[0]); 
 693         vPoint
[1].x 
= rRect
.xRight 
- 2; 
 694         vPoint
[1].y 
= rRect
.yTop 
- 2; 
 701         vLineBundle
.lColor     
= 0x00FFFFFF; // BLACK 
 702         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 703         vLineBundle
.fxWidth    
= 2; 
 704         vLineBundle
.lGeomWidth 
= 2; 
 705         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 706         vLineBundle
.usEnd      
= 0; 
 707         vLineBundle
.usJoin     
= 0; 
 710                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 714         vPoint
[0].x 
= rRect
.xLeft 
+ 3; 
 715         vPoint
[0].y 
= rRect
.yBottom 
+ 3; 
 716         ::GpiMove(hPS
, &vPoint
[0]); 
 717         vPoint
[1].x 
= rRect
.xRight 
- 3; 
 718         vPoint
[1].y 
= rRect
.yTop 
- 3; 
 726     if (dwStyle 
& wxRAISED_BORDER
) 
 728         LINEBUNDLE                      vLineBundle
; 
 730         vLineBundle
.lColor     
= 0x00000000; // BLACK 
 731         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 732         vLineBundle
.fxWidth    
= 2; 
 733         vLineBundle
.lGeomWidth 
= 2; 
 734         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 735         vLineBundle
.usEnd      
= 0; 
 736         vLineBundle
.usJoin     
= 0; 
 739                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 743         vPoint
[1].x 
= rRect
.xRight 
- 1; 
 744         vPoint
[1].y 
= rRect
.yTop 
- 1; 
 751        vPoint
[0].x 
= rRect
.xLeft 
+ 1; 
 752        vPoint
[0].y 
= rRect
.yBottom 
+ 1; 
 753        ::GpiMove(hPS
, &vPoint
[0]); 
 754         vPoint
[1].x 
= rRect
.xRight 
- 2; 
 755         vPoint
[1].y 
= rRect
.yTop 
- 2; 
 763         vLineBundle
.lColor     
= 0x00FFFFFF; // WHITE 
 764         vLineBundle
.usMixMode  
= FM_OVERPAINT
; 
 765         vLineBundle
.fxWidth    
= 2; 
 766         vLineBundle
.lGeomWidth 
= 2; 
 767         vLineBundle
.usType     
= LINETYPE_SOLID
; 
 768         vLineBundle
.usEnd      
= 0; 
 769         vLineBundle
.usJoin     
= 0; 
 772                       ,LBB_COLOR 
| LBB_MIX_MODE 
| LBB_WIDTH 
| LBB_GEOM_WIDTH 
| LBB_TYPE
 
 776         vPoint
[0].x 
= rRect
.xLeft 
+ 2; 
 777         vPoint
[0].y 
= rRect
.yBottom 
+ 2; 
 778         ::GpiMove(hPS
, &vPoint
[0]); 
 779         vPoint
[1].x 
= rRect
.xLeft 
+ 2; 
 780         vPoint
[1].y 
= rRect
.yTop 
- 3; 
 781         ::GpiLine(hPS
, &vPoint
[1]); 
 782         vPoint
[1].x 
= rRect
.xRight 
- 3; 
 783         vPoint
[1].y 
= rRect
.yTop 
- 3; 
 784         ::GpiLine(hPS
, &vPoint
[1]); 
 786         vPoint
[0].x 
= rRect
.xLeft 
+ 3; 
 787         vPoint
[0].y 
= rRect
.yBottom 
+ 3; 
 788         ::GpiMove(hPS
, &vPoint
[0]); 
 789         vPoint
[1].x 
= rRect
.xLeft 
+ 3; 
 790         vPoint
[1].y 
= rRect
.yTop 
- 4; 
 791         ::GpiLine(hPS
, &vPoint
[1]); 
 792         vPoint
[1].x 
= rRect
.xRight 
- 4; 
 793         vPoint
[1].y 
= rRect
.yTop 
- 4; 
 794         ::GpiLine(hPS
, &vPoint
[1]); 
 796 } // end of wxDrawBorder 
 800 , const wxFont
&                     rFont
 
 808     if (hWnd 
== NULLHANDLE
) 
 812     // The fonts available for Presentation Params are just a few 
 813     // outline fonts, the rest are available to the GPI, so we must 
 814     // map the families to one of these three 
 816     switch(rFont
.GetFamily()) 
 819             strcpy(zFacename
, "Script"); 
 823             strcpy(zFacename
, "WarpSans"); 
 827             strcpy(zFacename
,"Times New Roman"); 
 831             strcpy(zFacename
, "Courier New"); 
 835             strcpy(zFacename
, "Courier New"); 
 841             strcpy(zFacename
, "Helvetica"); 
 845     switch(rFont
.GetWeight()) 
 854         case wxFONTWEIGHT_MAX
: 
 855             strcpy(zWeight
, "Bold"); 
 859     switch(rFont
.GetStyle()) 
 863             strcpy(zStyle
, "Italic"); 
 870     sprintf(zFont
, "%d.%s", rFont
.GetPointSize(), zFacename
); 
 871     if (zWeight
[0] != '\0') 
 874         strcat(zFont
, zWeight
); 
 876     if (zStyle
[0] != '\0') 
 879         strcat(zFont
, zStyle
); 
 881     ::WinSetPresParam(hWnd
, PP_FONTNAMESIZE
, strlen(zFont
) + 1, (PVOID
)zFont
); 
 882 } // end of wxOS2SetFont 
 884 // --------------------------------------------------------------------------- 
 885 // Helper for taking a regular bitmap and giving it a disabled look 
 886 // --------------------------------------------------------------------------- 
 887 wxBitmap 
wxDisableBitmap( 
 892     wxMask
*                         pMask 
= rBmp
.GetMask(); 
 895         return(wxNullBitmap
); 
 897     DEVOPENSTRUC                    vDop  
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
 898     SIZEL                           vSize 
= {0, 0}; 
 899     HDC                             hDC   
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
 900     HPS                             hPS   
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
 901     BITMAPINFOHEADER2               vHeader
; 
 905     HBITMAP                         hBitmap 
=  (HBITMAP
)rBmp
.GetHBITMAP(); 
 906     HBITMAP                         hOldBitmap 
= NULLHANDLE
; 
 907     HBITMAP                         hOldMask   
= NULLHANDLE
; 
 908     HBITMAP                         hMask 
= (HBITMAP
)rBmp
.GetMask()->GetMaskBitmap(); 
 909     unsigned char*                  pucBits
;     // buffer that will contain the bitmap data 
 910     unsigned char*                  pucData
;     // pointer to use to traverse bitmap data 
 911     unsigned char*                  pucBitsMask
; // buffer that will contain the mask data 
 912     unsigned char*                  pucDataMask
; // pointer to use to traverse mask data 
 915     bool                            bpp16 
= (wxDisplayDepth() == 16); 
 917     memset(&vHeader
, '\0', 16); 
 920     memset(&vInfo
, '\0', 16); 
 922     vInfo
.cx              
= (ULONG
)rBmp
.GetWidth(); 
 923     vInfo
.cy              
= (ULONG
)rBmp
.GetHeight(); 
 925     vInfo
.cBitCount       
= 24; // Set to desired count going in 
 928     // Create the buffers for data....all wxBitmaps are 24 bit internally 
 930     int                             nBytesPerLine 
= rBmp
.GetWidth() * 3; 
 931     int                             nSizeDWORD    
= sizeof(DWORD
); 
 932     int                             nLineBoundary 
= nBytesPerLine 
% nSizeDWORD
; 
 938     // Bitmap must be ina double-word alligned address so we may 
 939     // have some padding to worry about 
 941     if (nLineBoundary 
> 0) 
 943         nPadding     
= nSizeDWORD 
- nLineBoundary
; 
 944         nBytesPerLine 
+= nPadding
; 
 946     pucBits 
= (unsigned char *)malloc(nBytesPerLine 
* rBmp
.GetHeight()); 
 947     memset(pucBits
, '\0', (nBytesPerLine 
* rBmp
.GetHeight())); 
 948     pucBitsMask 
= (unsigned char *)malloc(nBytesPerLine 
* rBmp
.GetHeight()); 
 949     memset(pucBitsMask
, '\0', (nBytesPerLine 
* rBmp
.GetHeight())); 
 952     // Extract the bitmap and mask data 
 954     if ((hOldBitmap 
= ::GpiSetBitmap(hPS
, hBitmap
)) == HBM_ERROR
) 
 956         vError 
= ::WinGetLastError(vHabmain
); 
 957         sError 
= wxPMErrorToStr(vError
); 
 959     ::GpiQueryBitmapInfoHeader(hBitmap
, &vHeader
); 
 960     vInfo
.cBitCount 
= 24; 
 961     if ((lScans 
= ::GpiQueryBitmapBits( hPS
 
 963                                        ,(LONG
)rBmp
.GetHeight() 
 968         vError 
= ::WinGetLastError(vHabmain
); 
 969         sError 
= wxPMErrorToStr(vError
); 
 971     if ((hOldMask 
= ::GpiSetBitmap(hPS
, hMask
)) == HBM_ERROR
) 
 973         vError 
= ::WinGetLastError(vHabmain
); 
 974         sError 
= wxPMErrorToStr(vError
); 
 976     ::GpiQueryBitmapInfoHeader(hMask
, &vHeader
); 
 977     vInfo
.cBitCount 
= 24; 
 978     if ((lScans 
= ::GpiQueryBitmapBits( hPS
 
 980                                        ,(LONG
)rBmp
.GetHeight() 
 985         vError 
= ::WinGetLastError(vHabmain
); 
 986         sError 
= wxPMErrorToStr(vError
); 
 988     if (( hMask 
= ::GpiSetBitmap(hPS
, hOldMask
)) == HBM_ERROR
) 
 990         vError 
= ::WinGetLastError(vHabmain
); 
 991         sError 
= wxPMErrorToStr(vError
); 
 994     pucDataMask 
= pucBitsMask
; 
 997     // Get the mask value 
 999     for (i 
= 0; i 
< rBmp
.GetHeight(); i
++) 
1001         for (j 
= 0; j 
< rBmp
.GetWidth(); j
++) 
1004             if (bpp16 
&& *pucDataMask 
== 0xF8) // 16 bit display gobblygook 
1009             else if (*pucDataMask 
== 0xFF) // set to grey 
1016                 *pucData 
= ((unsigned char)(lColor 
>> 16)); 
1021             if (bpp16 
&& *(pucDataMask 
+ 1) == 0xFC) // 16 bit display gobblygook 
1026             else if (*(pucDataMask 
+ 1) == 0xFF) // set to grey 
1033                 *pucData 
= ((unsigned char)(lColor 
>> 8)); 
1038             if (bpp16 
&& *(pucDataMask 
+ 2) == 0xF8) // 16 bit display gobblygook 
1043             else if (*(pucDataMask 
+ 2) == 0xFF) // set to grey 
1050                 *pucData 
= ((unsigned char)lColor
); 
1055         for (j 
= 0; j 
< nPadding
; j
++) 
1063     // Create a new bitmap and set the modified bits 
1065     wxBitmap                        
vNewBmp( rBmp
.GetWidth() 
1069     HBITMAP                         hNewBmp 
= (HBITMAP
)vNewBmp
.GetHBITMAP(); 
1071     if ((hOldBitmap 
= ::GpiSetBitmap(hPS
, hNewBmp
)) == HBM_ERROR
) 
1073         vError 
= ::WinGetLastError(vHabmain
); 
1074         sError 
= wxPMErrorToStr(vError
); 
1076     if ((lScansSet 
= ::GpiSetBitmapBits( hPS
 
1078                                         ,(LONG
)rBmp
.GetHeight() 
1084         vError 
= ::WinGetLastError(vHabmain
); 
1085         sError 
= wxPMErrorToStr(vError
); 
1089     pNewMask 
= new wxMask(pMask
->GetMaskBitmap()); 
1090     vNewBmp
.SetMask(pNewMask
); 
1092     ::GpiSetBitmap(hPS
, NULLHANDLE
); 
1093     ::GpiDestroyPS(hPS
); 
1097     return(wxNullBitmap
); 
1098 } // end of wxDisableBitmap 
1100 COLORREF 
wxColourToRGB( 
1101   const wxColour
&                   rColor
 
1104     return(OS2RGB(rColor
.Red(), rColor
.Green(), rColor
.Blue())); 
1105 } // end of wxColourToRGB