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