第九课:对话框(二) 建立一个基于对话框的应用程序,可以看到在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; }

评论