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