Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

ipicture.cpp

00001 // ipicture.cpp
00002 
00003 // Copyright (C) 2004 Steven Weiß (steven11@gmx.de)
00004 //
00005 // Permission to copy, use, sell and distribute this software is granted
00006 // provided this copyright notice appears in all copies.
00007 // Permission to modify the code and to distribute modified code is granted
00008 // provided this copyright notice appears in all copies, and a notice
00009 // that the code was modified is included with the copyright notice.
00010 //
00011 // This software is provided "as is" without express or implied warranty,
00012 // and with no claim as to its suitability for any purpose.
00013 
00014 
00015 #include <background_wnd/detail/ipicture.hpp>
00016 #include <crtdbg.h>
00017 #include <ocidl.h>                      // IPicture
00018 #include <olectl.h>                     // OleLoadPicture
00019 #include <shlwapi.h>
00020 
00021 
00022 namespace win32 { namespace gui {
00023 namespace bg_wnd {
00024 
00029 ipicture::ipicture()
00030     : pPicture_(NULL)
00031 {}
00032 
00033 ipicture::ipicture(const ipicture& image) : pPicture_(image.pPicture_)
00034 {
00035     if (pPicture_)
00036         pPicture_->AddRef();        
00037 }
00038 
00039 ipicture::~ipicture()
00040 {
00041      release();    
00042 }
00043 
00044 const ipicture& ipicture::operator= (const ipicture& image)
00045 {
00046     if (this != &image) {
00047         release();
00048         pPicture_ = image.pPicture_;
00049         if (pPicture_)
00050             pPicture_->AddRef();        
00051     }
00052     return *this;
00053 }
00054 
00055 void DPtoHIMETRIC(HDC hDC, int& cx, int& cy)
00056 {
00057      const int HIMETRIC_INCH = 2540;
00058 
00059     // map against logical inch for non-constrained mapping modes
00060     int cxPerInch = GetDeviceCaps(hDC, LOGPIXELSX);
00061     int cyPerInch = GetDeviceCaps(hDC, LOGPIXELSY);
00062     
00063     _ASSERTE(cxPerInch != 0 && cyPerInch != 0);
00064     cx = MulDiv(cx, HIMETRIC_INCH, cxPerInch);
00065     cy = MulDiv(cy, HIMETRIC_INCH, cyPerInch);
00066 }
00067 
00068 void HIMETRICtoDP(HDC hDC, LPSIZE lpSize)
00069 {    
00070     const int HIMETRIC_INCH = 2540;
00071 
00072     int nMapMode;
00073     if (hDC != NULL && (nMapMode = GetMapMode(hDC)) < MM_ISOTROPIC && nMapMode != MM_TEXT) {
00074         // when using a constrained map mode, map against physical inch
00075         SetMapMode(hDC, MM_HIMETRIC);
00076         POINT pt = { lpSize->cx, lpSize->cy };
00077         LPtoDP(hDC, &pt, 1);
00078         lpSize->cx = pt.x; lpSize->cy = pt.y;
00079         SetMapMode(hDC, nMapMode);
00080     }
00081     else {
00082         // map against logical inch for non-constrained mapping modes
00083         int cxPerInch = GetDeviceCaps(hDC, LOGPIXELSX);
00084         int cyPerInch = GetDeviceCaps(hDC, LOGPIXELSY);
00085         
00086         _ASSERTE(cxPerInch != 0 && cyPerInch != 0);
00087         lpSize->cx = MulDiv(lpSize->cx, cxPerInch, HIMETRIC_INCH);
00088         lpSize->cy = MulDiv(lpSize->cy, cyPerInch, HIMETRIC_INCH);
00089     }
00090 }
00091 
00096 bool ipicture::get_size(SIZE& size) const
00097 {
00098     _ASSERTE(pPicture_);                                        // Bild muss bereits geladen worden sein!
00099 
00100     if (pPicture_) {
00101         
00102         OLE_XSIZE_HIMETRIC width;
00103         OLE_YSIZE_HIMETRIC height;
00104         if (pPicture_->get_Width(&width) == S_OK && pPicture_->get_Height(&height) == S_OK) {                        
00105             
00106             HDC hDC = GetWindowDC(NULL);            
00107             size.cx = width;
00108             size.cy = height;
00109             
00110             HIMETRICtoDP(hDC, &size);        
00111             ReleaseDC(NULL, hDC);
00112 
00113             return true;
00114         }
00115     }
00116 
00117     return false;
00118 }
00119 
00121 IPicture* ipicture::raw_picture() const
00122 {
00123     return pPicture_;
00124 }
00125 
00127 bool ipicture::loaded() const
00128 {
00129     return pPicture_ != NULL;
00130 }
00131 
00133 bool ipicture::draw(HDC hDC, int x, int y, int cx, int cy, int xSrc, int ySrc, int cxSrc, int cySrc)
00134 {
00135      if (hDC && pPicture_) {
00136           // Pixel -> HIMETRIC          
00137           DPtoHIMETRIC(hDC, xSrc, ySrc);          
00138           DPtoHIMETRIC(hDC, cxSrc, cySrc);
00139 
00140           HRESULT hr = pPicture_->Render(hDC, 
00141                                                 x, y, cx, cy, 
00142                                                 xSrc, cySrc - ySrc, cxSrc, -cySrc, 
00143                                                 NULL);                                   
00144           return hr == S_OK;            
00145      }
00146      return false;
00147 }
00148 
00150 bool ipicture::draw(HDC hDC, int x, int y, int cx, int cy, int xSrc, int ySrc)
00151 {
00152      if (hDC && pPicture_) {
00153           SIZE size;
00154           get_size(size);
00155 
00156           return draw(hDC, 
00157                          x, y, cx, cy, 
00158                          xSrc, ySrc, size.cx, size.cy);
00159      }
00160     return false;
00161 }
00162 
00164 bool ipicture::draw(HDC hDC, int x, int y)
00165 {
00166      if (hDC && pPicture_) {
00167           SIZE size;
00168         if (get_size(size))                       
00169                return draw(hDC, 
00170                               x, y, size.cx, size.cy, 
00171                               0, 0);
00172      }
00173      return false;
00174 }
00175 
00177 bool ipicture::draw(HDC hDC, POINT pt)
00178 {    
00179     return draw(hDC, pt.x, pt.y);    
00180 }
00181 
00183 bool ipicture::draw_stretched(HDC hDC, const RECT& rc)
00184 {
00185     _ASSERTE(hDC);                                // DC muss gültig sein
00186     _ASSERTE(pPicture_);                               // image muss bereits geladen worden sein!
00187 
00188     if (hDC && pPicture_) {
00189         SIZE size;
00190         if (get_size(size)) {
00191 
00192             OLE_XSIZE_HIMETRIC cxSrc;
00193             OLE_YSIZE_HIMETRIC cySrc;
00194             pPicture_->get_Width(&cxSrc);
00195             pPicture_->get_Height(&cySrc);
00196 
00197             if (pPicture_->Render(hDC, 
00198                                    rc.left, rc.top, 
00199                                    rc.right - rc.left, rc.bottom - rc.top,
00200                                    0, cySrc, cxSrc, -cySrc,
00201                                    NULL) == S_OK)
00202                 return true;
00203         }
00204     }
00205 
00206     return false;
00207 }
00208 
00210 bool ipicture::load_from_file(const std::string& fileName)
00211 {    
00212     using namespace std;
00213     
00214     IStream* pStream;
00215     HRESULT hr = SHCreateStreamOnFile(fileName.c_str(), STGM_READ | STGM_SHARE_EXCLUSIVE, &pStream);
00216     if (hr == S_OK) {
00217         IPicture* pOldPic = pPicture_;
00218                         
00219         // image laden        
00220         hr = OleLoadPicture(pStream, 0, FALSE, IID_IPicture, (void**) &pPicture_);
00221         pStream->Release();
00222         if (hr == S_OK) {
00223             if (pOldPic)
00224                 pOldPic->Release();
00225             return true;
00226         }        
00227     }
00228 
00229     return false;
00230 }
00231 
00233 void ipicture::release()
00234 {
00235      if (pPicture_)
00236         pPicture_->Release();
00237 }
00238 
00239 }    // namespace bg_wnd
00240 } }  // namespace win32::gui

Generated on Mon Dec 27 15:30:11 2004 for background_wnd by  doxygen 1.3.9.1