国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

第三章-MFC運行機制

2019-11-11 05:26:31
字體:
供稿:網(wǎng)友

在Windows程序設(shè)計編程中,創(chuàng)建一個窗口要經(jīng)歷下面四個過程 (如有不懂,請看博客 win32初窺)

1設(shè)計一個窗口類;2注冊窗口類;3創(chuàng)建窗口;4顯示及更新窗口。 同樣的,WinMain也是入口函數(shù),具體的過程,請看孫鑫視頻20講之第三講 其中,孫鑫老師開始提出的一個問題是:在全局變量中,定義一個子類對象。。。[html] view plain copy#include<iostream>  #include<string>  using namespace std;    class Person  {  public:      Person *p;      Person()      {          p=this;//保存this指針      }      virtual void say()      {          cout<<"Person's say()"<<endl;      }    };    class Student:public Person  {  public:            Student()      {        }      void say()      {          cout<<"Student's say()"<<endl;      }    };    Student s;    int main()  {            s.p->say();//這里將調(diào)用子類的方法      return 0;  }   什么都不用做,直接用向?qū)梢粋€MFC窗口。下面是結(jié)構(gòu)圖,有五個類是這樣命名的,開頭的C表示Class ,C+工程名+(App,Doc,View...)

其中CMainFrame表示一個窗口(主窗體,包括標(biāo)題欄,菜單...),XXApp表示運用程序,XXDOC表示文檔類(加載數(shù)據(jù),實現(xiàn)數(shù)據(jù)的存儲與操作分離),XXView也表示一個窗口(相當(dāng)于Windows的客戶區(qū))

 

下面看看MFC中類的主要繼承關(guān)系:

由于繼承樹太大,這里只羅列了CWnd的繼承關(guān)系

 

 

API中CreateWindowEx和CreateWindow幾乎是一樣的,Ex表示擴展,多了一個參數(shù)

下面用API模擬CWnd

just模擬

[html] view plain copy//下面是模仿封裝API函數(shù)    class CWnd  {  public:      BOOL CreateEX(          DWord dwExStyle,      // extended window style          LPCTSTR lpClassName,  // registered class name          LPCTSTR lpWindowName, // window name          DWORD dwStyle,        // window style          int x,                // horizontal position of window          int y,                // vertical position of window          int nWidth,           // window width          int nHeight,          // window height          HWND hWndParent,      // handle to parent or owner window          HMENU hMenu,          // menu handle or child identifier          HINSTANCE hInstance,  // handle to application instance          LPVOID lpParam        // window-creation data          );        BOOL ShowWindow(int nCmdShow);        BOOL UpdateWindow();    public:      HWND m_hWnd;  };    BOOL CWnd::CreateEx(                 DWORD dwExStyle,      // extended window style                 LPCTSTR lpClassName,  // registered class name                 LPCTSTR lpWindowName, // window name                 DWORD dwStyle,        // window style                 int x,                // horizontal position of window                 int y,                // vertical position of window                 int nWidth,           // window width                 int nHeight,          // window height                 HWND hWndParent,      // handle to parent or owner window                 HMENU hMenu,          // menu handle or child identifier                 HINSTANCE hInstance,  // handle to application instance                 LPVOID lpParam        // window-creation data              );  {      m_hWnd=::CreateWindowEx(dwExstyle,lClassName,lpWindowName,dwStyle,x,y,nWidth,nHeight,hWndParent,                              hMenu,hInstance,lParam);        if(m_hWnd!=NULL)            return TRUE;      else          return FALSE;  }    BOOL CWnd::ShowWindow(int nCmdShow)  {      return ::ShowWindow(m_hWnd,nCmdShow);//調(diào)用的是SDK全局函數(shù),加個::說明是全局的  }    BOOL CWnd::UpdateWindow()  {      return ::UpdateWindow(m_hWnd);  }    int WINAPI WinMain(                       HINSTANCE hInstance,      // handle to current instance                        HINSTANCE hPRevInstance,  // handle to previous instance                        LPSTR lpCmdLine,          // command line                        int nCmdShow              // show state                        )    {        WNDCLASS wndclass;              wndclass.cbClsExtra=0;        wndclass.cbWndExtra=0;        wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);        wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);        wndclass.hIcon=LoadIcon(NULL,IDI_ERROR);        wndclass.hInstance=hInstance;       ...          CWnd cwnd;     cwnd.CreateEx(dwExstyle,...,...);        cwnd.ShowWindow(nCmdShow);        cwnd.UpdateWindow();              while(GetMessage(&msg,NULL,0,0))        {            TranslateMessage(&msg);            DispatchMessage(&msg);        }              ...  }    

 

下面是重頭戲(引用了某位仁兄的,太詳細(xì)了)

重點:MFC運行機制    提示:對于不想理解內(nèi)部運行過程的,可以不看這一章,可以看了后面的界面設(shè)計再回頭來看這一章,可能感覺更深刻。  這一次課和上一次的課的重點就是MFC的窗口類創(chuàng)建過程,而要反復(fù)說明的就是:MFC的程序和C語言的程序,從執(zhí)行原理上說,是完全一致的。  抓住這一點,那么對于理解MFC程序的運行機制也就相對于簡單了。  C中的main函數(shù)就相當(dāng)于MFC中的WinMain函數(shù)。  感興趣的可以利用VC的斷點設(shè)置自己跟蹤下面講述的各個函數(shù),就明白它的執(zhí)行順序了。    一、C語言程序執(zhí)行步驟  在C語言中,大約的步驟如下:  1, 全局變量內(nèi)存分配  2, 進(jìn)入main函數(shù)    二、MFC程序的運行步驟(主要是初始化)    打開一個MFC APPWizard(exe)工程,跟蹤其執(zhí)行步驟,可以發(fā)現(xiàn),是以下順序:  1) CXXApp中的全局變量定義  CXXApp theApp;  2) 調(diào)用CXXApp構(gòu)造函數(shù)  CXXApp ::CXXApp(){}  3) 進(jìn)入Winmain函數(shù)(_tWinMain為宏,值為WinMain)  _tWinMain(){}    4) 完成初始化工作:包括窗口類注冊、窗口產(chǎn)生、顯示和更新  pThread->InitInstance()    對于MFC程序,MainFrame,View,ToolBar,Controlbar等都是窗口,所以下面的窗口注冊與創(chuàng)建、顯示等要反復(fù)調(diào)用多次,一次對應(yīng)一個窗口    (1) 注冊窗口類    AfxEndDeferRegisterClass    (2) 創(chuàng)建窗口    CMainFrame::PreCreateWindow()//反復(fù)調(diào)用一次是給我們修改窗口屬性的機會    CFrameWnd::Create()    (3) 消息循環(huán)    PumpMessage()    補充1:    在MFC中,由于涉及到(窗口)類定義,所以定義全局變量的時候,需要進(jìn)行更多的步驟。    全局變量涉及到類定義(類似于C中的類型定義)的話,那么需要遵循以下步驟(以MFC的窗口類為例)    1) 設(shè)計一個窗口類    2) 注冊窗口類    3) 創(chuàng)建窗口    4) 顯示及更新窗口    5) 消息循環(huán)         補充2:其他需要注意的幾點    1, 每一個MFC程序,有且只有一個從WinApp類派生的類(應(yīng)用程序類),也只有一個從應(yīng)用程序類所事例化的對象,表示應(yīng)用程序本身。在WIN32程序當(dāng)中,表示應(yīng)用程序是通過WINMAIN入口函數(shù)來表示的(通過一個應(yīng)用程序的一個事例號這一個標(biāo)識來表示的)。在基于MFC應(yīng)用程序中,是通過產(chǎn)生一個應(yīng)用程序?qū)ο螅盟鼇砦ㄒ坏谋硎玖藨?yīng)用程序。    2, _tWinMain函數(shù)中通過調(diào)用AfxWinMain()函數(shù)來完成它要完成的功能。(Afx*前綴代表這是應(yīng)用程序框架函數(shù),是一些全局函數(shù),應(yīng)用程序框架是一套輔助生成應(yīng)用程序的框架模型,把一些類做一些有機的集成,我們可根據(jù)這些類函數(shù)來設(shè)計自己的應(yīng)用程序)。    3, 設(shè)計窗口類:在MFC中事先設(shè)計好了幾種缺省的窗口類,根據(jù)不同的應(yīng)用程序的選擇,調(diào)用AfxEndDeferRegisterClass()函數(shù)注冊所選擇的窗口類。    4, PreCreateWindow()是個虛函數(shù),如果子類有則調(diào)用子類的。    5, CreateWindowEx()函數(shù)參數(shù)與CREATESTRUCT結(jié)構(gòu)體成員完全一致,CreateWindowEx()函數(shù)與CREATESTRUCT結(jié)構(gòu)體參數(shù)的對應(yīng)關(guān)系,使我們在創(chuàng)建窗口之前通過可PreCreateWindow(cs)修改cs結(jié)構(gòu)體成員來修改所要的窗口外觀。    6,注意兩個函數(shù)。    ::TranslateMessage(&m_msgCur)函數(shù)進(jìn)行消息(如鍵盤消息)轉(zhuǎn)換    ::DispatchMessage(&m_msgCur)函數(shù)分派消息到窗口的回調(diào)函數(shù)處理(實際上分派的消息經(jīng)過消息映射,交由消息響應(yīng)函數(shù)進(jìn)行處理。)    7,可以認(rèn)為View類窗口是CMainFram類窗口的子窗口。DOCument類是文檔類。DOC-VIEW結(jié)構(gòu)將數(shù)據(jù)本身與它的顯示分離開。    文檔類用于數(shù)據(jù)的存儲,加載;視類用于數(shù)據(jù)的顯示,修改    8,CTEApp::InitInstance()函數(shù)中通過文檔模板將文檔類,視類,框架類的有機組織一起。語句如下:    CSingleDocTemplate* pDocTemplate;  pDocTemplate = new CSingleDocTemplate(   IDR_MAINFRAME,   RUNTIME_CLASS(CTEDoc),   RUNTIME_CLASS(CMainFrame), // main SDI frame window   RUNTIME_CLASS(CTEView));  AddDocTemplate(pDocTemplate);//增加到模板    補充3:本課涉及到MFC函數(shù)的源文件位置    根目錄    找到您安裝VC98下MFC的位置,比如我的機子上為:D:/Program Files/Microsoft Visual Studio/VC98/MFC。下面提供的就是相對路徑了。         CWinApp構(gòu)造函數(shù): MFC=>SRC=>APPCORE.CPP  AfxWinMain:MFC=>SRC=>WINMAIN.CPP  AfxEndDeferRegisterClass: MFC=>SRC=>APPCORE.CPP  CFrameWnd::PreCreateWindow()函數(shù)所在文件:MFC=>SRC=>WINFRM.CPP  CFrameWnd::Create()函數(shù)路徑:MFC=>SRC=>WINFRM.CPP  CWnd::CreateEx()函數(shù)路徑:MFC=>SRC=>WINCORE.CPP  CWinThread::Run()方法路徑:MFC=>SRC=>THRDCORE.CPP 創(chuàng)建按鈕

1在CMainFrame創(chuàng)建

雙擊CMainFrame,添加數(shù)據(jù)成員,CButton m_btn

在OnCreate方法添加如下代碼:

[html] view plain copym_btn.Create(TEXT("first Button"),BS_PUSHBUTTON|WS_CHILD,CRect(0,0,100,100),this,123);  m_btn.ShowWindow(SW_NORMAL);  

 

2在CXXView創(chuàng)建

雙擊CXXView,添加數(shù)據(jù)成員,CButton m_btn

在CXXView右鍵Add windows Message Handler 添加WM_CREATE消息處理,然后生成OnCreate函數(shù)

在OnCreate函數(shù)添加如下代碼

[html] view plain copym_btn.Create(TEXT("Button2"),BS_PUSHBUTTON|WS_CHILD|WS_VISIBLE,CRect(0,0,100,100),this,123);  

兩個代碼效果是等價的:


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 江口县| 陈巴尔虎旗| 临漳县| 堆龙德庆县| 鹿泉市| 茌平县| 吴桥县| 曲沃县| 科技| 伊春市| 山丹县| 花垣县| 鹤岗市| 宝应县| 黑河市| 安阳市| 万宁市| 巴中市| 永川市| 乐亭县| 阳新县| 忻州市| 宝山区| 辽宁省| 临汾市| 灌阳县| 盐亭县| 嘉鱼县| 义马市| 成安县| 平远县| 内丘县| 鱼台县| 伊通| 彩票| 光泽县| 西畴县| 浑源县| 平遥县| 龙州县| 二连浩特市|