1. 程式人生 > >MFC 獲得各類指標、控制代碼的方法

MFC 獲得各類指標、控制代碼的方法

最近有些人在問MFC程式設計一些要點,有一些控制代碼的獲取、指標的獲取是常見的問題,本文將對這些問題做以解釋,參考了前人的筆錄(見reference),希望能夠幫助大家更方便地進行MFC程式開發。

   一般我們使用的框架是VC提供的Wizard生成的MFC App Wizard(exe)框架,無論是多文件還是單文件,都存在指標和控制代碼獲取和操作問題。本文中將針對各類控制代碼的獲得、指標的獲得以及MFC中常見應用進行闡述並舉例。

本文內容索引:

=========================================================

MFC中獲取常見類控制代碼<檢視類,文件類,框架類,應用程式類>

MFC中獲取視窗控制代碼及相關函式 

MFC獲取控制元件控制代碼

MFC各類中獲取類指標詳解

 MSDN關於應用程式資訊和管理的各個函式

==========================================================

MFC中獲取常見類控制代碼<檢視類,文件類,框架類,應用程式類>

本節為VC中常用的文件類,檢視類,框架類,應用程式類,自定義類中獲取其它四個類的方法:
GET App 
   AfxGetInstanceHandle() 
   AfxGetApp() 
GET Frame->View->Document 
    SDI   AfxGetMainWnd() -> GetActiveView() -> GetDocument() 


    MDI   AfxGetMainWnd() -> MDIGetActive() -> GetActiveView() -> GetDocument() 
GET Menu 
     CMenu *pMenu=AfxGetApp()->m_pMainWnd->GetMenu(); 
GET ToolBar,StatusBar 
      (CMainFrame *)GetParent()->m_wndToolBar; 
      (CMainFrame *)GetParent()->m_wndStatusBar; 
      CStatusBar * pStatusBa=(CStatusBar*)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_STATUS_BAR); 

      CToolBar * pToolBar=(CtoolBar*)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_TOOLBAR); 
Get View from Document 
      GetFirstViewPosition 和 GetNextView 函式得到指標。 



MFC中獲取視窗控制代碼及相關函式 

首先,視窗控制代碼,在視窗類中直接使用成員變數m_hWnd,在視窗外最常見是用AfxGetMainWnd (獲取主視窗指標,其成員變數m_hWnd為主視窗控制代碼):

HWND hWnd = AfxGetMainWnd()->m_hWnd;

與其相關的函式說明如下,這些函式對於獲取視窗控制代碼非常有用:

GetTopWindow
函式功能:該函式檢查與特定父視窗相聯的子視窗z序(Z序:垂直螢幕的方向,即疊放次序),並返回在z序頂部的子視窗的控制代碼。
函式原型:HWND GetTopWindow(HWND hWnd);
引數:
  hWnd:被查序的父視窗的控制代碼。如果該引數為NULL,函式返回Z序頂部的視窗控制代碼。
返回值:
    如果函式成功,返回值為在Z序頂部的子視窗控制代碼。如果指定的視窗無子視窗,返回值為NULL。


GetForegroundWindow
函式功能:該函式返回當前系統的前臺視窗的視窗控制代碼。
函式原型:HWND GetForegroundWindow(VOID)  
返回值:函式返回前臺窗回的控制代碼。


GetActiveWindow獲取當前視窗控制代碼

函式功能:該函式可以獲得與呼叫該方法的執行緒的訊息佇列相關的活動視窗的視窗控制代碼(就是取得當前程序的活動視窗的視窗控制代碼)。
函式原型:HWND GetActiveWindow(VOID)
返回值:返回值是與呼叫執行緒的訊息佇列相關的活動視窗的控制代碼。否則,返回值為NULL。



GetSafeHwnd
函式功能:獲取某個視窗物件(CWnd的派生物件)指標的控制代碼(HWND)時,最安全的方法是使用GetSafeHwnd()函式。
通過下面的例子來看其理由:
  CWnd *pwnd = FindWindow(“ExploreWClass”,NULL); //希望找到資源管理器

CWnd *pwnd = FindWindow(“ExploreWClass”,NULL); //希望找到資源管理器
  HWND hwnd = pwnd->m_hwnd; //得到它的HWND

HWND hwnd = pwnd->m_hwnd; //得到它的HWND

  這樣的程式碼當開始得到的pwnd為空的時候就會出現一個“General protection error”,並關閉應用程式,因為一般不能對一個NULL指標訪問其成員,如果用下面的程式碼:
CWnd *pwnd = FindWindow(“ExploreWClass”,NULL); //希望找到資源管理器
  HWND hwnd = pwnd->GetSafeHwnd(); //得到它的HWND

就不會出現問題,因為儘管當pwnd是NULL時,GetSafeHwnd仍然可以用,只是返回NULL




IsWindowVisible
函式功能:該函式獲得給定視窗的可視狀態。
函式原型:BOOL IsWindowVisible(HWND hWnd);
引數;
  hWnd:被測試視窗的控制代碼。
返回值:
    如果指定的視窗及其父視窗具有WS_VISIBLE風格,返回值為非零;如果指定的視窗及其父視窗不具有WS_VISIBLE風格,返回值為零。由於返回值表明了視窗是否具有Ws_VISIBLE風格,因此,即使該視窗被其他視窗遮蓋,函式返回值也為非零。
備註:
    視窗的可視狀態由WS_VISIBLE位指示。當設定了WS_VISIBLE位,視窗就可顯示,而且只要視窗具有WS_VISIBLE風格,任何畫在視窗的資訊都將被顯示。



IsWindow:
函式功能:該函式確定給定的視窗控制代碼是否標示一個已存在的視窗。 
函式原型:BOOL IsWindow(HWND hWnd);
引數:
    hWnd:被測試視窗的控制代碼。
返回值:
    如果視窗控制代碼標識了一個已存在的視窗,返回值為TURE;如果視窗控制代碼未標識一個已存在視窗,返回值為FALSE。

FindWindow:
HWND FindWindow(LPCSTR lpClassName,LPCSTR lpWindowName );
引數:
lpClassName

  指向一個以null結尾的、用來指定類名的字串或一個可以確定類名字串的原子。如果這個引數是一個原子,那麼它必須是一個在呼叫此函式前已經通過GlobalAddAtom函式建立好的全域性原子。這個原子(一個16bit的值),必須被放置在lpClassName的低位位元組中,lpClassName的高位位元組置零。

lpWindowName
  指向一個以null結尾的、用來指定視窗名(即視窗標題)的字串。如果此引數為NULL,則匹配所有視窗名。
返回值:
如果函式執行成功,則返回值是擁有指定視窗類名或視窗名的視窗的控制代碼。

  如果函式執行失敗,則返回值為 NULL 。可以通過呼叫GetLastError函式獲得更加詳細的錯誤資訊。

來說個應用,視窗標題的改變,我們可以通過SetWindowText來實現:

注:如果視窗本身屬性是不顯示標題的,這個函式的呼叫不會影響視窗屬性。

//Set title for application’s main frame window .
AfxGetMainWnd ( ) -> SetWindowText (_T("Application title") )
//Set title for View’s MDI child frame window .
GetParentFrame ( ) -> SetWindowText ("_T ("MDI Child Frame new title") )
//Set title for dialog’s push button control.
GetDigitem (IDC_BUTTON) -> SetWindowText (_T ("Button new title ") )

MFC獲取控制元件控制代碼

SDI中的控制元件控制代碼獲取:

CWnd   *pWnd   =   GetDlgItem(ID_***); // 取得控制元件的指標
HWND hwnd = pWnd->GetSafeHwnd();  // 取得控制元件的控制代碼
取得CDC的指標是CDC* pdc = pwnd->GetWindowDC();

MFC各類中獲取類指標詳解


使用到的類需要包含響應的標頭檔案。首先一般獲得本類(視,文件,對話方塊都支援)例項指標 this,用this的目的,主要可以通過類中的函式向其他類或者函式中髮指針,以便於在非本類中操作和使用本類中的功能。這其中的關鍵在於理解 m_pMainWnd,AfxGetApp(),AfxGetMainWnd()的意義!


1)在View中獲得Doc指標
CYouSDIDoc *pDoc=GetDocument();一個視只能有一個文件。


2) 在App中獲得MainFrame指標
CWinApp 中的 m_pMainWnd變數就是MainFrame的指標,也可以: CMainFrame *pMain =(CMainFrame*)AfxGetMainWnd();


3) 在View中獲得MainFrame指標
CMainFrame *pMain=(CmaimFrame *)AfxGetApp()->m_pMainWnd;


4) 獲得View(已建立)指標
CMainFrame *pMain=(CmaimFrame *)AfxGetApp()->m_pMainWnd;
CyouView *pView=(CyouView *)pMain->GetActiveView();


5) 獲得當前文件指標
CDocument * pCurrentDoc =(CFrameWnd *)m_pMainWnd->GetActiveDocument();


6) 獲得狀態列與工具欄指標
CStatusBar * pStatusBar=(CStatusBar *)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_STATUS_BAR);
CToolBar * pToolBar=(CtoolBar*)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_TOOLBAR);


7) 如果框架中加入工具欄和狀態列變數還可以這樣
(CMainFrame *)GetParent()->m_wndToolBar;
(CMainFrame *)GetParent()->m_wndStatusBar;


8) 在Mainframe獲得選單指標
CMenu *pMenu=m_pMainWnd->GetMenu();


9) 在任何類中獲得應用程式類
AfxGetInstanceHandle 得到控制代碼,AfxGetApp得到指標


最後提醒大家,在提取到各個控制代碼之後,因為初次提取的都是標準類控制代碼,所以,在使用時要注意將標準控制代碼轉換成自己的類的控制代碼。
如:
AfxGetApp();//得到的是WinApp類的控制代碼,
所以操作前記得轉換成自己定義的類的控制代碼。
如:
((CMyApp*)AfxGetApp())->XXXX();//這的xxxx()就是你定義的類中間的成員。




MSDN關於應用程式資訊和管理的各個函式 When you write an application, you create a single CWinApp-derived object. Attimes, you may want to get information about this object from outside theCWinApp-derived object.
The Microsoft Foundation Class Library provides the following global functionsto help you accomplish these tasks:
Application Information and Management Functions
AfxFreeLibrary
Decrements the reference count of the loaded dynamic-link library (DLL) module;when the reference count reaches zero, the module is unmapped.


AfxGetApp
Returns a pointer to the application's single CWinApp object.


AfxGetAppName
Returns a string containing the application's name.


AfxGetInstanceHandle
Returns an HINSTANCE representing this instance of the application.


AfxGetMainWnd
Returns a pointer to the current "main" window of a non-OLEapplication, or the in-place frame window of a server application.


AfxGetResourceHandle
Returns an HINSTANCE to the source of the application's default resources. Usethis to access the application's resources directly.


AfxInitRichEdit
Initializes the version 1.0 rich edit control for the application.


AfxInitRichEdit2
Initializes the version 2.0 and later rich edit control for the application.


AfxLoadLibrary
Maps a DLL module and returns a handle that can be used to get the address of aDLL function.


AfxRegisterWndClass
Registers a Windows window class to supplement those registered automaticallyby MFC.


AfxSocketInit
Called in a CWinApp::InitInstance override to initialize Windows Sockets.


AfxSetResourceHandle
Sets the HINSTANCE handle where the default resources of the application areloaded.


AfxRegisterClass
Registers a window class in a DLL that uses MFC.


AfxBeginThread
Creates a new thread.


AfxEndThread
Terminates the current thread.


AfxGetThread
Retrieves a pointer to the current CWinThread object.


AfxWinInit
Called by the MFC-supplied WinMain function, as part of the CWinAppinitialization of a GUI-based application, to initialize MFC. Must be calleddirectly for console applications using MFC.

Reference:

如有其他MFC常見問題請在下方留言或在新浪微博Sophia_qing上與我聯絡,我將繼續補充