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(
521 long lLen
= ::WinQueryWindowTextLength((HWND
)hWnd
) + 1;
522 ::WinQueryWindowText((HWND
)hWnd
, lLen
, (PSZ
)(wxChar
*)wxStringBuffer(vStr
, lLen
));
528 wxString WXDLLEXPORT
wxGetWindowClass(
535 int nLen
= 256; // some starting value
539 int nCount
= ::WinQueryClassName((HWND
)hWnd
, nLen
, (PSZ
)(wxChar
*)wxStringBuffer(vStr
, nLen
));
543 // the class name might have been truncated, retry with larger
556 WXWORD WXDLLEXPORT
wxGetWindowId(
560 return ::WinQueryWindowUShort((HWND
)hWnd
, QWS_ID
);
571 vPoint
[0].x
= rRect
.xLeft
;
572 vPoint
[0].y
= rRect
.yBottom
;
573 ::GpiMove(hPS
, &vPoint
[0]);
574 if (dwStyle
& wxSIMPLE_BORDER
||
575 dwStyle
& wxSTATIC_BORDER
)
577 vPoint
[1].x
= rRect
.xRight
- 1;
578 vPoint
[1].y
= rRect
.yTop
- 1;
586 if (dwStyle
& wxSUNKEN_BORDER
)
588 LINEBUNDLE vLineBundle
;
590 vLineBundle
.lColor
= 0x00FFFFFF; // WHITE
591 vLineBundle
.usMixMode
= FM_OVERPAINT
;
592 vLineBundle
.fxWidth
= 2;
593 vLineBundle
.lGeomWidth
= 2;
594 vLineBundle
.usType
= LINETYPE_SOLID
;
595 vLineBundle
.usEnd
= 0;
596 vLineBundle
.usJoin
= 0;
599 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
603 vPoint
[1].x
= rRect
.xRight
- 1;
604 vPoint
[1].y
= rRect
.yTop
- 1;
611 vPoint
[0].x
= rRect
.xLeft
+ 1;
612 vPoint
[0].y
= rRect
.yBottom
+ 1;
613 ::GpiMove(hPS
, &vPoint
[0]);
614 vPoint
[1].x
= rRect
.xRight
- 2;
615 vPoint
[1].y
= rRect
.yTop
- 2;
623 vLineBundle
.lColor
= 0x00000000; // BLACK
624 vLineBundle
.usMixMode
= FM_OVERPAINT
;
625 vLineBundle
.fxWidth
= 2;
626 vLineBundle
.lGeomWidth
= 2;
627 vLineBundle
.usType
= LINETYPE_SOLID
;
628 vLineBundle
.usEnd
= 0;
629 vLineBundle
.usJoin
= 0;
632 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
636 vPoint
[0].x
= rRect
.xLeft
+ 2;
637 vPoint
[0].y
= rRect
.yBottom
+ 2;
638 ::GpiMove(hPS
, &vPoint
[0]);
639 vPoint
[1].x
= rRect
.xLeft
+ 2;
640 vPoint
[1].y
= rRect
.yTop
- 3;
641 ::GpiLine(hPS
, &vPoint
[1]);
642 vPoint
[1].x
= rRect
.xRight
- 3;
643 vPoint
[1].y
= rRect
.yTop
- 3;
644 ::GpiLine(hPS
, &vPoint
[1]);
646 vPoint
[0].x
= rRect
.xLeft
+ 3;
647 vPoint
[0].y
= rRect
.yBottom
+ 3;
648 ::GpiMove(hPS
, &vPoint
[0]);
649 vPoint
[1].x
= rRect
.xLeft
+ 3;
650 vPoint
[1].y
= rRect
.yTop
- 4;
651 ::GpiLine(hPS
, &vPoint
[1]);
652 vPoint
[1].x
= rRect
.xRight
- 4;
653 vPoint
[1].y
= rRect
.yTop
- 4;
654 ::GpiLine(hPS
, &vPoint
[1]);
656 if (dwStyle
& wxDOUBLE_BORDER
)
658 LINEBUNDLE vLineBundle
;
660 vLineBundle
.lColor
= 0x00FFFFFF; // WHITE
661 vLineBundle
.usMixMode
= FM_OVERPAINT
;
662 vLineBundle
.fxWidth
= 2;
663 vLineBundle
.lGeomWidth
= 2;
664 vLineBundle
.usType
= LINETYPE_SOLID
;
665 vLineBundle
.usEnd
= 0;
666 vLineBundle
.usJoin
= 0;
669 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
673 vPoint
[1].x
= rRect
.xRight
- 1;
674 vPoint
[1].y
= rRect
.yTop
- 1;
681 vLineBundle
.lColor
= 0x00000000; // WHITE
682 vLineBundle
.usMixMode
= FM_OVERPAINT
;
683 vLineBundle
.fxWidth
= 2;
684 vLineBundle
.lGeomWidth
= 2;
685 vLineBundle
.usType
= LINETYPE_SOLID
;
686 vLineBundle
.usEnd
= 0;
687 vLineBundle
.usJoin
= 0;
690 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
694 vPoint
[0].x
= rRect
.xLeft
+ 2;
695 vPoint
[0].y
= rRect
.yBottom
+ 2;
696 ::GpiMove(hPS
, &vPoint
[0]);
697 vPoint
[1].x
= rRect
.xRight
- 2;
698 vPoint
[1].y
= rRect
.yTop
- 2;
705 vLineBundle
.lColor
= 0x00FFFFFF; // BLACK
706 vLineBundle
.usMixMode
= FM_OVERPAINT
;
707 vLineBundle
.fxWidth
= 2;
708 vLineBundle
.lGeomWidth
= 2;
709 vLineBundle
.usType
= LINETYPE_SOLID
;
710 vLineBundle
.usEnd
= 0;
711 vLineBundle
.usJoin
= 0;
714 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
718 vPoint
[0].x
= rRect
.xLeft
+ 3;
719 vPoint
[0].y
= rRect
.yBottom
+ 3;
720 ::GpiMove(hPS
, &vPoint
[0]);
721 vPoint
[1].x
= rRect
.xRight
- 3;
722 vPoint
[1].y
= rRect
.yTop
- 3;
730 if (dwStyle
& wxRAISED_BORDER
)
732 LINEBUNDLE vLineBundle
;
734 vLineBundle
.lColor
= 0x00000000; // BLACK
735 vLineBundle
.usMixMode
= FM_OVERPAINT
;
736 vLineBundle
.fxWidth
= 2;
737 vLineBundle
.lGeomWidth
= 2;
738 vLineBundle
.usType
= LINETYPE_SOLID
;
739 vLineBundle
.usEnd
= 0;
740 vLineBundle
.usJoin
= 0;
743 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
747 vPoint
[1].x
= rRect
.xRight
- 1;
748 vPoint
[1].y
= rRect
.yTop
- 1;
755 vPoint
[0].x
= rRect
.xLeft
+ 1;
756 vPoint
[0].y
= rRect
.yBottom
+ 1;
757 ::GpiMove(hPS
, &vPoint
[0]);
758 vPoint
[1].x
= rRect
.xRight
- 2;
759 vPoint
[1].y
= rRect
.yTop
- 2;
767 vLineBundle
.lColor
= 0x00FFFFFF; // WHITE
768 vLineBundle
.usMixMode
= FM_OVERPAINT
;
769 vLineBundle
.fxWidth
= 2;
770 vLineBundle
.lGeomWidth
= 2;
771 vLineBundle
.usType
= LINETYPE_SOLID
;
772 vLineBundle
.usEnd
= 0;
773 vLineBundle
.usJoin
= 0;
776 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
780 vPoint
[0].x
= rRect
.xLeft
+ 2;
781 vPoint
[0].y
= rRect
.yBottom
+ 2;
782 ::GpiMove(hPS
, &vPoint
[0]);
783 vPoint
[1].x
= rRect
.xLeft
+ 2;
784 vPoint
[1].y
= rRect
.yTop
- 3;
785 ::GpiLine(hPS
, &vPoint
[1]);
786 vPoint
[1].x
= rRect
.xRight
- 3;
787 vPoint
[1].y
= rRect
.yTop
- 3;
788 ::GpiLine(hPS
, &vPoint
[1]);
790 vPoint
[0].x
= rRect
.xLeft
+ 3;
791 vPoint
[0].y
= rRect
.yBottom
+ 3;
792 ::GpiMove(hPS
, &vPoint
[0]);
793 vPoint
[1].x
= rRect
.xLeft
+ 3;
794 vPoint
[1].y
= rRect
.yTop
- 4;
795 ::GpiLine(hPS
, &vPoint
[1]);
796 vPoint
[1].x
= rRect
.xRight
- 4;
797 vPoint
[1].y
= rRect
.yTop
- 4;
798 ::GpiLine(hPS
, &vPoint
[1]);
800 } // end of wxDrawBorder
804 , const wxFont
& rFont
812 if (hWnd
== NULLHANDLE
)
816 // The fonts available for Presentation Params are just a few
817 // outline fonts, the rest are available to the GPI, so we must
818 // map the families to one of these three
820 switch(rFont
.GetFamily())
823 strcpy(zFacename
, "Script");
827 strcpy(zFacename
, "WarpSans");
831 strcpy(zFacename
,"Times New Roman");
835 strcpy(zFacename
, "Courier New");
839 strcpy(zFacename
, "Courier New");
845 strcpy(zFacename
, "Helvetica");
849 switch(rFont
.GetWeight())
858 case wxFONTWEIGHT_MAX
:
859 strcpy(zWeight
, "Bold");
863 switch(rFont
.GetStyle())
867 strcpy(zStyle
, "Italic");
874 sprintf(zFont
, "%d.%s", rFont
.GetPointSize(), zFacename
);
875 if (zWeight
[0] != '\0')
878 strcat(zFont
, zWeight
);
880 if (zStyle
[0] != '\0')
883 strcat(zFont
, zStyle
);
885 ::WinSetPresParam(hWnd
, PP_FONTNAMESIZE
, strlen(zFont
) + 1, (PVOID
)zFont
);
886 } // end of wxOS2SetFont
888 // ---------------------------------------------------------------------------
889 // Helper for taking a regular bitmap and giving it a disabled look
890 // ---------------------------------------------------------------------------
891 wxBitmap
wxDisableBitmap(
896 wxMask
* pMask
= rBmp
.GetMask();
899 return(wxNullBitmap
);
901 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
902 SIZEL vSize
= {0, 0};
903 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
904 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
905 BITMAPINFOHEADER2 vHeader
;
909 HBITMAP hBitmap
= (HBITMAP
)rBmp
.GetHBITMAP();
910 HBITMAP hOldBitmap
= NULLHANDLE
;
911 HBITMAP hOldMask
= NULLHANDLE
;
912 HBITMAP hMask
= (HBITMAP
)rBmp
.GetMask()->GetMaskBitmap();
913 unsigned char* pucBits
; // buffer that will contain the bitmap data
914 unsigned char* pucData
; // pointer to use to traverse bitmap data
915 unsigned char* pucBitsMask
; // buffer that will contain the mask data
916 unsigned char* pucDataMask
; // pointer to use to traverse mask data
919 bool bpp16
= (wxDisplayDepth() == 16);
921 memset(&vHeader
, '\0', 16);
924 memset(&vInfo
, '\0', 16);
926 vInfo
.cx
= (ULONG
)rBmp
.GetWidth();
927 vInfo
.cy
= (ULONG
)rBmp
.GetHeight();
929 vInfo
.cBitCount
= 24; // Set to desired count going in
932 // Create the buffers for data....all wxBitmaps are 24 bit internally
934 int nBytesPerLine
= rBmp
.GetWidth() * 3;
935 int nSizeDWORD
= sizeof(DWORD
);
936 int nLineBoundary
= nBytesPerLine
% nSizeDWORD
;
942 // Bitmap must be ina double-word alligned address so we may
943 // have some padding to worry about
945 if (nLineBoundary
> 0)
947 nPadding
= nSizeDWORD
- nLineBoundary
;
948 nBytesPerLine
+= nPadding
;
950 pucBits
= (unsigned char *)malloc(nBytesPerLine
* rBmp
.GetHeight());
951 memset(pucBits
, '\0', (nBytesPerLine
* rBmp
.GetHeight()));
952 pucBitsMask
= (unsigned char *)malloc(nBytesPerLine
* rBmp
.GetHeight());
953 memset(pucBitsMask
, '\0', (nBytesPerLine
* rBmp
.GetHeight()));
956 // Extract the bitmap and mask data
958 if ((hOldBitmap
= ::GpiSetBitmap(hPS
, hBitmap
)) == HBM_ERROR
)
960 vError
= ::WinGetLastError(vHabmain
);
961 sError
= wxPMErrorToStr(vError
);
963 ::GpiQueryBitmapInfoHeader(hBitmap
, &vHeader
);
964 vInfo
.cBitCount
= 24;
965 if ((lScans
= ::GpiQueryBitmapBits( hPS
967 ,(LONG
)rBmp
.GetHeight()
972 vError
= ::WinGetLastError(vHabmain
);
973 sError
= wxPMErrorToStr(vError
);
975 if ((hOldMask
= ::GpiSetBitmap(hPS
, hMask
)) == HBM_ERROR
)
977 vError
= ::WinGetLastError(vHabmain
);
978 sError
= wxPMErrorToStr(vError
);
980 ::GpiQueryBitmapInfoHeader(hMask
, &vHeader
);
981 vInfo
.cBitCount
= 24;
982 if ((lScans
= ::GpiQueryBitmapBits( hPS
984 ,(LONG
)rBmp
.GetHeight()
989 vError
= ::WinGetLastError(vHabmain
);
990 sError
= wxPMErrorToStr(vError
);
992 if (( hMask
= ::GpiSetBitmap(hPS
, hOldMask
)) == HBM_ERROR
)
994 vError
= ::WinGetLastError(vHabmain
);
995 sError
= wxPMErrorToStr(vError
);
998 pucDataMask
= pucBitsMask
;
1001 // Get the mask value
1003 for (i
= 0; i
< rBmp
.GetHeight(); i
++)
1005 for (j
= 0; j
< rBmp
.GetWidth(); j
++)
1008 if (bpp16
&& *pucDataMask
== 0xF8) // 16 bit display gobblygook
1013 else if (*pucDataMask
== 0xFF) // set to grey
1020 *pucData
= ((unsigned char)(lColor
>> 16));
1025 if (bpp16
&& *(pucDataMask
+ 1) == 0xFC) // 16 bit display gobblygook
1030 else if (*(pucDataMask
+ 1) == 0xFF) // set to grey
1037 *pucData
= ((unsigned char)(lColor
>> 8));
1042 if (bpp16
&& *(pucDataMask
+ 2) == 0xF8) // 16 bit display gobblygook
1047 else if (*(pucDataMask
+ 2) == 0xFF) // set to grey
1054 *pucData
= ((unsigned char)lColor
);
1059 for (j
= 0; j
< nPadding
; j
++)
1067 // Create a new bitmap and set the modified bits
1069 wxBitmap
vNewBmp( rBmp
.GetWidth()
1073 HBITMAP hNewBmp
= (HBITMAP
)vNewBmp
.GetHBITMAP();
1075 if ((hOldBitmap
= ::GpiSetBitmap(hPS
, hNewBmp
)) == HBM_ERROR
)
1077 vError
= ::WinGetLastError(vHabmain
);
1078 sError
= wxPMErrorToStr(vError
);
1080 if ((lScansSet
= ::GpiSetBitmapBits( hPS
1082 ,(LONG
)rBmp
.GetHeight()
1088 vError
= ::WinGetLastError(vHabmain
);
1089 sError
= wxPMErrorToStr(vError
);
1093 pNewMask
= new wxMask(pMask
->GetMaskBitmap());
1094 vNewBmp
.SetMask(pNewMask
);
1096 ::GpiSetBitmap(hPS
, NULLHANDLE
);
1097 ::GpiDestroyPS(hPS
);
1101 return(wxNullBitmap
);
1102 } // end of wxDisableBitmap
1104 COLORREF
wxColourToRGB(
1105 const wxColour
& rColor
1108 return(OS2RGB(rColor
.Red(), rColor
.Green(), rColor
.Blue()));
1109 } // end of wxColourToRGB