More image processing updates
[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 #endif
26
27 #include "wx/os2/private.h"
28 #include "assert.h"
29
30 #include "wx/icon.h"
31
32 IMPLEMENT_DYNAMIC_CLASS(wxIcon, wxGDIObject)
33
34 // ============================================================================
35 // implementation
36 // ============================================================================
37
38 // ----------------------------------------------------------------------------
39 // wxIconRefData
40 // ----------------------------------------------------------------------------
41
42 void wxIconRefData::Free()
43 {
44 if (m_hIcon)
45 ::WinFreeFileIcon((HPOINTER)m_hIcon);
46 }
47
48 // ----------------------------------------------------------------------------
49 // wxIcon
50 // ----------------------------------------------------------------------------
51
52 wxIcon::wxIcon()
53 {
54 }
55
56 wxIcon::wxIcon(
57 const char WXUNUSED(bits)[]
58 , int WXUNUSED(nWidth)
59 , int WXUNUSED(nHeight)
60 )
61 {
62 }
63
64 wxIcon::wxIcon(
65 const wxString& rIconFile
66 , long lFlags
67 , int nDesiredWidth
68 , int nDesiredHeight
69 )
70 {
71 //
72 // A very poor hack, but we have to have separate icon files from windows
73 // So we have a modified name where replace the last three characters
74 // with os2. Also need the extension.
75 //
76 wxString sOs2Name = rIconFile.Mid(0, rIconFile.Length() - 3);
77
78 sOs2Name += "Os2.ico";
79 LoadFile( sOs2Name
80 ,lFlags
81 ,nDesiredWidth
82 ,nDesiredHeight
83 );
84 }
85
86 wxIcon::~wxIcon()
87 {
88 }
89
90 void wxIcon::CreateIconFromXpm(
91 const char** ppData
92 )
93 {
94 wxBitmap vBmp(ppData);
95
96 CopyFromBitmap(vBmp);
97 } // end of wxIcon::CreateIconFromXpm
98
99 void wxIcon::CopyFromBitmap(
100 const wxBitmap& rBmp
101 )
102 {
103 wxMask* pMask = rBmp.GetMask();
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 POINTERINFO vIconInfo;
121
122 memset(&vIconInfo, '\0', sizeof(POINTERINFO));
123 vIconInfo.fPointer = FALSE; // we want an icon, not a pointer
124 vIconInfo.hbmPointer = (HBITMAP) pMask->GetMaskBitmap();
125 vIconInfo.hbmColor = GetHbitmapOf(rBmp);
126
127 SIZEL vSize = {0, 0};
128 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
129 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
130 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
131 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
132 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
133 POINTL vPoint[4] = { 0, 0, rBmp.GetWidth(), rBmp.GetHeight(),
134 0, 0, rBmp.GetWidth(), rBmp.GetHeight()
135 };
136 if ((hOldBitmap = ::GpiSetBitmap(hPSSrc, (HBITMAP) pMask->GetMaskBitmap())) == HBM_ERROR)
137 {
138 vError = ::WinGetLastError(vHabmain);
139 sError = wxPMErrorToStr(vError);
140 }
141 if ((hOldBitmap = ::GpiSetBitmap(hPSDst, (HBITMAP) vIconInfo.hbmColor)) == HBM_ERROR)
142 {
143 vError = ::WinGetLastError(vHabmain);
144 sError = wxPMErrorToStr(vError);
145 }
146 ::GpiSetBitmapId(hPSDst, (HBITMAP) vIconInfo.hbmColor, 1L);
147 if ((lHits = ::GpiBitBlt( hPSDst
148 ,hPSSrc
149 ,4L
150 ,vPoint
151 ,ROP_SRCAND
152 ,BBO_IGNORE
153 )) == GPI_ERROR)
154 {
155 vError = ::WinGetLastError(vHabmain);
156 sError = wxPMErrorToStr(vError);
157 }
158 if ((hOldBitmap = ::GpiSetBitmap(hPSSrc, NULLHANDLE)) == HBM_ERROR)
159 {
160 vError = ::WinGetLastError(vHabmain);
161 sError = wxPMErrorToStr(vError);
162 }
163 if ((hOldBitmap = ::GpiSetBitmap(hPSDst, NULLHANDLE)) == HBM_ERROR)
164 {
165 vError = ::WinGetLastError(vHabmain);
166 sError = wxPMErrorToStr(vError);
167 }
168
169 ::GpiSetBitmap(hPSSrc, NULL);
170 ::GpiSetBitmap(hPSDst, NULL);
171 ::GpiDestroyPS(hPSSrc);
172 ::GpiDestroyPS(hPSDst);
173 ::DevCloseDC(hDCSrc);
174 ::DevCloseDC(hDCDst);
175
176 HICON hIcon = ::WinCreatePointerIndirect( HWND_DESKTOP
177 ,&vIconInfo
178 );
179
180 if (!hIcon)
181 {
182 wxLogLastError(wxT("WinCreatePointerIndirect"));
183 vError = ::WinGetLastError(vHabmain);
184 sError = wxPMErrorToStr(vError);
185 }
186 else
187 {
188 SetHICON((WXHICON)hIcon);
189 SetSize( rBmp.GetWidth()
190 ,rBmp.GetHeight()
191 );
192 }
193
194 if (!rBmp.GetMask())
195 {
196 //
197 // We created the mask, now delete it
198 //
199 delete pMask;
200 }
201 } // end of wxIcon::CopyFromBitmap
202
203 bool wxIcon::LoadFile(
204 const wxString& rFilename
205 , long lType
206 , int nDesiredWidth
207 , int nDesiredHeight
208 )
209 {
210 HPS hPs = NULLHANDLE;
211
212 UnRef();
213
214 wxGDIImageHandler* pHandler = FindHandler(lType);
215
216 if (pHandler)
217 return(pHandler->Load( this
218 ,rFilename
219 ,hPs
220 ,lType
221 ,nDesiredWidth
222 ,nDesiredHeight
223 ));
224 else
225 return(FALSE);
226 }
227