9.1 修改应用程序窗口外观
9.1.1 在窗口创建之前,修改窗口的外观
由于PreCreateWindow(CREATESTRUCT &cs)函数是一个虚函数,并且参数是引用调用,所以在这里修改cs,可以反应在MFC底层代码中,在MFC底层代码调用CreateWindowEx()函数去创建窗口时,它就会用我们修改过的值去创建这个窗口。
例如修改窗口的大小
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
cs.cx=300;
cs.cy=200;
return TRUE;
}
修改应用程序的标题,插入如下代码
<span style="white-space:pre"> </span>cs.style&=~FWS_ADDTOTITLE;
cs.lpszName="更换标题";
9.1.2 在窗口创建以后,修改窗口外观
可以在OnCreate(LPCREATESTRUCT lpCreateStruct)函数中修改。
例如修改窗口最大化功能
<span style="background-color: rgb(255, 255, 255);"><span style="white-space: pre;"> </span>SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_hWnd,GWL_STYLE) & ~WS_MAXIMIZEBOX);</span>
9.2 修改窗口的光标、图标、背景
9.2.1 在窗口创建之前修改
修改图标
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,0,0,LoadIcon(NULL,IDI_WARNING));
return TRUE;
}
修改光标、背景
BOOL CStyleView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,
LoadCursor(NULL,IDC_CROSS),(HBRUSH)GetStockObject(BLACK_BRUSH),0);
cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW);
return CView::PreCreateWindow(cs);
}
9.2.2 在窗口创建之后修改
修改图标
SetClassLong(m_hWnd,GCL_HICON,(LONG)LoadIcon(NULL,IDI_ERROR));
修改光标和背景
int CStyleView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
SetClassLong(m_hWnd,GCL_HBRBACKGROUND,(LONG)GetStockObject(BLACK_BRUSH));
SetClassLong(m_hWnd,GCL_HCURSOR,(LONG)LoadCursor(NULL,IDC_HELP));
return 0;
}
9.3 使用自定义图标(在窗口创建之后使用自定义的图标)
9.3.1 加载图标资源
【资源视图】->【Icon】->【右击】->【添加资源】->【导入】
m_hIcons[0]=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1));
m_hIcons[1]=LoadIcon(theApp.m_hInstance,MAKEINTRESOURCE(IDI_ICON2));
m_hIcons[2]=LoadIcon(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDI_ICON3));
SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hIcons[0]);<span style="white-space:pre"> </span>//在窗口创建之后创建
9.4 状态栏编程
9.4.1 添加状态栏窗格,详见书本P341
9.4.2 为了将字符串显示在状态栏的的窗格上,可以调用CStatusBar类的SetPaneText(index,str);函数。下面是将时间显示在窗格上的例程
CTime t=CTime::GetCurrentTime();
CString str=t.Format("%H:%M:%S");
CClientDC dc(this);
CSize sz=dc.GetTextExtent(str);
int index=0;
index=m_wndStatusBar.CommandToIndex(IDS_TIMER);
m_wndStatusBar.SetPaneInfo(index,IDS_TIMER,SBPS_NORMAL,sz.cx);
m_wndStatusBar.SetPaneText(index,str);
9.5 进度栏的编程
9.5.1 创建
if(!m_progress.m_hWnd)
m_progress.Create(WS_CHILD | WS_VISIBLE ,//| PBS_SMOOTH,
rect,&m_wndStatusBar,123);
else
m_progress.MoveWindow(rect);
m_progress.SetPos(50);
9.5.2 在状态栏中创建
<span style="white-space:pre"> </span>CRect rect;
m_wndStatusBar.GetItemRect(2,&rect);
if(!m_progress.m_hWnd)
m_progress.Create(WS_CHILD | WS_VISIBLE ,//| PBS_SMOOTH,
rect,&m_wndStatusBar,123);
else
m_progress.MoveWindow(rect);
m_progress.SetPos(50);
9.5.3 自定义发送消息,以及消息处理
1. 在头文件stdafx.h中增加一个自定义消息宏
#define UM_USER WM_USER + 1
2. 在于增加新消息的窗口或对话框类的头文件中增加一个回调函数声明,注意要声明为public
afx_msg LRESULT OnUser(WPARAM wParam, LPARAM lParam);
3. 在窗口或对话框的cpp文件的BEGIN_MESSAGE_MAP,END_MESSAGE_MAP 中增加一行
ON_MESSAGE(UM_USER, OnUser)
4. 在窗口或对话框的cpp文件中增加回调函数的实现,如:
LRESULT ThreadDialog::OnUser(WPARAM wParam, LPARAM lParam)
{
TRACE("UM_USER message /n");
return 0;
}
5. 自定义消息的触发
::PostMessage(GetSafeHwnd(), UM_USER, 0, 0);
其中GetSafeHwnd()得到了一个当前窗口的句柄,此消息将发给当前窗口,如果想发送消息给其它
窗口只需改变这个句柄,前提是目的窗口也实现了此消息的处理函数
9.5.4 在状态栏显示进度条
<span style="white-space:pre"> </span><pre name="code" class="cpp">void CMainFrame::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
CRect rect;
m_wndStatusBar.GetItemRect(2,&rect);
if(!m_progress.m_hWnd)
m_progress.Create(WS_CHILD | WS_VISIBLE ,//| PBS_SMOOTH,
rect,&m_wndStatusBar,123);
else
m_progress.MoveWindow(rect);
m_progress.SetPos(50);
// Do not call CFrameWnd::OnPaint() for painting messages
}
9.5.5, 在状态栏中显示鼠标的坐标(在视类中增加WM_MOUSEMOVE的消息响应函数)
void CStyleView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CString str;
str.Format("x=%d,y=%d",point.x,point.y);
//((CMainFrame*)GetParent())->m_wndStatusBar.SetWindowText(str);
//((CMainFrame*)GetParent())->SetMessageText(str);
//((CMainFrame*)GetParent())->GetMessageBar()->SetWindowText(str);
GetParent()->GetDescendantWindow(AFX_IDW_STATUS_BAR)->SetWindowText(str);
CView::OnMouseMove(nFlags, point);
}