吕鑫MFC学习系列六

来源:互联网 发布:淘宝店怎么设置限购 编辑:程序博客网 时间:2024/05/16 01:40

这一章学习的相关知识框架:

一、根据主窗口类型,MFC软件工程可以分为以下几种架构模型:
1、SDI(Single Document Interface):单文档界面,一个主框架窗口下只能编辑一份文档。
例如:记事本和画笔等。
2、MDI(Multiple Document Interface):多文档界面,一个主框架窗口下可以同时编辑多份文档。
例如:VC++6.0,Photoshop等软件。
3、基于对话框的软件模型:主窗口是通过资源管理器,在对话框模板内摆放控件编辑而成的。
多数用于开发小规模软件,例如:任务管理器。
4、其他自定义窗口做主窗口:主窗口既不是框架也不是对话框,而是直接开发通用窗口类CWnd而成。
例如:输入法窗口、QQ和360软件等,有时这类软件也都可以使用框架或对话框模式来代替开发而成。

对话框常用相关消息映射函数:
二、对话框初始化消息:
1、WM_CREATE:通用窗口初始化消息
窗口还未显示出来,只有父窗口,子窗口还没创建
2、WM_INITDIALOG:对话框窗口专用消息
子窗口已经全部创建完成,可以调用和操作子窗口

三、对话框关闭过程消息:
1、WM_SYSCOMMAND:管理所有系统菜单和系统按钮消息
包括通过最大化、最小化、移动、大小和关闭等
2、WM_CLOSE:是WM_SYSCOMMAND消息的一个专用关闭的分支
在此消息处理过程可以取消本次关闭任务
3、IDCANCEL按钮消息:不但用于按钮回调消息,也是系统按钮关闭窗口的回调
执行真正关闭对话框函数EndDialog,在此消息处理过程可以取消本次关闭任务
4、WM_DESTROY:通用窗口销毁消息
窗口已经在屏幕中消失了,但是自身窗口和窗口内的控件都还可以调用
在此消息处理过程可以取消本次关闭任务

四、非模式对话框:
1、在调用EndDialog函数关闭时,非模式对话框只是隐藏没有真正关闭;
2、在调用DestroyWindow函数关闭时,只是隐藏没有真正关闭;
3、DestroyWindow函数时通用摧毁窗口的函数,适用于对话框、控件、框架和视图等。
五、CWnd成员函数:
1、DestroyWindow
2、Create和CreateEx
3、获取窗口句柄:
a)pWnd->m_hWnd:直接调用前最好判断一下指针是否为空。
b)operator HWND():自动类型转换,将对象转换为句柄。
c)GetSafeHwnd():可以避免的一种方法,因为指针为空造成的软件崩溃。

五、通用窗口风格:
#define WS_OVERLAPPED       0x00000000L
#define WS_POPUP            0x80000000L
#define WS_CHILD            0x40000000L
#define WS_MINIMIZE         0x20000000L //一般适用于主窗口
#define WS_VISIBLE          0x10000000L
#define WS_DISABLED         0x08000000L
#define WS_CLIPSIBLINGS     0x04000000L
#define WS_CLIPCHILDREN     0x02000000L
#define WS_MAXIMIZE         0x01000000L //一般适用于主窗口
#define WS_CAPTION          0x00C00000L     //一般适用于主窗口 
/* WS_BORDER | WS_DLGFRAME  */
#define WS_BORDER           0x00800000L
#define WS_DLGFRAME         0x00400000L //一般适用于主窗口 
#define WS_VSCROLL          0x00200000L
#define WS_HSCROLL          0x00100000L
#define WS_SYSMENU          0x00080000L
#define WS_THICKFRAME       0x00040000L
#define WS_GROUP            0x00020000L
#define WS_TABSTOP          0x00010000L

#define WS_MINIMIZEBOX      0x00020000L
#define WS_MAXIMIZEBOX      0x00010000L


#define WS_TILED            WS_OVERLAPPED
#define WS_ICONIC           WS_MINIMIZE
#define WS_SIZEBOX          WS_THICKFRAME
#define WS_TILEDWINDOW      WS_OVERLAPPEDWINDOW

这节做的例子是模态与非模态:

首先新建MFC应用程序,Test,然后添加两个按钮,分别命名为模式对话框和非模式,然后分别实现两个按钮的功能。

模式对话框通俗的说就是在主窗口打开一个副窗口,只有关闭副窗口才能处理主窗口,而非模式是在主窗口打开一个副窗口,然后还可以继续打开n个副窗口。

模式对话框添加的是一个关于软件的窗口:


其中图标是添加图片控件,Type选择Icon,Image选择IDR_MAINFRAME,文字添加一个Static Text控件,修改文字内容即可

非模式添加的对话框是一个聊天对话框:


这个比较简单,需要修改的Multiline,Auto HScroll,Vertical Scroll。

再分别添加类向导关联到主App类。

具体每一个函数怎么实现,不一一详细说明了,函数顺序就是按照程序运行先后排列的,cpp类的主要代码如下:

// TestDlg.cpp : 实现文件#include "stdafx.h"#include "Test.h"#include "TestDlg.h"#include "AboutDlg.h"#include "ChatDlg.h"#include "afxdialogex.h"#ifdef _DEBUG#define new DEBUG_NEW#endifCTestDlg::CTestDlg(CWnd* pParent /*=NULL*/): CDialogEx(CTestDlg::IDD, pParent){m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}void CTestDlg::DoDataExchange(CDataExchange* pDX){CDialogEx::DoDataExchange(pDX);}BEGIN_MESSAGE_MAP(CTestDlg, CDialogEx)ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BUTTON1, &CTestDlg::OnBnClickedButton1)ON_BN_CLICKED(IDC_BUTTON2, &CTestDlg::OnBnClickedButton2)ON_WM_CREATE()ON_WM_DESTROY()ON_WM_SYSCOMMAND()ON_WM_CLOSE()ON_BN_CLICKED(IDOK, &CTestDlg::OnBnClickedOk)ON_BN_CLICKED(IDCANCEL, &CTestDlg::OnBnClickedCancel)END_MESSAGE_MAP()//窗口未显示出来,只有父窗口没有子窗口int CTestDlg::OnCreate(LPCREATESTRUCT lpCreateStruct){if (CDialogEx::OnCreate(lpCreateStruct) == -1)return -1;SetWindowText(L"OnCreate");//GetDlgItem(IDC_BUTTON1)->SetWindowText(L"测试");return 0;}//通用窗口初始化消息//子窗口已经就绪,可以操作子窗口BOOL CTestDlg::OnInitDialog(){CDialogEx::OnInitDialog();SetWindowText(L"OnInitDialog");//GetDlgItem(IDC_BUTTON1)->SetWindowText(L"测试");// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动//  执行此操作SetIcon(m_hIcon, TRUE);// 设置大图标SetIcon(m_hIcon, FALSE);// 设置小图标// TODO:  在此添加额外的初始化代码return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE}// 如果向对话框添加最小化按钮,则需要下面的代码//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,//  这将由框架自动完成。void CTestDlg::OnPaint(){if (IsIconic()){CPaintDC dc(this); // 用于绘制的设备上下文SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);// 使图标在工作区矩形中居中int cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;// 绘制图标dc.DrawIcon(x, y, m_hIcon);}else{CDialogEx::OnPaint();}}//当用户拖动最小化窗口时系统调用此函数取得光标//显示。HCURSOR CTestDlg::OnQueryDragIcon(){return static_cast<HCURSOR>(m_hIcon);}void CTestDlg::OnBnClickedButton1(){CAboutDlg dlg;dlg.DoModal();}//必须在堆内申请对象,或在成员变量内申请对象void CTestDlg::OnBnClickedButton2(){//非模式对话框createCChatDlg *pDlg=new CChatDlg;pDlg->Create(IDD_CHAT_DLG,GetDesktopWindow());//获取独立的窗口pDlg->ShowWindow(SW_SHOW);/*CChatDlg dlg;dlg.Create(IDD_CHAT_DLG, GetDesktopWindow());dlg.ShowWindow(SW_SHOW);*/}//管理所有系统菜单和系统按钮消息void CTestDlg::OnSysCommand(UINT nID, LPARAM lParam){/*switch (nID){case SC_CLOSE:ShowWindow(SW_MINIMIZE);return;case SC_MINIMIZE:return;}CDialogEx::OnSysCommand(nID, lParam);*/}void CTestDlg::OnClose(){//WM_CLOSE:是WM_SYSCOMMAND消息的一个专用关闭的分支ShowWindow(SW_MINIMIZE);//CDialogEx::OnClose();}void CTestDlg::OnBnClickedOk(){CDialogEx::OnOK();}//IDCANCEL按钮消息:不但用于按钮回调消息,也是系统按钮关闭窗口的回调void CTestDlg::OnBnClickedCancel(){CDialogEx::OnCancel();}//通用窗口销毁消息,窗口已经消失了//无法取消关闭过程了void CTestDlg::OnDestroy(){CDialogEx::OnDestroy();CString str;GetDlgItemText(IDC_BUTTON1, str);}
结果图:


模式与非模式的区别具体看代码中的DoModal()和Create()。

========================================================================================================

 一个MFC软件工程由至少一个CWnd类的派生类和一个CWinApp派生类,
因此这两个类是MFC工程中最重要的两个类。
一、CWnd类成员函数:主要就是一个核心成员变量m_hWnd。
1、DestroyWindow:摧毁窗口。
2、Create和CreateEx:创建窗口,CreateEx创建时可以指定扩展风格。
3、获取窗口句柄:
a)pWnd->m_hWnd:直接调用前最好判断一下指针是否为空。
b)operator HWND():自动类型转换,将对象转换为句柄。
c)GetSafeHwnd():可以避免的a方法,因为指针为空造成的软件崩溃。
4、由句柄转为CWnd对象:
a)CWnd::FromHandle:生成一个临时性窗口类指针,只限于在当前函数内使用。
b)Attach和Detach:为一个CWnd对象嫁接和移除窗口句柄。
c)SubclassWindow和UnsubclassWindow:子类化和反子类化,还能通过子类接收窗口消息。
d)SubclassDlgItem:子类化指定ID对应的控件窗口,还能通过子类接收窗口消息。
5、获取和设置窗口信息:
a)GetWindowText和SetWindowText:获取和设置窗口的标题文字。
b)GetStyle和ModifyStyle:获取和设置窗口的基础风格。
c)GetExStyle和ModifyStyleEx:获取和设置窗口的扩展风格
6、计时器:
a)SetTimer:设置计时器
b)KillTimer:清除计时器
7、窗口操作:
a)ShowWindow:改变窗口显示状态,包括最大化最小化和隐藏等等。
b)EnableWindow:激活或者禁用窗口
c)MoveWindow:移动窗口(父窗口基于坐标系是屏幕坐标系,如果是子窗口坐标系是父窗口的客户区)
d)CenterWindow:居中窗口
e)SetWindowPos:可以同时对窗口的x,y,z轴方向进行修改,常用于前端显示功能的开发。
(如果是子窗口沿着z轴方向调整层叠顺序,如果是父窗口主要用于调整前端显示)
f)BringWindowToTop:不但可以再xy轴方向移动窗口,而且在z轴方向也可以移动
g)SetForegroundWindow:将任务栏内的一个主窗口推到前台
(对主窗口BringWindowToTop也能起到同样的功能)
h)SetActiveWindow:在同一进程内所有窗口中的一个窗口设置为激活状态。
i)FlashWindow:
8、窗口状态:
a)IsWindowVisible:判断窗口是否可见或被隐藏。
b)IsIconic:判断是否最小化
c)IsZoomed:判断是否最大化
d)IsWindowEnabled:判断窗口是激活或者禁用状态。
e)GetWindowRect:获取以屏幕坐标系为基础的窗口矩形区域。
f)GetClientRect:获取以对象关联的以其客户区为基础的客户区矩形区域。(left和top必然是0)
g)GetTopWindow:获取当前父窗口内所有子窗口中最底(top)的子窗口。
h)GetForegroundWindow:获取任务栏内目前正在前台的一个主窗口。
i)GetActiveWindow:在同一进程内所有窗口中处于激活状态的窗口。
9、窗口关系:
a)GetDlgItem:根据ID获取一个子窗口的对象地址(包含窗口句柄)
b)GetDlgItemText和SetDlgItemText:根据ID获取或设置一个子窗口标题文字
c)GetDlgItemInt和SetDlgItemInt:根据ID获取或设置一个子窗口内显示的数字
d)SetDlgCtrlID和GetDlgCtrlID:根据窗口对象内的句柄获取或设置该窗口的ID。
e)GetParent和IsChild:求出父窗口和判断一个窗口是否为子窗口
f)GetWindow:
g)GetNextWindow:
10、刷新函数:
Invalidate和InvalidateRect:
UpdateWindow:
RedrawWindow:
ScreenToClient和ClientToScreen:
二、等价关系:
1、IsChild与GetParent:
2、IsIconic与GetStyle()&WS_MINIMIZE:
3、IsZoomed与GetStyle()&WS_MAXIMIZE:
4、IsWindowVisible与GetStyle()&WS_VISIBLE:
5、SetDlgItemText与GetDlgItem(..)->SetWindowText

接着上面继续实现上面的几个函数:

先添加销毁函数的按钮,实现销毁确定键的功能,然后通过Create函数实现创建编辑框和按钮,

首先,学习销毁函数,第一步获取Dlg的句柄,第二步判断并消除空句柄的可能,调用DestroyWindow()销毁IDOK

其次,再点开MSDN帮助文档,查看CWnd的EXAMPLE:

void CMyDlg::OnCreateStatic() {   // m_pWndStatic is a CWnd* member of CMyDlg   m_pWndStatic = new CWnd;   m_pWndStatic->Create(_T("STATIC"), _T("Hi"), WS_CHILD | WS_VISIBLE,       CRect(0, 0, 20, 20), this, 1234);}
然后仿照例子实现自己的功能,在TestDlg.h文件中添加:

public:CWnd m_wnd, m_wButton;enum{IDC_NAME = 1008,IDC_TEST=1009};
再实现create按钮,代码见:

void CTestDlg::OnBnClickedButton4(){//m_pWndStatic = new CWnd;//m_pWndStatic->Create(_T("Edit"), _T("Hi"), WS_CHILD | WS_VISIBLE,//CRect(0, 0, 20, 20), this, IDC_NAME);//m_wnd.Create(_T("Edit"), _T(""), WS_CHILD | WS_VISIBLE, CRect(30, 130, 130, 170), this, IDC_NAME);m_wnd.CreateEx(WS_EX_CLIENTEDGE, _T("Edit"), _T(""), WS_CHILD | WS_VISIBLE, CRect(30, 130, 130, 170), this, IDC_NAME);m_wButton.Create(_T("BUTTON"), _T("测试create"), WS_CHILD | WS_VISIBLE, CRect(30, 180, 130, 220), this, IDC_TEST);}
完成这一节的基本功能,结果图:

先销毁确定键,然后创建编辑框和按钮



0 0
原创粉丝点击