动态收缩/扩展对话框:
实现这个功能首先要创建一个按钮,当我们点击这个按钮的时候,替换上面的文字并且改变窗口的尺寸大小,实现这样的功能有以下几步:
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顺序来响应回车获取焦点的。如果点击回车,它就会按找上面显示的数字来一个个获取焦点的(当然这个顺序是可以修改的)。