程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> vc教程 >> VC++深入詳解:在窗口中顯示按鈕(1)

VC++深入詳解:在窗口中顯示按鈕(1)

編輯:vc教程

  為了更好地理解窗口類、窗口類對象和窗口之間的關系,我們接下來實現在窗口中顯示一個按鈕這一功能,仍在已有的Test程序中實現。首先需要創建一個按鈕類對象,按鈕對應的MFC類是CButton類,其繼承層次結構如圖3.24所示,從而可以得知CButton類派生於CWnd類。

圖3.24 CButton類的繼承層次結構

  在MFC提供的資源類中,有些類的對象的構造(包括對象構造與初始化)直接通過其構造函數就可以完成。也就是說,這些對象的構造函數包含這個對象的初始化操作。但有些對象的產生除了調用構造函數外,還需要調用其他一些函數來進行初始化的工作,然後才能使用該對象。

  對於一個CButton對象,在定義之後就可以使用了。但是作為一個窗口類對象,即CWnd對象,如果在構造之後還需要產生這個窗口的話,還需要調用CreateEx函數來完成初始化工作。也就是說,如果要顯示一個按鈕的話,在定義這個CButton類對象之後,即調用CButton類的構造函數之後,還需要調用CButton的Create函數創建這個按鈕窗口,從而把按鈕窗口與CButton對象關聯起來。

  CButton的Create函數聲明如下。

  BOOL Create( LPCTSTR lpszCaption, DWord dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );

  各個參數的意義如下所述。

  n lpszCaption

  指定按鈕控件的文本。

  n dwStyle

  指定按鈕控件的風格。按鈕控件不僅具有按鈕風格類型,還具有窗口風格類型。多種風格類型可以通過位或操作加以組合。

  n rect

  指定按鈕控件的大小和位置。該參數是RECT結構體類型,通過指定左上角和右下角兩個點的坐標定義一個矩形。結構體也是一種特殊的類,所以可以用類CRect來構造一個RECT結構體。

  n pParentWnd

  指定按鈕控件的父窗口。這是一個CWnd類型的指針。MFC中不再通過窗口句柄,而是通過一個與窗口相關的C++窗口類對象指針來傳遞窗口對象。

  n nID

  指定按鈕控件的標識。

  為了在框架窗口上產生一個按鈕控件,顯然應該是在框架窗口產生之後,再創建該按鈕控件,否則沒有地方放置它。窗口創建時都會產生WM_CREATE消息,CMainFrame類提供一個OnCreate函數,該函數就是用來響應這條窗口創建消息的。該函數的默認實現代碼如例3-22所示。

  例3-22

  int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
  {
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
      return -1;
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
      | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
      !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
    {
      TRACE0("Failed to create toolbarn");
      return -1;   // fail to create
    }
    if (!m_wndStatusBar.Create(this) ||
      !m_wndStatusBar.SetIndicators(indicators,
       sizeof(indicators)/sizeof(UINT)))
    {
      TRACE0("Failed to create status barn");
      return -1;   // fail to create
    }
    // TODO: Delete these three lines if you don't want the toolbar to
    // be dockable
    m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
    EnableDocking(CBRS_ALIGN_ANY);
    DockControlBar(&m_wndToolBar);
    return 0;
  }

  從例3-22所示代碼可知,CMainFrame類的OnCreate函數首先調用基類CFrameWnd的OnCreate函數,創建一個窗口,然後創建工具條(m_wndToolBar)和狀態欄(m_ wndStatusBar)對象。我們可以在該函數的最後完成按鈕的創建工作,即在return語句之前添加例3-23所示代碼中加灰顯示的代碼。

  例3-23

  int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
  {
  ……
    CButton btn;
    btn.Create("按鈕",WS_CHILD | BS_DEFPUSHBUTTON,CRect(0,0,100,100),this, 123);
    return 0;
  }

  其中,將該按鈕的名稱設置為“按鈕”,其位置由CRect(0,0,100,100)這一矩形確定,ID號為123。前面已經講過,按鈕控件不僅具有按鈕風格類型,還具有窗口風格類型,因此,在按鈕的Create函數中指定該按鈕具有WS_CHILD窗口風格類型,同時還具有BS_DEFPUSHBUTTON按鈕風格類型,即下按按鈕風格。

  另外,我們知道每個對象都有一個this指針,代表對象本身。為了使按鈕控件的父窗口就是框架窗口,這裡可以直接將代表CMainFrame對象的this指針作為參數傳遞給按鈕的Create函數。

  編譯並運行Test程序,但發現按鈕並沒有顯示出來。問題的原因有兩個:一是這裡定義的btn對象是個局部對象,當執行到OnCreate函數的右大括號(})時,該對象的生命周期就結束了,就會發生析構。前面已經講過,如果一個窗口與一個C++窗口類對象相關聯,當這個C++對象生命周期結束時,該對象在析構時通常會把與之相關聯的窗口資源進行回收。這就是說,當執行到例3-22所示的OnCreate函數的右大括號時,剛剛創建的btn窗口就被與之相關的C++對象銷毀了。因此,不能將這個按鈕對象定義為一個局部對象。解決方法是:將其定義為CMainFrame類的一個成員變量,可以將其訪問權限定義為private類型以實現信息隱藏。

  有多種方法可以定義一個類的成員變量,可以直接在該類的定義中添加成員變量定義代碼,也可以利用VC++提供的工具來定義。後者的方法是:在ClassVIEw標簽頁中的類名上單擊鼠標右鍵,從彈出的快捷菜單上選擇【Add member variable…】菜單命令,將彈出Add Member Variable對話框。通常,在定義類的成員變量名稱時都以“m_”為前綴,表明這個變量是類的一個成員變量。在添加成員變量對話框的Variable Type(變量類型)文本框中輸入變量類型CButton,Variable Name(變量名稱)文本框中輸入按鈕對象名稱m_btn,並為其選擇private類型的訪問權限,如圖3.25所示。

圖3.25 Add Member Variable對話框

  然後單擊對話框上的【OK】按鈕,即可以在CMainFrame類的頭文件中看到新成員變量的定義,代碼如下:

  private:

  CButton m_btn;

  修改例3-23所示CMainFrame類OnCreate函數中創建按鈕的代碼,刪除局部按鈕對象的定義,並將按鈕創建函數的對象名稱改為m_btn,結果如例3-24所示。

  例3-24

  int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
  {
  ……
    m_btn.Create("按鈕",WS_CHILD | BS_DEFPUSHBUTTON,CRect(0,0,100,100), this,123);
    return 0;
  }

  再次運行Test程序,將會發現按鈕還沒有出現。這一問題的第二個原因就是在一個窗口創建完成之後,應該將這個窗口顯示出來。因此,需要在調用Create函數之後再添加一條窗口顯示代碼,如例3-25所示。


  例3-25

  int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
  {
  ……
  1. m_btn.Create("按鈕",WS_CHILD | BS_DEFPUSHBUTTON,CRect(0,0,100,100), this,123);
  2. m_btn.ShowWindow(SW_SHOWNORMAL);
    return 0;
  }

  再次運行Test程序,這時就可以看到按鈕出現了,如圖3.26所示。

圖3.26 在框架窗口中顯示按鈕

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved