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 wxToolkitInfo
& wxGUIAppTraits::GetToolkitInfo()
442 static wxToolkitInfo vInfo
;
443 ULONG ulSysInfo
[QSV_MAX
] = {0};
446 vInfo
.shortName
= _T("PM");
447 vInfo
.name
= _T("wxOS2");
448 #ifdef __WXUNIVERSAL__
449 vInfo
.shortName
<< _T("univ");
450 vInfo
.name
<< _T("/wxUniversal");
452 ulrc
= ::DosQuerySysInfo( 1L
455 ,sizeof(ULONG
) * QSV_MAX
459 vInfo
.versionMajor
= ulSysInfo
[QSV_VERSION_MAJOR
] / 10;
460 vInfo
.versionMinor
= ulSysInfo
[QSV_VERSION_MINOR
];
466 // ---------------------------------------------------------------------------
467 // window information functions
468 // ---------------------------------------------------------------------------
470 wxString WXDLLEXPORT
wxGetWindowText( WXHWND hWnd
)
476 long lLen
= ::WinQueryWindowTextLength((HWND
)hWnd
) + 1;
477 ::WinQueryWindowText((HWND
)hWnd
, lLen
, (PSZ
)(wxChar
*)wxStringBuffer(vStr
, lLen
));
483 wxString WXDLLEXPORT
wxGetWindowClass( WXHWND hWnd
)
488 int nLen
= 256; // some starting value
492 int nCount
= ::WinQueryClassName((HWND
)hWnd
, nLen
, (PSZ
)(wxChar
*)wxStringBuffer(vStr
, nLen
));
496 // the class name might have been truncated, retry with larger
509 WXWORD WXDLLEXPORT
wxGetWindowId(
513 return ::WinQueryWindowUShort((HWND
)hWnd
, QWS_ID
);
524 vPoint
[0].x
= rRect
.xLeft
;
525 vPoint
[0].y
= rRect
.yBottom
;
526 ::GpiMove(hPS
, &vPoint
[0]);
527 if (dwStyle
& wxSIMPLE_BORDER
||
528 dwStyle
& wxSTATIC_BORDER
)
530 vPoint
[1].x
= rRect
.xRight
- 1;
531 vPoint
[1].y
= rRect
.yTop
- 1;
539 if (dwStyle
& wxSUNKEN_BORDER
)
541 LINEBUNDLE vLineBundle
;
543 vLineBundle
.lColor
= 0x00FFFFFF; // WHITE
544 vLineBundle
.usMixMode
= FM_OVERPAINT
;
545 vLineBundle
.fxWidth
= 2;
546 vLineBundle
.lGeomWidth
= 2;
547 vLineBundle
.usType
= LINETYPE_SOLID
;
548 vLineBundle
.usEnd
= 0;
549 vLineBundle
.usJoin
= 0;
552 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
556 vPoint
[1].x
= rRect
.xRight
- 1;
557 vPoint
[1].y
= rRect
.yTop
- 1;
564 vPoint
[0].x
= rRect
.xLeft
+ 1;
565 vPoint
[0].y
= rRect
.yBottom
+ 1;
566 ::GpiMove(hPS
, &vPoint
[0]);
567 vPoint
[1].x
= rRect
.xRight
- 2;
568 vPoint
[1].y
= rRect
.yTop
- 2;
576 vLineBundle
.lColor
= 0x00000000; // BLACK
577 vLineBundle
.usMixMode
= FM_OVERPAINT
;
578 vLineBundle
.fxWidth
= 2;
579 vLineBundle
.lGeomWidth
= 2;
580 vLineBundle
.usType
= LINETYPE_SOLID
;
581 vLineBundle
.usEnd
= 0;
582 vLineBundle
.usJoin
= 0;
585 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
589 vPoint
[0].x
= rRect
.xLeft
+ 2;
590 vPoint
[0].y
= rRect
.yBottom
+ 2;
591 ::GpiMove(hPS
, &vPoint
[0]);
592 vPoint
[1].x
= rRect
.xLeft
+ 2;
593 vPoint
[1].y
= rRect
.yTop
- 3;
594 ::GpiLine(hPS
, &vPoint
[1]);
595 vPoint
[1].x
= rRect
.xRight
- 3;
596 vPoint
[1].y
= rRect
.yTop
- 3;
597 ::GpiLine(hPS
, &vPoint
[1]);
599 vPoint
[0].x
= rRect
.xLeft
+ 3;
600 vPoint
[0].y
= rRect
.yBottom
+ 3;
601 ::GpiMove(hPS
, &vPoint
[0]);
602 vPoint
[1].x
= rRect
.xLeft
+ 3;
603 vPoint
[1].y
= rRect
.yTop
- 4;
604 ::GpiLine(hPS
, &vPoint
[1]);
605 vPoint
[1].x
= rRect
.xRight
- 4;
606 vPoint
[1].y
= rRect
.yTop
- 4;
607 ::GpiLine(hPS
, &vPoint
[1]);
609 if (dwStyle
& wxDOUBLE_BORDER
)
611 LINEBUNDLE vLineBundle
;
613 vLineBundle
.lColor
= 0x00FFFFFF; // WHITE
614 vLineBundle
.usMixMode
= FM_OVERPAINT
;
615 vLineBundle
.fxWidth
= 2;
616 vLineBundle
.lGeomWidth
= 2;
617 vLineBundle
.usType
= LINETYPE_SOLID
;
618 vLineBundle
.usEnd
= 0;
619 vLineBundle
.usJoin
= 0;
622 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
626 vPoint
[1].x
= rRect
.xRight
- 1;
627 vPoint
[1].y
= rRect
.yTop
- 1;
634 vLineBundle
.lColor
= 0x00000000; // WHITE
635 vLineBundle
.usMixMode
= FM_OVERPAINT
;
636 vLineBundle
.fxWidth
= 2;
637 vLineBundle
.lGeomWidth
= 2;
638 vLineBundle
.usType
= LINETYPE_SOLID
;
639 vLineBundle
.usEnd
= 0;
640 vLineBundle
.usJoin
= 0;
643 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
647 vPoint
[0].x
= rRect
.xLeft
+ 2;
648 vPoint
[0].y
= rRect
.yBottom
+ 2;
649 ::GpiMove(hPS
, &vPoint
[0]);
650 vPoint
[1].x
= rRect
.xRight
- 2;
651 vPoint
[1].y
= rRect
.yTop
- 2;
658 vLineBundle
.lColor
= 0x00FFFFFF; // BLACK
659 vLineBundle
.usMixMode
= FM_OVERPAINT
;
660 vLineBundle
.fxWidth
= 2;
661 vLineBundle
.lGeomWidth
= 2;
662 vLineBundle
.usType
= LINETYPE_SOLID
;
663 vLineBundle
.usEnd
= 0;
664 vLineBundle
.usJoin
= 0;
667 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
671 vPoint
[0].x
= rRect
.xLeft
+ 3;
672 vPoint
[0].y
= rRect
.yBottom
+ 3;
673 ::GpiMove(hPS
, &vPoint
[0]);
674 vPoint
[1].x
= rRect
.xRight
- 3;
675 vPoint
[1].y
= rRect
.yTop
- 3;
683 if (dwStyle
& wxRAISED_BORDER
)
685 LINEBUNDLE vLineBundle
;
687 vLineBundle
.lColor
= 0x00000000; // BLACK
688 vLineBundle
.usMixMode
= FM_OVERPAINT
;
689 vLineBundle
.fxWidth
= 2;
690 vLineBundle
.lGeomWidth
= 2;
691 vLineBundle
.usType
= LINETYPE_SOLID
;
692 vLineBundle
.usEnd
= 0;
693 vLineBundle
.usJoin
= 0;
696 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
700 vPoint
[1].x
= rRect
.xRight
- 1;
701 vPoint
[1].y
= rRect
.yTop
- 1;
708 vPoint
[0].x
= rRect
.xLeft
+ 1;
709 vPoint
[0].y
= rRect
.yBottom
+ 1;
710 ::GpiMove(hPS
, &vPoint
[0]);
711 vPoint
[1].x
= rRect
.xRight
- 2;
712 vPoint
[1].y
= rRect
.yTop
- 2;
720 vLineBundle
.lColor
= 0x00FFFFFF; // WHITE
721 vLineBundle
.usMixMode
= FM_OVERPAINT
;
722 vLineBundle
.fxWidth
= 2;
723 vLineBundle
.lGeomWidth
= 2;
724 vLineBundle
.usType
= LINETYPE_SOLID
;
725 vLineBundle
.usEnd
= 0;
726 vLineBundle
.usJoin
= 0;
729 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
733 vPoint
[0].x
= rRect
.xLeft
+ 2;
734 vPoint
[0].y
= rRect
.yBottom
+ 2;
735 ::GpiMove(hPS
, &vPoint
[0]);
736 vPoint
[1].x
= rRect
.xLeft
+ 2;
737 vPoint
[1].y
= rRect
.yTop
- 3;
738 ::GpiLine(hPS
, &vPoint
[1]);
739 vPoint
[1].x
= rRect
.xRight
- 3;
740 vPoint
[1].y
= rRect
.yTop
- 3;
741 ::GpiLine(hPS
, &vPoint
[1]);
743 vPoint
[0].x
= rRect
.xLeft
+ 3;
744 vPoint
[0].y
= rRect
.yBottom
+ 3;
745 ::GpiMove(hPS
, &vPoint
[0]);
746 vPoint
[1].x
= rRect
.xLeft
+ 3;
747 vPoint
[1].y
= rRect
.yTop
- 4;
748 ::GpiLine(hPS
, &vPoint
[1]);
749 vPoint
[1].x
= rRect
.xRight
- 4;
750 vPoint
[1].y
= rRect
.yTop
- 4;
751 ::GpiLine(hPS
, &vPoint
[1]);
753 } // end of wxDrawBorder
757 , const wxFont
& rFont
765 if (hWnd
== NULLHANDLE
)
769 // The fonts available for Presentation Params are just a few
770 // outline fonts, the rest are available to the GPI, so we must
771 // map the families to one of these three
773 switch(rFont
.GetFamily())
776 strcpy(zFacename
, "Script");
780 strcpy(zFacename
, "WarpSans");
784 strcpy(zFacename
,"Times New Roman");
788 strcpy(zFacename
, "Courier New");
792 strcpy(zFacename
, "Courier New");
798 strcpy(zFacename
, "Helvetica");
802 switch(rFont
.GetWeight())
811 case wxFONTWEIGHT_MAX
:
812 strcpy(zWeight
, "Bold");
816 switch(rFont
.GetStyle())
820 strcpy(zStyle
, "Italic");
827 sprintf(zFont
, "%d.%s", rFont
.GetPointSize(), zFacename
);
828 if (zWeight
[0] != '\0')
831 strcat(zFont
, zWeight
);
833 if (zStyle
[0] != '\0')
836 strcat(zFont
, zStyle
);
838 ::WinSetPresParam(hWnd
, PP_FONTNAMESIZE
, strlen(zFont
) + 1, (PVOID
)zFont
);
839 } // end of wxOS2SetFont
841 // ---------------------------------------------------------------------------
842 // Helper for taking a regular bitmap and giving it a disabled look
843 // ---------------------------------------------------------------------------
844 wxBitmap
wxDisableBitmap(
849 wxMask
* pMask
= rBmp
.GetMask();
852 return(wxNullBitmap
);
854 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
855 SIZEL vSize
= {0, 0};
856 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
857 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
858 BITMAPINFOHEADER2 vHeader
;
862 HBITMAP hBitmap
= (HBITMAP
)rBmp
.GetHBITMAP();
863 HBITMAP hOldBitmap
= NULLHANDLE
;
864 HBITMAP hOldMask
= NULLHANDLE
;
865 HBITMAP hMask
= (HBITMAP
)rBmp
.GetMask()->GetMaskBitmap();
866 unsigned char* pucBits
; // buffer that will contain the bitmap data
867 unsigned char* pucData
; // pointer to use to traverse bitmap data
868 unsigned char* pucBitsMask
; // buffer that will contain the mask data
869 unsigned char* pucDataMask
; // pointer to use to traverse mask data
872 bool bpp16
= (wxDisplayDepth() == 16);
874 memset(&vHeader
, '\0', 16);
877 memset(&vInfo
, '\0', 16);
879 vInfo
.cx
= (ULONG
)rBmp
.GetWidth();
880 vInfo
.cy
= (ULONG
)rBmp
.GetHeight();
882 vInfo
.cBitCount
= 24; // Set to desired count going in
885 // Create the buffers for data....all wxBitmaps are 24 bit internally
887 int nBytesPerLine
= rBmp
.GetWidth() * 3;
888 int nSizeDWORD
= sizeof(DWORD
);
889 int nLineBoundary
= nBytesPerLine
% nSizeDWORD
;
895 // Bitmap must be in a double-word aligned address so we may
896 // have some padding to worry about
898 if (nLineBoundary
> 0)
900 nPadding
= nSizeDWORD
- nLineBoundary
;
901 nBytesPerLine
+= nPadding
;
903 pucBits
= (unsigned char *)malloc(nBytesPerLine
* rBmp
.GetHeight());
904 memset(pucBits
, '\0', (nBytesPerLine
* rBmp
.GetHeight()));
905 pucBitsMask
= (unsigned char *)malloc(nBytesPerLine
* rBmp
.GetHeight());
906 memset(pucBitsMask
, '\0', (nBytesPerLine
* rBmp
.GetHeight()));
909 // Extract the bitmap and mask data
911 if ((hOldBitmap
= ::GpiSetBitmap(hPS
, hBitmap
)) == HBM_ERROR
)
913 vError
= ::WinGetLastError(vHabmain
);
914 sError
= wxPMErrorToStr(vError
);
916 ::GpiQueryBitmapInfoHeader(hBitmap
, &vHeader
);
917 vInfo
.cBitCount
= 24;
918 if ((lScans
= ::GpiQueryBitmapBits( hPS
920 ,(LONG
)rBmp
.GetHeight()
925 vError
= ::WinGetLastError(vHabmain
);
926 sError
= wxPMErrorToStr(vError
);
928 if ((hOldMask
= ::GpiSetBitmap(hPS
, hMask
)) == HBM_ERROR
)
930 vError
= ::WinGetLastError(vHabmain
);
931 sError
= wxPMErrorToStr(vError
);
933 ::GpiQueryBitmapInfoHeader(hMask
, &vHeader
);
934 vInfo
.cBitCount
= 24;
935 if ((lScans
= ::GpiQueryBitmapBits( hPS
937 ,(LONG
)rBmp
.GetHeight()
942 vError
= ::WinGetLastError(vHabmain
);
943 sError
= wxPMErrorToStr(vError
);
945 if (( hMask
= ::GpiSetBitmap(hPS
, hOldMask
)) == HBM_ERROR
)
947 vError
= ::WinGetLastError(vHabmain
);
948 sError
= wxPMErrorToStr(vError
);
951 pucDataMask
= pucBitsMask
;
954 // Get the mask value
956 for (i
= 0; i
< rBmp
.GetHeight(); i
++)
958 for (j
= 0; j
< rBmp
.GetWidth(); j
++)
961 if (bpp16
&& *pucDataMask
== 0xF8) // 16 bit display gobblygook
966 else if (*pucDataMask
== 0xFF) // set to grey
973 *pucData
= ((unsigned char)(lColor
>> 16));
978 if (bpp16
&& *(pucDataMask
+ 1) == 0xFC) // 16 bit display gobblygook
983 else if (*(pucDataMask
+ 1) == 0xFF) // set to grey
990 *pucData
= ((unsigned char)(lColor
>> 8));
995 if (bpp16
&& *(pucDataMask
+ 2) == 0xF8) // 16 bit display gobblygook
1000 else if (*(pucDataMask
+ 2) == 0xFF) // set to grey
1007 *pucData
= ((unsigned char)lColor
);
1012 for (j
= 0; j
< nPadding
; j
++)
1020 // Create a new bitmap and set the modified bits
1022 wxBitmap
vNewBmp( rBmp
.GetWidth()
1026 HBITMAP hNewBmp
= (HBITMAP
)vNewBmp
.GetHBITMAP();
1028 if ((hOldBitmap
= ::GpiSetBitmap(hPS
, hNewBmp
)) == HBM_ERROR
)
1030 vError
= ::WinGetLastError(vHabmain
);
1031 sError
= wxPMErrorToStr(vError
);
1033 if ((lScansSet
= ::GpiSetBitmapBits( hPS
1035 ,(LONG
)rBmp
.GetHeight()
1041 vError
= ::WinGetLastError(vHabmain
);
1042 sError
= wxPMErrorToStr(vError
);
1046 pNewMask
= new wxMask(pMask
->GetMaskBitmap());
1047 vNewBmp
.SetMask(pNewMask
);
1049 ::GpiSetBitmap(hPS
, NULLHANDLE
);
1050 ::GpiDestroyPS(hPS
);
1054 return(wxNullBitmap
);
1055 } // end of wxDisableBitmap
1057 COLORREF
wxColourToRGB(
1058 const wxColour
& rColor
1061 return(OS2RGB(rColor
.Red(), rColor
.Green(), rColor
.Blue()));
1062 } // end of wxColourToRGB