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