孙鑫VC++讲座笔记(7) 对话框编程

时间:2021-07-12 21:12:34

1. Insert -->Resource --->Dialog------>New 新建一个对话框

2.在VC++ 中,一个窗口与一个C++ 类进行关联,对话框的基类为CDialog 类,对话框分为模态对话框与非模态对话框,模态对话框在应用程序能进行其它操作之前必须关闭,非模态的对话框允许不关闭对话框而进行应用程序操作.

MSDN的说明:

This class is the base class used for displaying dialog boxes on the screen. Dialog boxes are of two types: modal and modeless. A modal dialog box must be closed by the user before the application continues. A modeless dialog box allows the user to display the dialog box and return to another task without canceling or removing the dialog box.

3.确定选中新学添加的对话框,View ---> ClassWizard 创建一个基于CDialog 的类与本对话框关联,输入类名,文件名,基类名,对话框ID , 此时,我们在工程中添加了一个类

4.对话框的创建

a.模态对话框:DoModal()  //Calls a modal dialog box and returns when done.

//Return Value:An int value that specifies the value of the nResult parameter that was passed to the CDialog::EndDialog member function, which is used to close the dialog box. The return value is –1 if the function could not create the dialog box, or IDABORT if some other error occurred, in which case the Output window will contain error information from GetLastError.

b.非模态对话框:

CTestDialog *pDlg=new CTestDialog();
 pDlg->Create(IDD_DIALOG1,this);
 pDlg->ShowWindow(SW_SHOW);

virtual BOOL Create(
   UINT nIDTemplate,  //对话框ID号
   CWnd* pParentWnd = NULL   //对话框父窗口C++对象指针
); //Initializes the CDialog object. Creates a modeless dialog box and attaches it to the CDialog object.

BOOL ShowWindow(int nCmdShow ); //Sets the visibility state of the window

NOTE:

非模态对话框要覆盖其基类的OnOk()函数 ,在MSDN中的说明: If you implement the OK button in a modeless dialog box, you must override the OnOK member function and call DestroyWindow from within it. Don't call the base-class member function, because it calls EndDialog, which makes the dialog box invisible but does not destroy it.

5.创建动态按钮:

CButton m_btn;
...........
if(!m_btn.m_hWnd)  //如果没有创建
 {
  m_btn.Create("Mickor.Guo",BS_DEFPUSHBUTTON |WS_CHILD|WS_VISIBLE,
   CRect(0,10,100,30),this,123);
 }
 else
 {
  m_btn.DestroyWindow();  //消毁窗口
 }

NOTE:

virtual BOOL CButton::Create(
   LPCTSTR lpszCaption,    //Specifies the button control's text.  按钮文本
   DWORD dwStyle,  //按钮样式  Specifies the button control's style. Apply any combination of button styles to the button.
   const RECT& rect,  //按钮位置与大小  Specifies the button control's size and position.
   CWnd* pParentWnd,  //父窗口指针
   UINT nID   //按钮ID
);  //Creates the Windows button control and attaches it to the CButton object.

6.静态文本框编程:

CString str;
 if(GetDlgItem(IDC_NUMBER1)->GetWindowText(str),str=="Number1")
 {
  GetDlgItem(IDC_NUMBER1)->SetWindowText("数字1");
 }

NOTE:

a.   CWnd* GetDlgItem ( int nID ) const; //This method retrieves a pointer to the specified control or child window in a dialog box or other window. The pointer returned is usually cast to the type of control identified by nID. //通过控件ID 获得控件C++对象指针
b.   void GetWindowText(CString& rString )const;  //This method copies the CWnd caption title into the buffer pointed to by lpszStringBuf or into the destination string rString. If the CWnd object is a control, the GetWindowText method copies the text within the control instead of copying the caption.   //获得窗口文本
C.   void SetWindowText( LPCTSTR lpszString );  //This method sets the window title to the specified text. If the window is a control, the text within the control is set. This method causes a WM_SETTEXT message to be sent to this window.   //设置窗口文本
D.   逗号(",")运算符的应用
E. 在此之前,要设置静态文本控件的Notify 属性为真

7.EditBox 输入框编程:

int GetDlgItemText( int nID,  // 控件ID
LPTSTR lpStr,  //字符串数组
int nMaxCount  //最大的字符数
) const; //在一个窗口控件中读取文本到字符数组中
//This method retrieves the title or text associated with a control in a dialog box. This method copies the text to the location pointed to by lpStr and returns a count of the number of bytes it copies.

void SetDlgItemText(
int nID,  //控件ID
LPCTSTR lpszString );  //字符串
//设置控件的文本内容   This method sets the caption or text of a control owned by a window or dialog box. SetDlgItemText sends a WM_SETTEXT message to the given control


int atoi( const char *string ); // 把一个字符串转为INT 类型的数值

char *_itoa(
   int value,  //要换的数值
   char *string,  //转换成的字符串
   int radix  //数值的进制  2--36
); //把一个数值转换成字符串

UINT GetDlgItemInt(
int nID,  //控件ID
BOOL* lpTrans = NULL,  //控件文本是否有非数字字符,当设为NULL 时,不进行报错
BOOL bSigned = TRUE )  //是否为有符号数值
const; //获得控件文本,并转换成数值类型 The CWnd::GetDlgItemInt method retrieves the text of the control identified by the nID parameter. This method translates the text into an integer value by stripping any extra spaces at the beginning of the text and converting decimal digits. It stops the translation when it reaches the end of the text or encounters any nonnumeric character.

void SetDlgItemInt(
int nID,  //控件ID
UINT nValue,  //数值
BOOL bSigned = TRUE  //是否为有符号数值
); //把一个数值设置成控件文本  This method sets the text of a specified control in a dialog box to the string representation of a specified integer value. SetDlgItemInt sends a WM_SETTEXT message to the given control.

8.数据交换与较验

  A. View ---> ClassWizard ---> Member Variables 在此界面添加数据成员与控件的数据关联操作,类名,控件名,数据成员名,数据类型,数据范围等
  B. 此时,ClassWizard 在程序中添加了如下代码:
     头文件中: //{{AFX_DATA(CTestDialog)
 enum { IDD = IDD_DIALOG1 };
 int  m_num1;
 int  m_num2;
 int  m_num3;
 //}}AFX_DATA
     源文件中的DoDataExchange 函数中:
 DDX_Text(pDX, IDC_EDIT1, m_num1);
 DDV_MinMaxInt(pDX, m_num1, 0, 100);
 DDX_Text(pDX, IDC_EDIT2, m_num2);
 DDX_Text(pDX, IDC_EDIT3, m_num3);
 //}}AFX_DATA_MAP
     在DoDataExchange 函数中进行了数据交换与较验的设置.
   
     MSDN中NOTE:
       virtual void DoDataExchange( CDataExchange* pDX );
     //This method is called by the framework to exchange and validate dialog data
  C. 想要在程序中进行数据交互,必须调用 UpdateData() 函数
       BOOL UpdateData(BOOL bSaveAndValidate = TRUE );
     //NOTE:This method initializes data in a dialog box, or retrieves and validates dialog data.Specifies a flag that indicates whether dialog box is being initialized (FALSE) or data is being retrieved (TRUE).

9.通过控件对象进行数据交互与关联
 
  A. 如同上面(7) 一样,在 Add Member Variables 界面的Category 下拉列表框中,选择Control ,进行控件关联操作
  B. 此时,添加的控件对象就如同窗口控件的一个COPY ,直接对此对象进行操作即可.

10.通过Windows 消息进行数据交互

  A. 想要获得一个控件文本,可以有以下四种方式:
       ::SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd,WM_GETTEXT,10,(LPARAM)ch1);
       ::SendMessage(m_edit1.m_hWnd,WM_GETTEXT,10,(LPARAM)ch1);
       GetDlgItem(IDC_EDIT1)->SendMessage(WM_GETTEXT,10,(LPARAM)ch1);
       m_edit1.SendMessage(WM_GETTEXT,10,(LPARAM)ch1);

  B. 设置文本:
     m_edit1.SendMessage(WM_SETTEXT,0,(LPARAM)ch1);
     ::SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd,WM_SETTEXT,0,(LPARAM)ch1);

  C. CWnd::SendDlgItemMessage(IDC_EDIT1,WM_GETTEXT,10,(LPARAM)ch1);

     NOTE:
      LRESULT SendMessage(
        HWND hWnd,    //控件句柄
        UINT Msg,     //Windows 消息 , 这里为WM_GETTEXT 获得文本/WM_SETTEXT 设置文本
        WPARAM wParam, //WM_GETTEXT 时,为最大字符数量 ,WM_SETTEXT 时,要设为0
        LPARAM lParam  //要获得或设置的文本
      ); //发送一个Windows 消息

      LRESULT SendDlgItemMessage(
        int nID,  //控件ID
        UINT message,
        WPARAM wParam = 0,
        LPARAM lParam = 0
     ); //This method sends a message to a control. 参数同上

11.设置文本复选
  
   SendDlgItemMessage(IDC_EDIT3,EM_SETSEL,0,-1);
   m_edit3.SetFocus();  //获得焦点

   NOTE:
     SendMessage(      // 设置复选     
        (HWND) hWndControl,      // handle to destination control    
        (UINT) EM_SETSEL,      // message ID    
        (WPARAM) wParam,      // = (WPARAM) () wParam;    //开始位置
        (LPARAM) lParam      // = (LPARAM) () lParam;     //结束位置
     ); //The EM_SETSEL message selects a range of characters in an edit control. You can send this message to either an edit control or a rich edit control.

     SendMessage(      // 获得复选内容  
        (HWND) hWndControl,      // handle to destination control    
        (UINT) EM_GETSEL,      // message ID    
        (WPARAM) wParam,      // = (WPARAM) () wParam;    //开始位置
        (LPARAM) lParam      // = (LPARAM) () lParam;     //结束位置
     ); //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.

12.对话框控件的七种访问方式:

A.   GetDlgItem()->Get(Set)WindowText()
B.   GetDlgItemText()/SetDlgItemText()
C.   GetDlgItemInt()/SetDlgItemInt()
D.   将控件和整型变量相关联
E.    将控件和控件变量相关联
F.    SendMessage()
G.   SendDlgItemMessage()

13.扩展窗口

   A. 实现
     SetWindowPos(NULL,0,0,rectSmall.Width(),rectSmall.Height(),
   SWP_NOMOVE|SWP_NOZORDER);

     void GetWindowRect(LPRECT lpRect )const;  //获得窗口大小
     BOOL SetWindowPos (const CWnd* pWndInsertAfter,int x,int y,int cx,int cy,UINT nFlags ); //设置窗口大小与位置

     NOTE:
      void GetWindowRect(LPRECT lpRect )const;  //获得窗口大小
         //This method copies the dimensions of the bounding rectangle of the CWnd object into the structure pointed to by lpRect. The dimensions are given in screen coordinates relative to the upper-left corner of the display screen. The dimensions of the caption, border, and scroll bars, if present, are included.
    
      BOOL SetWindowPos (
         const CWnd* pWndInsertAfter,//指定此窗口Z-order 位置的前一窗口指针,也可以用NULL 或预设值
         int x,  //left
         int y,  //top
         int cx, //Width
         int cy, //Height
         UINT nFlags  //指定窗口的配置选项  //Specifies sizing and positioning options
      );

   B. Z-order 说明:
      窗口的Z次序表明了重叠窗口堆中窗口的位置,这个窗口堆是按一个假想的轴定位的,这个轴就是从屏幕向外伸展的Z轴。Z次序最上面的窗口覆盖所有其它的窗口,Z次序最底层的窗口被所有其它的窗口覆盖。应用程序设置窗口在Z次序中的位置是通过把它放在一个给定窗口的后面,或是放在窗口堆的顶部或底部。Windows系统管理三个独立的Z次序——一个用于顶层窗口、一个用于兄弟窗口,还有一个是用于最顶层窗口。最顶层窗口覆盖所有其它非最顶层窗口,而不管它是不是活动窗口或是前台窗口。应用程序通过设置WS_EX_TOPMOST风格创建最顶层窗口。一般情况下,Windows系统把刚刚创建的窗口放在Z次序的顶部,用户可通过激活另外一个窗口来改变Z次序;Windows系统总是把活动的窗口放在Z次序的顶部,应用程序可用函数BringWindowToTop把一个窗口放置到Z次序的顶部。函数SetWindowPos和DeferWindowPos用来重排Z次序。

      a.兄弟窗口
         共享同一个父窗口的多个子窗口叫兄弟窗口。
      b.活动窗口
         活动窗口是应用程序的顶层窗口,也就是当前使用的窗口。只有一个顶层窗口可以是活动窗口,如果用户使用的是一个子窗口,Windows系统就激活与这个子窗口相应的顶层窗口。任何时候系统中只能有一个顶层窗口是活动的。用户通过单击窗口(或其中的一个子窗口)、使用ALT+TAB或ALT+ESC组合键来激活一个顶层窗口,应用程序则调用函数SetActiveWindow来激活一个顶层窗口。
      c.前台窗口和后台窗口
         在Windows系统中,每一个进程可运行多个线程,每个线程都能创建窗口。创建正在使用窗口的线程称之为前台线程,这个窗口就称之为前台窗口。所有其它的线程都是后台线程,由后台线程所创建的窗口叫后台窗口。用户通过单击一个窗口、使用ALT+TAB或ALT+ESC组合键来设置前台窗口,应用程序则用函数SetForegroundWindow设置前台窗口。如果新的前台窗口是一个顶层窗口,那么Windows系统就激活它,换句话说,Windows系统激活相应的顶层窗口。
    
14.焦点事件(回车)

   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 CTestDialog::OnInitDialog()
   {
 CDialog::OnInitDialog();

 prevProc=(WNDPROC)SetWindowLong(GetDlgItem(IDC_EDIT1)->m_hWnd,GWL_WNDPROC,
  (LONG)WinSunProc);
 return TRUE;
   }

   A.操作过程:
    1). 屏蔽掉OnOk() 函数
    2). 重载 WM_INITDIALOG 消息处理 OnInitDialog()
    3). 用 SetWindowLong 函数指定特定的窗口过程处理函数
    4). 在特定的窗口过程函数中写入处理代码
    5). 注意:输入文本框的Multiline 属性 设为真

   B.NOTE:
     LONG SetWindowLong(
       HWND hWnd,   //窗口句柄
       int nIndex,  //指定要修改的属性  GWL_WNDPROC 为窗口处理过程函数
       LONG dwNewLong //处理函数地址
     ); //设置窗口指定的属性  This function changes an attribute of the specified window.The function also sets the 32-bit (long) value at the specified offset into the extra window memory.
     //If the function succeeds, the return value is the previous value of the specified 32-bit integer.

     HWND GetNextWindow(         
        HWND hWnd,   //本窗口句柄
        UINT wCmd    //方向  GW_HWNDNEXT 或   GW_HWNDPREV
     ); //按指定方向取得本窗口下一窗口句柄

     HWND GetWindow(HWND hWnd,UINT uCmd);  //参数同上设置 

     HWND GetNextDlgTabItem(         
        HWND hDlg,   //Dialog Handle
        HWND hCtl,   //This Handle
        BOOL bPrevious  //Specifies how the function is to search the dialog box. 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.
     );//The GetNextDlgTabItem function searches controls in the order (or reverse order) they were created in the dialog box template. The function returns the first control it locates that is visible, not disabled, and has the WS_TABSTOP style. If no such control exists, the function returns hCtl.

15.焦点事件(Tab Stop)
    GetFocus()->GetNextWindow()->SetFocus();
    GetFocus()->GetWindow(GW_HWNDNEXT)->SetFocus();
    GetNextDlgTabItem(GetFocus())->SetFocus();

    NOTE:
      static CWnd* PASCAL GetFocus( );  //This method obtains a pointer to the CWnd that currently has the input focus
    
      CWnd* GetNextDlgTabItem(
        CWnd* pWndCtl,
        BOOL bPrevious = FALSE )
      const; //This method obtains a pointer to the first control that was created with the WS_TABSTOP style, that precedes, or follows the specified control.
        //pWndCtl:Identifies the control to be used as the starting point for the search
        //bPrevious:Specifies how the function is to search the dialog box. If TRUE, the function searches for the previous control in the dialog box; if FALSE, it searches for the next control.

来源:http://blog.csdn.net/mickorguo/archive/2006/01/06/571813.aspx

c#用多了.vc好不习惯啊.呵呵,