现在的位置: 首页 > 综合 > 正文

MFC学习日记十:Mfc对话框编程控件的调用

2018年02月03日 ⁄ 综合 ⁄ 共 2830字 ⁄ 字号 评论关闭

动态收缩/扩展对话框:

实现这个功能首先要创建一个按钮,当我们点击这个按钮的时候,替换上面的文字并且改变窗口的尺寸大小,实现这样的功能有以下几步:

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按钮,添加一个IDIDOK的按钮即可重新得到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顺序来响应回车获取焦点的。如果点击回车,它就会按找上面显示的数字来一个个获取焦点的(当然这个顺序是可以修改的)。


抱歉!评论已关闭.