第九课:对话框(二)
建立一个基于对话框的应用程序,可以看到在CXxxApp的InitInstance()函数中:
CDlgaDlg dlg;
m_pMainWnd = &dlg;
应用程序启动时,必须对CXxxApp的成员变量m_pMainWnd进行赋值,否则无法运行。在单文档的工程中,我们看不到这种赋值操作,它是在
if (!ProcessShellCommand(cmdInfo))
return FALSE;
在ProcessShellCommand函数中对m_pMainWnd赋了值。
一、return false和return ture的区别:
1. 在CXxxApp的InitInstance()函数中:
return false:退出应用程序,不进入消息循环。
return ture:应用程序进入消息循环。
2. 在对话框类中的OnInitDialog()中:
return false:如果在OnInitDialog()函数中设置了某控件得到焦点,如:
GetDlgItem(IDC_EDIT1))->SetFocus();
应return false,否则上一句代码不会生效。
return ture:在OnInitDialog()函数中没有设置了某控件得到焦点,应return ture。
说明:要使对话框上的某个控件在一显示对话框,就具有焦点,还可以将该控件的
Table Order设为1。
二、在对话框中响应回车键:
在对话框中回车,会执行缺省按钮(Default Button)的函数,默认的缺省按钮是IDOK。如果没有缺省按钮,会执行对话框中的OnOK()函数。所以,在一个对话框中要控制回车键,可以采用下面的方法:
1. 在OnOK()函数中添加代码:
在对话框中添加四个文本框,我们想用户按回车键时,四个文本框依次循环得到焦点:
if(GetFocus()==GetDlgItem(IDC_EDIT4)) //如果第四个文本框得到焦点
GetDlgItem(IDC_EDIT1)->SetFocus(); //使第一个文本框得到焦点
else if (GetFocus()->GetDlgCtrlID()==IDOK) //如果“确定”按钮得到焦点
CDialog::OnOK(); //对话框返回
else
GetFocus()->GetNextWindow()->SetFocus();
//使当前具有焦点窗口的下一个(按照Table Order顺序)窗口得到焦点
2. 添加按钮,将其设置为缺省按钮,Visible属性设为false,为它添加响应函数,在其中编程(代码类似1)。
3. 更换回调函数:
我们更换第一个文本框的回调函数,让它不响应回车键。
i. 定义一个全局变量WNDPROC oldProc; 用于保存原来的回调函数的指针。
ii. 在对话框类中的OnInitDialog()中用SetWindowLong函数更换第一个文本框的回调函数为newProc
oldProc=(WNDPROC)SetWindowLong(GetDlgItem(IDC_EDIT1)->m_hWnd,GWL_WNDPROC,(long) newProc);
iii. 定义newProc函数:
LRESULT CALLBACK newProc (
HWND hwnd,UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if(uMsg==WM_CHAR) //如果是字符消息
{
if(0xd==wParam) //如果是回车键
return 1; //不处理就返回,即不响应回车键
}
return oldProc (hwnd,uMsg,wParam,lParam);
//其它消息仍由原来的回调函数处理
}
说明:此种方法要文本设置文本框的MultiLine 和Want return属性设为有效。
三、制作一个可以响应WM_MOUSEMOVE消息的按钮:
1. 新建一个类CHide ,从CButton派生,增加成员对象CHide *m_btnFriend,在类中响应WM_MOUSEMOVE消息,在OnMouseMove中添加代码:
ShowWindow(SW_HIDE);
m_pmyFriend->ShowWindow(SW_NORMAL);
2. 在对话框的头文件中加入#include “hide.h”
3. 为对话框上的“确定”和“取消”按钮添加捆绑变量
i. 静态绑定:
a. 用ClassWizard为对话框上的“确定”和“取消”按钮添加捆绑变量,
CHide m_btnOK;
CHide m_btnCancel;
并将其中一个按钮的Visible属性设为false。
b. 此种方法会在对话框的DoDataExchange函数中添加
DDX_Control(pDX, IDCANCEL, m_btnCancel);
DDX_Control(pDX, IDOK, m_btnOK);
c. 在对话框类中的OnInitDialog()中添加代码:
m_btnOK.m_pmyFriend=&m_btnCancel;
m_btnCancel.m_pmyFriend=&m_btnOK;
ii. 动态绑定:
a. 定义两个成员变量:
CHide m_btnOK;
CHide m_btnCancel;
b. 在对话框类中的OnInitDialog()中添加代码:
m_btnOK.m_pmyFriend=&m_btnCancel;
m_btnCancel.m_pmyFriend=&m_btnOK;
m_btnOK.SubclassDlgItem(IDOK,this);
m_btnCancel.SubclassDlgItem(IDCANCEL,this);
四、用代码改变窗口的大小:
1. 在对话框类中定义两个成员变量:
CRect m_rectLarge; //用于保存大窗口的大小
CRect m_rectSmall; //用于保存小窗口的大小
2. 在对话框中添加一个Picture 控件,用于分隔大小窗口,将其IDIDC_LAND
3. 在OnInitDialog()中为其赋值:
GetWindowRect(&m_rectLarge); //得到大窗口的大小
m_rectSmall=m_rectLarge; //将小窗口先赋为大窗口
CRect rect;
GetDlgItem(IDC_LAND)->GetWindowRect(rect);// 得到分隔条的矩形,
m_rectSmall.bottom=rect.bottom; //为小窗口进行赋值
4. 添加成员函数EnableVisibleChildren(),将不属于当前窗口的控件设为失效。
CRect rectVisible,rectCtrl,rectTemp;
GetWindowRect(&rectVisible);
CWnd *pWnd=GetWindow(GW_CHILD);
while(pWnd)
{
pWnd->GetWindowRect(&rectCtrl);
if(rectTemp.IntersectRect(&rectVisible,&rectCtrl))
pWnd->EnableWindow(true);
else
pWnd->EnableWindow(false);
pWnd=pWnd->GetNextWindow();
}
5. 增加一个按钮,并为其添加响应函数,在其中改变窗口的大小:
CString str;
if(GetDlgItemText(IDC_BUTTON3,str),str=="<<collapse")
{
SetWindowPos(NULL,0,0,m_rectSmall.Width(),m_rectSmall.Height(),
SWP_NOMOVE|SWP_NOZORDER);
SetDlgItemText(IDC_BUTTON3,"expand>>");
}
else
{
SetWindowPos(NULL,0,0,m_rectLarge.Width(),m_rectLarge.Height(),
SWP_NOMOVE|SWP_NOZORDER);
SetDlgItemText(IDC_BUTTON3,"<<collapse");
}
EnableVisibleChildren();
五、隐藏对话框:
1. 可以在OnPaint()中
ShowWindow(SW_HIDE);
2. 可以用定时器:
在OnInitDialog()中
SetTimer(1,1000,NULL);
添加WM_TIMER的消息响应函数OnTimer,在其中添加:
ShowWindow(SW_HIDE);
3. 也可以在OnInitDialog()中发送消息
a. 在OnInitDialog()加入
PostMessage(WM_USER+1);
b. 在消息响应表中添加消息映射:
ON_MESSAGE(WM_USER+1,OnHideDlg)
c. 添加成员函数OnHideDlg
LRESULT CDlgaDlg::OnHideDlg(WPARAM wParam, LPARAM lParam)
{
ShowWindow(SW_HIDE);
return 1;
}
评论