ATLTANGRAMCANVASIMPL.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:5k
源码类别:

Windows编程

开发平台:

Visual C++

  1. // AtlTangramCanvasImpl.cpp : Implementation of CAtlTangramCanvas
  2. //
  3. // This is a part of the Active Template Library.
  4. // Copyright (C) 1996-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Active Template Library Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Active Template Library product.
  12. #include "stdafx.h"
  13. #include "ATLTangramCanvas.h"
  14. #include "AtlTangramCanvasImpl.h"
  15. /////////////////////////////////////////////////////////////////////////////
  16. // CAtlTangramCanvas
  17. //
  18. ///////////////////////////////////////////////////////////
  19. //
  20. // Initialize
  21. //  
  22. HRESULT CAtlTangramCanvas::Initialize(HWND hWnd, long cx, long cy)
  23. {
  24. // Hard coded to 8 bits per pixel.
  25. int ibitcount = 8 ; 
  26. // Preconditions.
  27. if ( hWnd == NULL || !::IsWindow(hWnd) || cx <= 0 || cy <= 0)
  28. {
  29. // Definsive code.
  30. ASSERT(hWnd != NULL) ;
  31. ASSERT(::IsWindow(hWnd)) ;
  32. ASSERT(cx > 0);
  33. ASSERT(cy > 0);
  34. return E_INVALIDARG ;
  35. }
  36. // Cache a copy of the window handle.
  37. m_hWnd = hWnd ; 
  38. // Destroy parts of objects if we are recreating it.
  39. if ((m_hdc != NULL) || (m_hbmp != NULL))
  40. {
  41. // destroy() ;
  42. }
  43. // Save size for drawing later.
  44. m_sizeDIB.cx = cx ;
  45. m_sizeDIB.cy = cy ;
  46. // Create a BITMAPINFOHEADER structure to describe the DIB
  47. BITMAPINFOHEADER BIH ;
  48. int iSize = sizeof(BITMAPINFOHEADER) ;
  49. memset(&BIH, 0, iSize);
  50. // Fill in the header info.
  51. BIH.biSize = iSize;
  52. BIH.biWidth = cx;
  53. BIH.biHeight = cy;
  54. BIH.biPlanes = 1;
  55. BIH.biBitCount = ibitcount;
  56. BIH.biCompression = BI_RGB;
  57. // Create a new DC.
  58. m_hdc = ::CreateCompatibleDC(NULL) ;
  59. // Create the DIB section.
  60. m_hbmp = CreateDIBSection( m_hdc,
  61. (BITMAPINFO*)&BIH,
  62. DIB_PAL_COLORS,
  63. &m_pBits,
  64. NULL,
  65. 0);
  66. ASSERT(m_hbmp);
  67. ASSERT(m_pBits);
  68. // Select the new bitmap into the buffer DC
  69. if (m_hbmp)
  70. {
  71. m_hbmOld = (HBITMAP)::SelectObject( m_hdc, 
  72. m_hbmp);
  73. }
  74. return S_OK ;
  75. }
  76. ///////////////////////////////////////////////////////////
  77. //
  78. // Transfer the dib section to a DC. 
  79. // Called in response to paint and draw messages.
  80. //
  81. HRESULT CAtlTangramCanvas::Paint(HDC hdcDest, RECT rectUpdate)
  82. {
  83. // Preconditions
  84. if ( hdcDest == NULL)
  85. {
  86. ASSERT(hdcDest != NULL) ;
  87. return E_INVALIDARG ;
  88. }
  89. // Select in a palette if we have one.
  90. HPALETTE hPalOld = NULL;
  91. if (m_hPal)
  92. {
  93. hPalOld = ::SelectPalette(hdcDest, (HPALETTE)m_hPal, 0);
  94. ::RealizePalette(hdcDest);
  95. }
  96. // If the rectangle is empty or null, repaint the entire area.
  97. RECT rect, rectNull ;
  98. ::SetRectEmpty(&rectNull) ;
  99. ::CopyRect(&rect, &rectUpdate) ;
  100. if (::EqualRect(&rect, &rectNull) || ::IsRectEmpty(&rect))
  101. {
  102. // Note: you do not need to select the palette into
  103. // the memory DC because the DIB section is using palette
  104. // index values not colors
  105. ::BitBlt(hdcDest, 0, 0,
  106. m_sizeDIB.cx, m_sizeDIB.cy,
  107. m_hdc, 
  108. 0,0,
  109. SRCCOPY);
  110. }
  111. else
  112. {
  113. // Just repaint the updated area.
  114. ::BitBlt(hdcDest,
  115. rect.left, rect.top,
  116. rect.right - rect.left, rect.bottom - rect.top,
  117. m_hdc, 
  118. rect.left, rect.top,
  119. SRCCOPY);
  120. }
  121. // We are done with the palette
  122. if (hPalOld) 
  123. {
  124. ::SelectPalette(hdcDest, hPalOld, 0);
  125. }
  126. return S_OK ;
  127. }
  128. ///////////////////////////////////////////////////////////
  129. //
  130. // Update
  131. //
  132. HRESULT CAtlTangramCanvas::Update(RECT rectUpdate)
  133. {
  134. HDC hdcDest = ::GetDC(m_hWnd) ;
  135. Paint(hdcDest, rectUpdate) ;
  136. ::ReleaseDC(m_hWnd, hdcDest);
  137. return S_OK ;
  138. }
  139. ///////////////////////////////////////////////////////////
  140. //
  141. // GetHDC
  142. //
  143. HRESULT CAtlTangramCanvas::GetHDC(HDC* phdc)
  144. {
  145. // Pre conditions.
  146. if (!IsValidAddress(phdc, sizeof(HDC), TRUE))
  147. {
  148. ASSERT(0) ;
  149. return E_FAIL ;
  150. }
  151. // Return device context.
  152. *phdc = m_hdc ;
  153. return S_OK ;
  154. }
  155. ///////////////////////////////////////////////////////////
  156. //
  157. // Set the color table in the DIB section.
  158. //
  159. HRESULT __stdcall CAtlTangramCanvas::SetPalette(HPALETTE hPal) 
  160. {
  161. if (hPal == NULL)
  162. {
  163. ASSERT(hPal != NULL);
  164. return E_INVALIDARG ;
  165. }
  166. // Keep a copy of the palette around for painting.
  167. m_hPal = hPal ;
  168. // get the colors from the palette
  169. int iColors = 0;
  170. ::GetObject(hPal, sizeof(iColors), &iColors) ;
  171. ASSERT(iColors > 0);
  172. PALETTEENTRY* pPE = new PALETTEENTRY[iColors];
  173. ::GetPaletteEntries(hPal, 0, iColors, pPE);
  174. // Build a table of RGBQUADS
  175. RGBQUAD* pRGB = new RGBQUAD[iColors];
  176. ASSERT(pRGB);
  177. for (int i = 0; i < iColors; i++) {
  178. pRGB[i].rgbRed = pPE[i].peRed;
  179. pRGB[i].rgbGreen = pPE[i].peGreen;
  180. pRGB[i].rgbBlue = pPE[i].peBlue;
  181. pRGB[i].rgbReserved = 0;
  182. }
  183. ::SetDIBColorTable(m_hdc, 
  184.    0, iColors,
  185.    pRGB);
  186. delete [] pRGB;
  187. delete [] pPE;
  188. return S_OK ;
  189. }
  190. ///////////////////////////////////////////////////////////
  191. //
  192. // Called when the main window gets a QueryNewPalette or a
  193. // PaletteChanged message.
  194. //
  195. HRESULT __stdcall CAtlTangramCanvas::OnQueryNewPalette(HWND hWndReceived)
  196. {
  197. if (hWndReceived == NULL)
  198. {
  199. return E_FAIL ;
  200. }
  201. if (m_hPal)
  202. {
  203. HDC hdc = ::GetDC(hWndReceived) ;
  204. ::SelectPalette(hdc, m_hPal, FALSE) ;
  205. UINT u = ::RealizePalette(hdc) ;
  206. ::ReleaseDC(hWndReceived, hdc) ;
  207. if (u != 0)
  208. {
  209. ::InvalidateRect(hWndReceived, NULL, TRUE) ;
  210. }
  211. }
  212. return S_OK ;
  213. }