]> git.saurik.com Git - wxWidgets.git/blob - src/os2/icon.cpp
Blind fix for bug #1209944, wxFileConfig constructor corrupts the stack
[wxWidgets.git] / src / os2 / icon.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: icon.cpp
3 // Purpose: wxIcon class
4 // Author: David Webster
5 // Modified by:
6 // Created: 10/09/99
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #ifndef WX_PRECOMP
20 #include "wx/defs.h"
21 #include "wx/list.h"
22 #include "wx/utils.h"
23 #include "wx/app.h"
24 #include "wx/icon.h"
25 #include "wx/log.h"
26 #endif
27
28 #include "wx/os2/private.h"
29 #include "assert.h"
30
31 #include "wx/icon.h"
32
33 IMPLEMENT_DYNAMIC_CLASS(wxIcon, wxGDIObject)
34
35 // ============================================================================
36 // implementation
37 // ============================================================================
38
39 // ----------------------------------------------------------------------------
40 // wxIconRefData
41 // ----------------------------------------------------------------------------
42
43 void wxIconRefData::Free()
44 {
45 if (m_hIcon)
46 ::WinFreeFileIcon((HPOINTER)m_hIcon);
47 }
48
49 // ----------------------------------------------------------------------------
50 // wxIcon
51 // ----------------------------------------------------------------------------
52
53 wxIcon::wxIcon()
54 : m_bIsXpm(FALSE)
55 {
56 }
57
58 wxIcon::wxIcon(
59 const char WXUNUSED(bits)[]
60 , int WXUNUSED(nWidth)
61 , int WXUNUSED(nHeight)
62 )
63 : m_bIsXpm(FALSE)
64 {
65 }
66
67 wxIcon::wxIcon(
68 const wxString& rIconFile
69 , long lFlags
70 , int nDesiredWidth
71 , int nDesiredHeight
72 )
73 : m_bIsXpm(FALSE)
74 {
75 //
76 // A very poor hack, but we have to have separate icon files from windows
77 // So we have a modified name where replace the last three characters
78 // with os2. Also need the extension.
79 //
80 wxString sOs2Name = rIconFile.Mid(0, rIconFile.Length() - 3);
81
82 sOs2Name += wxT("Os2.ico");
83 LoadFile( sOs2Name
84 ,lFlags
85 ,nDesiredWidth
86 ,nDesiredHeight
87 );
88 }
89
90 wxIcon::~wxIcon()
91 {
92 }
93
94 void wxIcon::CreateIconFromXpm(
95 const char** ppData
96 )
97 {
98 wxBitmap vBmp(ppData);
99
100 CopyFromBitmap(vBmp);
101 if (GetHICON())
102 {
103 m_bIsXpm = TRUE;
104 m_vXpmSrc = vBmp;
105 }
106 } // end of wxIcon::CreateIconFromXpm
107
108 void wxIcon::CopyFromBitmap(
109 const wxBitmap& rBmp
110 )
111 {
112 wxMask* pMask = rBmp.GetMask();
113 HBITMAP hBmp = NULLHANDLE;
114 HBITMAP hBmpMask = NULLHANDLE;
115 HBITMAP hOldBitmap = NULLHANDLE;
116 ERRORID vError;
117 wxString sError;
118 LONG lHits;
119
120 if (!pMask)
121 {
122 //
123 // We must have a mask for an icon, so even if it's probably incorrect,
124 // do create it (grey is the "standard" transparent colour)
125 //
126 pMask = new wxMask( rBmp
127 ,*wxLIGHT_GREY
128 );
129 }
130
131 BITMAPINFOHEADER2 vHeader;
132 SIZEL vSize = {0, 0};
133 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
134 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
135 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
136 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
137 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
138 POINTL vPoint[4] = { {0, 0}, {rBmp.GetWidth(), rBmp.GetHeight()},
139 {0, 0}, {rBmp.GetWidth(), rBmp.GetHeight()}
140 };
141 POINTL vPointMask[4] = { {0, 0}, {rBmp.GetWidth(), rBmp.GetHeight() * 2},
142 {0, 0}, {rBmp.GetWidth(), rBmp.GetHeight()}
143 };
144
145 POINTERINFO vIconInfo;
146
147 memset(&vIconInfo, '\0', sizeof(POINTERINFO));
148 vIconInfo.fPointer = FALSE; // we want an icon, not a pointer
149
150 memset(&vHeader, '\0', 16);
151 vHeader.cbFix = 16;
152 vHeader.cx = (ULONG)rBmp.GetWidth();
153 vHeader.cy = (ULONG)rBmp.GetHeight();
154 vHeader.cPlanes = 1L;
155 vHeader.cBitCount = 24;
156
157 hBmp = ::GpiCreateBitmap( hPSDst
158 ,&vHeader
159 ,0L
160 ,NULL
161 ,NULL
162 );
163
164 if ((hOldBitmap = ::GpiSetBitmap(hPSDst, hBmp)) == HBM_ERROR)
165 {
166 vError = ::WinGetLastError(vHabmain);
167 sError = wxPMErrorToStr(vError);
168 }
169 if ((hOldBitmap = ::GpiSetBitmap(hPSSrc, (HBITMAP)rBmp.GetHBITMAP())) == HBM_ERROR)
170 {
171 vError = ::WinGetLastError(vHabmain);
172 sError = wxPMErrorToStr(vError);
173 }
174 if ((lHits = ::GpiBitBlt( hPSDst
175 ,hPSSrc
176 ,4L
177 ,vPoint
178 ,ROP_SRCCOPY
179 ,BBO_IGNORE
180 )) == GPI_ERROR)
181 {
182 vError = ::WinGetLastError(vHabmain);
183 sError = wxPMErrorToStr(vError);
184 }
185 if ((hOldBitmap = ::GpiSetBitmap(hPSDst, NULLHANDLE)) == HBM_ERROR)
186 {
187 vError = ::WinGetLastError(vHabmain);
188 sError = wxPMErrorToStr(vError);
189 }
190 if ((hOldBitmap = ::GpiSetBitmap(hPSSrc, NULLHANDLE)) == HBM_ERROR)
191 {
192 vError = ::WinGetLastError(vHabmain);
193 sError = wxPMErrorToStr(vError);
194 }
195 vIconInfo.hbmColor = hBmp;
196
197 vHeader.cy = (ULONG)rBmp.GetHeight() * 2;
198 hBmpMask = ::GpiCreateBitmap( hPSDst
199 ,&vHeader
200 ,0L
201 ,NULL
202 ,NULL
203 );
204
205 if ((hOldBitmap = ::GpiSetBitmap(hPSDst, hBmpMask)) == HBM_ERROR)
206 {
207 vError = ::WinGetLastError(vHabmain);
208 sError = wxPMErrorToStr(vError);
209 }
210 if ((hOldBitmap = ::GpiSetBitmap(hPSSrc, (HBITMAP)pMask->GetMaskBitmap())) == HBM_ERROR)
211 {
212 vError = ::WinGetLastError(vHabmain);
213 sError = wxPMErrorToStr(vError);
214 }
215 if ((lHits = ::GpiBitBlt( hPSDst
216 ,hPSSrc
217 ,4L
218 ,vPointMask
219 ,ROP_SRCCOPY
220 ,BBO_IGNORE
221 )) == GPI_ERROR)
222 {
223 vError = ::WinGetLastError(vHabmain);
224 sError = wxPMErrorToStr(vError);
225 }
226 if ((hOldBitmap = ::GpiSetBitmap(hPSSrc, NULLHANDLE)) == HBM_ERROR)
227 {
228 vError = ::WinGetLastError(vHabmain);
229 sError = wxPMErrorToStr(vError);
230 }
231 if ((hOldBitmap = ::GpiSetBitmap(hPSDst, NULLHANDLE)) == HBM_ERROR)
232 {
233 vError = ::WinGetLastError(vHabmain);
234 sError = wxPMErrorToStr(vError);
235 }
236
237 vIconInfo.hbmPointer = hBmpMask;
238
239 HICON hIcon = ::WinCreatePointerIndirect( HWND_DESKTOP
240 ,&vIconInfo
241 );
242
243 if (!hIcon)
244 {
245 wxLogLastError(wxT("WinCreatePointerIndirect"));
246 vError = ::WinGetLastError(vHabmain);
247 sError = wxPMErrorToStr(vError);
248 }
249 else
250 {
251 SetHICON((WXHICON)hIcon);
252 SetSize( rBmp.GetWidth()
253 ,rBmp.GetHeight()
254 );
255 }
256
257 if (!rBmp.GetMask())
258 {
259 //
260 // We created the mask, now delete it
261 //
262 delete pMask;
263 }
264 ::GpiSetBitmap(hPSSrc, NULL);
265 ::GpiSetBitmap(hPSDst, NULL);
266 ::GpiDestroyPS(hPSSrc);
267 ::GpiDestroyPS(hPSDst);
268 ::DevCloseDC(hDCSrc);
269 ::DevCloseDC(hDCDst);
270 } // end of wxIcon::CopyFromBitmap
271
272 bool wxIcon::LoadFile(
273 const wxString& rFilename
274 , long lType
275 , int nDesiredWidth
276 , int nDesiredHeight
277 )
278 {
279 HPS hPs = NULLHANDLE;
280
281 UnRef();
282
283 wxGDIImageHandler* pHandler = FindHandler(lType);
284
285 if (pHandler)
286 return(pHandler->Load( this
287 ,rFilename
288 ,hPs
289 ,lType
290 ,nDesiredWidth
291 ,nDesiredHeight
292 ));
293 else
294 return(FALSE);
295 }
296