BkDialogST.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. #include "stdafx.h"
  2. #include "BkDialogST.h"
  3. #ifdef _DEBUG
  4. #define new DEBUG_NEW
  5. #undef THIS_FILE
  6. static char THIS_FILE[] = __FILE__;
  7. #endif
  8. #ifndef WM_NCLBUTTONDOWN
  9. #define WM_NCLBUTTONDOWN 0x00A1
  10. #define BKDLGST_DEFINES
  11. #endif
  12. CBkDialogST::CBkDialogST(CWnd* pParent /*=NULL*/)
  13. {
  14. //{{AFX_DATA_INIT(CBkDialogST)
  15. // NOTE: the ClassWizard will add member initialization here
  16. //}}AFX_DATA_INIT
  17. Init();
  18. }
  19. CBkDialogST::CBkDialogST(UINT uResourceID, CWnd* pParent)
  20. : CDialog(uResourceID, pParent)
  21. {
  22. Init();
  23. }
  24. CBkDialogST::CBkDialogST(LPCTSTR pszResourceID, CWnd* pParent)
  25. : CDialog(pszResourceID, pParent)
  26. {
  27. Init();
  28. }
  29. CBkDialogST::~CBkDialogST()
  30. {
  31. FreeResources();
  32. }
  33. void CBkDialogST::DoDataExchange(CDataExchange* pDX)
  34. {
  35. CDialog::DoDataExchange(pDX);
  36. //{{AFX_DATA_MAP(CBkDialogST)
  37. // NOTE: the ClassWizard will add DDX and DDV calls here
  38. //}}AFX_DATA_MAP
  39. }
  40. BEGIN_MESSAGE_MAP(CBkDialogST, CDialog)
  41. //{{AFX_MSG_MAP(CBkDialogST)
  42. ON_WM_ERASEBKGND()
  43. ON_WM_SIZE()
  44. //}}AFX_MSG_MAP
  45. ON_WM_LBUTTONDOWN()
  46. END_MESSAGE_MAP()
  47. void CBkDialogST::Init()
  48. {
  49. FreeResources(FALSE);
  50. // Default drawing bitmap mode
  51. m_byMode = BKDLGST_MODE_TILE;
  52. // No EasyMove mode
  53. m_bEasyMoveMode = FALSE;
  54. } // End of Init
  55. void CBkDialogST::FreeResources(BOOL bCheckForNULL)
  56. {
  57. if (bCheckForNULL == TRUE)
  58. {
  59. // Destroy bitmap
  60. if (m_hBitmap) ::DeleteObject(m_hBitmap);
  61. #ifndef UNDER_CE
  62. // Destroy region
  63. if (m_hRegion)
  64. {
  65. ::SetWindowRgn(m_hWnd, NULL, FALSE);
  66. ::DeleteObject(m_hRegion);
  67. } // if
  68. #endif
  69. } // if
  70. m_hBitmap = NULL;
  71. #ifndef UNDER_CE
  72. m_hRegion = NULL;
  73. #endif
  74. m_dwWidth = 0;
  75. m_dwHeight = 0;
  76. } // End of FreeResources
  77. void CBkDialogST::OnLButtonDown(UINT nFlags, CPoint point)
  78. {
  79. // EasyMove mode
  80. if (m_bEasyMoveMode == TRUE)
  81. PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
  82. CDialog::OnLButtonDown(nFlags, point);
  83. } // End of OnLButtonDown
  84. void CBkDialogST::OnSize(UINT nType, int cx, int cy)
  85. {
  86. CDialog::OnSize(nType, cx, cy);
  87. // If there is a bitmap loaded
  88. if (m_hBitmap != NULL)
  89. {
  90. Invalidate();
  91. } // if
  92. } // End of OnSize
  93. BOOL CBkDialogST::OnEraseBkgnd(CDC* pDC)
  94. {
  95. CRect rWnd;
  96. int nX = 0;
  97. int nY = 0;
  98. BOOL bRetValue = CDialog::OnEraseBkgnd(pDC);
  99. // If there is a bitmap loaded
  100. if (m_hBitmap)
  101. {
  102. GetClientRect(rWnd);
  103. CDC dcMemoryDC;
  104. CBitmap bmpMemoryBitmap;
  105. CBitmap* pbmpOldMemoryBitmap = NULL;
  106. dcMemoryDC.CreateCompatibleDC(pDC);
  107. bmpMemoryBitmap.CreateCompatibleBitmap(pDC, rWnd.Width(), rWnd.Height());
  108. pbmpOldMemoryBitmap = (CBitmap*)dcMemoryDC.SelectObject(&bmpMemoryBitmap);
  109. // Fill background
  110. dcMemoryDC.FillSolidRect(rWnd, pDC->GetBkColor());
  111. CDC dcTempDC;
  112. HBITMAP hbmpOldTempBitmap = NULL;
  113. dcTempDC.CreateCompatibleDC(pDC);
  114. hbmpOldTempBitmap = (HBITMAP)::SelectObject(dcTempDC.m_hDC, m_hBitmap);
  115. switch (m_byMode)
  116. {
  117. case BKDLGST_MODE_TILE:
  118. // Tile the bitmap
  119. while (nY < rWnd.Height())
  120. {
  121. while(nX < rWnd.Width())
  122. {
  123. dcMemoryDC.BitBlt(nX, nY, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY);
  124. nX += m_dwWidth;
  125. } // while
  126. nX = 0;
  127. nY += m_dwHeight;
  128. } // while
  129. break;
  130. case BKDLGST_MODE_CENTER:
  131. nX = ((rWnd.Width() - m_dwWidth)/2);
  132. nY = ((rWnd.Height() - m_dwHeight)/2);
  133. dcMemoryDC.BitBlt(nX, nY, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY);
  134. break;
  135. case BKDLGST_MODE_STRETCH:
  136. // Stretch the bitmap
  137. dcMemoryDC.StretchBlt(0, 0, rWnd.Width(), rWnd.Height(), &dcTempDC, 0, 0, m_dwWidth, m_dwHeight, SRCCOPY);
  138. break;
  139. case BKDLGST_MODE_TILETOP:
  140. while(nX < rWnd.Width())
  141. {
  142. dcMemoryDC.BitBlt(nX, 0, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY);
  143. nX += m_dwWidth;
  144. } // while
  145. break;
  146. case BKDLGST_MODE_TILEBOTTOM:
  147. while(nX < rWnd.Width())
  148. {
  149. dcMemoryDC.BitBlt(nX, rWnd.bottom - m_dwHeight, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY);
  150. nX += m_dwWidth;
  151. } // while
  152. break;
  153. case BKDLGST_MODE_TILELEFT:
  154. while (nY < rWnd.Height())
  155. {
  156. dcMemoryDC.BitBlt(0, nY, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY);
  157. nY += m_dwHeight;
  158. } // while
  159. break;
  160. case BKDLGST_MODE_TILERIGHT:
  161. while (nY < rWnd.Height())
  162. {
  163. dcMemoryDC.BitBlt(rWnd.right - m_dwWidth, nY, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY);
  164. nY += m_dwHeight;
  165. } // while
  166. break;
  167. case BKDLGST_MODE_TOPLEFT:
  168. dcMemoryDC.BitBlt(0, 0, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY);
  169. break;
  170. case BKDLGST_MODE_TOPRIGHT:
  171. dcMemoryDC.BitBlt(rWnd.right - m_dwWidth, 0, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY);
  172. break;
  173. case BKDLGST_MODE_TOPCENTER:
  174. nX = ((rWnd.Width() - m_dwWidth)/2);
  175. dcMemoryDC.BitBlt(nX, 0, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY);
  176. break;
  177. case BKDLGST_MODE_BOTTOMLEFT:
  178. dcMemoryDC.BitBlt(0, rWnd.bottom - m_dwHeight, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY);
  179. break;
  180. case BKDLGST_MODE_BOTTOMRIGHT:
  181. dcMemoryDC.BitBlt(rWnd.right - m_dwWidth, rWnd.bottom - m_dwHeight, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY);
  182. break;
  183. case BKDLGST_MODE_BOTTOMCENTER:
  184. nX = ((rWnd.Width() - m_dwWidth)/2);
  185. dcMemoryDC.BitBlt(nX, rWnd.bottom - m_dwHeight, m_dwWidth, m_dwHeight, &dcTempDC, 0, 0, SRCCOPY);
  186. break;
  187. } // switch
  188. pDC->BitBlt(0, 0, rWnd.Width(), rWnd.Height(), &dcMemoryDC, 0, 0, SRCCOPY);
  189. OnPostEraseBkgnd(&dcMemoryDC);
  190. ::SelectObject(dcTempDC.m_hDC, hbmpOldTempBitmap);
  191. dcMemoryDC.SelectObject(pbmpOldMemoryBitmap);
  192. } // if
  193. return bRetValue;
  194. } // End of OnEraseBkgnd
  195. void CBkDialogST::OnPostEraseBkgnd(CDC* pDC)
  196. {
  197. } // End of OnPostEraseBkgnd
  198. // -------------------------------------------------------------------------------------
  199. // Scan a bitmap and return a perfect fit region.
  200. // The caller must release the memory...
  201. // (this method starts with a full region and excludes inside the loop)
  202. // -------------------------------------------------------------------------------------
  203. // Credits for this function go to Vander Nunes
  204. //
  205. #ifndef UNDER_CE
  206. HRGN CBkDialogST::ScanRegion(HBITMAP hBitmap, BYTE byTransR, BYTE byTransG, BYTE byTransB)
  207. {
  208. // bitmap width and height
  209. DWORD dwBmpWidth = 0, dwBmpHeight = 0;
  210. // the final region and a temporary region
  211. HRGN hRgn = NULL, hTmpRgn = NULL;
  212. // 24bit pixels from the bitmap
  213. LPBYTE lpbyPixels = Get24BitPixels(hBitmap, &dwBmpWidth, &dwBmpHeight);
  214. if (!lpbyPixels) return NULL;
  215. // create our working region
  216. hRgn = ::CreateRectRgn(0, 0, dwBmpWidth, dwBmpHeight);
  217. if (!hRgn)
  218. {
  219. delete lpbyPixels;
  220. return NULL;
  221. } // if
  222. // ---------------------------------------------------------
  223. // scan the bitmap
  224. // ---------------------------------------------------------
  225. DWORD p=0;
  226. for (DWORD y=0; y<dwBmpHeight; y++)
  227. {
  228. for (DWORD x=0; x<dwBmpWidth; x++)
  229. {
  230. BYTE jRed = lpbyPixels[p+2];
  231. BYTE jGreen = lpbyPixels[p+1];
  232. BYTE jBlue = lpbyPixels[p+0];
  233. if (jRed == byTransR && jGreen == byTransG && jBlue == byTransB)
  234. {
  235. // remove transparent color from region
  236. hTmpRgn = ::CreateRectRgn(x,y,x+1,y+1);
  237. ::CombineRgn(hRgn, hRgn, hTmpRgn, RGN_XOR);
  238. ::DeleteObject(hTmpRgn);
  239. } // if
  240. // next pixel
  241. p+=3;
  242. } // for
  243. } // for
  244. // release pixels
  245. delete lpbyPixels;
  246. // return the region
  247. return hRgn;
  248. } // End of ScanRegion
  249. #endif
  250. // -------------------------------------------------------------------------------------
  251. // Return bitmap pixels in 24bits format.
  252. // The caller must release the memory...
  253. // -------------------------------------------------------------------------------------
  254. // Credits for this function go to Vander Nunes
  255. //
  256. #ifndef UNDER_CE
  257. LPBYTE CBkDialogST::Get24BitPixels(HBITMAP hBitmap, LPDWORD lpdwWidth, LPDWORD lpdwHeight)
  258. {
  259. // a bitmap object just to get bitmap width and height
  260. BITMAP bmpBmp;
  261. // pointer to original bitmap info
  262. LPBITMAPINFO pbmiInfo;
  263. // bitmap info will hold the new 24bit bitmap info
  264. BITMAPINFO bmiInfo;
  265. // width and height of the bitmap
  266. DWORD dwBmpWidth = 0, dwBmpHeight = 0;
  267. // ---------------------------------------------------------
  268. // get some info from the bitmap
  269. // ---------------------------------------------------------
  270. ::GetObject(hBitmap, sizeof(bmpBmp),&bmpBmp);
  271. pbmiInfo = (LPBITMAPINFO)&bmpBmp;
  272. // get width and height
  273. dwBmpWidth = (DWORD)pbmiInfo->bmiHeader.biWidth;
  274. dwBmpWidth -= (dwBmpWidth%4); // width is 4 byte boundary aligned.
  275. dwBmpHeight = (DWORD)pbmiInfo->bmiHeader.biHeight;
  276. // copy to caller width and height parms
  277. *lpdwWidth = dwBmpWidth;
  278. *lpdwHeight = dwBmpHeight;
  279. // ---------------------------------------------------------
  280. // allocate width * height * 24bits pixels
  281. LPBYTE lpbyPixels = new BYTE[dwBmpWidth * dwBmpHeight * 3];
  282. if (!lpbyPixels) return NULL;
  283. // get user desktop device context to get pixels from
  284. HDC hDC = ::GetWindowDC(NULL);
  285. // fill desired structure
  286. bmiInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  287. bmiInfo.bmiHeader.biWidth = dwBmpWidth;
  288. bmiInfo.bmiHeader.biHeight = 0 - (int)dwBmpHeight;
  289. bmiInfo.bmiHeader.biPlanes = 1;
  290. bmiInfo.bmiHeader.biBitCount = 24;
  291. bmiInfo.bmiHeader.biCompression = BI_RGB;
  292. bmiInfo.bmiHeader.biSizeImage = dwBmpWidth * dwBmpHeight * 3;
  293. bmiInfo.bmiHeader.biXPelsPerMeter = 0;
  294. bmiInfo.bmiHeader.biYPelsPerMeter = 0;
  295. bmiInfo.bmiHeader.biClrUsed = 0;
  296. bmiInfo.bmiHeader.biClrImportant = 0;
  297. // get pixels from the original bitmap converted to 24bits
  298. int iRes = ::GetDIBits(hDC,hBitmap, 0, dwBmpHeight, (LPVOID)lpbyPixels, &bmiInfo, DIB_RGB_COLORS);
  299. // release the device context
  300. ::ReleaseDC(NULL,hDC);
  301. // if failed, cancel the operation.
  302. if (!iRes)
  303. {
  304. delete lpbyPixels;
  305. return NULL;
  306. } // if
  307. // return the pixel array
  308. return lpbyPixels;
  309. } // End of Get24BitPixels
  310. #endif
  311. //
  312. // Parameters:
  313. // [IN] bActivate
  314. // TRUE if EasyMove mode must be activated.
  315. //
  316. // Return value:
  317. // BKDLGST_OK
  318. // Function executed successfully.
  319. //
  320. DWORD CBkDialogST::ActivateEasyMoveMode(BOOL bActivate)
  321. {
  322. m_bEasyMoveMode = bActivate;
  323. return BKDLGST_OK;
  324. } // End of ActivateEasyMoveMode
  325. //
  326. // Parameters:
  327. // [IN] nBitmap
  328. // Resource ID of the bitmap to use as background.
  329. // [IN] crTransColor
  330. // A COLORREF value indicating the color to "remove" from the
  331. // bitmap. When crTransColor is specified (different from -1L)
  332. // a region will be created using the supplied bitmap and applied
  333. // to the window.
  334. //
  335. // Return value:
  336. // BKDLGST_OK
  337. // Function executed successfully.
  338. // BKDLGST_INVALIDRESOURCE
  339. // The resource specified cannot be found or loaded.
  340. // BKDLGST_FAILEDREGION
  341. // Failed creating region
  342. //
  343. DWORD CBkDialogST::SetBitmap(int nBitmap, COLORREF crTransColor)
  344. {
  345. HBITMAP hBitmap = NULL;
  346. HINSTANCE hInstResource = NULL;
  347. // Find correct resource handle
  348. hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nBitmap), RT_BITMAP);
  349. // Load bitmap In
  350. hBitmap = (HBITMAP)::LoadImage(hInstResource, MAKEINTRESOURCE(nBitmap), IMAGE_BITMAP, 0, 0, 0);
  351. return SetBitmap(hBitmap, crTransColor);
  352. } // End of SetBitmap
  353. //
  354. // Parameters:
  355. // [IN] hBitmap
  356. // Handle to the bitmap to use as background.
  357. // [IN] crTransColor
  358. // A COLORREF value indicating the color to "remove" from the
  359. // bitmap. When crTransColor is specified (different from -1L)
  360. // a region will be created using the supplied bitmap and applied
  361. // to the window.
  362. //
  363. // Return value:
  364. // BKDLGST_OK
  365. // Function executed successfully.
  366. // BKDLGST_INVALIDRESOURCE
  367. // The resource specified cannot be found or loaded.
  368. // BKDLGST_FAILEDREGION
  369. // Failed creating region
  370. //
  371. DWORD CBkDialogST::SetBitmap(HBITMAP hBitmap, COLORREF crTransColor)
  372. {
  373. int nRetValue;
  374. BITMAP csBitmapSize;
  375. // Free any loaded resource
  376. FreeResources();
  377. if (hBitmap)
  378. {
  379. m_hBitmap = hBitmap;
  380. // Get bitmap size
  381. nRetValue = ::GetObject(hBitmap, sizeof(csBitmapSize), &csBitmapSize);
  382. if (nRetValue == 0)
  383. {
  384. FreeResources();
  385. return BKDLGST_INVALIDRESOURCE;
  386. } // if
  387. m_dwWidth = (DWORD)csBitmapSize.bmWidth;
  388. m_dwHeight = (DWORD)csBitmapSize.bmHeight;
  389. #ifndef UNDER_CE
  390. // Create region ?
  391. if (crTransColor != -1L)
  392. {
  393. m_hRegion = ScanRegion(m_hBitmap, GetRValue(crTransColor), GetGValue(crTransColor), GetBValue(crTransColor));
  394. if (m_hRegion == NULL)
  395. {
  396. FreeResources();
  397. return BKDLGST_FAILEDREGION;
  398. } // if
  399. ::SetWindowRgn(m_hWnd, m_hRegion, FALSE);
  400. } // if
  401. #endif
  402. } // if
  403. Invalidate();
  404. return BKDLGST_OK;
  405. } // End of SetBitmap
  406. //
  407. // Parameters:
  408. // [IN] byMode
  409. // Specifies how the bitmap will be placed in the dialog background.
  410. // [IN] bRepaint
  411. // If TRUE the dialog will be repainted.
  412. //
  413. // Return value:
  414. // BKDLGST_OK
  415. // Function executed successfully.
  416. // BKDLGST_INVALIDMODE
  417. // Invalid mode.
  418. //
  419. DWORD CBkDialogST::SetMode(BYTE byMode, BOOL bRepaint)
  420. {
  421. if (byMode >= BKDLGST_MAX_MODES) return BKDLGST_INVALIDMODE;
  422. // Set new mode
  423. m_byMode = byMode;
  424. if (bRepaint == TRUE) Invalidate();
  425. return BKDLGST_OK;
  426. } // End of SetMode
  427. #ifndef UNDER_CE
  428. DWORD CBkDialogST::ShrinkToFit(BOOL bRepaint)
  429. {
  430. CRect rWnd;
  431. CRect rClient;
  432. DWORD dwDiffCX;
  433. DWORD dwDiffCY;
  434. GetWindowRect(&rWnd);
  435. GetClientRect(&rClient);
  436. dwDiffCX = rWnd.Width() - rClient.Width();
  437. dwDiffCY = rWnd.Height() - rClient.Height();
  438. m_byMode = BKDLGST_MODE_CENTER;
  439. MoveWindow(rWnd.left, rWnd.top, dwDiffCX + m_dwWidth, dwDiffCY + m_dwHeight, bRepaint);
  440. return BKDLGST_OK;
  441. } // End of ShrinkToFit
  442. #endif
  443. #ifdef BKDLGST_DEFINES
  444. #undef BKDLGST_DEFINES
  445. #undef WM_NCLBUTTONDOWN
  446. #endif