模态对话框:
CTestDlg dlg;
dlg.DoModal();
非模态对话框:
CTestDlg dlg;
dlg.Create(IDD_DIALOG1,this);
dlg.ShowWindow(SW_SHOW);
CTestDlg* pDlg;
pDlg->Create(IDD_DIALOG1,this);
pDlg->ShowWindow(SW_SHOW);
第一种,在析构函数中释放:
delete pDlg;
pDlg = NULL;
第二种,在对话框类中重载PostNcDestroy()函数:
//此函数在窗口被销毁后调用
void CTestDlg::PostNcDestroy()
{
delete pDlg;
pDlg = NULL;
CDialog::PostNcDestroy();
}
创建:m_btn.Create();//函数中的参数具体的再查
销毁:m_btn.DestroyWindow();
void CTestDlg::OnBnClickedBtnCreate()
{
// TODO: Add your control notification handler code here
if (!m_bFlag)
{
m_Btn.Create(_T("hello"),BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD,
CRect(0,0,100,100),this,100);
m_bFlag = true;
}
else
{
m_Btn.DestroyWindow();
m_bFlag = false;
}
}
一个知识点:Windows消息分为三类:标准消息、命令消息和通告消息;
像按钮的单击、列表框的选择这类消息都属于通告消息;
第一、静态文本控件在默认状态下是不发送通告消息的
第二、使一个静态文本控件响应鼠标单击消息:
//首先,改变控件的ID;
//之后,在其属性的对话框上选中Notify选项,Notify消息是在控件被点击或双击的时候发送给其父窗口的
void CTestDlg::OnStnClickedStaticNum()
{
// TODO: Add your control notification handler code here
CString strTemp;
this->GetDlgItemText(IDC_STATIC_Num,strTemp);
if (_T("Number 1:") != strTemp)
{
this->SetDlgItemText(IDC_STATIC_Num,(LPCTSTR)_T("Number 1:"));
}
else
{
this->SetDlgItemText(IDC_STATIC_Num,(LPCTSTR)_T("数字 1:"));
}
}
这里讲述了大约7中方式,但是本人习惯用的一种方式如下:
第一步:选择一个控件,拖拽到对话框上
第二步:给控件一个能够清楚表述的ID
第三步:利用vs编译器,给控件添加变量,可以选择值类型或者控件类型,OK了
知识点1:DoDataExchange函数内部实现了对话框控件与类成员变量的关联。
知识点2:MFC提供了多种以DDX_为前缀的函数,这些函数分别用于不同控件的数据交换。
知识点3:MFC提供了多种以DDV_为前缀的函数,这些函数分别用于数据校验。
知识点4:EM_开头的消息是指编辑框控件消息(Edit Control Message)。
原理:在对话框的某一位置,引入一个Picture Control控件(直线状),点击伸缩功能的时候,记录对话框本身的位置和Picture Control控件的位置,之后的扩展和伸缩的时候就显示对应大小的矩形即可,下面直接上关键段代码:
void CDlgTest::OnBnClickedBtnControl()
{
// TODO: Add your control notification handler code here
CString strBtnText;
if (GetDlgItemText(IDC_BTN_Control,strBtnText),_T("收缩") == strBtnText)
{
SetDlgItemText(IDC_BTN_Control,_T("扩展"));
}
else
{
SetDlgItemText(IDC_BTN_Control,_T("收缩"));
}
static CRect rtLarge;//扩展后的对话框位置
static CRect rtSmall;//收缩后的对话框位置
if (rtLarge.IsRectNull())
{
GetWindowRect(&rtLarge);
CRect rtPC;//Picture Control控件的位置
GetDlgItem(IDC_Separator)->GetWindowRect(&rtPC);
rtSmall.left = rtLarge.left;
rtSmall.top = rtLarge.top;
rtSmall.right = rtLarge.right;
rtSmall.bottom = rtPC.bottom;
}
if (_T("收缩") == strBtnText)
{
SetWindowPos(NULL,0,0,rtSmall.Width(),rtSmall.Height(),SWP_NOMOVE | SWP_NOZORDER);
}
else
{
SetWindowPos(NULL,0,0,rtLarge.Width(),rtLarge.Height(),SWP_NOMOVE | SWP_NOZORDER);
}
}
Active Window(活动窗口),可以是前台窗口,也可以是后台窗口。关键就在于标题栏高亮。活动窗口必须是顶层窗口。
Foreground Window(前台窗口),可以是活动的,也可以是非活动的。
Focused Window(焦点窗口),就是拥有键盘输入的窗口。
用SetWindowLong函数来改变窗口的窗口过程函数,实现输入焦点在子控件间依次传递,上代码进行分析
// DlgTest.cpp : implementation file
//
#include "stdafx.h"
#include "Persist.h"
#include "DlgTest.h"
// CDlgTest dialog
IMPLEMENT_DYNAMIC(CDlgTest, CDialog)
CDlgTest::CDlgTest(CWnd* pParent /*=NULL*/)
: CDialog(CDlgTest::IDD, pParent)
{
}
CDlgTest::~CDlgTest()
{
}
void CDlgTest::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CDlgTest, CDialog)
ON_BN_CLICKED(IDC_BTN_Control, &CDlgTest::OnBnClickedBtnControl)
END_MESSAGE_MAP()
// CDlgTest message handlers
void CDlgTest::OnBnClickedBtnControl()
{
// TODO: Add your control notification handler code here
CString strBtnText;
if (GetDlgItemText(IDC_BTN_Control,strBtnText),_T("收缩") == strBtnText)
{
SetDlgItemText(IDC_BTN_Control,_T("扩展"));
}
else
{
SetDlgItemText(IDC_BTN_Control,_T("收缩"));
}
static CRect rtLarge;//扩展后的对话框位置
static CRect rtSmall;//收缩后的对话框位置
if (rtLarge.IsRectNull())
{
GetWindowRect(&rtLarge);
CRect rtPC;//Picture Control控件的位置
GetDlgItem(IDC_Separator)->GetWindowRect(&rtPC);
rtSmall.left = rtLarge.left;
rtSmall.top = rtLarge.top;
rtSmall.right = rtLarge.right;
rtSmall.bottom = rtPC.bottom;
}
if (_T("收缩") == strBtnText)
{
SetWindowPos(NULL,0,0,rtSmall.Width(),rtSmall.Height(),SWP_NOMOVE | SWP_NOZORDER);
}
else
{
SetWindowPos(NULL,0,0,rtLarge.Width(),rtLarge.Height(),SWP_NOMOVE | SWP_NOZORDER);
}
}
void CDlgTest::OnOK()
{
// TODO: Add your specialized code here and/or call the base class
//GetFocus()->GetNextWindow()->SetFocus();
//GetDlgItem(IDC_EDIT1)->GetNextWindow()->SetFocus();
GetNextDlgTabItem(GetFocus())->SetFocus();
//CDialog::OnOK();
}
WNDPROC prevProc;
LRESULT CALLBACK WinWCProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
if (uMsg == WM_CHAR && wParam == 0x0d)
{
/*::SetFocus(::GetNextWindow(hwnd,GW_HWNDNEXT));*/
//::SetFocus(::GetWindow(hwnd,GW_HWNDNEXT));
//::SetFocus(::GetNextDlgTabItem(GetParent(hwnd),hwnd,FALSE));
return 1;
}
else
{
return prevProc(hwnd,uMsg,wParam,lParam);
}
}
BOOL CDlgTest::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
prevProc = (WNDPROC)::SetWindowLong(GetDlgItem(IDC_EDIT1)->m_hWnd,GWL_WNDPROC,
(LONG)WinWCProc);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
(10)需要掌握的函数
1.SendMessage
2.EM_GETSEL消息和EM_SETSEL消息,EM_开头的消息是编辑框控件消息
3.SetWindowLong
4.GetNextWindow和GetWindow,后者更为强大
5.GetNextDlgTabItem
6.回调函数WinProc是静态函数,在静态函数中尽量使用Win32平台的全局函数