动态收缩/扩展对话框:
实现这个功能首先要创建一个按钮,当我们点击这个按钮的时候,替换上面的文字并且改变窗口的尺寸大小,实现这样的功能有以下几步:
1、添加一个按钮,并且为这个按钮在CTestDlg类中添加响应函数OnButton()(这里有一个快捷方式,只需要双击我们用资源编辑器托出来的按钮,就可以实现我们用建立类向导添加响应函数一样的东西);
2、在对话窗中添加一条线,用来标识我们收缩和放大窗口的界线,这里用图像控件来拖出一条线即可(这个图像控件的属性改为:样式:凹陷(勾选),可见(勾选去掉))。
3、实现收缩/扩展功能。这里用到Msdn中查到的一个函数:
BOOL SetWindowPos( const CWnd* pWndInsertAfter, int x, int y, int cx, int cy, UINT nFlags );参数的意思分别是:
1)一个CWnd类的指针,用来重排应用程序窗口的z次序,这里不需要可以赋值 NULL。
2)修改后窗口的左上角坐标x位置(在这里不用)。
3)修改后窗口的坐上角坐标y位置(在这里不用)。
4)修改后窗口的宽度。
5)修改后窗口的高度。
6)设置这个函数要修改和保留的窗口参数的配置,这里要用到SWP_NOMOVE(保留当前窗口位置,忽略第二第三个参数)、SWP_NOZORDER(保留当前窗口的Z次序,忽略第一个参数)。
void CTestDlg::OnButton2() { // TODO: Add your control notification handler code here CString str; if(GetDlgItemText(IDC_BUTTON2,str),str=="收缩<<") //判断当前按钮显示文字并作修改 { SetDlgItemText(IDC_BUTTON2,"扩展>>"); } else { SetDlgItemText(IDC_BUTTON2,"收缩<<"); } static CRect rectLarge; //创建静态参数,防止每次进来都重新赋值 static CRect rectSmall; if(rectLarge.IsRectNull()) { //给我们定义的rectSmall和rectLarge赋初值 CRect rectSeparator; //用这个来获取创建的那条线的y值 GetWindowRect(&rectLarge); GetDlgItem(IDC_SEPARATOR)->GetWindowRect(&rectSeparator); rectSmall.left=rectLarge.left; rectSmall.top=rectLarge.top; rectSmall.right=rectLarge.right; rectSmall.bottom=rectSeparator.bottom; } if(str=="收缩<<") { SetWindowPos(NULL,0,0,rectSmall.Width(),rectSmall.Height(), SWP_NOMOVE | SWP_NOZORDER); //调用收缩窗口为rectSmall的大小 } else { SetWindowPos(NULL,0,0,rectLarge.Width(),rectLarge.Height(), SWP_NOMOVE | SWP_NOZORDER); }
点击回车自动跳到下一个文本编辑框:
弹出的对话框,有一个默认响应回车的按钮就是OK按钮,首先我们要修改OK按钮的属性里的缺省复选框去掉,然后覆盖基类的OnOk函数(有一个简单的方法是:在资源编辑器中双击对话框的OK按钮,会在代码中自动生成重写(覆盖)的OnOk函数);然后把重写的OnOk函数中调用基类OnOk函数语句猪是掉。
实现:
方法一:
这里有一个消息,是在对话框创建完成将要显示之前处理的消息WM_INITDIALOG。加入一个响应函数OnInitDialog();这里我们用重写窗口过程函数WinSunProc(这个函数可以在WNDCLASS里点击第二个参数即可获得WIindowProc这里只需要修改它的名字为WinSunProc即可,在这个函数中只能调用平台SDK函数)来实现我们想要的功能;
想要用这个方法实现想要的功能,首先要把编辑框窗口设置为接收回车按键字符,即属性里-》多行勾选。
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)); SetFocus(::GetNextDlgTabItem(::GetParent(hwnd),hwnd,FALSE)); return 1; } else { return prevProc(hwnd,uMsg,wParam,lParam); } } BOOL CTestDlg::OnInitDialog() { CDialog::OnInitDialog(); prevProc=(WNDPROC)SetWindowLong(GetDlgItem(IDC_EDIT1)->m_hWnd,GWL_WNDPROC,(LONG)WinSunProc); //调用我们自己写的窗口过程函数 return TRUE; }
方法二:
这种方法是直接在OnOK函数中响应回车消息(这里不管有没有OK按钮,程序回车都会响应OnOK函数,如删除了OK按钮,添加一个ID为IDOK的按钮即可重新得到OK按钮);在此首先要把前面设置的文本编辑框中的属性多行的勾选给去掉。
void CTestDlg::OnOK() { // TODO: Add extra validation here //GetDlgItem(IDC_EDIT1)->GetNextWindow()->SetFocus(); //GetFocus()->GetNextWindow()->SetFocus(); //GetFocus()->GetWindow(GW_HWNDNEXT)->SetFocus(); GetNextDlgTabItem(GetFocus())->SetFocus(); // CDialog::OnOK(); }
这里是根据资源编辑器中对话框的布局里的Tab顺序来响应回车获取焦点的。如果点击回车,它就会按找上面显示的数字来一个个获取焦点的(当然这个顺序是可以修改的)。