Picture.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. // Picture.cpp: implementation of the CPicture class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "newclient.h"
  6. #include "Picture.h"
  7. #ifdef _DEBUG
  8. #undef THIS_FILE
  9. static char THIS_FILE[]=__FILE__;
  10. #define new DEBUG_NEW
  11. #endif
  12. //////////////////////////////////////////////////////////////////////
  13. // Construction/Destruction
  14. //////////////////////////////////////////////////////////////////////
  15. CPicture::CPicture()
  16. {
  17. }
  18. CPicture::~CPicture()
  19. {
  20. }
  21. //-----------------------------------------------------------------------------
  22. // Does: Free The Allocated Memory That Holdes The IPicture Interface Data
  23. // ~~~~ And Clear Picture Information
  24. //
  25. // Note: This Might Also Be Useful If U Only Need To Show The Picture Once
  26. // ~~~~~ Or If U Copy The Picture To The Device Context, So It Can Still
  27. // Remain On Screen - But IPicture Data Is Not Needed No More
  28. //
  29. //-----------------------------------------------------------------------------
  30. void CPicture::UnloadPicture()
  31. //=============================================================================
  32. {
  33. if(m_pPict != NULL){
  34. m_pPict->Release();
  35. m_pPict = NULL;
  36. }
  37. }
  38. //-----------------------------------------------------------------------------
  39. // Does: Open a Resource And Load It Into IPicture (Interface)
  40. // ~~~~ (.BMP .DIB .EMF .GIF .ICO .JPG .WMF)
  41. //
  42. // Note: When Adding a Bitmap Resource It Would Automatically Show On "Bitmap"
  43. // ~~~~ This NOT Good Coz We Need To Load It From a Custom Resource "BMP"
  44. // To Add a Custom Rresource: Import Resource -> Open As -> Custom
  45. // (Both .BMP And .DIB Should Be Found Under "BMP")
  46. //
  47. // InPut: ResourceName - As a UINT Defined (Example: IDR_PICTURE_RESOURCE)
  48. // ~~~~~ ResourceType - Type Name (Example: "JPG")
  49. //
  50. // OutPut: TRUE If Succeeded...
  51. // ~~~~~~
  52. //-----------------------------------------------------------------------------
  53. BOOL CPicture::Load(HINSTANCE hInstance,LPCTSTR lpszResourceName, LPCSTR ResourceType)
  54. //=============================================================================
  55. {
  56. HGLOBAL hGlobal = NULL;
  57. HRSRC hSource = NULL;
  58. LPVOID lpVoid = NULL;
  59. int nSize = 0;
  60. BOOL bResult=FALSE;
  61. if(m_pPict != NULL) UnloadPicture(); // Important - Avoid Leaks...
  62. hSource = FindResource(hInstance, lpszResourceName, ResourceType);
  63. if(hSource == NULL)
  64. {
  65. HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd;
  66. MessageBoxEx(hWnd, "FindResource() Failed\t", "ERROR"/*ERROR_TITLE*/, MB_OK | MB_ICONSTOP, LANG_ENGLISH);
  67. return(FALSE);
  68. }
  69. hGlobal = LoadResource(hInstance, hSource);
  70. if(hGlobal == NULL)
  71. {
  72. HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd;
  73. MessageBoxEx(hWnd, "LoadResource() Failed\t", "ERROR"/*ERROR_TITLE*/, MB_OK | MB_ICONSTOP, LANG_ENGLISH);
  74. return(FALSE);
  75. }
  76. lpVoid = LockResource(hGlobal);
  77. if(lpVoid == NULL)
  78. {
  79. HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd;
  80. MessageBoxEx(hWnd, "LockResource() Failed\t", "ERROR"/*ERROR_TITLE*/, MB_OK | MB_ICONSTOP, LANG_ENGLISH);
  81. return(FALSE);
  82. }
  83. nSize = (UINT)SizeofResource(hInstance, hSource);
  84. if(LoadPictureData((BYTE*)hGlobal, nSize)) bResult = TRUE;
  85. UnlockResource(hGlobal); // 16Bit Windows Needs This
  86. FreeResource(hGlobal); // 16Bit Windows Needs This (32Bit - Automatic Release)
  87. return(bResult);
  88. }
  89. //-----------------------------------------------------------------------------
  90. // Does: Open a File And Load It Into IPicture (Interface)
  91. // ~~~~ (.BMP .DIB .EMF .GIF .ICO .JPG .WMF)
  92. //
  93. // InPut: sFilePathName - Path And FileName Target To Save
  94. // ~~~~~
  95. //
  96. // OutPut: TRUE If Succeeded...
  97. // ~~~~~~
  98. //-----------------------------------------------------------------------------
  99. BOOL CPicture::Load(CString sFilePathName)
  100. //=============================================================================
  101. {
  102. //if(!PathFileExists(sFilePathName))return FALSE;
  103. /*
  104. CFile file;
  105. if (!file.Open(sFilePathName, CFile::modeRead/ *|CFile::shareDenyWrite* /))
  106. return FALSE;*/
  107. BOOL bResult = FALSE;
  108. CFile PictureFile;
  109. CFileException e;
  110. int nSize = 0;
  111. if(m_pPict != NULL) UnloadPicture(); // Important - Avoid Leaks...
  112. if(PictureFile.Open(sFilePathName, CFile::modeRead | CFile::typeBinary, &e))
  113. {
  114. nSize = PictureFile.GetLength();
  115. BYTE* pBuffer = new BYTE[nSize];
  116. if(PictureFile.Read(pBuffer, nSize) > 0)
  117. {
  118. if(LoadPictureData(pBuffer, nSize)) bResult = TRUE;
  119. }
  120. PictureFile.Close();
  121. delete [] pBuffer;
  122. }
  123. else // Open Failed...
  124. {
  125. TCHAR szCause[255];
  126. e.GetErrorMessage(szCause, 255, NULL);
  127. HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd;
  128. MessageBoxEx(hWnd, szCause, "ERROR"/*ERROR_TITLE*/, MB_OK | MB_ICONSTOP, LANG_ENGLISH);
  129. bResult = FALSE;
  130. }
  131. return(bResult);
  132. }
  133. //-----------------------------------------------------------------------------
  134. // Does: Read The Picture Data From a Source (File / Resource)
  135. // ~~~~ And Load It Into The Current IPicture Object In Use
  136. //
  137. // InPut: Buffer Of Data Source (File / Resource) And Its Size
  138. // ~~~~~
  139. //
  140. // OutPut: Feed The IPicture Object With The Picture Data
  141. // ~~~~~~ (Use Draw Functions To Show It On a Device Context)
  142. // TRUE If Succeeded...
  143. //-----------------------------------------------------------------------------
  144. BOOL CPicture::LoadPictureData(BYTE *pBuffer, int nSize)
  145. //=============================================================================
  146. {
  147. BOOL bResult = FALSE;
  148. HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, nSize);
  149. if(hGlobal == NULL)
  150. {
  151. HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd;
  152. MessageBoxEx(hWnd, "Can not allocate enough memory\t", "ERROR"/*ERROR_TITLE*/, MB_OK | MB_ICONSTOP, LANG_ENGLISH);
  153. return(FALSE);
  154. }
  155. void* pData = GlobalLock(hGlobal);
  156. memcpy(pData, pBuffer, nSize);
  157. GlobalUnlock(hGlobal);
  158. IStream* pStream = NULL;
  159. if(CreateStreamOnHGlobal(hGlobal, TRUE, &pStream) == S_OK)
  160. {
  161. HRESULT hr;
  162. if((hr = OleLoadPicture(pStream, nSize, FALSE, IID_IPicture, (LPVOID *)&m_pPict)) == E_NOINTERFACE)
  163. {
  164. HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd;
  165. MessageBoxEx(hWnd, "IPicture interface is not supported\t", "ERROR"/*ERROR_TITLE*/, MB_OK | MB_ICONSTOP, LANG_ENGLISH);
  166. return(FALSE);
  167. }
  168. else // S_OK
  169. {
  170. pStream->Release();
  171. pStream = NULL;
  172. bResult = TRUE;
  173. }
  174. }
  175. FreeResource(hGlobal); // 16Bit Windows Needs This (32Bit - Automatic Release)
  176. return(bResult);
  177. }
  178. //-----------------------------------------------------------------------------
  179. // Does: Draw The Loaded Picture Direct To The Client DC
  180. // ~~~~
  181. //
  182. // Note: Bigger OR Smaller Dimentions Than The Original Picture Size
  183. // ~~~~ Will Draw The Picture Streached To Its New Given NEW Dimentions...
  184. //
  185. // InPut: pDC - Given DC To Draw On
  186. // ~~~~~ pSrcRect- Dimentions Of The Picture To Draw From(As a Rectangle)
  187. // DrawRect - Dimentions Of The Picture To Draw To(As a Rectangle)
  188. // OutPut: TRUE If Succeeded...
  189. // ~~~~~~
  190. //-----------------------------------------------------------------------------
  191. //=============================================================================
  192. void CPicture::Render(CDC* pDC, LPRECT pDrawRect, LPRECT pSrcRect/*=NULL*/,LPCRECT prcWBounds/*=NULL*/)
  193. {
  194. if (pDC == NULL || m_pPict == NULL) return ;
  195. CRect recrDest(pDrawRect);
  196. long Width = 0;
  197. long Height = 0;
  198. m_pPict->get_Width(&Width);
  199. m_pPict->get_Height(&Height);
  200. CRect SrcRect(0,0,Width,Height);
  201. if(pSrcRect){
  202. SrcRect=*pSrcRect;
  203. }
  204. CRect DrawRect(pDrawRect);
  205. HRESULT hrP = NULL;
  206. hrP = m_pPict->Render(pDC->m_hDC,
  207. DrawRect.left, // Left
  208. DrawRect.top, // Top
  209. DrawRect.Width(), // Right
  210. DrawRect.Height(), // Bottom
  211. SrcRect.left,
  212. SrcRect.top,
  213. SrcRect.Width(),
  214. SrcRect.Height(),
  215. prcWBounds);
  216. if (SUCCEEDED(hrP)) return;
  217. AfxThrowMemoryException();
  218. return;
  219. }//-----------------------------------------------------------------------------
  220. // Does: Saves The Picture That Is Stored In The IPicture Object As a Bitmap
  221. // ~~~~ (Converts From Any Known Picture Type To a Bitmap / Icon File)
  222. //
  223. // InPut: sFilePathName - Path And FileName Target To Save
  224. // ~~~~~
  225. //
  226. // OutPut: TRUE If Succeeded...
  227. // ~~~~~~
  228. //-----------------------------------------------------------------------------
  229. BOOL CPicture::SaveAsBitmap(CString sFilePathName)
  230. //=============================================================================
  231. {
  232. BOOL bResult = FALSE;
  233. ILockBytes *Buffer = 0;
  234. IStorage *pStorage = 0;
  235. IStream *FileStream = 0;
  236. BYTE *BufferBytes;
  237. STATSTG BytesStatistics;
  238. DWORD OutData;
  239. long OutStream;
  240. CFile BitmapFile; CFileException e;
  241. double SkipFloat = 0;
  242. DWORD ByteSkip = 0;
  243. _ULARGE_INTEGER RealData;
  244. CreateILockBytesOnHGlobal(NULL, TRUE, &Buffer); // Create ILockBytes Buffer
  245. HRESULT hr = ::StgCreateDocfileOnILockBytes(Buffer,
  246. STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, &pStorage);
  247. hr = pStorage->CreateStream(L"PICTURE",
  248. STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, 0, &FileStream);
  249. m_pPict->SaveAsFile(FileStream, TRUE, &OutStream); // Copy Data Stream
  250. FileStream->Release();
  251. pStorage->Release();
  252. Buffer->Flush();
  253. // Get Statistics For Final Size Of Byte Array
  254. Buffer->Stat(&BytesStatistics, STATFLAG_NONAME);
  255. // Cut UnNeeded Data Coming From SaveAsFile() (Leave Only "Pure" Picture Data)
  256. SkipFloat = (double(OutStream) / 512); // Must Be In a 512 Blocks...
  257. if(SkipFloat > DWORD(SkipFloat)) ByteSkip = (DWORD)SkipFloat + 1;
  258. else ByteSkip = (DWORD)SkipFloat;
  259. ByteSkip = ByteSkip * 512; // Must Be In a 512 Blocks...
  260. // Find Difference Between The Two Values
  261. ByteSkip = (DWORD)(BytesStatistics.cbSize.QuadPart - ByteSkip);
  262. // Allocate Only The "Pure" Picture Data
  263. RealData.LowPart = 0;
  264. RealData.HighPart = 0;
  265. RealData.QuadPart = ByteSkip;
  266. BufferBytes = (BYTE*)malloc(OutStream);
  267. if(BufferBytes == NULL)
  268. {
  269. Buffer->Release();
  270. HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd;
  271. MessageBoxEx(hWnd, "Can not allocate enough memory\t", "ERROR"/*ERROR_TITLE*/, MB_OK | MB_ICONSTOP, LANG_ENGLISH);
  272. }
  273. Buffer->ReadAt(RealData, BufferBytes, OutStream, &OutData);
  274. if(BitmapFile.Open(sFilePathName, CFile::typeBinary | CFile::modeCreate | CFile::modeWrite, &e))
  275. {
  276. BitmapFile.Write(BufferBytes, OutData);
  277. BitmapFile.Close();
  278. bResult = TRUE;
  279. }
  280. else // Write File Failed...
  281. {
  282. TCHAR szCause[255];
  283. e.GetErrorMessage(szCause, 255, NULL);
  284. HWND hWnd = AfxGetApp()->GetMainWnd()->m_hWnd;
  285. MessageBoxEx(hWnd, szCause, "ERROR"/*ERROR_TITLE*/, MB_OK | MB_ICONSTOP, LANG_ENGLISH);
  286. bResult = FALSE;
  287. }
  288. Buffer->Release();
  289. free(BufferBytes);
  290. return(bResult);
  291. }
  292. LONG CPicture::get_Height()
  293. {
  294. LONG nHeight = 0;
  295. if (m_pPict != NULL)
  296. {
  297. m_pPict->get_Height(&nHeight);
  298. }
  299. return nHeight;
  300. }
  301. LONG CPicture::get_Width()
  302. {
  303. LONG nWidth = 0;
  304. if (m_pPict != NULL)
  305. {
  306. m_pPict->get_Width(&nWidth);
  307. }
  308. return nWidth;
  309. }