资源添加对话框,双击对话框创建对话框类。
在menu中增加对话框菜单项,将其设为非popup的,并为其在view类下添加响应函数。View类中增加#include "TestDlg.h"。
在响应函数void CMyboleView::OnDialog()中:
CTestDlg dlg;
dlg.DoModal();
模态对话框即程序运行到此处被阻滞,停在此处,不可以执行其他内容。
CTestDlg m_dlg;
m_dlg .Create (IDD_DIALOG1,this); //this为对话框父窗口的指针
m_dlg .ShowWindow (SW_SHOW);
注意:这里非模态对话框要设置为成员变量。另外非模态对话框点击非模态对话框的OnOK按纽时,它并没有关闭,而是隐藏了。需要调用destroyWindow()。
在对话框资源中从工具中拖一个button到对话框中,将其名称改为ADD,为其在CTestDlg类中添加响应函数。
void CTestDlg::OnBnClickedBtnAdd()
{
if(m_blsCreate==false) // m_blsCreate是bool型成员变量判断是否已经创建
{
m_btn.Create (_T("维新"),BS_DEFPUSHBUTTON|WS_VISIBLE|WS_CHILD,
CRect(0,0,100,100),this,123); //动态创建button,其中m_btn为CBtton类型的成员变量
m_blsCreate=true;
}
else
{
m_btn.DestroyWindow ();
m_blsCreate=false;
}
}
另外m_blsCreate可以不定义为成员变量,而定义为static bool blsCreate=false;
每个窗口都有一个m_hWnd的成员变量,当窗口被创建后m_hWnd为非零值,当窗口被销毁后(窗口类对象仍然存在)值为零,因此可以通过判断m_hWnd的方式来判断button对象是否被创建。
void CTestDlg::OnBnClickedBtnAdd()
{
if(!m_btn.m_hWnd )
{
m_btn.Create (_T("维新"), BS_DEFPUSHBUTTON|WS_VISIBLE|WS_CHILD, CRect(0,0,100,100),this,123);
}
else
{
m_btn.DestroyWindow ();
}
}
在对话框资源文件中从工具箱拖出三个静态文本框Static Text,将其名称改为Number1,Number2,Number3,将ID号改为IDC_NUMBER1, IDC_NUMBER2, IDC_NUMBER3,将Notify项设为True,如果不这么设置则无法接受相应消息。
在CTestDlg类中给文本框添加点击响应函数:
CString str;
if(GetDlgItem(IDC_NUMBER1)->GetWindowText(str),str==_T("Number1"))
{
GetDlgItem(IDC_NUMBER1)->SetWindowText(_T("数值:"));
}
else
{
GetDlgItem(IDC_NUMBER1)->SetWindowText(_T("Number1"));
}
注释:GetDlgItem(IDC_NUMBER1)通过对话框中的控件ID获取控件句柄Cwnd*。
GetWindowText(str) 拷贝控件的名称到str。
SetWindowText(_T("数值:"))设置控件名称。
在CTestDlg::OnBnClickedBtnAdd()函数中添加如下响应函数:
方法一:使用GetDlgItem(),GetWindowText(),SetWindowText()
int num1,num2,num3;
char ch1[10],ch2[10],ch3[10];
GetDlgItem(IDC_EDIT1)->GetWindowText(ch1,10); //获取文本的最大个数是10
GetDlgItem(IDC_EDIT2)->GetWindowText(ch2,10);
num1=atoi(ch1);
num2=atoi(ch2);
num3=num1+num2;
itoa(num3,ch3,10);
GetDlgItem(IDC_EDIT3)->SetWindowText(ch3);
注释:atoi(ch1)将char*类型转换为int,itoa将int转换为char*,最后一个参数为转换进制数。
方法二:使用GetDlgItemText()和SetDlgItemText()
int num1,num2,num3;
char ch1[10],ch2[10],ch3[10];
GetDlgItemText(IDC_EDIT1,ch1,10);
GetDlgItemText(IDC_EDIT2,ch2,10);
num1=atoi(ch1);
num2=atoi(ch2);
num3=num1+num2;
itoa(num3,ch3,10);
SetDlgItemText(IDC_EDIT3,ch3);
注释:GetDlgItemText()相当于GetDlgItem(),GetWindowText()的组合。
方法三:使用GetDlgItemInt(),SetDlgItemInt()
int num1,num2,num3;
num1=GetDlgItemInt(IDC_EDIT1);
num2=GetDlgItemInt(IDC_EDIT2);
num3=num1+num2;
SetDlgItemInt(IDC_EDIT3,num3);
注释:GetDlgItemInt(
int nIDDlgItem, // 控件id
BOOL *lpTranslated, // success state ,默认为NULL,不警告任何错误
BOOL bSigned // 有符号或无符号,默认为真有符号
);
BOOL SetDlgItemInt(int nIDDlgItem,UINT uValue,BOOL bSigned);
方法四:关联成员变量法
方法五:发送消息SendMessage
方法六:发送消息SendDlgItemMessage
资源文件中控件上右击添加变量,private,变量类型int,变量名:m_num1,控件类别将control改为value。
可以看到在代码中增加了如下内容:
CTestDlg.h中:
private:
// 控件关联成员变量
int m_num1;
int m_num2;
int m_num3;
CTestDlg.cpp中:
void CTestDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_num1);
DDX_Text(pDX, IDC_EDIT2, m_num2);
DDX_Text(pDX, IDC_EDIT3, m_num3);
}
在CTestDlg::OnBnClickedBtnAdd()函数中添加如下响应函数:
UpdateData();
m_num3=m_num1+m_num2;
UpdateData(false);
注释: UpdateData()参数只有一个,默认为TRUE。为TRUE时刷新控件的值到对应的变量(外部输入值交给内部变量)。为false时拷贝变量值到控件显示(变量的最终运算结果值交给外部输出显示)。
在函数DoDataExchange中DDX_Text(pDX, IDC_EDIT1, m_num1);语句后添加:
DDV_MinMaxInt(pDX,m_num1,0,100); //m_num限定在0到100
资源文件中控件上右击添加变量,private,变量类型CEdit,变量名:m_edit1,控件类别为control。
可以看到在代码中增加了如下内容:
CTestDlg.h中:
private:
// 控件关联成员变量
CEdit m_edit1;
CEdit m_edit2;
CEdit m_edit3;
CTestDlg.cpp中:
void CTestDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_EDIT1, m_edit1);
DDX_Control(pDX, IDC_EDIT2, m_edit2);
DDX_Control(pDX, IDC_EDIT3, m_edit3);
}
由于CEdit类型也是从Cwnd继承的,所以在CTestDlg::OnBnClickedBtnAdd()函数中添加如下响应函数:
int num1,num2,num3;
char ch1[10],ch2[10],ch3[10];
m_edit1.GetWindowText(ch1,10);
m_edit2.GetWindowText(ch2,10);
num1=atoi(ch1);
num2=atoi(ch2);
num3=num1+num2;
itoa(num3,ch3,10);
m_edit3.SetWindowTextA (ch3);
在CTestDlg::OnBnClickedBtnAdd()函数中添加如下响应函数:
int num1,num2,num3;
char ch1[10],ch2[10],ch3[10];
//::SendMessageA(GetDlgItem(IDC_EDIT1)->m_hWnd , WM_GETTEXT ,10, (LPARAM)ch1 );
//::SendMessageA(m_edit1->m_hWnd , WM_GETTEXT ,10,(LPARAM)ch1);
//GetDlgItem(IDC_EDIT1)->SendMessage (WM_GETTEXT,10,(LPARAM)ch1);
m_edit1.SendMessage (WM_GETTEXT,10,(LPARAM)ch1);
m_edit2.SendMessage (WM_GETTEXT,10,(LPARAM)ch2); //第二个参数为发送数据量,第三个为接受数据的buffer
num1=atoi(ch1);
num2=atoi(ch2);
num3=num1+num2;
itoa(num3,ch3,10);
m_edit3.SendMessage (WM_SETTEXT,0,(LPARAM)ch3);
在CTestDlg::OnBnClickedBtnAdd()函数中添加如下响应函数:
int num1,num2,num3;
char ch1[10],ch2[10],ch3[10];
SendDlgItemMessage(IDC_EDIT1,WM_GETTEXT,10,(LPARAM)ch1);
SendDlgItemMessage(IDC_EDIT2,WM_GETTEXT,10,(LPARAM)ch2);
num1=atoi(ch1);
num2=atoi(ch2);
num3=num1+num2;
itoa(num3,ch3,10);
SendDlgItemMessage(IDC_EDIT3,WM_SETTEXT,10,(LPARAM)ch3);
在上面代码后面加上:
SendDlgItemMessage(IDC_EDIT3,EM_SETSEL,1,3);
m_edit3.SetFocus ();
< xmlnamespace prefix ="v" ns ="urn:schemas-microsoft-com:vml" />
SendDlgItemMessage开始位置为0,结束位置为-1,可将整个框内数据复选上。
在对话框窗口资源上加一个picture control画一条线,更改其属性,他的ID是static的,不能接受notify消息,将其改为IDC_SEPARATOR,Sunken设置为true,visiable设置为false。
增加一个button,命名为”收缩<<”,并对其添加消息处理函数。
void CTestDlg::OnBnClickedButton2()
{
CString str;
if(GetDlgItemText(IDC_BUTTON2,str),str=="收缩《")
{
SetDlgItemText(IDC_BUTTON2,"扩展》");
}
else
{
SetDlgItemText(IDC_BUTTON2,"收缩《");
}
static CRect rectLarge;
static CRect rectSmall;
if(rectLarge.IsRectNull())
{
CRect rectSeparator;
GetWindowRect(&rectLarge);
GetDlgItem(IDC_SEPARATOR)->GetWindowRect(&rectSeparator);
rectSmall.left =rectLarge.left ;
rectSmall.top=rectLarge.top;
rectSmall.right =rectLarge.right;
rectSmall.bottom=rectSeparator.top ;
}
if(str=="收缩《")
{
SetWindowPos(NULL,0,0,rectSmall.Width (),rectSmall.Height(),
SWP_NOMOVE|SWP_NOZORDER); //重新设置大小
}
else
{
SetWindowPos(NULL,0,0,rectLarge.Width (),rectLarge.Height(),
SWP_NOMOVE|SWP_NOZORDER);
}
}
Ok按钮是缺省的按钮,属性中Default button为true。当按下回车自动相当于按下Ok键。Ok的ID号为IDOK,如果自己创建一个按钮ID号为IDC_OK,虽然响应函数都为OnOk但不同。另外OK按钮不管存不存在对话框上,其响应都会存在。
增加ok消息响应函数,在其中屏蔽对基类CDialogEx::OnOK();的调用。
SetWindowLong()改变窗口的属性。
改变控件的回调函数,注意IDC_EDIT1的MultiLine要复选上,这样才能响应按键操作。
WNDPROC prevProc;
LRESULT CALLBACK WinSunProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
if(uMsg==WM_CHAR && wParam==0x0d)
{
//::SetFocus(::GetNextWindow(hwnd,GW_HWNDNEXT));
//SetFocus(::GetWindow(hwnd,GW_HWNDNEXT));
CString str;
str.Format("%d",hwnd);
AfxMessageBox(str);//, UINT nType = MB_OK, UINT nIDHelp = 0 );
// AfxGetApp()->
SetFocus(::GetNextDlgTabItem(::GetParent(hwnd),hwnd,FALSE));
return 1;
}
else
{
return prevProc(hwnd,uMsg,wParam,lParam);
}
}
BOOL CTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TOD Add extra initialization here
prevProc=(WNDPROC)SetWindowLong(GetDlgItem(IDC_EDIT1)->m_hWnd,GWL_WNDPROC,
(LONG)WinSunProc);//设置回调函数
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
在OnOK响应函数中加入代码
//GetDlgItem(IDC_EDIT1)->GetNextWindow()->SetFocus();
//GetFocus()->GetNextWindow()->SetFocus();
//GetFocus()->GetWindow(GW_HWNDNEXT)->SetFocus();
GetNextDlgTabItem(GetFocus())->SetFocus(); //焦点可以依次传递,查找完一遍不会出问题