📄 program.txt
字号:
==============================WM_CTLCOLOR==========================================
WM_CTLCOLOR是一个由控制(Control)发送给它父窗口的通知消息(Notification message)。
生成一个标准的单文档应用程序框架,假设应用程序的名称为Color。我将利用它的About对话框做示范。
在About dialog中添加两个Edit control,设定其ID为IDC_EDIT1与IDC_EDIT2;
第一种方法(对应于IDC_EDIT1): 按照标准的Windows编程,由其父窗口的消息处理函数负责处理WM_CTLCOLOR消息。
1. 在CAboutDlg中添加一个数据成员:HBRUSH m_brMine;
2. 利用向导映射AboutDlg的WM_CTLCOLOR消息,产生函数:HBRUSH CAboutDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);pDC是AboutDlg的设备上下文,pWnd是AboutDlg中发送该消息的control指针,nCtlColor市Control的类型编码。对其进行如下修改:
HBRUSH CAboutDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
if ((pWnd->GetDlgCtrlID() == IDC_EDIT1) && (nCtlColor == CTLCOLOR_EDIT))
{
COLORREF clr = RGB(255,0,0);
pDC->SetTextColor(clr); //设置红色的文本
clr = RGB(0,0,0);
pDC->SetBkColor(clr); //设置黑色的背景
m_brMine = ::CreateSolidBrush(clr);
return m_brMine; //作为约定,返回背景色对应的刷子句柄
}
else
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
return hbr;
}
}
第二种方法(对应于IDC_EDIT2): 利用MFC 4.0的新特性: Message relection。
1.利用向导添加一个新的类:CColorEdit,基类为CEdit;
2.在CColorEdit中添加一个数据成员: HBRUSH m_bkBrush;
3.利用向导映射CColorEdit的"=WM_CTLCOLOR"消息,产生函数:HBRUSH CColorEdit::CtlColor(CDC* pDC, UINT nCtlColor); 对其进行如下修改:
HBRUSH CColorEdit::CtlColor(CDC* pDC, UINT nCtlColor)
{
COLORREF clr = RGB(0,0,0);
pDC->SetTextColor(clr); //设置黑色的文本
clr = RGB(255,0,0);
pDC->SetBkColor(clr); //设置红色的背景
m_bkBrush = ::CreateSolidBrush(clr);
return m_bkBrush; //作为约定,返回背景色对应的刷子句柄
}
4.利用向导为IDC_EDIT2生成一个数据成员CColorEdit m_coloredit;
5.在定义CAboutDlg的color.cpp文件中加入:#include "coloredit.h"
=================================加入全局变量的办法===============================================
第一种办法:假设这个全局变量int MyGlobal在View中使用得最多,于是在View的CPP文件中加入这个变量的声明,然后在StdAfx.h中加入extern int MyGlobal即可。
第二种办法:在App中加入这个全局变量int MyGlobal(public型,实际已经不是真正意义上的全局变量,而是App的数据成员),然后在需要的地方利用如下代码访问它:
CColorApp * pApp = (CColorApp *)AfxGetApp();
pApp->MyGlobal = 8888;
=================================利用GDI中的Path画一个奇异的矩形==================================
我将在View的OnPaint()中实现它。
为了代码清晰,为View添加两个方法,DrawSpecialRect()用来画出这个矩形,DrawSinLine()用来画出一条Sin()函数曲线。
因为要使用sin()函数,所以还必须在StdAfx.h中#include <math.h>。
void CChildView::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
// I will draw a rectangle with a sin() edge.
dc.BeginPath();
CRect rectTemp(200,200,500,400);
DrawSpecialRect(dc, rectTemp);
dc.EndPath();
CBrush MyBrush (RGB(255,0,255));
CBrush * OldBrush = (CBrush *) dc.SelectObject(&MyBrush);
dc.StrokeAndFillPath();
dc.SelectObject(OldBrush);
// Do not call CWnd::OnPaint() for painting messages
}
void CChildView::DrawSpecialRect(CPaintDC &dc, CRect rect)
{
CPoint pt1, pt2, pt3, pt4;
pt1 = rect.TopLeft();
pt2 = pt1 + CSize(rect.Width(), 0);
pt3 = rect.BottomRight();
pt4 = pt1 + CSize(0, rect.Height());
dc.MoveTo(pt1);
DrawSinLine(dc, pt1, pt2);
dc.LineTo(pt3);
dc.LineTo(pt4);
dc.LineTo(pt1);
}
void CChildView::DrawSinLine(CPaintDC &dc, CPoint pt1, CPoint pt2)
{
// Note: (pt1.y == pt2.y) && (pt2.x > pt1.x)
// I will draw the line with 1000 points in two circle of sin();
double step = double(pt2.x - pt1.x) / 1000;
double x, y;
for (x = 0; x <= 1000; x++)
{
y = sin(8*3.1415926*x/1000); // 1000 points adapts to 4*Pi
dc.LineTo(pt1.x+ int(x*step),pt1.y-int(y*20));
}
}
============================== 在状态条中显示鼠标的设备坐标与逻辑坐标 ======================
显示器的设备坐标系的原点在客户区的左上角,x轴向右增长,y轴向下增长。
我们要设置的逻辑坐标系的原点则在客户区的中心,x轴向右增长,y轴向上增长,如一个笛卡尔坐标系一般。
为CChildView添加一个成员函数void OnPrepareDC(CDC * pDC, CPrintInfo * pInfo = NULL);
void OnPrepareDC(CDC * pDC, CPrintInfo * pInfo)
{
CRect rect;
// Set the MapMode to LOMETRIC (0.1mm),Right-Up direction.
pDC->SetMapMode (MM_LOMETRIC);
// Set the origin of logical coordinate to the center of client area.
GetClientRect(rect);
pDC->SetViewportOrg(rect.Width()/2, rect.Height()/2);
}
为CChildView响应鼠标移动消息,并在状态条中显示鼠标的坐标值。m_ptMouse数据成员是原打算做十字交叉线用的,在此使用无意义。
void CChildView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CClientDC dc(this);
CString str;
OnPrepareDC(&dc);
//To access CMainFrame, you need include file mainfrm.h
CMainFrame * pFrame = (CMainFrame *) AfxGetApp()->m_pMainWnd;
//To access m_wndStatusBar, you need public the member variable.
CStatusBar * pStatus = (CStatusBar *) &pFrame->m_wndStatusBar;
m_ptMouse = point;
str.Format ("设备坐标 X=%i pixel, Y=%i pixel", m_ptMouse.x, m_ptMouse.y);
pStatus->SetPaneText(1, str);
dc.DPtoLP(&m_ptMouse);
str.Format ("逻辑坐标 X=%i * 0.1mm, Y=%i * 0.1mm", m_ptMouse.x, m_ptMouse.y);
pStatus->SetPaneText(2, str);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -