00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <background_wnd/detail/ipicture.hpp>
00016 #include <crtdbg.h>
00017 #include <ocidl.h>
00018 #include <olectl.h>
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
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
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
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_);
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
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);
00186 _ASSERTE(pPicture_);
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
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 }
00240 } }