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"
33 #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)
62 const wxString
& rSection
63 , const wxString
& rEntry
64 , const wxString
& rValue
65 , const wxString
& rFile
73 hIni
= ::PrfOpenProfile(hab
, (PSZ
)WXSTRINGCAST rFile
);
76 return (::PrfWriteProfileString( hIni
77 ,(PSZ
)WXSTRINGCAST rSection
78 ,(PSZ
)WXSTRINGCAST rEntry
79 ,(PSZ
)WXSTRINGCAST rValue
84 return (::PrfWriteProfileString( HINI_PROFILE
85 ,(PSZ
)WXSTRINGCAST rSection
86 ,(PSZ
)WXSTRINGCAST rEntry
87 ,(PSZ
)WXSTRINGCAST rValue
93 const wxString
& rSection
94 , const wxString
& rEntry
96 , const wxString
& rFile
101 wxSprintf(zBuf
, "%.4f", fValue
);
102 return wxWriteResource( rSection
109 bool wxWriteResource(
110 const wxString
& rSection
111 , const wxString
& rEntry
113 , const wxString
& rFile
118 wxSprintf(zBuf
, "%ld", lValue
);
119 return wxWriteResource( rSection
126 bool wxWriteResource(
127 const wxString
& rSection
128 , const wxString
& rEntry
130 , const wxString
& rFile
135 wxSprintf(zBuf
, "%d", lValue
);
136 return wxWriteResource( rSection
144 const wxString
& rSection
145 , const wxString
& rEntry
147 , const wxString
& rFile
152 wxChar zDefunkt
[] = _T("$$default");
157 hIni
= ::PrfOpenProfile(hab
, (PSZ
)WXSTRINGCAST rFile
);
160 ULONG n
= ::PrfQueryProfileString( hIni
161 ,(PSZ
)WXSTRINGCAST rSection
162 ,(PSZ
)WXSTRINGCAST rEntry
169 if (n
== 0L || wxStrcmp(zBuf
, zDefunkt
) == 0)
178 ULONG n
= ::PrfQueryProfileString( HINI_PROFILE
179 ,(PSZ
)WXSTRINGCAST rSection
180 ,(PSZ
)WXSTRINGCAST rEntry
187 if (n
== 0L || wxStrcmp(zBuf
, zDefunkt
) == 0)
191 strcpy((char*)*ppValue
, zBuf
);
196 const wxString
& rSection
197 , const wxString
& rEntry
199 , const wxString
& rFile
204 zStr
= new wxChar
[1000];
205 bool bSucc
= wxGetResource( rSection
213 *pValue
= (float)wxStrtod(zStr
, NULL
);
225 const wxString
& rSection
226 , const wxString
& rEntry
228 , const wxString
& rFile
233 zStr
= new wxChar
[1000];
234 bool bSucc
= wxGetResource( rSection
242 *pValue
= wxStrtol(zStr
, NULL
, 10);
254 const wxString
& rSection
255 , const wxString
& rEntry
257 , const wxString
& rFile
262 zStr
= new wxChar
[1000];
263 bool bSucc
= wxGetResource( rSection
271 *pValue
= (int)wxStrtol(zStr
, NULL
, 10);
281 #endif // wxUSE_RESOURCES
283 // ---------------------------------------------------------------------------
284 // helper functions for showing a "busy" cursor
285 // ---------------------------------------------------------------------------
287 HCURSOR gs_wxBusyCursor
= 0; // new, busy cursor
288 HCURSOR gs_wxBusyCursorOld
= 0; // old cursor
289 static int gs_wxBusyCursorCount
= 0;
291 // Set the cursor to the busy cursor for all windows
292 void wxBeginBusyCursor(const wxCursor
* pCursor
)
294 if ( gs_wxBusyCursorCount
++ == 0 )
296 gs_wxBusyCursor
= (HCURSOR
)pCursor
->GetHCURSOR();
297 ::WinSetPointer(HWND_DESKTOP
, (HPOINTER
)gs_wxBusyCursor
);
299 //else: nothing to do, already set
302 // Restore cursor to normal
303 void wxEndBusyCursor()
305 wxCHECK_RET( gs_wxBusyCursorCount
> 0
306 ,_T("no matching wxBeginBusyCursor() for wxEndBusyCursor()")
309 if (--gs_wxBusyCursorCount
== 0)
311 ::WinSetPointer(HWND_DESKTOP
, (HPOINTER
)gs_wxBusyCursorOld
);
312 gs_wxBusyCursorOld
= 0;
316 // TRUE if we're between the above two calls
319 return (gs_wxBusyCursorCount
> 0);
322 // Check whether this window wants to process messages, e.g. Stop button
323 // in long calculations.
324 bool wxCheckForInterrupt(
332 HWND hwndFilter
= NULLHANDLE
;
334 while(::WinPeekMsg(hab
, &vMsg
, hwndFilter
, 0, 0, PM_REMOVE
))
336 ::WinDispatchMsg(hab
, &vMsg
);
338 return TRUE
;//*** temporary?
342 wxFAIL_MSG(_T("pWnd==NULL !!!"));
343 return FALSE
;//*** temporary?
347 // ----------------------------------------------------------------------------
349 // ----------------------------------------------------------------------------
351 // See also the wxGetMousePosition in window.cpp
352 // Deprecated: use wxPoint wxGetMousePosition() instead
353 void wxGetMousePosition(
360 ::WinQueryPointerPos(HWND_DESKTOP
, &vPt
);
365 // Return TRUE if we have a colour display
366 bool wxColourDisplay()
373 hpsScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
374 hdcScreen
= ::GpiQueryDevice(hpsScreen
);
375 ::DevQueryCaps(hdcScreen
, CAPS_COLORS
, 1L, &lColors
);
376 return(lColors
> 1L);
378 // I don't see how the PM display could not be color. Besides, this
379 // was leaking DCs and PSs!!! MN
384 // Returns depth of screen
391 static LONG nDepth
= 0;
393 // The screen colordepth ain't gonna change. No reason to query
396 hpsScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
397 hdcScreen
= ::GpiQueryDevice(hpsScreen
);
398 ::DevQueryCaps(hdcScreen
, CAPS_COLOR_PLANES
, 1L, &lPlanes
);
399 ::DevQueryCaps(hdcScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitsPerPixel
);
401 nDepth
= (int)(lPlanes
* lBitsPerPixel
);
402 ::DevCloseDC(hdcScreen
);
403 ::WinReleasePS(hpsScreen
);
408 // Get size of display
416 static LONG lWidth
= 0;
417 static LONG lHeight
= 0;
419 // The screen size ain't gonna change either so just cache the values
421 hpsScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
422 hdcScreen
= ::GpiQueryDevice(hpsScreen
);
423 ::DevQueryCaps(hdcScreen
, CAPS_WIDTH
, 1L, &lWidth
);
424 ::DevQueryCaps(hdcScreen
, CAPS_HEIGHT
, 1L, &lHeight
);
425 ::DevCloseDC(hdcScreen
);
426 ::WinReleasePS(hpsScreen
);
429 *pWidth
= (int)lWidth
;
431 *pHeight
= (int)lHeight
;
434 void wxDisplaySizeMM(
442 hpsScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
443 hdcScreen
= ::GpiQueryDevice(hpsScreen
);
446 ::DevQueryCaps( hdcScreen
447 ,CAPS_HORIZONTAL_RESOLUTION
452 ::DevQueryCaps( hdcScreen
453 ,CAPS_VERTICAL_RESOLUTION
457 ::DevCloseDC(hdcScreen
);
458 ::WinReleasePS(hpsScreen
);
461 void wxClientDisplayRect(int *x
, int *y
, int *width
, int *height
)
463 // This is supposed to return desktop dimensions minus any window
464 // manager panels, menus, taskbars, etc. If there is a way to do that
465 // for this platform please fix this function, otherwise it defaults
466 // to the entire desktop.
469 wxDisplaySize(width
, height
);
472 void wxGUIAppTraits::InitializeGui(unsigned long &ulHab
)
474 ulHab
= ::WinInitialize(0);
477 void wxGUIAppTraits::TerminateGui(unsigned long ulHab
)
479 ::WinTerminate(ulHab
);
482 wxToolkitInfo
& wxGUIAppTraits::GetToolkitInfo()
484 static wxToolkitInfo vInfo
;
485 ULONG ulSysInfo
[QSV_MAX
] = {0};
488 vInfo
.shortName
= _T("PM");
489 vInfo
.name
= _T("wxOS2");
490 #ifdef __WXUNIVERSAL__
491 vInfo
.shortName
<< _T("univ");
492 vInfo
.name
<< _T("/wxUniversal");
494 ulrc
= ::DosQuerySysInfo( 1L
497 ,sizeof(ULONG
) * QSV_MAX
501 vInfo
.versionMajor
= ulSysInfo
[QSV_VERSION_MAJOR
] / 10;
502 vInfo
.versionMinor
= ulSysInfo
[QSV_VERSION_MINOR
];
508 // ---------------------------------------------------------------------------
509 // window information functions
510 // ---------------------------------------------------------------------------
512 wxString WXDLLEXPORT
wxGetWindowText( WXHWND hWnd
)
518 long lLen
= ::WinQueryWindowTextLength((HWND
)hWnd
) + 1;
519 ::WinQueryWindowText((HWND
)hWnd
, lLen
, (PSZ
)(wxChar
*)wxStringBuffer(vStr
, lLen
));
525 wxString WXDLLEXPORT
wxGetWindowClass( WXHWND hWnd
)
530 int nLen
= 256; // some starting value
534 int nCount
= ::WinQueryClassName((HWND
)hWnd
, nLen
, (PSZ
)(wxChar
*)wxStringBuffer(vStr
, nLen
));
538 // the class name might have been truncated, retry with larger
551 WXWORD WXDLLEXPORT
wxGetWindowId(
555 return ::WinQueryWindowUShort((HWND
)hWnd
, QWS_ID
);
566 vPoint
[0].x
= rRect
.xLeft
;
567 vPoint
[0].y
= rRect
.yBottom
;
568 ::GpiMove(hPS
, &vPoint
[0]);
569 if (dwStyle
& wxSIMPLE_BORDER
||
570 dwStyle
& wxSTATIC_BORDER
)
572 vPoint
[1].x
= rRect
.xRight
- 1;
573 vPoint
[1].y
= rRect
.yTop
- 1;
581 if (dwStyle
& wxSUNKEN_BORDER
)
583 LINEBUNDLE vLineBundle
;
585 vLineBundle
.lColor
= 0x00FFFFFF; // WHITE
586 vLineBundle
.usMixMode
= FM_OVERPAINT
;
587 vLineBundle
.fxWidth
= 2;
588 vLineBundle
.lGeomWidth
= 2;
589 vLineBundle
.usType
= LINETYPE_SOLID
;
590 vLineBundle
.usEnd
= 0;
591 vLineBundle
.usJoin
= 0;
594 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
598 vPoint
[1].x
= rRect
.xRight
- 1;
599 vPoint
[1].y
= rRect
.yTop
- 1;
606 vPoint
[0].x
= rRect
.xLeft
+ 1;
607 vPoint
[0].y
= rRect
.yBottom
+ 1;
608 ::GpiMove(hPS
, &vPoint
[0]);
609 vPoint
[1].x
= rRect
.xRight
- 2;
610 vPoint
[1].y
= rRect
.yTop
- 2;
618 vLineBundle
.lColor
= 0x00000000; // BLACK
619 vLineBundle
.usMixMode
= FM_OVERPAINT
;
620 vLineBundle
.fxWidth
= 2;
621 vLineBundle
.lGeomWidth
= 2;
622 vLineBundle
.usType
= LINETYPE_SOLID
;
623 vLineBundle
.usEnd
= 0;
624 vLineBundle
.usJoin
= 0;
627 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
631 vPoint
[0].x
= rRect
.xLeft
+ 2;
632 vPoint
[0].y
= rRect
.yBottom
+ 2;
633 ::GpiMove(hPS
, &vPoint
[0]);
634 vPoint
[1].x
= rRect
.xLeft
+ 2;
635 vPoint
[1].y
= rRect
.yTop
- 3;
636 ::GpiLine(hPS
, &vPoint
[1]);
637 vPoint
[1].x
= rRect
.xRight
- 3;
638 vPoint
[1].y
= rRect
.yTop
- 3;
639 ::GpiLine(hPS
, &vPoint
[1]);
641 vPoint
[0].x
= rRect
.xLeft
+ 3;
642 vPoint
[0].y
= rRect
.yBottom
+ 3;
643 ::GpiMove(hPS
, &vPoint
[0]);
644 vPoint
[1].x
= rRect
.xLeft
+ 3;
645 vPoint
[1].y
= rRect
.yTop
- 4;
646 ::GpiLine(hPS
, &vPoint
[1]);
647 vPoint
[1].x
= rRect
.xRight
- 4;
648 vPoint
[1].y
= rRect
.yTop
- 4;
649 ::GpiLine(hPS
, &vPoint
[1]);
651 if (dwStyle
& wxDOUBLE_BORDER
)
653 LINEBUNDLE vLineBundle
;
655 vLineBundle
.lColor
= 0x00FFFFFF; // WHITE
656 vLineBundle
.usMixMode
= FM_OVERPAINT
;
657 vLineBundle
.fxWidth
= 2;
658 vLineBundle
.lGeomWidth
= 2;
659 vLineBundle
.usType
= LINETYPE_SOLID
;
660 vLineBundle
.usEnd
= 0;
661 vLineBundle
.usJoin
= 0;
664 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
668 vPoint
[1].x
= rRect
.xRight
- 1;
669 vPoint
[1].y
= rRect
.yTop
- 1;
676 vLineBundle
.lColor
= 0x00000000; // WHITE
677 vLineBundle
.usMixMode
= FM_OVERPAINT
;
678 vLineBundle
.fxWidth
= 2;
679 vLineBundle
.lGeomWidth
= 2;
680 vLineBundle
.usType
= LINETYPE_SOLID
;
681 vLineBundle
.usEnd
= 0;
682 vLineBundle
.usJoin
= 0;
685 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
689 vPoint
[0].x
= rRect
.xLeft
+ 2;
690 vPoint
[0].y
= rRect
.yBottom
+ 2;
691 ::GpiMove(hPS
, &vPoint
[0]);
692 vPoint
[1].x
= rRect
.xRight
- 2;
693 vPoint
[1].y
= rRect
.yTop
- 2;
700 vLineBundle
.lColor
= 0x00FFFFFF; // BLACK
701 vLineBundle
.usMixMode
= FM_OVERPAINT
;
702 vLineBundle
.fxWidth
= 2;
703 vLineBundle
.lGeomWidth
= 2;
704 vLineBundle
.usType
= LINETYPE_SOLID
;
705 vLineBundle
.usEnd
= 0;
706 vLineBundle
.usJoin
= 0;
709 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
713 vPoint
[0].x
= rRect
.xLeft
+ 3;
714 vPoint
[0].y
= rRect
.yBottom
+ 3;
715 ::GpiMove(hPS
, &vPoint
[0]);
716 vPoint
[1].x
= rRect
.xRight
- 3;
717 vPoint
[1].y
= rRect
.yTop
- 3;
725 if (dwStyle
& wxRAISED_BORDER
)
727 LINEBUNDLE vLineBundle
;
729 vLineBundle
.lColor
= 0x00000000; // BLACK
730 vLineBundle
.usMixMode
= FM_OVERPAINT
;
731 vLineBundle
.fxWidth
= 2;
732 vLineBundle
.lGeomWidth
= 2;
733 vLineBundle
.usType
= LINETYPE_SOLID
;
734 vLineBundle
.usEnd
= 0;
735 vLineBundle
.usJoin
= 0;
738 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
742 vPoint
[1].x
= rRect
.xRight
- 1;
743 vPoint
[1].y
= rRect
.yTop
- 1;
750 vPoint
[0].x
= rRect
.xLeft
+ 1;
751 vPoint
[0].y
= rRect
.yBottom
+ 1;
752 ::GpiMove(hPS
, &vPoint
[0]);
753 vPoint
[1].x
= rRect
.xRight
- 2;
754 vPoint
[1].y
= rRect
.yTop
- 2;
762 vLineBundle
.lColor
= 0x00FFFFFF; // WHITE
763 vLineBundle
.usMixMode
= FM_OVERPAINT
;
764 vLineBundle
.fxWidth
= 2;
765 vLineBundle
.lGeomWidth
= 2;
766 vLineBundle
.usType
= LINETYPE_SOLID
;
767 vLineBundle
.usEnd
= 0;
768 vLineBundle
.usJoin
= 0;
771 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
775 vPoint
[0].x
= rRect
.xLeft
+ 2;
776 vPoint
[0].y
= rRect
.yBottom
+ 2;
777 ::GpiMove(hPS
, &vPoint
[0]);
778 vPoint
[1].x
= rRect
.xLeft
+ 2;
779 vPoint
[1].y
= rRect
.yTop
- 3;
780 ::GpiLine(hPS
, &vPoint
[1]);
781 vPoint
[1].x
= rRect
.xRight
- 3;
782 vPoint
[1].y
= rRect
.yTop
- 3;
783 ::GpiLine(hPS
, &vPoint
[1]);
785 vPoint
[0].x
= rRect
.xLeft
+ 3;
786 vPoint
[0].y
= rRect
.yBottom
+ 3;
787 ::GpiMove(hPS
, &vPoint
[0]);
788 vPoint
[1].x
= rRect
.xLeft
+ 3;
789 vPoint
[1].y
= rRect
.yTop
- 4;
790 ::GpiLine(hPS
, &vPoint
[1]);
791 vPoint
[1].x
= rRect
.xRight
- 4;
792 vPoint
[1].y
= rRect
.yTop
- 4;
793 ::GpiLine(hPS
, &vPoint
[1]);
795 } // end of wxDrawBorder
799 , const wxFont
& rFont
807 if (hWnd
== NULLHANDLE
)
811 // The fonts available for Presentation Params are just a few
812 // outline fonts, the rest are available to the GPI, so we must
813 // map the families to one of these three
815 switch(rFont
.GetFamily())
818 strcpy(zFacename
, "Script");
822 strcpy(zFacename
, "WarpSans");
826 strcpy(zFacename
,"Times New Roman");
830 strcpy(zFacename
, "Courier New");
834 strcpy(zFacename
, "Courier New");
840 strcpy(zFacename
, "Helvetica");
844 switch(rFont
.GetWeight())
853 case wxFONTWEIGHT_MAX
:
854 strcpy(zWeight
, "Bold");
858 switch(rFont
.GetStyle())
862 strcpy(zStyle
, "Italic");
869 sprintf(zFont
, "%d.%s", rFont
.GetPointSize(), zFacename
);
870 if (zWeight
[0] != '\0')
873 strcat(zFont
, zWeight
);
875 if (zStyle
[0] != '\0')
878 strcat(zFont
, zStyle
);
880 ::WinSetPresParam(hWnd
, PP_FONTNAMESIZE
, strlen(zFont
) + 1, (PVOID
)zFont
);
881 } // end of wxOS2SetFont
883 // ---------------------------------------------------------------------------
884 // Helper for taking a regular bitmap and giving it a disabled look
885 // ---------------------------------------------------------------------------
886 wxBitmap
wxDisableBitmap(
891 wxMask
* pMask
= rBmp
.GetMask();
894 return(wxNullBitmap
);
896 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
897 SIZEL vSize
= {0, 0};
898 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
899 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
900 BITMAPINFOHEADER2 vHeader
;
904 HBITMAP hBitmap
= (HBITMAP
)rBmp
.GetHBITMAP();
905 HBITMAP hOldBitmap
= NULLHANDLE
;
906 HBITMAP hOldMask
= NULLHANDLE
;
907 HBITMAP hMask
= (HBITMAP
)rBmp
.GetMask()->GetMaskBitmap();
908 unsigned char* pucBits
; // buffer that will contain the bitmap data
909 unsigned char* pucData
; // pointer to use to traverse bitmap data
910 unsigned char* pucBitsMask
; // buffer that will contain the mask data
911 unsigned char* pucDataMask
; // pointer to use to traverse mask data
914 bool bpp16
= (wxDisplayDepth() == 16);
916 memset(&vHeader
, '\0', 16);
919 memset(&vInfo
, '\0', 16);
921 vInfo
.cx
= (ULONG
)rBmp
.GetWidth();
922 vInfo
.cy
= (ULONG
)rBmp
.GetHeight();
924 vInfo
.cBitCount
= 24; // Set to desired count going in
927 // Create the buffers for data....all wxBitmaps are 24 bit internally
929 int nBytesPerLine
= rBmp
.GetWidth() * 3;
930 int nSizeDWORD
= sizeof(DWORD
);
931 int nLineBoundary
= nBytesPerLine
% nSizeDWORD
;
937 // Bitmap must be in a double-word aligned address so we may
938 // have some padding to worry about
940 if (nLineBoundary
> 0)
942 nPadding
= nSizeDWORD
- nLineBoundary
;
943 nBytesPerLine
+= nPadding
;
945 pucBits
= (unsigned char *)malloc(nBytesPerLine
* rBmp
.GetHeight());
946 memset(pucBits
, '\0', (nBytesPerLine
* rBmp
.GetHeight()));
947 pucBitsMask
= (unsigned char *)malloc(nBytesPerLine
* rBmp
.GetHeight());
948 memset(pucBitsMask
, '\0', (nBytesPerLine
* rBmp
.GetHeight()));
951 // Extract the bitmap and mask data
953 if ((hOldBitmap
= ::GpiSetBitmap(hPS
, hBitmap
)) == HBM_ERROR
)
955 vError
= ::WinGetLastError(vHabmain
);
956 sError
= wxPMErrorToStr(vError
);
958 ::GpiQueryBitmapInfoHeader(hBitmap
, &vHeader
);
959 vInfo
.cBitCount
= 24;
960 if ((lScans
= ::GpiQueryBitmapBits( hPS
962 ,(LONG
)rBmp
.GetHeight()
967 vError
= ::WinGetLastError(vHabmain
);
968 sError
= wxPMErrorToStr(vError
);
970 if ((hOldMask
= ::GpiSetBitmap(hPS
, hMask
)) == HBM_ERROR
)
972 vError
= ::WinGetLastError(vHabmain
);
973 sError
= wxPMErrorToStr(vError
);
975 ::GpiQueryBitmapInfoHeader(hMask
, &vHeader
);
976 vInfo
.cBitCount
= 24;
977 if ((lScans
= ::GpiQueryBitmapBits( hPS
979 ,(LONG
)rBmp
.GetHeight()
984 vError
= ::WinGetLastError(vHabmain
);
985 sError
= wxPMErrorToStr(vError
);
987 if (( hMask
= ::GpiSetBitmap(hPS
, hOldMask
)) == HBM_ERROR
)
989 vError
= ::WinGetLastError(vHabmain
);
990 sError
= wxPMErrorToStr(vError
);
993 pucDataMask
= pucBitsMask
;
996 // Get the mask value
998 for (i
= 0; i
< rBmp
.GetHeight(); i
++)
1000 for (j
= 0; j
< rBmp
.GetWidth(); j
++)
1003 if (bpp16
&& *pucDataMask
== 0xF8) // 16 bit display gobblygook
1008 else if (*pucDataMask
== 0xFF) // set to grey
1015 *pucData
= ((unsigned char)(lColor
>> 16));
1020 if (bpp16
&& *(pucDataMask
+ 1) == 0xFC) // 16 bit display gobblygook
1025 else if (*(pucDataMask
+ 1) == 0xFF) // set to grey
1032 *pucData
= ((unsigned char)(lColor
>> 8));
1037 if (bpp16
&& *(pucDataMask
+ 2) == 0xF8) // 16 bit display gobblygook
1042 else if (*(pucDataMask
+ 2) == 0xFF) // set to grey
1049 *pucData
= ((unsigned char)lColor
);
1054 for (j
= 0; j
< nPadding
; j
++)
1062 // Create a new bitmap and set the modified bits
1064 wxBitmap
vNewBmp( rBmp
.GetWidth()
1068 HBITMAP hNewBmp
= (HBITMAP
)vNewBmp
.GetHBITMAP();
1070 if ((hOldBitmap
= ::GpiSetBitmap(hPS
, hNewBmp
)) == HBM_ERROR
)
1072 vError
= ::WinGetLastError(vHabmain
);
1073 sError
= wxPMErrorToStr(vError
);
1075 if ((lScansSet
= ::GpiSetBitmapBits( hPS
1077 ,(LONG
)rBmp
.GetHeight()
1083 vError
= ::WinGetLastError(vHabmain
);
1084 sError
= wxPMErrorToStr(vError
);
1088 pNewMask
= new wxMask(pMask
->GetMaskBitmap());
1089 vNewBmp
.SetMask(pNewMask
);
1091 ::GpiSetBitmap(hPS
, NULLHANDLE
);
1092 ::GpiDestroyPS(hPS
);
1096 return(wxNullBitmap
);
1097 } // end of wxDisableBitmap
1099 COLORREF
wxColourToRGB(
1100 const wxColour
& rColor
1103 return(OS2RGB(rColor
.Red(), rColor
.Green(), rColor
.Blue()));
1104 } // end of wxColourToRGB