孙鑫VC学习(第7课-对话框(收缩按钮,回车光标自动传))

新建一个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();

}

你可能感兴趣的:(孙鑫VC学习(第7课-对话框(收缩按钮,回车光标自动传)))