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 static wxTimer
* wxTheSleepTimer
= NULL
;
62 // Reading and writing resources (eg WIN.INI, .Xdefaults)
65 const wxString
& rSection
66 , const wxString
& rEntry
67 , const wxString
& rValue
68 , const wxString
& rFile
76 hIni
= ::PrfOpenProfile(hab
, (PSZ
)WXSTRINGCAST rFile
);
79 return (::PrfWriteProfileString( hIni
80 ,(PSZ
)WXSTRINGCAST rSection
81 ,(PSZ
)WXSTRINGCAST rEntry
82 ,(PSZ
)WXSTRINGCAST rValue
87 return (::PrfWriteProfileString( HINI_PROFILE
88 ,(PSZ
)WXSTRINGCAST rSection
89 ,(PSZ
)WXSTRINGCAST rEntry
90 ,(PSZ
)WXSTRINGCAST rValue
96 const wxString
& rSection
97 , const wxString
& rEntry
99 , const wxString
& rFile
104 wxSprintf(zBuf
, "%.4f", fValue
);
105 return wxWriteResource( rSection
112 bool wxWriteResource(
113 const wxString
& rSection
114 , const wxString
& rEntry
116 , const wxString
& rFile
121 wxSprintf(zBuf
, "%ld", lValue
);
122 return wxWriteResource( rSection
129 bool wxWriteResource(
130 const wxString
& rSection
131 , const wxString
& rEntry
133 , const wxString
& rFile
138 wxSprintf(zBuf
, "%d", lValue
);
139 return wxWriteResource( rSection
147 const wxString
& rSection
148 , const wxString
& rEntry
150 , const wxString
& rFile
155 wxChar zDefunkt
[] = _T("$$default");
160 hIni
= ::PrfOpenProfile(hab
, (PSZ
)WXSTRINGCAST rFile
);
163 ULONG n
= ::PrfQueryProfileString( hIni
164 ,(PSZ
)WXSTRINGCAST rSection
165 ,(PSZ
)WXSTRINGCAST rEntry
172 if (n
== 0L || wxStrcmp(zBuf
, zDefunkt
) == 0)
181 ULONG n
= ::PrfQueryProfileString( HINI_PROFILE
182 ,(PSZ
)WXSTRINGCAST rSection
183 ,(PSZ
)WXSTRINGCAST rEntry
190 if (n
== 0L || wxStrcmp(zBuf
, zDefunkt
) == 0)
194 strcpy((char*)*ppValue
, zBuf
);
199 const wxString
& rSection
200 , const wxString
& rEntry
202 , const wxString
& rFile
207 zStr
= new wxChar
[1000];
208 bool bSucc
= wxGetResource( rSection
216 *pValue
= (float)wxStrtod(zStr
, NULL
);
228 const wxString
& rSection
229 , const wxString
& rEntry
231 , const wxString
& rFile
236 zStr
= new wxChar
[1000];
237 bool bSucc
= wxGetResource( rSection
245 *pValue
= wxStrtol(zStr
, NULL
, 10);
257 const wxString
& rSection
258 , const wxString
& rEntry
260 , const wxString
& rFile
265 zStr
= new wxChar
[1000];
266 bool bSucc
= wxGetResource( rSection
274 *pValue
= (int)wxStrtol(zStr
, NULL
, 10);
284 #endif // wxUSE_RESOURCES
286 // ---------------------------------------------------------------------------
287 // helper functions for showing a "busy" cursor
288 // ---------------------------------------------------------------------------
290 HCURSOR gs_wxBusyCursor
= 0; // new, busy cursor
291 HCURSOR gs_wxBusyCursorOld
= 0; // old cursor
292 static int gs_wxBusyCursorCount
= 0;
294 // Set the cursor to the busy cursor for all windows
295 void wxBeginBusyCursor(
299 if ( gs_wxBusyCursorCount
++ == 0 )
301 gs_wxBusyCursor
= (HCURSOR
)pCursor
->GetHCURSOR();
302 ::WinSetPointer(HWND_DESKTOP
, (HPOINTER
)gs_wxBusyCursor
);
304 //else: nothing to do, already set
307 // Restore cursor to normal
308 void wxEndBusyCursor()
310 wxCHECK_RET( gs_wxBusyCursorCount
> 0
311 ,_T("no matching wxBeginBusyCursor() for wxEndBusyCursor()")
314 if (--gs_wxBusyCursorCount
== 0)
316 ::WinSetPointer(HWND_DESKTOP
, (HPOINTER
)gs_wxBusyCursorOld
);
317 gs_wxBusyCursorOld
= 0;
321 // TRUE if we're between the above two calls
324 return (gs_wxBusyCursorCount
> 0);
327 // Check whether this window wants to process messages, e.g. Stop button
328 // in long calculations.
329 bool wxCheckForInterrupt(
337 HWND hwndFilter
= NULLHANDLE
;
338 HWND hwndWin
= (HWND
) pWnd
->GetHWND();
340 while(::WinPeekMsg(hab
, &vMsg
, hwndFilter
, 0, 0, PM_REMOVE
))
342 ::WinDispatchMsg(hab
, &vMsg
);
344 return TRUE
;//*** temporary?
348 wxFAIL_MSG(_T("pWnd==NULL !!!"));
349 return FALSE
;//*** temporary?
353 // ----------------------------------------------------------------------------
355 // ----------------------------------------------------------------------------
357 // See also the wxGetMousePosition in window.cpp
358 // Deprecated: use wxPoint wxGetMousePosition() instead
359 void wxGetMousePosition(
366 ::WinQueryPointerPos(HWND_DESKTOP
, &vPt
);
371 // Return TRUE if we have a colour display
372 bool wxColourDisplay()
379 hpsScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
380 hdcScreen
= ::GpiQueryDevice(hpsScreen
);
381 ::DevQueryCaps(hdcScreen
, CAPS_COLORS
, 1L, &lColors
);
382 return(lColors
> 1L);
384 // I don't see how the PM display could not be color. Besides, this
385 // was leaking DCs and PSs!!! MN
390 // Returns depth of screen
397 static LONG nDepth
= 0;
399 // The screen colordepth ain't gonna change. No reason to query
402 hpsScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
403 hdcScreen
= ::GpiQueryDevice(hpsScreen
);
404 ::DevQueryCaps(hdcScreen
, CAPS_COLOR_PLANES
, 1L, &lPlanes
);
405 ::DevQueryCaps(hdcScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitsPerPixel
);
407 nDepth
= (int)(lPlanes
* lBitsPerPixel
);
408 ::DevCloseDC(hdcScreen
);
409 ::WinReleasePS(hpsScreen
);
414 // Get size of display
422 static LONG lWidth
= 0;
423 static LONG lHeight
= 0;
425 // The screen size ain't gonna change either so just cache the values
427 hpsScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
428 hdcScreen
= ::GpiQueryDevice(hpsScreen
);
429 ::DevQueryCaps(hdcScreen
, CAPS_WIDTH
, 1L, &lWidth
);
430 ::DevQueryCaps(hdcScreen
, CAPS_HEIGHT
, 1L, &lHeight
);
431 ::DevCloseDC(hdcScreen
);
432 ::WinReleasePS(hpsScreen
);
434 *pWidth
= (int)lWidth
;
435 *pHeight
= (int)lHeight
;
438 void wxDisplaySizeMM(
446 hpsScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
447 hdcScreen
= ::GpiQueryDevice(hpsScreen
);
450 ::DevQueryCaps( hdcScreen
451 ,CAPS_HORIZONTAL_RESOLUTION
456 ::DevQueryCaps( hdcScreen
457 ,CAPS_VERTICAL_RESOLUTION
461 ::DevCloseDC(hdcScreen
);
462 ::WinReleasePS(hpsScreen
);
465 void wxClientDisplayRect(int *x
, int *y
, int *width
, int *height
)
467 // This is supposed to return desktop dimensions minus any window
468 // manager panels, menus, taskbars, etc. If there is a way to do that
469 // for this platform please fix this function, otherwise it defaults
470 // to the entire desktop.
473 wxDisplaySize(width
, height
);
476 void wxGUIAppTraits::InitializeGui(unsigned long &ulHab
)
478 ulHab
= ::WinInitialize(0);
481 void wxGUIAppTraits::TerminateGui(unsigned long ulHab
)
483 ::WinTerminate(ulHab
);
486 wxToolkitInfo
& wxGUIAppTraits::GetToolkitInfo()
488 static wxToolkitInfo vInfo
;
489 ULONG ulSysInfo
[QSV_MAX
] = {0};
492 vInfo
.shortName
= _T("PM");
493 vInfo
.name
= _T("wxOS2");
494 #ifdef __WXUNIVERSAL__
495 vInfo
.shortName
<< _T("univ");
496 vInfo
.name
<< _T("/wxUniversal");
498 ulrc
= ::DosQuerySysInfo( 1L
501 ,sizeof(ULONG
) * QSV_MAX
505 vInfo
.versionMajor
= ulSysInfo
[QSV_VERSION_MAJOR
] / 10;
506 vInfo
.versionMinor
= ulSysInfo
[QSV_VERSION_MINOR
];
512 // ---------------------------------------------------------------------------
513 // window information functions
514 // ---------------------------------------------------------------------------
516 wxString WXDLLEXPORT
wxGetWindowText(
521 long lLen
= ::WinQueryWindowTextLength((HWND
)hWnd
) + 1;
523 ::WinQueryWindowText((HWND
)hWnd
, lLen
, vStr
.GetWriteBuf((int)lLen
));
524 vStr
.UngetWriteBuf();
529 wxString WXDLLEXPORT
wxGetWindowClass(
534 int nLen
= 256; // some starting value
538 int nCount
= ::WinQueryClassName((HWND
)hWnd
, nLen
, vStr
.GetWriteBuf(nLen
));
540 vStr
.UngetWriteBuf();
543 // the class name might have been truncated, retry with larger
555 WXWORD WXDLLEXPORT
wxGetWindowId(
559 return ::WinQueryWindowUShort((HWND
)hWnd
, QWS_ID
);
570 vPoint
[0].x
= rRect
.xLeft
;
571 vPoint
[0].y
= rRect
.yBottom
;
572 ::GpiMove(hPS
, &vPoint
[0]);
573 if (dwStyle
& wxSIMPLE_BORDER
||
574 dwStyle
& wxSTATIC_BORDER
)
576 vPoint
[1].x
= rRect
.xRight
- 1;
577 vPoint
[1].y
= rRect
.yTop
- 1;
585 if (dwStyle
& wxSUNKEN_BORDER
)
587 LINEBUNDLE vLineBundle
;
589 vLineBundle
.lColor
= 0x00FFFFFF; // WHITE
590 vLineBundle
.usMixMode
= FM_OVERPAINT
;
591 vLineBundle
.fxWidth
= 2;
592 vLineBundle
.lGeomWidth
= 2;
593 vLineBundle
.usType
= LINETYPE_SOLID
;
594 vLineBundle
.usEnd
= 0;
595 vLineBundle
.usJoin
= 0;
598 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
602 vPoint
[1].x
= rRect
.xRight
- 1;
603 vPoint
[1].y
= rRect
.yTop
- 1;
610 vPoint
[0].x
= rRect
.xLeft
+ 1;
611 vPoint
[0].y
= rRect
.yBottom
+ 1;
612 ::GpiMove(hPS
, &vPoint
[0]);
613 vPoint
[1].x
= rRect
.xRight
- 2;
614 vPoint
[1].y
= rRect
.yTop
- 2;
622 vLineBundle
.lColor
= 0x00000000; // BLACK
623 vLineBundle
.usMixMode
= FM_OVERPAINT
;
624 vLineBundle
.fxWidth
= 2;
625 vLineBundle
.lGeomWidth
= 2;
626 vLineBundle
.usType
= LINETYPE_SOLID
;
627 vLineBundle
.usEnd
= 0;
628 vLineBundle
.usJoin
= 0;
631 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
635 vPoint
[0].x
= rRect
.xLeft
+ 2;
636 vPoint
[0].y
= rRect
.yBottom
+ 2;
637 ::GpiMove(hPS
, &vPoint
[0]);
638 vPoint
[1].x
= rRect
.xLeft
+ 2;
639 vPoint
[1].y
= rRect
.yTop
- 3;
640 ::GpiLine(hPS
, &vPoint
[1]);
641 vPoint
[1].x
= rRect
.xRight
- 3;
642 vPoint
[1].y
= rRect
.yTop
- 3;
643 ::GpiLine(hPS
, &vPoint
[1]);
645 vPoint
[0].x
= rRect
.xLeft
+ 3;
646 vPoint
[0].y
= rRect
.yBottom
+ 3;
647 ::GpiMove(hPS
, &vPoint
[0]);
648 vPoint
[1].x
= rRect
.xLeft
+ 3;
649 vPoint
[1].y
= rRect
.yTop
- 4;
650 ::GpiLine(hPS
, &vPoint
[1]);
651 vPoint
[1].x
= rRect
.xRight
- 4;
652 vPoint
[1].y
= rRect
.yTop
- 4;
653 ::GpiLine(hPS
, &vPoint
[1]);
655 if (dwStyle
& wxDOUBLE_BORDER
)
657 LINEBUNDLE vLineBundle
;
659 vLineBundle
.lColor
= 0x00FFFFFF; // WHITE
660 vLineBundle
.usMixMode
= FM_OVERPAINT
;
661 vLineBundle
.fxWidth
= 2;
662 vLineBundle
.lGeomWidth
= 2;
663 vLineBundle
.usType
= LINETYPE_SOLID
;
664 vLineBundle
.usEnd
= 0;
665 vLineBundle
.usJoin
= 0;
668 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
672 vPoint
[1].x
= rRect
.xRight
- 1;
673 vPoint
[1].y
= rRect
.yTop
- 1;
680 vLineBundle
.lColor
= 0x00000000; // WHITE
681 vLineBundle
.usMixMode
= FM_OVERPAINT
;
682 vLineBundle
.fxWidth
= 2;
683 vLineBundle
.lGeomWidth
= 2;
684 vLineBundle
.usType
= LINETYPE_SOLID
;
685 vLineBundle
.usEnd
= 0;
686 vLineBundle
.usJoin
= 0;
689 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
693 vPoint
[0].x
= rRect
.xLeft
+ 2;
694 vPoint
[0].y
= rRect
.yBottom
+ 2;
695 ::GpiMove(hPS
, &vPoint
[0]);
696 vPoint
[1].x
= rRect
.xRight
- 2;
697 vPoint
[1].y
= rRect
.yTop
- 2;
704 vLineBundle
.lColor
= 0x00FFFFFF; // BLACK
705 vLineBundle
.usMixMode
= FM_OVERPAINT
;
706 vLineBundle
.fxWidth
= 2;
707 vLineBundle
.lGeomWidth
= 2;
708 vLineBundle
.usType
= LINETYPE_SOLID
;
709 vLineBundle
.usEnd
= 0;
710 vLineBundle
.usJoin
= 0;
713 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
717 vPoint
[0].x
= rRect
.xLeft
+ 3;
718 vPoint
[0].y
= rRect
.yBottom
+ 3;
719 ::GpiMove(hPS
, &vPoint
[0]);
720 vPoint
[1].x
= rRect
.xRight
- 3;
721 vPoint
[1].y
= rRect
.yTop
- 3;
729 if (dwStyle
& wxRAISED_BORDER
)
731 LINEBUNDLE vLineBundle
;
733 vLineBundle
.lColor
= 0x00000000; // BLACK
734 vLineBundle
.usMixMode
= FM_OVERPAINT
;
735 vLineBundle
.fxWidth
= 2;
736 vLineBundle
.lGeomWidth
= 2;
737 vLineBundle
.usType
= LINETYPE_SOLID
;
738 vLineBundle
.usEnd
= 0;
739 vLineBundle
.usJoin
= 0;
742 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
746 vPoint
[1].x
= rRect
.xRight
- 1;
747 vPoint
[1].y
= rRect
.yTop
- 1;
754 vPoint
[0].x
= rRect
.xLeft
+ 1;
755 vPoint
[0].y
= rRect
.yBottom
+ 1;
756 ::GpiMove(hPS
, &vPoint
[0]);
757 vPoint
[1].x
= rRect
.xRight
- 2;
758 vPoint
[1].y
= rRect
.yTop
- 2;
766 vLineBundle
.lColor
= 0x00FFFFFF; // WHITE
767 vLineBundle
.usMixMode
= FM_OVERPAINT
;
768 vLineBundle
.fxWidth
= 2;
769 vLineBundle
.lGeomWidth
= 2;
770 vLineBundle
.usType
= LINETYPE_SOLID
;
771 vLineBundle
.usEnd
= 0;
772 vLineBundle
.usJoin
= 0;
775 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
779 vPoint
[0].x
= rRect
.xLeft
+ 2;
780 vPoint
[0].y
= rRect
.yBottom
+ 2;
781 ::GpiMove(hPS
, &vPoint
[0]);
782 vPoint
[1].x
= rRect
.xLeft
+ 2;
783 vPoint
[1].y
= rRect
.yTop
- 3;
784 ::GpiLine(hPS
, &vPoint
[1]);
785 vPoint
[1].x
= rRect
.xRight
- 3;
786 vPoint
[1].y
= rRect
.yTop
- 3;
787 ::GpiLine(hPS
, &vPoint
[1]);
789 vPoint
[0].x
= rRect
.xLeft
+ 3;
790 vPoint
[0].y
= rRect
.yBottom
+ 3;
791 ::GpiMove(hPS
, &vPoint
[0]);
792 vPoint
[1].x
= rRect
.xLeft
+ 3;
793 vPoint
[1].y
= rRect
.yTop
- 4;
794 ::GpiLine(hPS
, &vPoint
[1]);
795 vPoint
[1].x
= rRect
.xRight
- 4;
796 vPoint
[1].y
= rRect
.yTop
- 4;
797 ::GpiLine(hPS
, &vPoint
[1]);
799 } // end of wxDrawBorder
803 , const wxFont
& rFont
811 if (hWnd
== NULLHANDLE
)
815 // The fonts available for Presentation Params are just a few
816 // outline fonts, the rest are available to the GPI, so we must
817 // map the families to one of these three
819 switch(rFont
.GetFamily())
822 strcpy(zFacename
, "Script");
826 strcpy(zFacename
, "WarpSans");
830 strcpy(zFacename
,"Times New Roman");
834 strcpy(zFacename
, "Courier New");
838 strcpy(zFacename
, "Courier New");
844 strcpy(zFacename
, "Helvetica");
848 switch(rFont
.GetWeight())
857 case wxFONTWEIGHT_MAX
:
858 strcpy(zWeight
, "Bold");
862 switch(rFont
.GetStyle())
866 strcpy(zStyle
, "Italic");
873 sprintf(zFont
, "%d.%s", rFont
.GetPointSize(), zFacename
);
874 if (zWeight
[0] != '\0')
877 strcat(zFont
, zWeight
);
879 if (zStyle
[0] != '\0')
882 strcat(zFont
, zStyle
);
884 ::WinSetPresParam(hWnd
, PP_FONTNAMESIZE
, strlen(zFont
) + 1, (PVOID
)zFont
);
885 } // end of wxOS2SetFont
887 // ---------------------------------------------------------------------------
888 // Helper for taking a regular bitmap and giving it a disabled look
889 // ---------------------------------------------------------------------------
890 wxBitmap
wxDisableBitmap(
895 wxMask
* pMask
= rBmp
.GetMask();
898 return(wxNullBitmap
);
900 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
901 SIZEL vSize
= {0, 0};
902 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
903 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
904 BITMAPINFOHEADER2 vHeader
;
908 HBITMAP hBitmap
= (HBITMAP
)rBmp
.GetHBITMAP();
909 HBITMAP hOldBitmap
= NULLHANDLE
;
910 HBITMAP hOldMask
= NULLHANDLE
;
911 HBITMAP hMask
= (HBITMAP
)rBmp
.GetMask()->GetMaskBitmap();
912 unsigned char* pucBits
; // buffer that will contain the bitmap data
913 unsigned char* pucData
; // pointer to use to traverse bitmap data
914 unsigned char* pucBitsMask
; // buffer that will contain the mask data
915 unsigned char* pucDataMask
; // pointer to use to traverse mask data
918 bool bpp16
= (wxDisplayDepth() == 16);
920 memset(&vHeader
, '\0', 16);
923 memset(&vInfo
, '\0', 16);
925 vInfo
.cx
= (ULONG
)rBmp
.GetWidth();
926 vInfo
.cy
= (ULONG
)rBmp
.GetHeight();
928 vInfo
.cBitCount
= 24; // Set to desired count going in
931 // Create the buffers for data....all wxBitmaps are 24 bit internally
933 int nBytesPerLine
= rBmp
.GetWidth() * 3;
934 int nSizeDWORD
= sizeof(DWORD
);
935 int nLineBoundary
= nBytesPerLine
% nSizeDWORD
;
941 // Bitmap must be ina double-word alligned address so we may
942 // have some padding to worry about
944 if (nLineBoundary
> 0)
946 nPadding
= nSizeDWORD
- nLineBoundary
;
947 nBytesPerLine
+= nPadding
;
949 pucBits
= (unsigned char *)malloc(nBytesPerLine
* rBmp
.GetHeight());
950 memset(pucBits
, '\0', (nBytesPerLine
* rBmp
.GetHeight()));
951 pucBitsMask
= (unsigned char *)malloc(nBytesPerLine
* rBmp
.GetHeight());
952 memset(pucBitsMask
, '\0', (nBytesPerLine
* rBmp
.GetHeight()));
955 // Extract the bitmap and mask data
957 if ((hOldBitmap
= ::GpiSetBitmap(hPS
, hBitmap
)) == HBM_ERROR
)
959 vError
= ::WinGetLastError(vHabmain
);
960 sError
= wxPMErrorToStr(vError
);
962 ::GpiQueryBitmapInfoHeader(hBitmap
, &vHeader
);
963 vInfo
.cBitCount
= 24;
964 if ((lScans
= ::GpiQueryBitmapBits( hPS
966 ,(LONG
)rBmp
.GetHeight()
971 vError
= ::WinGetLastError(vHabmain
);
972 sError
= wxPMErrorToStr(vError
);
974 if ((hOldMask
= ::GpiSetBitmap(hPS
, hMask
)) == HBM_ERROR
)
976 vError
= ::WinGetLastError(vHabmain
);
977 sError
= wxPMErrorToStr(vError
);
979 ::GpiQueryBitmapInfoHeader(hMask
, &vHeader
);
980 vInfo
.cBitCount
= 24;
981 if ((lScans
= ::GpiQueryBitmapBits( hPS
983 ,(LONG
)rBmp
.GetHeight()
988 vError
= ::WinGetLastError(vHabmain
);
989 sError
= wxPMErrorToStr(vError
);
991 if (( hMask
= ::GpiSetBitmap(hPS
, hOldMask
)) == HBM_ERROR
)
993 vError
= ::WinGetLastError(vHabmain
);
994 sError
= wxPMErrorToStr(vError
);
997 pucDataMask
= pucBitsMask
;
1000 // Get the mask value
1002 for (i
= 0; i
< rBmp
.GetHeight(); i
++)
1004 for (j
= 0; j
< rBmp
.GetWidth(); j
++)
1007 if (bpp16
&& *pucDataMask
== 0xF8) // 16 bit display gobblygook
1012 else if (*pucDataMask
== 0xFF) // set to grey
1019 *pucData
= ((unsigned char)(lColor
>> 16));
1024 if (bpp16
&& *(pucDataMask
+ 1) == 0xFC) // 16 bit display gobblygook
1029 else if (*(pucDataMask
+ 1) == 0xFF) // set to grey
1036 *pucData
= ((unsigned char)(lColor
>> 8));
1041 if (bpp16
&& *(pucDataMask
+ 2) == 0xF8) // 16 bit display gobblygook
1046 else if (*(pucDataMask
+ 2) == 0xFF) // set to grey
1053 *pucData
= ((unsigned char)lColor
);
1058 for (j
= 0; j
< nPadding
; j
++)
1066 // Create a new bitmap and set the modified bits
1068 wxBitmap
vNewBmp( rBmp
.GetWidth()
1072 HBITMAP hNewBmp
= (HBITMAP
)vNewBmp
.GetHBITMAP();
1074 if ((hOldBitmap
= ::GpiSetBitmap(hPS
, hNewBmp
)) == HBM_ERROR
)
1076 vError
= ::WinGetLastError(vHabmain
);
1077 sError
= wxPMErrorToStr(vError
);
1079 if ((lScansSet
= ::GpiSetBitmapBits( hPS
1081 ,(LONG
)rBmp
.GetHeight()
1087 vError
= ::WinGetLastError(vHabmain
);
1088 sError
= wxPMErrorToStr(vError
);
1092 pNewMask
= new wxMask(pMask
->GetMaskBitmap());
1093 vNewBmp
.SetMask(pNewMask
);
1095 ::GpiSetBitmap(hPS
, NULLHANDLE
);
1096 ::GpiDestroyPS(hPS
);
1100 return(wxNullBitmap
);
1101 } // end of wxDisableBitmap
1103 COLORREF
wxColourToRGB(
1104 const wxColour
& rColor
1107 return(OS2RGB(rColor
.Red(), rColor
.Green(), rColor
.Blue()));
1108 } // end of wxColourToRGB