新建一个MFC的单文档的程序。名字是TEST。添加一个对话框。
void CTestView::OnDialog()
{
// TODO: Add your command handler code here
CDialog1 dlg;
dlg.DoModal();//模态对话框
}
下面点击按钮,动态添加一个按钮。
为DLG添加: CButton m_btn;
void CDialog1::OnButton1()
{
// TODO: Add your control notification handler code here
if (!m_btn.m_hWnd)//通过句柄判断此按钮存在是否
{
m_btn.Create("new button!",WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON,//按钮也是窗口的一种,也要显示出来
CRect(0,0,100,70),this,1);
}
else
{
m_btn.DestroyWindow();
}
}
或者:
void CDialog1::OnButton1()
{
// TODO: Add your control notification handler code here
static CButton *pbtn=new CButton;//存在一个问题,如何释放这个堆空间?应该在析构函数中释放的话,就不应该写成局部变量
if (!pbtn->m_hWnd)
{
pbtn->Create("new button!",WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON,
CRect(0,0,100,70),this,1);
}
else
{
pbtn->DestroyWindow();
}
}
void CDialog1::OnButton2()
{
// TODO: Add your control notification handler code here IDC_SEPRATOR
static CRect lrect,srect,nsrect;//得到后,就不应该更改,所以为static
if (lrect.IsRectEmpty())//IsRectNull说明是否四个角都是0值
{
GetWindowRect(&lrect);//screen coordinates ,此时为在屏幕上面的坐标。
}
if (srect.IsRectEmpty())
{
GetDlgItem(IDC_SEPRATOR)->GetWindowRect(&srect);
}
nsrect.left=lrect.left;
nsrect.right=lrect.right;
nsrect.top=lrect.top;
nsrect.bottom=srect.bottom;
CString str;
if (GetDlgItemText(IDC_BUTTON2,str),str=="收缩")
{
SetDlgItemText(IDC_BUTTON2,"扩展");
}
else
{
SetDlgItemText(IDC_BUTTON2,"收缩");
}
if (GetDlgItemText(IDC_BUTTON2,str),str=="收缩")//large rect
{
SetWindowPos(NULL,lrect.left,lrect.top,lrect.Width(),lrect.Height(),SWP_NOMOVE|SWP_NOZORDER );
//MoveWindow( reLarge.left, reLarge.top, reLarge.Width(), reLarge.Height());也可以实现这个功能,即MoveWindow也可以。
}
else//small rect
{
SetWindowPos(NULL,nsrect.left,nsrect.top,nsrect.Width(),nsrect.Height(),SWP_NOMOVE|SWP_NOZORDER );
}
}
void CDialog1::OnOK()
{
// TODO: Add extra validation here
// CDialog::OnOK();
}
让输入焦点移动到下一个编辑框:
通过修改编辑框原先的窗口过程。
修改编辑框属性,让它接受多行。
WNDPROC preProc;
LRESULT CALLBACK newProc(
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));//全局函数,只能用SDK的函数 ,因为这个函数不是dialog的成员函数
//::SetFocus(::GetWindow(hwnd,GW_HWNDNEXT));或者这句也可以。注意此时的hwnd是指的编辑框的句柄,因为是对编辑框进行窗口处理函数的更改,所以这个新的窗口过程//和普通的窗口过程函数类似,hwnd是指编辑框的句柄
//::SetFocus(::GetNextDlgTabItem(GetParent(hwnd),hwnd,FALSE));或者这句也可以。
//::GetWindow(hwnd, GW_OWNER);;返回的值不等于::GetParent(hwnd);返回的句柄,故这2句不能通用,因为返回的值都不一样。GetNextDlgTabItem这个函数的顺序是以tab
//键的顺序来进行的 看TAB的顺序可以通过把控件先中,再点tools/tab order来看,可以手动改变,在控件中,只有属性支持tab stop的控件才支持GetNextDlgTabItem这个函数,当点击ok 或者 cancel键时,对话框不见了,都是因为cdialog里面的onok和oncancel里的函数实现将对话框销毁了(模式对话框,可以参见MSDN)
return 1;
}
else
{
return preProc(hwnd,uMsg,wParam,lParam);
}
}
BOOL CDialog1::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
preProc=(WNDPROC)SetWindowLong(GetDlgItem(IDC_EDIT1)->m_hWnd, GWL_WNDPROC,
(LONG)newProc);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
这样就将焦点从第一个编辑框传到第二个编辑框。//注意要将编辑框的属性选择为支持多行,不然不支持回车,主要是在编辑框中,只有multiline才支持回车
下面介绍一种方便的方法,将输入焦点依次住下传。
void CDialog1::OnOK()//OnOK在CDialog的一个虚函数,如果不想用系统内部的定义好的行为,可以在派生类中自己重写此函数来实现,如果把系统本身的IDOK给删除了,自己重新新建了一个BUTTON,那么这个BUTTON的其它属性无所谓,但是ID一定要为IDOK,就和系统的的IDOK一样了,和是不是default button没关系。
{
// TODO: Add extra validation here
//(GetDlgItem(IDC_EDIT1)->GetNextWindow())->SetFocus();
GetNextDlgTabItem(GetFocus( ),FALSE)->SetFocus();
// CDialog::OnOK();
}