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"
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)
62 bool wxWriteResource( const wxString
& rSection
,
63 const wxString
& rEntry
,
64 const wxString
& rValue
,
65 const wxString
& rFile
)
72 hIni
= ::PrfOpenProfile(hab
, (PSZ
)WXSTRINGCAST rFile
);
75 return (::PrfWriteProfileString( hIni
76 ,(PSZ
)WXSTRINGCAST rSection
77 ,(PSZ
)WXSTRINGCAST rEntry
78 ,(PSZ
)WXSTRINGCAST rValue
83 return (::PrfWriteProfileString( HINI_PROFILE
84 ,(PSZ
)WXSTRINGCAST rSection
85 ,(PSZ
)WXSTRINGCAST rEntry
86 ,(PSZ
)WXSTRINGCAST rValue
92 const wxString
& rSection
93 , const wxString
& rEntry
95 , const wxString
& rFile
100 wxSprintf(zBuf
, "%.4f", fValue
);
101 return wxWriteResource( rSection
108 bool wxWriteResource(
109 const wxString
& rSection
110 , const wxString
& rEntry
112 , const wxString
& rFile
117 wxSprintf(zBuf
, "%ld", lValue
);
118 return wxWriteResource( rSection
125 bool wxWriteResource( const wxString
& rSection
,
126 const wxString
& rEntry
,
128 const wxString
& rFile
)
132 wxSprintf(zBuf
, "%d", lValue
);
133 return wxWriteResource( rSection
, rEntry
, zBuf
, rFile
);
136 bool wxGetResource( const wxString
& rSection
,
137 const wxString
& rEntry
,
139 const wxString
& rFile
)
143 wxChar zDefunkt
[] = _T("$$default");
148 hIni
= ::PrfOpenProfile(hab
, (PSZ
)WXSTRINGCAST rFile
);
151 ULONG n
= ::PrfQueryProfileString( hIni
152 ,(PSZ
)WXSTRINGCAST rSection
153 ,(PSZ
)WXSTRINGCAST rEntry
160 if (n
== 0L || wxStrcmp(zBuf
, zDefunkt
) == 0)
169 ULONG n
= ::PrfQueryProfileString( HINI_PROFILE
170 ,(PSZ
)WXSTRINGCAST rSection
171 ,(PSZ
)WXSTRINGCAST rEntry
178 if (n
== 0L || wxStrcmp(zBuf
, zDefunkt
) == 0)
182 strcpy((char*)*ppValue
, zBuf
);
186 bool wxGetResource( const wxString
& rSection
,
187 const wxString
& rEntry
,
189 const wxString
& rFile
)
193 zStr
= new wxChar
[1000];
194 bool bSucc
= wxGetResource( rSection
, rEntry
, (wxChar
**)&zStr
, rFile
);
198 *pValue
= (float)wxStrtod(zStr
, NULL
);
205 bool wxGetResource( const wxString
& rSection
,
206 const wxString
& rEntry
,
208 const wxString
& rFile
)
212 zStr
= new wxChar
[1000];
213 bool bSucc
= wxGetResource( rSection
, rEntry
, (wxChar
**)&zStr
, rFile
);
217 *pValue
= wxStrtol(zStr
, NULL
, 10);
224 bool wxGetResource( const wxString
& rSection
,
225 const wxString
& rEntry
,
227 const wxString
& rFile
)
231 zStr
= new wxChar
[1000];
232 bool bSucc
= wxGetResource( rSection
, rEntry
, (wxChar
**)&zStr
, rFile
);
236 *pValue
= (int)wxStrtol(zStr
, NULL
, 10);
242 #endif // wxUSE_RESOURCES
244 // ---------------------------------------------------------------------------
245 // helper functions for showing a "busy" cursor
246 // ---------------------------------------------------------------------------
248 HCURSOR gs_wxBusyCursor
= 0; // new, busy cursor
249 HCURSOR gs_wxBusyCursorOld
= 0; // old cursor
250 static int gs_wxBusyCursorCount
= 0;
252 // Set the cursor to the busy cursor for all windows
253 void wxBeginBusyCursor(const wxCursor
* pCursor
)
255 if ( gs_wxBusyCursorCount
++ == 0 )
257 gs_wxBusyCursor
= (HCURSOR
)pCursor
->GetHCURSOR();
258 ::WinSetPointer(HWND_DESKTOP
, (HPOINTER
)gs_wxBusyCursor
);
260 //else: nothing to do, already set
263 // Restore cursor to normal
264 void wxEndBusyCursor()
266 wxCHECK_RET( gs_wxBusyCursorCount
> 0
267 ,_T("no matching wxBeginBusyCursor() for wxEndBusyCursor()")
270 if (--gs_wxBusyCursorCount
== 0)
272 ::WinSetPointer(HWND_DESKTOP
, (HPOINTER
)gs_wxBusyCursorOld
);
273 gs_wxBusyCursorOld
= 0;
277 // true if we're between the above two calls
280 return (gs_wxBusyCursorCount
> 0);
283 // Check whether this window wants to process messages, e.g. Stop button
284 // in long calculations.
285 bool wxCheckForInterrupt( wxWindow
* pWnd
)
291 HWND hwndFilter
= NULLHANDLE
;
293 while(::WinPeekMsg(hab
, &vMsg
, hwndFilter
, 0, 0, PM_REMOVE
))
295 ::WinDispatchMsg(hab
, &vMsg
);
297 return true;//*** temporary?
301 wxFAIL_MSG(_T("pWnd==NULL !!!"));
302 return false;//*** temporary?
306 // ----------------------------------------------------------------------------
308 // ----------------------------------------------------------------------------
310 // See also the wxGetMousePosition in window.cpp
311 // Deprecated: use wxPoint wxGetMousePosition() instead
312 void wxGetMousePosition(
319 ::WinQueryPointerPos(HWND_DESKTOP
, &vPt
);
324 // Return true if we have a colour display
325 bool wxColourDisplay()
332 hpsScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
333 hdcScreen
= ::GpiQueryDevice(hpsScreen
);
334 ::DevQueryCaps(hdcScreen
, CAPS_COLORS
, 1L, &lColors
);
335 return(lColors
> 1L);
337 // I don't see how the PM display could not be color. Besides, this
338 // was leaking DCs and PSs!!! MN
343 // Returns depth of screen
350 static LONG nDepth
= 0;
352 // The screen colordepth ain't gonna change. No reason to query
355 hpsScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
356 hdcScreen
= ::GpiQueryDevice(hpsScreen
);
357 ::DevQueryCaps(hdcScreen
, CAPS_COLOR_PLANES
, 1L, &lPlanes
);
358 ::DevQueryCaps(hdcScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitsPerPixel
);
360 nDepth
= (int)(lPlanes
* lBitsPerPixel
);
361 ::DevCloseDC(hdcScreen
);
362 ::WinReleasePS(hpsScreen
);
367 // Get size of display
375 static LONG lWidth
= 0;
376 static LONG lHeight
= 0;
378 // The screen size ain't gonna change either so just cache the values
380 hpsScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
381 hdcScreen
= ::GpiQueryDevice(hpsScreen
);
382 ::DevQueryCaps(hdcScreen
, CAPS_WIDTH
, 1L, &lWidth
);
383 ::DevQueryCaps(hdcScreen
, CAPS_HEIGHT
, 1L, &lHeight
);
384 ::DevCloseDC(hdcScreen
);
385 ::WinReleasePS(hpsScreen
);
388 *pWidth
= (int)lWidth
;
390 *pHeight
= (int)lHeight
;
393 void wxDisplaySizeMM(
401 hpsScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
402 hdcScreen
= ::GpiQueryDevice(hpsScreen
);
405 ::DevQueryCaps( hdcScreen
406 ,CAPS_HORIZONTAL_RESOLUTION
411 ::DevQueryCaps( hdcScreen
412 ,CAPS_VERTICAL_RESOLUTION
416 ::DevCloseDC(hdcScreen
);
417 ::WinReleasePS(hpsScreen
);
420 void wxClientDisplayRect(int *x
, int *y
, int *width
, int *height
)
422 // This is supposed to return desktop dimensions minus any window
423 // manager panels, menus, taskbars, etc. If there is a way to do that
424 // for this platform please fix this function, otherwise it defaults
425 // to the entire desktop.
428 wxDisplaySize(width
, height
);
431 void wxGUIAppTraits::InitializeGui(unsigned long &ulHab
)
433 ulHab
= ::WinInitialize(0);
436 void wxGUIAppTraits::TerminateGui(unsigned long ulHab
)
438 ::WinTerminate(ulHab
);
441 wxPortId
wxGUIAppTraits::GetToolkitVersion(int *verMaj
, int *verMin
) const
443 // How to get version of PM ? I guess, just reusing the OS version is OK.
444 (void) wxGetOsVersion(verMaj
, verMin
);
449 // ---------------------------------------------------------------------------
450 // window information functions
451 // ---------------------------------------------------------------------------
453 wxString WXDLLEXPORT
wxGetWindowText( WXHWND hWnd
)
459 long lLen
= ::WinQueryWindowTextLength((HWND
)hWnd
) + 1;
460 ::WinQueryWindowText((HWND
)hWnd
, lLen
, (PSZ
)(wxChar
*)wxStringBuffer(vStr
, lLen
));
466 wxString WXDLLEXPORT
wxGetWindowClass( WXHWND hWnd
)
471 int nLen
= 256; // some starting value
475 int nCount
= ::WinQueryClassName((HWND
)hWnd
, nLen
, (PSZ
)(wxChar
*)wxStringBuffer(vStr
, nLen
));
479 // the class name might have been truncated, retry with larger
492 WXWORD WXDLLEXPORT
wxGetWindowId(
496 return ::WinQueryWindowUShort((HWND
)hWnd
, QWS_ID
);
507 vPoint
[0].x
= rRect
.xLeft
;
508 vPoint
[0].y
= rRect
.yBottom
;
509 ::GpiMove(hPS
, &vPoint
[0]);
510 if (dwStyle
& wxSIMPLE_BORDER
||
511 dwStyle
& wxSTATIC_BORDER
)
513 vPoint
[1].x
= rRect
.xRight
- 1;
514 vPoint
[1].y
= rRect
.yTop
- 1;
522 if (dwStyle
& wxSUNKEN_BORDER
)
524 LINEBUNDLE vLineBundle
;
526 vLineBundle
.lColor
= 0x00FFFFFF; // WHITE
527 vLineBundle
.usMixMode
= FM_OVERPAINT
;
528 vLineBundle
.fxWidth
= 2;
529 vLineBundle
.lGeomWidth
= 2;
530 vLineBundle
.usType
= LINETYPE_SOLID
;
531 vLineBundle
.usEnd
= 0;
532 vLineBundle
.usJoin
= 0;
535 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
539 vPoint
[1].x
= rRect
.xRight
- 1;
540 vPoint
[1].y
= rRect
.yTop
- 1;
547 vPoint
[0].x
= rRect
.xLeft
+ 1;
548 vPoint
[0].y
= rRect
.yBottom
+ 1;
549 ::GpiMove(hPS
, &vPoint
[0]);
550 vPoint
[1].x
= rRect
.xRight
- 2;
551 vPoint
[1].y
= rRect
.yTop
- 2;
559 vLineBundle
.lColor
= 0x00000000; // BLACK
560 vLineBundle
.usMixMode
= FM_OVERPAINT
;
561 vLineBundle
.fxWidth
= 2;
562 vLineBundle
.lGeomWidth
= 2;
563 vLineBundle
.usType
= LINETYPE_SOLID
;
564 vLineBundle
.usEnd
= 0;
565 vLineBundle
.usJoin
= 0;
568 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
572 vPoint
[0].x
= rRect
.xLeft
+ 2;
573 vPoint
[0].y
= rRect
.yBottom
+ 2;
574 ::GpiMove(hPS
, &vPoint
[0]);
575 vPoint
[1].x
= rRect
.xLeft
+ 2;
576 vPoint
[1].y
= rRect
.yTop
- 3;
577 ::GpiLine(hPS
, &vPoint
[1]);
578 vPoint
[1].x
= rRect
.xRight
- 3;
579 vPoint
[1].y
= rRect
.yTop
- 3;
580 ::GpiLine(hPS
, &vPoint
[1]);
582 vPoint
[0].x
= rRect
.xLeft
+ 3;
583 vPoint
[0].y
= rRect
.yBottom
+ 3;
584 ::GpiMove(hPS
, &vPoint
[0]);
585 vPoint
[1].x
= rRect
.xLeft
+ 3;
586 vPoint
[1].y
= rRect
.yTop
- 4;
587 ::GpiLine(hPS
, &vPoint
[1]);
588 vPoint
[1].x
= rRect
.xRight
- 4;
589 vPoint
[1].y
= rRect
.yTop
- 4;
590 ::GpiLine(hPS
, &vPoint
[1]);
592 if (dwStyle
& wxDOUBLE_BORDER
)
594 LINEBUNDLE vLineBundle
;
596 vLineBundle
.lColor
= 0x00FFFFFF; // WHITE
597 vLineBundle
.usMixMode
= FM_OVERPAINT
;
598 vLineBundle
.fxWidth
= 2;
599 vLineBundle
.lGeomWidth
= 2;
600 vLineBundle
.usType
= LINETYPE_SOLID
;
601 vLineBundle
.usEnd
= 0;
602 vLineBundle
.usJoin
= 0;
605 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
609 vPoint
[1].x
= rRect
.xRight
- 1;
610 vPoint
[1].y
= rRect
.yTop
- 1;
617 vLineBundle
.lColor
= 0x00000000; // WHITE
618 vLineBundle
.usMixMode
= FM_OVERPAINT
;
619 vLineBundle
.fxWidth
= 2;
620 vLineBundle
.lGeomWidth
= 2;
621 vLineBundle
.usType
= LINETYPE_SOLID
;
622 vLineBundle
.usEnd
= 0;
623 vLineBundle
.usJoin
= 0;
626 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
630 vPoint
[0].x
= rRect
.xLeft
+ 2;
631 vPoint
[0].y
= rRect
.yBottom
+ 2;
632 ::GpiMove(hPS
, &vPoint
[0]);
633 vPoint
[1].x
= rRect
.xRight
- 2;
634 vPoint
[1].y
= rRect
.yTop
- 2;
641 vLineBundle
.lColor
= 0x00FFFFFF; // BLACK
642 vLineBundle
.usMixMode
= FM_OVERPAINT
;
643 vLineBundle
.fxWidth
= 2;
644 vLineBundle
.lGeomWidth
= 2;
645 vLineBundle
.usType
= LINETYPE_SOLID
;
646 vLineBundle
.usEnd
= 0;
647 vLineBundle
.usJoin
= 0;
650 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
654 vPoint
[0].x
= rRect
.xLeft
+ 3;
655 vPoint
[0].y
= rRect
.yBottom
+ 3;
656 ::GpiMove(hPS
, &vPoint
[0]);
657 vPoint
[1].x
= rRect
.xRight
- 3;
658 vPoint
[1].y
= rRect
.yTop
- 3;
666 if (dwStyle
& wxRAISED_BORDER
)
668 LINEBUNDLE vLineBundle
;
670 vLineBundle
.lColor
= 0x00000000; // BLACK
671 vLineBundle
.usMixMode
= FM_OVERPAINT
;
672 vLineBundle
.fxWidth
= 2;
673 vLineBundle
.lGeomWidth
= 2;
674 vLineBundle
.usType
= LINETYPE_SOLID
;
675 vLineBundle
.usEnd
= 0;
676 vLineBundle
.usJoin
= 0;
679 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
683 vPoint
[1].x
= rRect
.xRight
- 1;
684 vPoint
[1].y
= rRect
.yTop
- 1;
691 vPoint
[0].x
= rRect
.xLeft
+ 1;
692 vPoint
[0].y
= rRect
.yBottom
+ 1;
693 ::GpiMove(hPS
, &vPoint
[0]);
694 vPoint
[1].x
= rRect
.xRight
- 2;
695 vPoint
[1].y
= rRect
.yTop
- 2;
703 vLineBundle
.lColor
= 0x00FFFFFF; // WHITE
704 vLineBundle
.usMixMode
= FM_OVERPAINT
;
705 vLineBundle
.fxWidth
= 2;
706 vLineBundle
.lGeomWidth
= 2;
707 vLineBundle
.usType
= LINETYPE_SOLID
;
708 vLineBundle
.usEnd
= 0;
709 vLineBundle
.usJoin
= 0;
712 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
716 vPoint
[0].x
= rRect
.xLeft
+ 2;
717 vPoint
[0].y
= rRect
.yBottom
+ 2;
718 ::GpiMove(hPS
, &vPoint
[0]);
719 vPoint
[1].x
= rRect
.xLeft
+ 2;
720 vPoint
[1].y
= rRect
.yTop
- 3;
721 ::GpiLine(hPS
, &vPoint
[1]);
722 vPoint
[1].x
= rRect
.xRight
- 3;
723 vPoint
[1].y
= rRect
.yTop
- 3;
724 ::GpiLine(hPS
, &vPoint
[1]);
726 vPoint
[0].x
= rRect
.xLeft
+ 3;
727 vPoint
[0].y
= rRect
.yBottom
+ 3;
728 ::GpiMove(hPS
, &vPoint
[0]);
729 vPoint
[1].x
= rRect
.xLeft
+ 3;
730 vPoint
[1].y
= rRect
.yTop
- 4;
731 ::GpiLine(hPS
, &vPoint
[1]);
732 vPoint
[1].x
= rRect
.xRight
- 4;
733 vPoint
[1].y
= rRect
.yTop
- 4;
734 ::GpiLine(hPS
, &vPoint
[1]);
736 } // end of wxDrawBorder
740 , const wxFont
& rFont
748 if (hWnd
== NULLHANDLE
)
752 // The fonts available for Presentation Params are just a few
753 // outline fonts, the rest are available to the GPI, so we must
754 // map the families to one of these three
756 switch(rFont
.GetFamily())
759 strcpy(zFacename
, "Script");
763 strcpy(zFacename
, "WarpSans");
767 strcpy(zFacename
,"Times New Roman");
771 strcpy(zFacename
, "Courier New");
775 strcpy(zFacename
, "Courier New");
781 strcpy(zFacename
, "Helvetica");
785 switch(rFont
.GetWeight())
794 case wxFONTWEIGHT_MAX
:
795 strcpy(zWeight
, "Bold");
799 switch(rFont
.GetStyle())
803 strcpy(zStyle
, "Italic");
810 sprintf(zFont
, "%d.%s", rFont
.GetPointSize(), zFacename
);
811 if (zWeight
[0] != '\0')
814 strcat(zFont
, zWeight
);
816 if (zStyle
[0] != '\0')
819 strcat(zFont
, zStyle
);
821 ::WinSetPresParam(hWnd
, PP_FONTNAMESIZE
, strlen(zFont
) + 1, (PVOID
)zFont
);
822 } // end of wxOS2SetFont
824 // ---------------------------------------------------------------------------
825 // Helper for taking a regular bitmap and giving it a disabled look
826 // ---------------------------------------------------------------------------
827 wxBitmap
wxDisableBitmap(
832 wxMask
* pMask
= rBmp
.GetMask();
835 return(wxNullBitmap
);
837 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
838 SIZEL vSize
= {0, 0};
839 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
840 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
841 BITMAPINFOHEADER2 vHeader
;
845 HBITMAP hBitmap
= (HBITMAP
)rBmp
.GetHBITMAP();
846 HBITMAP hOldBitmap
= NULLHANDLE
;
847 HBITMAP hOldMask
= NULLHANDLE
;
848 HBITMAP hMask
= (HBITMAP
)rBmp
.GetMask()->GetMaskBitmap();
849 unsigned char* pucBits
; // buffer that will contain the bitmap data
850 unsigned char* pucData
; // pointer to use to traverse bitmap data
851 unsigned char* pucBitsMask
; // buffer that will contain the mask data
852 unsigned char* pucDataMask
; // pointer to use to traverse mask data
855 bool bpp16
= (wxDisplayDepth() == 16);
857 memset(&vHeader
, '\0', 16);
860 memset(&vInfo
, '\0', 16);
862 vInfo
.cx
= (ULONG
)rBmp
.GetWidth();
863 vInfo
.cy
= (ULONG
)rBmp
.GetHeight();
865 vInfo
.cBitCount
= 24; // Set to desired count going in
868 // Create the buffers for data....all wxBitmaps are 24 bit internally
870 int nBytesPerLine
= rBmp
.GetWidth() * 3;
871 int nSizeDWORD
= sizeof(DWORD
);
872 int nLineBoundary
= nBytesPerLine
% nSizeDWORD
;
878 // Bitmap must be in a double-word aligned address so we may
879 // have some padding to worry about
881 if (nLineBoundary
> 0)
883 nPadding
= nSizeDWORD
- nLineBoundary
;
884 nBytesPerLine
+= nPadding
;
886 pucBits
= (unsigned char *)malloc(nBytesPerLine
* rBmp
.GetHeight());
887 memset(pucBits
, '\0', (nBytesPerLine
* rBmp
.GetHeight()));
888 pucBitsMask
= (unsigned char *)malloc(nBytesPerLine
* rBmp
.GetHeight());
889 memset(pucBitsMask
, '\0', (nBytesPerLine
* rBmp
.GetHeight()));
892 // Extract the bitmap and mask data
894 if ((hOldBitmap
= ::GpiSetBitmap(hPS
, hBitmap
)) == HBM_ERROR
)
896 vError
= ::WinGetLastError(vHabmain
);
897 sError
= wxPMErrorToStr(vError
);
899 ::GpiQueryBitmapInfoHeader(hBitmap
, &vHeader
);
900 vInfo
.cBitCount
= 24;
901 if ((lScans
= ::GpiQueryBitmapBits( hPS
903 ,(LONG
)rBmp
.GetHeight()
908 vError
= ::WinGetLastError(vHabmain
);
909 sError
= wxPMErrorToStr(vError
);
911 if ((hOldMask
= ::GpiSetBitmap(hPS
, hMask
)) == HBM_ERROR
)
913 vError
= ::WinGetLastError(vHabmain
);
914 sError
= wxPMErrorToStr(vError
);
916 ::GpiQueryBitmapInfoHeader(hMask
, &vHeader
);
917 vInfo
.cBitCount
= 24;
918 if ((lScans
= ::GpiQueryBitmapBits( hPS
920 ,(LONG
)rBmp
.GetHeight()
925 vError
= ::WinGetLastError(vHabmain
);
926 sError
= wxPMErrorToStr(vError
);
928 if (( hMask
= ::GpiSetBitmap(hPS
, hOldMask
)) == HBM_ERROR
)
930 vError
= ::WinGetLastError(vHabmain
);
931 sError
= wxPMErrorToStr(vError
);
934 pucDataMask
= pucBitsMask
;
937 // Get the mask value
939 for (i
= 0; i
< rBmp
.GetHeight(); i
++)
941 for (j
= 0; j
< rBmp
.GetWidth(); j
++)
944 if (bpp16
&& *pucDataMask
== 0xF8) // 16 bit display gobblygook
949 else if (*pucDataMask
== 0xFF) // set to grey
956 *pucData
= ((unsigned char)(lColor
>> 16));
961 if (bpp16
&& *(pucDataMask
+ 1) == 0xFC) // 16 bit display gobblygook
966 else if (*(pucDataMask
+ 1) == 0xFF) // set to grey
973 *pucData
= ((unsigned char)(lColor
>> 8));
978 if (bpp16
&& *(pucDataMask
+ 2) == 0xF8) // 16 bit display gobblygook
983 else if (*(pucDataMask
+ 2) == 0xFF) // set to grey
990 *pucData
= ((unsigned char)lColor
);
995 for (j
= 0; j
< nPadding
; j
++)
1003 // Create a new bitmap and set the modified bits
1005 wxBitmap
vNewBmp( rBmp
.GetWidth()
1009 HBITMAP hNewBmp
= (HBITMAP
)vNewBmp
.GetHBITMAP();
1011 if ((hOldBitmap
= ::GpiSetBitmap(hPS
, hNewBmp
)) == HBM_ERROR
)
1013 vError
= ::WinGetLastError(vHabmain
);
1014 sError
= wxPMErrorToStr(vError
);
1016 if ((lScansSet
= ::GpiSetBitmapBits( hPS
1018 ,(LONG
)rBmp
.GetHeight()
1024 vError
= ::WinGetLastError(vHabmain
);
1025 sError
= wxPMErrorToStr(vError
);
1029 pNewMask
= new wxMask(pMask
->GetMaskBitmap());
1030 vNewBmp
.SetMask(pNewMask
);
1032 ::GpiSetBitmap(hPS
, NULLHANDLE
);
1033 ::GpiDestroyPS(hPS
);
1037 return(wxNullBitmap
);
1038 } // end of wxDisableBitmap
1040 COLORREF
wxColourToRGB(
1041 const wxColour
& rColor
1044 return(OS2RGB(rColor
.Red(), rColor
.Green(), rColor
.Blue()));
1045 } // end of wxColourToRGB