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