BitmapDialog.cpp
上传用户:cxh888fhc
上传日期:2017-07-08
资源大小:240k
文件大小:12k
源码类别:

钩子与API截获

开发平台:

Visual C++

  1. // BitmapDialog.cpp : implementation file
  2. //
  3. // Created by David Forrester, January 1, 2001
  4. // Feel free to use this code in any way you want.
  5. #include "stdafx.h"
  6. #include "BitmapDialog.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. /////////////////////////////////////////////////////////////////////////////
  13. // CBitmapDialog dialog
  14. //----------------------------------------------------------------
  15. // CBitmapDialog :: CBitmapDialog - constructor for CBitmapDialog
  16. //
  17. // Parameters:
  18. //  lpszTemplateName - the name of the dialog template resource
  19. //  nIDTemplate - the ID of the dialog template resource
  20. //  pParentWnd - the parent window
  21. //
  22. // You can leave any or all of the below NULL or 0 to not use it
  23. //  lpszResourceName - the name of the bitmap resource to load
  24. //  nIDResource - the ID of the bitmap resource to load
  25. //  lpszFilename - the filename of the bitmap file to load
  26. //  pBitmap - the bitmap to use (user is responsible for handling the bitmap)
  27. // The common constructor for CBitmapDialog
  28. void CBitmapDialog :: Constructor (LPCTSTR lpszResourceName, UINT nIDResource,
  29.    LPCTSTR lpszFilename, CBitmap *pBitmap)
  30. {
  31. m_bTransparent = FALSE; // No transparency
  32. m_bStaticTransparent = TRUE; // Static controls are transparent
  33. m_bBitmapCreated = FALSE; // Don't automatically release the bitmap
  34. m_bBitmapExists = FALSE; // IS there a bitmap?
  35. m_bClickAnywhereMove = FALSE; // Clicking anywhere moves
  36. // Create a hollow brush used in making static controls transparent
  37. m_brushHollow = (HBRUSH) GetStockObject (HOLLOW_BRUSH);
  38. // Load a bitmap from a resource name
  39. if (lpszResourceName != NULL)
  40. {
  41. LoadBitmap (lpszResourceName, NULL);
  42. }
  43. // Load a bitmap from a resource ID
  44. else if (nIDResource != 0)
  45. {
  46. LoadBitmap (nIDResource);
  47. }
  48. // Use the passed bitmap
  49. else if (pBitmap != 0)
  50. {
  51. // NOTE: The user is responsible for handling the bitmap
  52. SetBitmap (pBitmap);
  53. }
  54. // else: No bitmap has been created yet
  55. }
  56. CBitmapDialog::CBitmapDialog (LPCTSTR lpszTemplateName, CWnd* pParentWnd,
  57.   LPCTSTR lpszResourceName, UINT nIDResource,
  58.   LPCTSTR lpszFilename, CBitmap *pBitmap)
  59. : CDialog (lpszTemplateName, pParentWnd)
  60. {
  61. Constructor (lpszResourceName, nIDResource, lpszFilename, pBitmap);
  62. }
  63. CBitmapDialog::CBitmapDialog (UINT nIDTemplate, CWnd* pParentWnd,
  64.   LPCTSTR lpszResourceName, UINT nIDResource,
  65.   LPCTSTR lpszFilename, CBitmap *pBitmap)
  66. : CDialog (nIDTemplate, pParentWnd)
  67. {
  68. Constructor (lpszResourceName, nIDResource, lpszFilename, pBitmap);
  69. }
  70. CBitmapDialog::CBitmapDialog (LPCTSTR lpszResourceName, UINT nIDResource,
  71.   LPCTSTR lpszFilename, CBitmap *pBitmap)
  72. : CDialog ()
  73. {
  74. Constructor (lpszResourceName, nIDResource, lpszFilename, pBitmap);
  75. }
  76. //----------------------------------------------------------------
  77. // CBitmapDialog :: LoadBitmap - load a bitmap from a resource or file
  78. //
  79. // Parameters:
  80. //  lpszResourceName - the name of the bitmap resource to load.
  81. //    Set this to NULL if you use lpszFilename.
  82. //  lpszFilename - the filename of the bitmap file to load.
  83. //    Set this to NULL if you use lpszResourceName.
  84. //  nIDResource - the ID of the bitmap resource to load
  85. BOOL CBitmapDialog :: LoadBitmap (LPCTSTR lpszResourceName, LPCTSTR lpszFilename)
  86. {
  87. // Release the bitmap if it was created
  88. ReleaseBitmap ();
  89. if (lpszResourceName != NULL)
  90. {
  91. // Load the bitmap from a resource
  92. m_bmBitmap = new CBitmap;
  93. if (!m_bmBitmap->LoadBitmap (lpszResourceName))
  94. return FALSE;
  95. // Automatically delete the object
  96. m_bBitmapCreated = TRUE;
  97. m_bBitmapExists = TRUE;
  98. // Make the window transparent if needed
  99. MakeWindowRgn ();
  100. }
  101. else
  102. {
  103. // Load the bitmap from a file
  104. HBITMAP hbm = (HBITMAP) LoadImage (NULL, lpszFilename, IMAGE_BITMAP, 0, 0,
  105. LR_LOADFROMFILE|LR_CREATEDIBSECTION);
  106. if (hbm == NULL) return FALSE;
  107. // Get the CBitmap object
  108. CopyBitmapFrom (CBitmap::FromHandle(hbm));
  109. //m_bmBitmap = CBitmap::FromHandle (hbm);
  110. }
  111. return TRUE;
  112. }
  113. BOOL CBitmapDialog :: LoadBitmap (UINT nIDResource)
  114. {
  115. // Release the bitmap if it was created
  116. ReleaseBitmap ();
  117. // Load the bitmap
  118. m_bmBitmap = new CBitmap;
  119. if (!m_bmBitmap->LoadBitmap (nIDResource))
  120. return FALSE;
  121. // Automatically delete the object
  122. m_bBitmapCreated = TRUE;
  123. m_bBitmapExists = TRUE;
  124. // Make the window transparent if needed
  125. MakeWindowRgn ();
  126. return TRUE;
  127. }
  128. //----------------------------------------------------------------
  129. // CBitmapDialog :: CopyBitmapFrom - sets the bitmap to a copy
  130. //  of a CBitmap.
  131. //
  132. // Parameters:
  133. //  pBitmap - a pointer to the bitmap to make a copy of and use.
  134. BOOL CBitmapDialog :: CopyBitmapFrom (CBitmap *pBitmap)
  135. {
  136. // Release the bitmap if it was created
  137. ReleaseBitmap ();
  138. // Get the bitmap information
  139. BITMAP bmSrc;
  140. pBitmap->GetBitmap (&bmSrc);
  141. // Get a DC to the source bitmap
  142. CDC dcSrc;
  143. dcSrc.CreateCompatibleDC (NULL);
  144. CBitmap *bmSrcOld = dcSrc.SelectObject (pBitmap);
  145. // Create a new bitmap
  146. m_bmBitmap = new CBitmap;
  147. if (!m_bmBitmap->CreateCompatibleBitmap (&dcSrc, bmSrc.bmWidth, bmSrc.bmHeight))
  148. return FALSE;
  149. // Get a DC to the destination bitmap
  150. CDC dcDst;
  151. dcDst.CreateCompatibleDC (NULL);
  152. CBitmap *bmDstOld = dcDst.SelectObject (m_bmBitmap);
  153. // Copy the bitmap
  154. dcDst.BitBlt (0, 0, bmSrc.bmWidth, bmSrc.bmHeight, &dcSrc, 0, 0, SRCCOPY);
  155. // Release
  156. dcSrc.SelectObject (bmSrcOld);
  157. dcDst.SelectObject (bmDstOld);
  158. dcSrc.DeleteDC ();
  159. dcDst.DeleteDC ();
  160. // Automatically delete the object
  161. m_bBitmapCreated = TRUE;
  162. m_bBitmapExists = TRUE;
  163. // Make the window transparent if needed
  164. MakeWindowRgn ();
  165. return TRUE;
  166. }
  167. //----------------------------------------------------------------
  168. // CBitmapDialog :: SetBitmap - sets the bitmap
  169. //
  170. // Parameters:
  171. //  pBitmap - a pointer to the bitmap to use.
  172. //
  173. // NOTE: This function does not copy the bitmap.  You are responsible
  174. //  for handling the bitmap.  Use CopyBitmapFrom() to copy a bitmap.
  175. void CBitmapDialog :: SetBitmap (CBitmap *pBitmap)
  176. {
  177. // Release the bitmap if it was created
  178. ReleaseBitmap ();
  179. // Set the bitmap
  180. m_bmBitmap = pBitmap;
  181. // The bitmap exists, but was not created
  182. m_bBitmapExists = TRUE;
  183. // Make the window transparent if needed
  184. MakeWindowRgn ();
  185. }
  186. //----------------------------------------------------------------
  187. // CBitmapDialog :: ReleaseBitmap - releases a bitmap if it was
  188. //  created using LoadBitmap or CopyBitmapFrom.
  189. void CBitmapDialog :: ReleaseBitmap ()
  190. {
  191. // Make sure that the bitmap was created using LoadBitmap or CopyBitmapFrom
  192. if (m_bBitmapCreated)
  193. {
  194. // Delete the bitmap
  195. m_bmBitmap->DeleteObject ();
  196. delete m_bmBitmap;
  197. // The bitmap has not been created yet
  198. m_bBitmapCreated = FALSE;
  199. }
  200. m_bBitmapExists = FALSE;
  201. }
  202. //----------------------------------------------------------------
  203. // CBitmapDialog :: SetTransparent - sets the dialog's transparent
  204. //  state.
  205. void CBitmapDialog :: SetTransparent (BOOL bTransparent)
  206. {
  207. m_bTransparent = bTransparent;
  208. MakeWindowRgn ();
  209. }
  210. void CBitmapDialog :: SetTransColor (COLORREF col)
  211. {
  212. m_colTrans = col;
  213. MakeWindowRgn ();
  214. }
  215. //----------------------------------------------------------------
  216. // CBitmapDialog :: MakeWindowRgn - makes a window region from
  217. //  the bitmap and uses it if on transparent mode.
  218. void CBitmapDialog :: MakeWindowRgn ()
  219. {
  220. if (!m_bTransparent)
  221. {
  222. // Set the window region to the full window
  223. CRect rc;
  224. GetWindowRect (rc);
  225. CRgn rgn;
  226. rgn.CreateRectRgn (0, 0, rc.Width(), rc.Height());
  227. SetWindowRgn (rgn, TRUE);
  228. }
  229. else
  230. {
  231. // Set the region to the window rect minus the client rect
  232. CRect rcWnd;
  233. GetWindowRect (rcWnd);
  234. CRgn rgn;
  235. rgn.CreateRectRgn (rcWnd.left, rcWnd.top, rcWnd.right, rcWnd.bottom);
  236. CRect rcClient;
  237. GetClientRect (rcClient);
  238. ClientToScreen (rcClient);
  239. CRgn rgnClient;
  240. rgnClient.CreateRectRgn (rcClient.left, rcClient.top, rcClient.right,
  241. rcClient.bottom);
  242. // Subtract rgnClient from rgn
  243. rgn.CombineRgn (&rgn, &rgnClient, RGN_XOR);
  244. // Get a DC for the bitmap
  245. CDC dcImage;
  246. dcImage.CreateCompatibleDC (NULL);
  247. CBitmap *pOldBitmap = dcImage.SelectObject (m_bmBitmap);
  248. // Get the bitmap for width and height information
  249. BITMAP bm;
  250. m_bmBitmap->GetBitmap (&bm);
  251. // Get window width and height
  252. CRect rc;
  253. GetClientRect (rc);
  254. // Use the minimum width and height
  255. int width = min (bm.bmWidth, rc.Width());
  256. int height = min (bm.bmHeight, rc.Height());
  257. // Use RLE (run-length) style because it goes faster.
  258. // Row start is where the first opaque pixel is found.  Once
  259. // a transparent pixel is found, a line region is created.
  260. // Then row_start becomes the next opaque pixel.
  261. int row_start;
  262. // Go through all rows
  263. for (int y=0; y<height; y++)
  264. {
  265. // Start looking at the beginning
  266. row_start = 0;
  267. // Go through all columns
  268. for (int x=0; x<width; x++)
  269. {
  270. // If this pixel is transparent
  271. if (dcImage.GetPixel(x, y) == m_colTrans)
  272. {
  273. // If we haven't found an opaque pixel yet, keep searching
  274. if (row_start == x) row_start ++;
  275. else
  276. {
  277. // We have found the start (row_start) and end (x) of
  278. // an opaque line.  Add it to the region.
  279. CRgn rgnAdd;
  280. rgnAdd.CreateRectRgn (rcClient.left+row_start,
  281. rcClient.top+y, rcClient.left+x, rcClient.top+y+1);
  282. rgn.CombineRgn (&rgn, &rgnAdd, RGN_OR);
  283. row_start = x+1;
  284. }
  285. }
  286. }
  287. // If the last pixel is still opaque, make a region.
  288. if (row_start != x)
  289. {
  290. CRgn rgnAdd;
  291. rgnAdd.CreateRectRgn (rcClient.left+row_start, rcClient.top+y,
  292. rcClient.left+x, rcClient.top+y+1);
  293. rgn.CombineRgn (&rgn, &rgnAdd, RGN_OR);
  294. }
  295. }
  296. SetWindowRgn (rgn, TRUE);
  297. }
  298. }
  299. BEGIN_MESSAGE_MAP(CBitmapDialog, CDialog)
  300. //{{AFX_MSG_MAP(CBitmapDialog)
  301. ON_WM_ERASEBKGND()
  302. ON_WM_LBUTTONDOWN()
  303. ON_WM_CTLCOLOR()
  304. //}}AFX_MSG_MAP
  305. END_MESSAGE_MAP()
  306. /////////////////////////////////////////////////////////////////////////////
  307. // CBitmapDialog message handlers
  308. //----------------------------------------------------------------
  309. // CBitmapDialog :: OnEraseBkgnd - normally erases the background.
  310. //  We override this function to replace it with window drawing
  311. //  code.
  312. BOOL CBitmapDialog :: OnEraseBkgnd (CDC *pDC)
  313. {
  314. // If no bitmap is loaded, behave like a normal dialog box
  315. if (!m_bBitmapExists)
  316. return CDialog :: OnEraseBkgnd (pDC);
  317. // Get the client rectangle of the window
  318. CRect rc;
  319. GetClientRect (rc);
  320. // Get a DC for the bitmap
  321. CDC dcImage;
  322. dcImage.CreateCompatibleDC (pDC);
  323. CBitmap *pOldBitmap = dcImage.SelectObject (m_bmBitmap);
  324. // Get bitmap width and height
  325. BITMAP bm;
  326. m_bmBitmap->GetBitmap (&bm);
  327. // Use the minimum width and height
  328. int width = min (bm.bmWidth, rc.Width());
  329. int height = min (bm.bmHeight, rc.Height());
  330. // Draw the bitmap as the window background
  331. pDC->BitBlt (0, 0, rc.Width(), rc.Height(), &dcImage, 0, 0, SRCCOPY);
  332. // Release
  333. dcImage.SelectObject (pOldBitmap);
  334. dcImage.DeleteDC ();
  335. // Return value: Nonzero if it erases the background.
  336. return TRUE;
  337. }
  338. //----------------------------------------------------------------
  339. // CBitmapDialog :: OnLButtonDown - left mouse button is clicked
  340. //  on the window
  341. void CBitmapDialog::OnLButtonDown(UINT nFlags, CPoint point) 
  342. {
  343. // TODO: Add your message handler code here and/or call default
  344. CDialog::OnLButtonDown(nFlags, point);
  345. // Fool windows into thinking that we clicked on the caption
  346. if (m_bClickAnywhereMove)
  347. PostMessage (WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x,point.y));
  348. }
  349. //----------------------------------------------------------------
  350. // CBitmapDialog :: OnCtlColor - set the colors for controls
  351. HBRUSH CBitmapDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
  352. {
  353. HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
  354. // TODO: Change any attributes of the DC here
  355. // Make static controls transparent
  356. if (m_bStaticTransparent && nCtlColor == CTLCOLOR_STATIC)
  357. {
  358. // Make sure that it's not a slider control
  359. char lpszClassName[256];
  360. GetClassName (pWnd->m_hWnd, lpszClassName, 255);
  361. if (strcmp (lpszClassName, TRACKBAR_CLASS) == 0)
  362. return CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
  363. pDC->SetBkMode (TRANSPARENT);
  364. return m_brushHollow;
  365. }
  366. // TODO: Return a different brush if the default is not desired
  367. return hbr;
  368. }