Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

384 lines
9.6 KiB

  1. // Preview.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "MSQSCAN.h"
  5. #include "Preview.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CPreview
  13. CPreview::CPreview()
  14. {
  15. m_hBitmap = NULL;
  16. }
  17. CPreview::~CPreview()
  18. {
  19. }
  20. void CPreview::GetSelectionRect(RECT *pRect)
  21. {
  22. CopyRect(pRect,&m_RectTracker.m_rect);
  23. }
  24. void CPreview::SetSelectionRect(RECT *pRect)
  25. {
  26. CopyRect(&m_RectTracker.m_rect,pRect);
  27. InvalidateSelectionRect();
  28. }
  29. void CPreview::SetPreviewRect(CRect Rect)
  30. {
  31. m_PreviewRect.left = 0;
  32. m_PreviewRect.top = 0;
  33. m_PreviewRect.right = Rect.Width();
  34. m_PreviewRect.bottom = Rect.Height();
  35. //
  36. // set selection rect styles
  37. //
  38. m_RectTracker.m_rect.left = PREVIEW_SELECT_OFFSET;
  39. m_RectTracker.m_rect.top = PREVIEW_SELECT_OFFSET;
  40. m_RectTracker.m_rect.right = Rect.Width()-PREVIEW_SELECT_OFFSET;
  41. m_RectTracker.m_rect.bottom = Rect.Height()-PREVIEW_SELECT_OFFSET;
  42. m_RectTracker.m_nStyle = CRectTracker::resizeInside|CRectTracker::dottedLine;
  43. m_RectTracker.SetClippingWindow(m_RectTracker.m_rect);
  44. }
  45. BEGIN_MESSAGE_MAP(CPreview, CWnd)
  46. //{{AFX_MSG_MAP(CPreview)
  47. ON_WM_LBUTTONDOWN()
  48. ON_WM_SETCURSOR()
  49. ON_WM_PAINT()
  50. //}}AFX_MSG_MAP
  51. END_MESSAGE_MAP()
  52. /////////////////////////////////////////////////////////////////////////////
  53. // CPreview message handlers
  54. void CPreview::OnLButtonDown(UINT nFlags, CPoint point)
  55. {
  56. m_RectTracker.Track(this,point,FALSE,this);
  57. InvalidateSelectionRect();
  58. CWnd::OnLButtonDown(nFlags, point);
  59. }
  60. BOOL CPreview::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  61. {
  62. if(m_RectTracker.SetCursor(pWnd,nHitTest))
  63. return TRUE;
  64. return CWnd::OnSetCursor(pWnd, nHitTest, message);
  65. }
  66. void CPreview::OnPaint()
  67. {
  68. CPaintDC dc(this); // device context for painting
  69. if(m_hBitmap == NULL) {
  70. CRect TrueRect;
  71. GetWindowRect(TrueRect);
  72. //
  73. // convert to client coords
  74. //
  75. CWnd* pParent = GetParent();
  76. if(pParent) {
  77. ScreenToClient(TrueRect);
  78. //
  79. // create a white brush
  80. //
  81. CBrush WhiteBrush;
  82. WhiteBrush.CreateSolidBrush(RGB(255,255,255));
  83. //
  84. // select white brush, while saving previously selected brush
  85. //
  86. CBrush* pOldBrush = dc.SelectObject(&WhiteBrush);
  87. //
  88. // fill the preview window with white
  89. //
  90. dc.FillRect(TrueRect,&WhiteBrush);
  91. //
  92. // put back the previously selected brush
  93. //
  94. dc.SelectObject(pOldBrush);
  95. //
  96. // destroy the white brush
  97. //
  98. WhiteBrush.DeleteObject();
  99. }
  100. } else {
  101. //
  102. // paint preview bitmap
  103. //
  104. PaintHBITMAPToDC();
  105. }
  106. //
  107. // draw the selection rect, over the image
  108. //
  109. m_RectTracker.Draw(&dc);
  110. }
  111. void CPreview::InvalidateSelectionRect()
  112. {
  113. //
  114. // get parent window
  115. //
  116. CWnd* pParent = GetParent();
  117. if(pParent) {
  118. //
  119. // get your window rect
  120. //
  121. CRect TrueRect;
  122. GetWindowRect(TrueRect);
  123. //
  124. // convert to client coords
  125. //
  126. pParent->ScreenToClient(TrueRect);
  127. //
  128. // invalidate through parent, because we are using the parent's DC to
  129. // draw images.
  130. //
  131. pParent->InvalidateRect(TrueRect);
  132. }
  133. }
  134. void CPreview::SetHBITMAP(HBITMAP hBitmap)
  135. {
  136. m_hBitmap = hBitmap;
  137. PaintHBITMAPToDC();
  138. }
  139. void CPreview::PaintHBITMAPToDC()
  140. {
  141. //
  142. // get hdc
  143. //
  144. HDC hMemorydc = NULL;
  145. HDC hdc = ::GetWindowDC(m_hWnd);
  146. BITMAP bitmap;
  147. if(hdc != NULL){
  148. //
  149. // create a memory dc
  150. //
  151. hMemorydc = ::CreateCompatibleDC(hdc);
  152. if(hMemorydc != NULL){
  153. //
  154. // select HBITMAP into your hMemorydc
  155. //
  156. if(::GetObject(m_hBitmap,sizeof(BITMAP),(LPSTR)&bitmap) != 0) {
  157. HGDIOBJ hGDIObj = ::SelectObject(hMemorydc,m_hBitmap);
  158. RECT ImageRect;
  159. ImageRect.top = 0;
  160. ImageRect.left = 0;
  161. ImageRect.right = bitmap.bmWidth;
  162. ImageRect.bottom = bitmap.bmHeight;
  163. ScaleBitmapToDC(hdc,hMemorydc,&m_PreviewRect,&ImageRect);
  164. } else {
  165. OutputDebugString(TEXT("Failed GetObject\n"));
  166. }
  167. }
  168. //
  169. // delete hMemorydc
  170. //
  171. ::DeleteDC(hMemorydc);
  172. }
  173. //
  174. // delete hdc
  175. //
  176. ::ReleaseDC(m_hWnd,hdc);
  177. }
  178. void CPreview::ScreenRectToClientRect(HWND hWnd,LPRECT pRect)
  179. {
  180. POINT PtConvert;
  181. PtConvert.x = pRect->left;
  182. PtConvert.y = pRect->top;
  183. //
  184. // convert upper left point
  185. //
  186. ::ScreenToClient(hWnd,&PtConvert);
  187. pRect->left = PtConvert.x;
  188. pRect->top = PtConvert.y;
  189. PtConvert.x = pRect->right;
  190. PtConvert.y = pRect->bottom;
  191. //
  192. // convert lower right point
  193. //
  194. ::ScreenToClient(hWnd,&PtConvert);
  195. pRect->right = PtConvert.x;
  196. pRect->bottom = PtConvert.y;
  197. pRect->bottom-=1;
  198. pRect->left+=1;
  199. pRect->right-=1;
  200. pRect->top+=1;
  201. }
  202. void CPreview::ScaleBitmapToDC(HDC hDC, HDC hDCM, LPRECT lpDCRect, LPRECT lpDIBRect)
  203. {
  204. ::SetStretchBltMode(hDC, COLORONCOLOR);
  205. if ((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDIBRect)) &&
  206. (RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect)))
  207. ::BitBlt (hDC, // hDC
  208. lpDCRect->left, // DestX
  209. lpDCRect->top, // DestY
  210. RECTWIDTH(lpDCRect), // nDestWidth
  211. RECTHEIGHT(lpDCRect), // nDestHeight
  212. hDCM,
  213. 0,
  214. 0,
  215. SRCCOPY);
  216. else {
  217. StretchBlt(hDC, // hDC
  218. lpDCRect->left, // DestX
  219. lpDCRect->top, // DestY
  220. lpDCRect->right,//ScaledWidth, // nDestWidth
  221. lpDCRect->bottom,//ScaledHeight, // nDestHeight
  222. hDCM,
  223. 0, // SrcX
  224. 0, // SrcY
  225. RECTWIDTH(lpDIBRect), // wSrcWidth
  226. RECTHEIGHT(lpDIBRect), // wSrcHeight
  227. SRCCOPY); // dwROP
  228. }
  229. }
  230. /////////////////////////////////////////////////////////////////////////////
  231. // CRectTrackerEx overridden functions
  232. void CRectTrackerEx::AdjustRect( int nHandle, LPRECT lpRect )
  233. {
  234. //
  235. // if clipping rect is empty, do nothing
  236. //
  237. if (!m_rectClippingWindow.IsRectEmpty()) {
  238. if (nHandle == hitMiddle) {
  239. // user is dragging entire selection around...
  240. // make sure selection rect does not get out of clipping
  241. // rect
  242. //
  243. CRect rect = lpRect;
  244. if (rect.right > m_rectClippingWindow.right)
  245. rect.OffsetRect(m_rectClippingWindow.right - rect.right, 0);
  246. if (rect.left < m_rectClippingWindow.left)
  247. rect.OffsetRect(m_rectClippingWindow.left - rect.left, 0);
  248. if (rect.bottom > m_rectClippingWindow.bottom)
  249. rect.OffsetRect(0, m_rectClippingWindow.bottom - rect.bottom);
  250. if (rect.top < m_rectClippingWindow.top)
  251. rect.OffsetRect(0, m_rectClippingWindow.top - rect.top);
  252. *lpRect = rect;
  253. } else {
  254. //
  255. // user is resizing the selection rect
  256. // make sure selection rect does not extend outside of clipping
  257. // rect
  258. //
  259. int *px, *py;
  260. //
  261. // get X and Y selection axis
  262. //
  263. GetModifyPointers(nHandle, &px, &py, NULL, NULL);
  264. if (px != NULL)
  265. *px = max(min(m_rectClippingWindow.right, *px), m_rectClippingWindow.left);
  266. if (py != NULL)
  267. *py = max(min(m_rectClippingWindow.bottom, *py), m_rectClippingWindow.top);
  268. CRect rect = lpRect;
  269. //
  270. // check/adjust X axis
  271. //
  272. if (px != NULL && abs(rect.Width()) < m_sizeMin.cx) {
  273. if (*px == rect.left)
  274. rect.left = rect.right;
  275. else
  276. rect.right = rect.left;
  277. }
  278. //
  279. // check/adjust Y axis
  280. //
  281. if (py != NULL && abs(rect.Height()) < m_sizeMin.cy) {
  282. if (*py == rect.top)
  283. rect.top = rect.bottom;
  284. else
  285. rect.bottom = rect.top;
  286. }
  287. //
  288. // save the adjusted rectangle
  289. //
  290. *lpRect = rect;
  291. }
  292. }
  293. }
  294. void CRectTrackerEx::SetClippingWindow(CRect Rect)
  295. {
  296. m_rectClippingWindow = Rect;
  297. }