孙鑫:第七讲 对话框

来源:互联网 发布:jquery 数组转为json 编辑:程序博客网 时间:2024/05/16 18:13

类的继承图表

CObject
  CCmdTarget
    CWnd       //由CWnd派生,是一个窗口类
      CDialog     

对话框分为模态对话框和非模态的对话框

CDialog::DoModal
 //virtual int DoModal()
 调用DoModal()创建一个模态的对话框
 它的返回值是做为CDialog::EndDailog成员函数的参数,这个参数用来关闭对话框  
CDialog::EndDailog
 //用来关闭模态的对话框                
CDialog::Create
 //创建非模态的对话框
 //初始化一个CDialog对象,创建一个非模态的对话框(modeless dialog box)
 //把它将一个CDialog对象关联起来
 //BOOL Create( LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL);
 //BOOL Create( UINT nIDTemplate, CWnd* pParentWnd = NULL);
 //lpszTemplateName: 对话框模板的名字
 //nIDTemplate:      对话框模板的ID号
 //pParentWnd:       对话框父窗口的指针,如果为NULL,则对话框的父窗口将被设置为主应用程序窗口

模态对话框的显示不用调用ShowWindow
而非模态的对话框在调用Create创建完对话框之后,需要调用ShowWindow显示对话框//ShowWindow(SW_SHOW)

CAUTION:
    对于模态的对话框,在模态的对话框显示时,应用程序是暂停执行的,所以模态的对话框对象可以
 是局部对象,不会在模态的对话框显示之前析构。
    而对于非模态的对话框,应用程序不会暂停执行,所以非模态对话框的对象不能是局部对象,非模态的
 对话框对象有两种定义方法:
 1:定义对话框成员变量
 2:在堆上分配内存,在堆上分配的内存和我们整个应用程序的生命周期是一样的,可以如下定义:
    CTestDlg *pDlg=new CTestDlg();    //注意内存看见的回收,防止memory leak
   
   
CAUTION:
  对于模态的对话框,当我们点击OK或者Cancel按钮时这个对话框窗口是被销毁了的
  对于非模态的对话框,这个对话框窗口并没有被销毁,只不过是隐藏了,当我们点击OK时,由基类的
  虚函数OnOK()响应
 
CDialog::OnOK
 //virtual void OnOK();
 //如果你在一个非模态的对话框中实现了一个OK Button,你必须重载OnOK成员函数,在它内部调用
 //DestroyWindow,不要调用基类的成员函数,因为它调用的是EndDialog,which makes the dialog
 //box invisible but does not destroy it.
 
 
CButton::Create
 //BOOL Create(LPCTSTR lpszCaption, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)
 //创建Button
 //按钮也是子窗口,如果dwstyle中不包含WS_VISIBLE,则在创建完Button后,继续调用ShowWindow()显示
 //按钮
 

CWnd和任何由CWnd类派生出来的窗口类对象,内部都有一个成员变量m_hWnd保存和这个对象相关联的窗口的
句柄,没有窗口和它关联时,m_hWnd的值为NULL

静态的文本框也是一个窗口,要获取静态文本框的文本,可以使用函数 CWnd::GetWindowText
设置文本使用 CWnd::SetWindowText
 CWnd::GetWindowText
  //int GetWindowText( LPTSTR lpszStringBuf, int nMaxCount )const;
  //void GetWindowText( CString& rString ) const;
 CWnd::SetWindowText
  // void SetWindowText( LPTSTR lpszString)
  
对于静态的文本框是不能接收通告消息的,如果让它接收通告消息,需要把它的属性的style的"Notify"项选上

atoi函数
  int atoi( const char *string)  //将数值字符,转化为整形数值
  char* _itoa( int value, char *string, int radix);  //Convert an integer to a string
  //string 指向结果
  //radix 2-36数值的*进制

访问控件的方式
  
1、获取对话框上控件的指针
 CWnd::GetDlgItem
  CWnd* GetDlgItem( int nID ) const;
  void CWnd::GetDlgItem( int nID,HWND* phWnd ) const;
   
2、CWnd::GetDlgItemText
 //int GetDlgItemText( int nID, LPTSTR lpStr, int nMaxCount ) const;
 //int GetDlgItemText( int nID, CString& rString ) const;
CWnd::SetDlgItemText
 //void SetDlgItemText( int nID, LPCTSTR lpszString);
 
3、CWnd::GetDlgItemInt
 //UINT GetDlgItemInt( int nID, BOOL* lpTrans = NULL, BOOL bSigned = TRUE ) const;
 //可以获取控件的文本,并把它转化为无符号整形
 //如果遇到非数值字符,或者数值超过所能表示的最大值,将会发生错误。此时lpTrans指向0,如果没有错误
 //lpTrans接收一个非零的值,如果lpTrans为NULL,GetDlgItemInt不会对错误产生警告
 //bSigned指示接收的数值字符是否是有符号的
CWnd::SetDlgItemInt
 //void SetDlgItemInt( int nID, UINT nValue, BOOL bSigned = TRUE );

4、控件与成员变量的关联,在DoDataExchange函数中
void CTestDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CTestDlg)
 DDX_Text(pDX, IDC_EDIT1, m_num1);          //将控件IDC_EDIT1与成员变量m_num1相关联
 DDX_Text(pDX, IDC_EDIT2, m_num2);
 DDX_Text(pDX, IDC_EDIT3, m_num3);
 //}}AFX_DATA_MAP
}
 DDX_函数有很多种,关联不同的控件,需要选择不同的DDX_函数,如DDX_Scroll,DDX_Radio等
 
DoDataExchange的调用时间:
  //Called by the framework to exchange an validate dialog data
  //由框架调用,来交换和调用对话框的数据
  //Never call this function directly.It is called by the UpdateData member function.
  //我们重来不会直接调用这个函数,它由UpdateData成员函数调用
  //Call UpdateData to initialize a dialog box's control or retrive data from a dialog box
  //调用UpdateData来初始化一个对话框控件,或者从对话框获得数据

CWnd::UpdateData
 //BOOL UpdatData( BOOL bSaveAndValidate = TRUE )
 //Call the member function to initialize data in a dialog box, or to retrieve and validate
 //dialog data
 //Flag that indicates whether dialog box is being initialized (FALSE) or data is being retrieve
 //(TRUE)
 //The framework automatically calls UpdateData with bSaveAndValidate set to FALSE when a modal
 //dialog box is created in the default implementation of CDialog::OnInitDialog

在控件关联的成员变量设置最大最小值后,DoDataExchange函数中会增加如下几条语句

void CTestDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CTestDlg)
 DDX_Text(pDX, IDC_EDIT1, m_num1);           //DDX : Dialog Data Exchange
DDV_MinMaxInt(pDX, m_num1, 0, 100);         //DDV : Dialog Data Validate
 DDX_Text(pDX, IDC_EDIT2, m_num2);
DDV_MinMaxInt(pDX, m_num2, 0, 100);         //DDV_函数也有很多,同DDX_函数一样
 DDX_Text(pDX, IDC_EDIT3, m_num3);
 //}}AFX_DATA_MAP
}

获取文本的消息:WM_GETTEXT
   An application sends a WM_GETTEXT message to copy the text that corresponds to a window into a
   buffer provided by the caller.
   To send this message,call the SendMessage function with the following parameters.
   SendMessage{
          (HWND) hWnd,              //handle to destination window
          WM_GETTEXT,               //message to send
          (WPARAM) wParam,          //number of the character to copy
          (LPARAM) lParam           //text buffer
              }
             
设置文本的时候使用消息 WM_SETTEXT  

SendMessage{
          (HWND) hWnd,              //handle to destination window
           WM_SETTEXT,               //message to send
          (WPARAM) wParam,          //not used;must be zero
          (LPARAM) lParam           //window-text string (LPCTSTR)
           }

给对话框的子控件发送消息
CWnd::SendDlgMessage
 LRESULT SendDlgItemMessage( int nID, UINT message, WPARAM wParam=0, LPARAM lParam = 0)
 //等价于我们现调用GetDlgItem再调用SendMessage
 
编辑框消息 EM_GETSEL
 //The EM_GETSEL message retrieves the starting and ending character positions of the current
 //selection in an edit control. You can send this message to either an edit control or a rich 
 //edit control      
 SendMessage{                                                            
           (HWND) hWnd,              //handle to destination window   
           WM_GETTEXT,               //message to send                      
        (WPARAM) wParam,           //starting position (LPDWORD) 
        (LPARAM) lParam            //ending position (LPDWORD)                    
                                                                    
 
EM_SETSEL设置复选的开始位置和结束位置    
SendMessage{                                                                  
        (HWND) hWnd,              //handle to destination window       
        WM_SETTEXT,               //message to send                    
       (WPARAM) wParam,           //starting position       
       (LPARAM) lParam            //ending position         
          }
 //If the start is 0 and the end is -1, all the text in the edit control is selected.
 //If the start is -1,any current selection is deselected
        
设置窗口的焦点 CWnd::SetFocus
 CWnd* SetFocus();

总结:
    对话框控件访问七种方式
    1、GetDlgItem()->Get(Set)WindowText()  //常用
    2、GetDlgItemText()/SetDlgItemText()
    3、GetDlgItemInt()/SetDlgItemInt()
    4、将控件和整型变量相关联              //常用
    5、将控件和控件变量相关联        //常用
    6、SendMessage()                       //不常用
    7、SendDlgItemMessage()                //不常用
   
对话框的收缩与扩展
  CRect::IsRectEmpty
   //Determines whether CRect is empty.CRect is empty if the width and/or height are 0;
  CRect::IsRectNull
   //Determines whether the top, bottom, left,and right member variables are all equal to 0.
 
  CWnd::GetWindowRect
   void GetWindowRect( LPRECT lpRect) const;
  //获取窗口矩形区域的大小
 
  CWnd::SetWindowPos
   //BOOL SetWindowPos( const CWnd* pWndInsertAfter, int x,int y, int cx, int cy, UINT nFlags);
   SetWindowPos和DeferWindowPos用来重排Z-order
   //应用程序通过设置WS_EX_TOPMOST风格创建最顶层窗口。
    //应用程序可用函数BringWindowToTop把一个窗口放置到Z次序的顶部。
兄弟窗口
     共享同一个父窗口的多个子窗口叫兄弟窗口。
活动窗口
     活动窗口是应用程序的顶层窗口
     应用程序则调用函数SetActiveWindow来激活一个顶层窗口

前台窗口和后台窗口
     在Windows系统中,每一个进程可运行多个线程,每个线程都能创建窗口。创建正在使用窗口的线程
  称之为前台线程,这个窗口就称之为前台窗口。所有其它的线程都是后台线程,由后台线程所创建的
  窗口叫后台窗口。
     用户通过单击一个窗口、使用ALT+TAB或ALT+ESC组合键来设置前台窗口,应用程序则用函数
  SetForegroundWindow设置前台窗口。如果新的前台窗口是一个顶层窗口,那么Windows系统就激活它,
  换句话说,Windows系统激活相应的顶层窗口。
 
       SetWindowPos???

SetWindowLong函数
  //The SetWindowLong function changes an attribute of the specified window
  //SetWindowLong函数可以改变指定窗口的属性
  long SetWindowLong
  {
   HWND hWnd,              // handle to window
   int  nIndex,            // offset of value to set   
   long dwNewLong          // new value 
 }
 
 当 nIndex=GWL_WNDPROC   可以Sets a new address for the window procedure
 此时可以把dwNewLong设置成新的窗口过程的地址。

函数的返回值:
    If the function succeeds, the return value is the previous value of the specified 32-bit integer
    If the function fails , the return value is zero
    当 nIndex=GWL_WNDPROC ,它的返回值就是以前的窗口过程的地址
   
当对话框上的子控件全部创建完毕,对话框将要显示时发送消息:WM_INITDIALOG
    //Sent to a dialog box before the dialog box is displayed

子控件的创建时间在对话框创建之后,对话框将要显示之前

窗口过程函数的写法:
  LRESULT CALLBACK WindowProc{
             HWND      hwnd,       //handle to window
             UINT      uMsg,       //message identifier
             WPARAM    wParam,     //first message parameter
             LPARAM    lParam      //second message parameter
             }
            
当处理的是WM_CHAR消息时,wParam表示字符的ASCII码

CAUTION!
   窗口过程函数是一个全局函数

全局的SetFocus函数
    HWND SetFocus(
         HWND  hwnd    //handle to window
         );     
        
全局的GetNextWindow函数:
 HWND GetNextWindow(
      HWND hWnd,        //handle to current window
      UINT uCmd         // direction
      );
   //当 uCmd=GW_HWNDNEXT    当前窗口的下一个窗口                                                                      
   //当 uCmd=GW_HWNDPREV    当前窗口的上一个窗口
  
编辑框的Style如果如果没有复选Multiline属性,则编辑框无法接受回车符发送的消息
取消Multiline属性是在 02:29:10 写OnOK函数时

获取窗口句柄的GetWindow全局函数
  HWND  GetWindow(
        HWND hWnd,   // handle to original window
        UINT uCmd    // relationship
 
 GetNextDlgTabItem函数
 //The GetNextDlgTabItem function retrieves a handle to the first control that has the
 //WS_TABSTOP style that precedes(前面)( or follows)the specified control.
 HWND GetNextDlgTabItem(
      HWND hDlg,       //handle to dialog box
      HWND hCtrl,      //handle to known control 已知控件的句柄
      bool bPrevious   //direction flag 方向。If this parameter is TRUE, the function searches
                       //for the previous control in the dialog box.If this parameter is FALSE,
                       //the function searches for the next control in the dialog box
       );
CWnd::GetNextWindow
 CWnd* GetNextWindow( UINT nFlag = GW_HWNDNEXT )const;//具有缺省的方向GW_HWNDNEXT

获取当前具有输入焦点的窗口的指针的函数: CWnd::GetFocus  
 
CWnd::GetWindow
 CWnd* GetWindow( UINT nCmd) const;

CWnd::GetNextDlgTabItem
 CWnd* GetNextDlgTabItem( CWnd* pWndCtrl, bool bPrevious = FALSE) const;
 //函数寻找具有WS_TABSTOP style的control,循环依次调用
 
菜单项 Layout->TabOrder显示顺序

void CTestDlg::OnOK() 什么时候调用????????

 

原创粉丝点击