作者 陈华涛
一.简单窗体
1.创建窗口类,从CWindowImpl类派生;例子如下:
(代码:myChild.h)
1.1创建一个窗口类
1.1.1弹出式窗口类(myPopup.h)
class CMyPopup :
public CWindowImpl<CMyPopup, CWindow, CFrameWinTraits >
//typedef CWinTraits<WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN
//| WS_CLIPSIBLINGS, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE> CFrameWinTraits;
{
public:
DECLARE_WND_CLASS(L"CMyPopup"); // 注册窗口类
};
1.1.2子窗口类(myChild.h)
class CMyChild :
public CWindowImpl<CMyChild, CWindow, CControlWinTraits >
// typedef CWinTraits<WS_CHILD | WS_VISIBLE
// | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0> CControlWinTraits;
{
public:
DECLARE_WND_CLASS(L"CMyChild");
};
注:创建弹出式窗口类与子窗口类都是派生于CWindowImpl,不同的是这窗口风格,即是CWindowImpl的第三个参数,详见MSDN;
注册窗口类也可以用
DECLARE_WND_CLASS_EX(
WndClassName, // 类名
style, // 风格,比如可以设置当大小发生变化是是否发生重绘,设置关闭按钮不可用等,详见MSDN中的WNDCLASSEX里的style;
bkgnd); // 窗口的背景颜色,详见MSDN中WNDCLASSEX里的hbrBackground;
DECLARE_WND_CLASS(L"CMyChild"); 等于DECLARE_WND_CLASS_EX(L"CMyChild",CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,COLOR_WINDOW);
1.2在类中添加消息映射和处理函数;
BEGIN_MSG_MAP(CMyChild)
// 消息映射添加在这里
MESSAGE_HANDLER(WM_PAINT, OnPaint) // 这是重绘的消息映射
MESSAGE_HANDLER(WM_DESTROY, OnDestroy) // 销毁消息映射
END_MSG_MAP()
LRESULT OnPaint(UINT, WPARAM, LPARAM, BOOL&) // 处理函数
{
RECT rc;
this->GetClientRect(&rc);
PAINTSTRUCT ps;
HDC hdc=this->BeginPaint(&ps);
// 重绘内容在这里
::DrawText(ps.hdc,str,len,&rc,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
this->EndPaint(&ps);
return 0;
}
LRESULT OnDestroy(UINT, WPARAM, LPARAM, BOOL&) // 这里是对销毁消息的处理
{
return 0;
}
注:窗口初始化消息为WM_CREATE,下面介绍的对话框初始化消息为WM_INITDIALOG;
2.使用自己创建的窗口类来创建窗体;
2.1创建窗口类对象
CMyChild child;
CMyPopup popup;
2.2用创建的窗口类对象来Create窗体
HWND childhwnd = child.Create(this->m_hWnd,rc,L"子窗");
创建一个可见的什么都没有的子窗体如下图:
HWND popuphwnd = popup.Create(this->m_hWnd,rc,L"弹出子窗");
popup.ShowWindow(SW_SHOW); // 由于这个类是没有设置可见的,所以要加上这句;
创建一个可见的弹出式窗体,
如图:
,其他设置参见MSDN。
原函数定义:
HWND Create(HWND hWndParent, // 父窗句柄
_U_RECT rect = NULL, // 子窗大小及位置(相对于父窗客户区的位置)
LPCTSTR szWindowName = NULL,// 子窗标题
DWORD dwStyle = 0, // 子窗的风格,一般在CWindowImpl第三个参数设置,详见MSND的Window Styles
DWORD dwExStyle = 0, // 扩展风格详见MSND的CreateWindowEx中的dwExStyle
_U_MENUorID MenuOrID = 0U, // 这个窗口的ID
LPVOID lpCreateParam = NULL)//
3.设置窗体大小、位置;
(参见myWindow.h修改子窗体按钮的处理函数)
::SetWindowPos(
IN HWND hWnd, // 要设置的窗体句柄
IN HWND hWndInsertAfter, // Z轴的位置
IN int X, // 位置
IN int Y, // 位置
IN int cx, // 宽度
IN int cy, // 长度
IN UINT uFlags); // 窗口尺寸和定位的标志
第二个参数hWndInsertAfter如果是句柄,则表示显示在这个句柄窗体的下方,也可以用下面一些参数:
HWND_TOP:在Z轴最顶端
HWND_BOTTOM:在Z轴最底端
HWND_TOPMOST:置于非顶层窗口之上,即使窗口未被激活窗口也将保持顶级位置
最后一个参数标示常用如下:
设置SWP_HIDEWINDOW,则是隐藏窗口;
设置SWP_NOMOVE:维持当前位置(即忽略X和Y参数);
设置SWP_NOSIZE:维持当前尺寸(即忽略cx和Cy参数);
设置SWP_NOZORDER:维持当前Z序(即忽略hWndlnsertAfter参数);
其他详见MSDN
4.重绘
::InvalidateRect( // 将客户区标记为无效,并产生WM_PAINT消息,放到消息队列中,等系统去执行OnPaint,不是直接执行OnPaint()
HWND hwnd; // 要重绘的句柄
LPCRECT lpRect, // 重绘的区域
BOOL bErase) // 是否擦除背景,FALSE为不擦除,TRUE为擦除;
::RedrawWindow( // 通知系统更新区域无效,并立即执行OnPaint
IN HWND hWnd,
IN CONST RECT *lprcUpdate,
IN HRGN hrgnUpdate,
IN UINT flags);
最后一个参数设置如下可以重画该客户区域上的子窗口
RDW_ALLCHILDREN 重画操作包括子窗口
相反的:RDW_NOCHILDREN 重画操作排除子窗口
5.隐藏窗口,禁用窗口
ShowWindow(
IN HWND hWnd,
IN int nCmdShow); // SW_HIDE:隐藏窗口,SW_SHOW:显示窗口,还有最大化窗口等等,详见MSDN
EnableWindow(
IN HWND hWnd,
IN BOOL bEnable); // TRUE时,窗口正常,FALSE时,窗口禁用;
6.获取活动窗体
GetActiveWindow(); // 返回当前活动窗体的句柄;子窗体的话,是返回父窗的句柄,独立窗体则返回它自己的句柄
GetForegroundWindow(); // 该函数返回前台窗口(用户当前工作的窗口)。系统分配给产生前台窗口的线程一个稍高一点的优先级。
二、对话框
1.使用向导添加对话框类;(演示)
1.1把类与对话框资源联系
在对话框类中添加enum { IDD = IDD_MYDLG };就可以把类跟对话框资源进行关联;
2.创建和销毁对话框;
2.1模式对话框的创建和销毁
模式对话框创建使用DoModal();
销毁使用EndDialog();
2.2非模式对话框的创建和销毁
2.2.1创建对话框
CmyDlg dlg; // 创建一个对象
HWND dlghwnd = dlg.Create(NULL); // 创建对话框,参数如果为NULL,则对话框初始位置在屏幕的左上角,如果是父窗句柄的话,位置是在父窗客户区的左上角;
dlg->ShowWindow(SW_SHOW); // 显示对话框
2.2.2销毁对话框
修改关闭对话框处理函数
LRESULT OnClickedCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
if(this->m_bModal) // 判断是不是模式对话框
EndDialog(wID); // 模式对话框用这个
else
DestroyWindow(); // 非模式对话框用这个
return 0;
}
3.重绘对话框;
3.1添加消息映射和消息处理函数
3.2重绘对话框
注意:如果对话框上有控件或子窗口,在重绘对话框时,有时候会出现控件或子窗口会被对话框背景色给覆盖,处理:可以先重绘对话框再重绘各个控件或窗口,也可以重绘对话框时不要重绘控件及子窗口的位置。
4.设置对话框的大小和位置;
与窗体一样;
举报/反馈

聊聊密码学

3197获赞 320粉丝
交流一些有趣、冷门、实用的知识及感悟。
关注
0
0
收藏
分享