DlgLinerPara.cpp
上传用户:gdjinyi
上传日期:2013-02-01
资源大小:1701k
文件大小:8k
源码类别:

源码/资料

开发平台:

Visual C++

  1. // DlgLinerPara.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "ch1_1.h"
  5. #include "DlgLinerPara.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CDlgLinerPara dialog
  13. CDlgLinerPara::CDlgLinerPara(CWnd* pParent /*=NULL*/)
  14. : CDialog(CDlgLinerPara::IDD, pParent)
  15. {
  16. //{{AFX_DATA_INIT(CDlgLinerPara)
  17. m_fA = 0.0f;
  18. m_fB = 0.0f;
  19. //}}AFX_DATA_INIT
  20. }
  21. void CDlgLinerPara::DoDataExchange(CDataExchange* pDX)
  22. {
  23. CDialog::DoDataExchange(pDX);
  24. //{{AFX_DATA_MAP(CDlgLinerPara)
  25. DDX_Text(pDX, IDC_EDIT_A, m_fA);
  26. DDX_Text(pDX, IDC_EDIT_B, m_fB);
  27. //}}AFX_DATA_MAP
  28. }
  29. BEGIN_MESSAGE_MAP(CDlgLinerPara, CDialog)
  30. //{{AFX_MSG_MAP(CDlgLinerPara)
  31. ON_WM_PAINT()
  32. ON_EN_KILLFOCUS(IDC_EDIT_A, OnKillfocusEditA)
  33. ON_EN_KILLFOCUS(IDC_EDIT_B, OnKillfocusEditB)
  34. ON_WM_LBUTTONDOWN()
  35. ON_WM_LBUTTONUP()
  36. ON_WM_MOUSEMOVE()
  37. //}}AFX_MSG_MAP
  38. END_MESSAGE_MAP()
  39. /////////////////////////////////////////////////////////////////////////////
  40. // CDlgLinerPara message handlers
  41. BOOL CDlgLinerPara::OnInitDialog() 
  42. {
  43. // 调用默认OnInitDialog函数
  44. CDialog::OnInitDialog();
  45. // 获取绘制直方图的标签
  46. CWnd* pWnd = GetDlgItem(IDC_COORD);
  47. // 计算接受鼠标事件的有效区域
  48. pWnd->GetClientRect(m_MouseRect);
  49. pWnd->ClientToScreen(&m_MouseRect);
  50. CRect rect;
  51. GetClientRect(rect);
  52. ClientToScreen(&rect);
  53. m_MouseRect.top -= rect.top;
  54. m_MouseRect.left -= rect.left;
  55. // 设置接受鼠标事件的有效区域
  56. m_MouseRect.top += 25;
  57. m_MouseRect.left += 10;
  58. m_MouseRect.bottom = m_MouseRect.top + 255;
  59. m_MouseRect.right = m_MouseRect.left + 256;
  60. // 初始化拖动状态
  61. m_bIsDraging = FALSE;
  62. // 返回TRUE
  63. return TRUE; 
  64. }
  65. void CDlgLinerPara::OnKillfocusEditA() 
  66. {
  67. // 保存用户设置
  68. UpdateData(TRUE);
  69. // 重绘
  70. InvalidateRect(m_MouseRect, TRUE);
  71. }
  72. void CDlgLinerPara::OnKillfocusEditB() 
  73. {
  74. // 保存用户设置
  75. UpdateData(TRUE);
  76. // 重绘
  77. InvalidateRect(m_MouseRect, TRUE);
  78. }
  79. void CDlgLinerPara::OnLButtonDown(UINT nFlags, CPoint point) 
  80. {
  81. // 当用户单击鼠标左键开始拖动
  82. if(m_MouseRect.PtInRect(point))
  83. {
  84. // 保存当前鼠标位置
  85. m_p1 = point;
  86. // 转换坐标系
  87. m_p1.x = m_p1.x - m_MouseRect.left + 10;
  88. m_p1.y = m_p1.y - m_MouseRect.top + 25;
  89. // 设置拖动状态
  90. m_bIsDraging = TRUE;
  91. // 设置m_bDrawed为FALSE
  92. m_bDrawed = FALSE;
  93. // 更改光标
  94. ::SetCursor(::LoadCursor(NULL, IDC_CROSS));
  95. // 开始跟踪鼠标事件(保证当鼠标移动到窗体外时也可以接收到鼠标释放事件)
  96. SetCapture();
  97. }
  98. // 默认单击鼠标左键处理事件
  99. CDialog::OnLButtonDown(nFlags, point);
  100. }
  101. void CDlgLinerPara::OnMouseMove(UINT nFlags, CPoint point) 
  102. {
  103. // 判断当前光标是否在绘制区域
  104. if(m_MouseRect.PtInRect(point))
  105. {
  106. // 更改光标
  107. ::SetCursor(::LoadCursor(NULL, IDC_CROSS));
  108. // 判断是否正在拖动
  109. if (m_bIsDraging)
  110. {
  111. // 获取绘图的标签
  112. CWnd* pWnd = GetDlgItem(IDC_COORD);
  113. // 获取设备上下文
  114. CDC* pDC = pWnd->GetDC();
  115. // 设置绘制方式为异或模式
  116. int nOldDrawMode = pDC->SetROP2(R2_XORPEN);
  117. // 创建新的画笔
  118. CPen* pPen = new CPen;
  119. pPen->CreatePen(PS_DOT,1,RGB(0,0,0));
  120. // 选中新画笔
  121. CGdiObject* pOldPen = pDC->SelectObject(pPen);
  122. // 判断是否已经画过橡皮筋线
  123. if (m_bDrawed)
  124. {
  125. // 擦去以前的橡皮筋线
  126. pDC->MoveTo(m_p1);
  127. pDC->LineTo(m_p2);
  128. }
  129. // 保存当前的坐标
  130. m_p2 = point;
  131. // 转换坐标系
  132. m_p2.x = m_p2.x - m_MouseRect.left + 10;
  133. m_p2.y = m_p2.y - m_MouseRect.top + 25;
  134. // 绘制一条新橡皮筋线
  135. pDC->MoveTo(m_p1);
  136. pDC->LineTo(m_p2);
  137. // 设置m_bDrawed为TRUE
  138. m_bDrawed = TRUE;
  139. // 选回以前的画笔
  140. pDC->SelectObject(pOldPen);
  141. // 恢复成以前的绘制模式
  142. pDC->SetROP2(nOldDrawMode);
  143. delete pPen;
  144. ReleaseDC(pDC);
  145. }
  146. }
  147. else
  148. {
  149. // 判断是否正在拖动
  150. if (m_bIsDraging)
  151. {
  152. // 更改光标
  153. ::SetCursor(::LoadCursor(NULL, IDC_NO));
  154. }
  155. }
  156. // 默认鼠标移动处理事件
  157. CDialog::OnMouseMove(nFlags, point);
  158. }
  159. void CDlgLinerPara::OnLButtonUp(UINT nFlags, CPoint point) 
  160. {
  161. // 当用户释放鼠标左键停止拖动
  162. if (m_bIsDraging)
  163. {
  164. // 判断当前光标是否在绘制区域
  165. if(m_MouseRect.PtInRect(point))
  166. {
  167. // 保存当前鼠标位置
  168. m_p2 = point;
  169. // 转换坐标系
  170. m_p2.x = m_p2.x - m_MouseRect.left + 10;
  171. m_p2.y = m_p2.y - m_MouseRect.top + 25;
  172. if ((m_p1 != m_p2) && (m_p1.x != m_p2.x))
  173. {
  174. // 转换坐标系
  175. m_p1.x = m_p1.x - 10;
  176. m_p1.y = 280 - m_p1.y;
  177. m_p2.x = m_p2.x - 10;
  178. m_p2.y = 280 - m_p2.y;
  179. // 计算斜率和截距
  180. m_fA = (float) (m_p2.y - m_p1.y) / (m_p2.x - m_p1.x);
  181. m_fB = m_p1.y - m_fA * m_p1.x;
  182. // 保存变动
  183. UpdateData(FALSE);
  184. }
  185. // 重绘
  186. InvalidateRect(m_MouseRect, TRUE);
  187. }
  188. else
  189. {
  190. // 用户在绘制区域外放开鼠标左键
  191. // 获取绘图的标签
  192. CWnd* pWnd = GetDlgItem(IDC_COORD);
  193. // 获取设备上下文
  194. CDC* pDC = pWnd->GetDC();
  195. // 设置绘制方式为异或模式
  196. int nOldDrawMode = pDC->SetROP2(R2_XORPEN);
  197. // 创建新的画笔
  198. CPen* pPen = new CPen;
  199. pPen->CreatePen(PS_DOT,1,RGB(0,0,0));
  200. // 选中新画笔
  201. CGdiObject* pOldPen = pDC->SelectObject(pPen);
  202. // 判断是否已经画过橡皮筋线
  203. if (m_bDrawed)
  204. {
  205. // 擦去以前的橡皮筋线
  206. pDC->MoveTo(m_p1);
  207. pDC->LineTo(m_p2);
  208. }
  209. // 选回以前的画笔
  210. pDC->SelectObject(pOldPen);
  211. // 恢复成以前的绘制模式
  212. pDC->SetROP2(nOldDrawMode);
  213. delete pPen;
  214. ReleaseDC(pDC);
  215. }
  216. // 解除对鼠标事件的跟踪
  217. ::ReleaseCapture();
  218. // 重置拖动状态
  219. m_bIsDraging = FALSE;
  220. }
  221. // 默认释放鼠标左键处理事件
  222. CDialog::OnLButtonUp(nFlags, point);
  223. }
  224. void CDlgLinerPara::OnPaint() 
  225. {
  226. // 字符串
  227. CString str;
  228. // 直线和坐标轴二个交点坐标
  229. int x1, y1, x2, y2;
  230. // 设备上下文
  231. CPaintDC dc(this);
  232. // 获取绘制坐标的文本框
  233. CWnd* pWnd = GetDlgItem(IDC_COORD);
  234. // 指针
  235. CDC* pDC = pWnd->GetDC();
  236. pWnd->Invalidate();
  237. pWnd->UpdateWindow();
  238. pDC->Rectangle(0,0,330,300);
  239. // 创建画笔对象
  240. CPen* pPenRed = new CPen;
  241. // 红色画笔
  242. pPenRed->CreatePen(PS_SOLID,2,RGB(255,0,0));
  243. // 创建画笔对象
  244. CPen* pPenBlue = new CPen;
  245. // 蓝色画笔
  246. pPenBlue->CreatePen(PS_SOLID,2,RGB(0,0, 255));
  247. // 选中当前红色画笔,并保存以前的画笔
  248. CGdiObject* pOldPen = pDC->SelectObject(pPenRed);
  249. // 绘制坐标轴
  250. pDC->MoveTo(10,10);
  251. // 垂直轴
  252. pDC->LineTo(10,280);
  253. // 水平轴
  254. pDC->LineTo(320,280);
  255. // 写坐标
  256. str.Format("0");
  257. pDC->TextOut(10, 281, str);
  258. str.Format("255");
  259. pDC->TextOut(265, 281, str);
  260. pDC->TextOut(11, 25, str);
  261. // 绘制X轴箭头
  262. pDC->LineTo(315,275);
  263. pDC->MoveTo(320,280);
  264. pDC->LineTo(315,285);
  265. // 绘制X轴箭头
  266. pDC->MoveTo(10,10);
  267. pDC->LineTo(5,15);
  268. pDC->MoveTo(10,10);
  269. pDC->LineTo(15,15);
  270. // 更改成蓝色画笔
  271. pDC->SelectObject(pPenBlue);
  272. // 计算直线和坐标轴二个交点坐标
  273. if (m_fA >= 0)
  274. {
  275. if (((m_fA * 255 + m_fB) >= 0) && (m_fB < 255))
  276. {
  277. // 计算(x1, y1)坐标
  278. if (m_fB < 0)
  279. {
  280. x1 = (int) (- m_fB/m_fA + 0.5);
  281. y1 = 0;
  282. }
  283. else
  284. {
  285. x1 = 0;
  286. y1 = (int) (m_fB + 0.5);
  287. }
  288. // 计算(x2, y2)坐标
  289. if ((m_fA * 255 + m_fB) > 255)
  290. {
  291. x2 = (int) ((255- m_fB)/m_fA + 0.5);
  292. y2 = 255;
  293. }
  294. else
  295. {
  296. x2 = 255;
  297. y2 = (int) (255* m_fA + m_fB + 0.5);
  298. }
  299. }
  300. else if(((m_fA * 255 + m_fB) < 0))
  301. {
  302. // 转换后所有象素值都小于0,直接设置为0
  303. x1 = 0;
  304. y1 = 0;
  305. x2 = 255;
  306. y2 = 0;
  307. }
  308. else
  309. {
  310. // 转换后所有象素值都大于255,直接设置为255
  311. x1 = 0;
  312. y1 = 255;
  313. x2 = 255;
  314. y2 = 255;
  315. }
  316. }
  317. else  // 斜率小于0
  318. {
  319. if ((m_fB > 0) && (255* m_fA + m_fB < 255))
  320. {
  321. // 计算(x1, y1)坐标
  322. if (m_fB > 255)
  323. {
  324. x1 = (int) ((255- m_fB)/m_fA + 0.5);
  325. y1 = 255;
  326. }
  327. else
  328. {
  329. x1 = 0;
  330. y1 = (int) (m_fB + 0.5);
  331. }
  332. // 计算(x2, y2)坐标
  333. if ((m_fA * 255 + m_fB) < 0)
  334. {
  335. x2 = (int) (- m_fB/m_fA + 0.5);
  336. y2 = 0;
  337. }
  338. else
  339. {
  340. x2 = 255;
  341. y2 = (int) (255* m_fA + m_fB + 0.5);
  342. }
  343. }
  344. else if (m_fB <=0)
  345. {
  346. // 转换后所有象素值都小于0,直接设置为0
  347. x1 = 0;
  348. y1 = 0;
  349. x2 = 255;
  350. y2 = 0;
  351. }
  352. else
  353. {
  354. // 转换后所有象素值都大于255,直接设置为255
  355. x1 = 0;
  356. y1 = 255;
  357. x2 = 255;
  358. y2 = 255;
  359. }
  360. }
  361. // 绘制坐标值
  362. str.Format("(%d, %d)", x1, y1);
  363. pDC->TextOut(x1 + 10, 280 - y1 + 1, str);
  364. str.Format("(%d, %d)", x2, y2);
  365. pDC->TextOut(x2 + 10, 280 - y2 + 1, str);
  366. // 绘制用户指定的线性变换直线(注意转换坐标系)
  367. pDC->MoveTo(x1 + 10, 280 - y1);
  368. pDC->LineTo(x2 + 10, 280 - y2);
  369. // 恢复以前的画笔
  370. pDC->SelectObject(pOldPen);
  371. // 绘制边缘
  372. pDC->MoveTo(10,25);
  373. pDC->LineTo(265,25);
  374. pDC->LineTo(265,280);
  375. // 删除新的画笔
  376. delete pPenRed;
  377. delete pPenBlue;
  378. }