jasmine214--love

          只有當(dāng)你的內(nèi)心總是充滿快樂、美好的愿望和寧靜時(shí),你才能擁有強(qiáng)壯的體魄和明朗、快樂或者寧靜的面容。
          posts - 731, comments - 60, trackbacks - 0, articles - 0

          Frame窗口類型

          Posted on 2010-08-28 20:24 幻海藍(lán)夢 閱讀(687) 評(píng)論(0)  編輯  收藏 所屬分類: C++

          http://xz7.2000y.net/mb/2/ReadNews.asp?NewsID=443411
          3.5.1  框架窗口

            框架窗口為應(yīng)用程序的用戶界面提供結(jié)構(gòu)框架,它是應(yīng)用程序的主窗口,負(fù)責(zé)管理其包容的窗口,一個(gè)應(yīng)用程序的最頂層的框架窗口是應(yīng)用程序啟動(dòng)時(shí)創(chuàng)建的第一個(gè)窗口。
            MFC提供三種類型的框架窗口:單文檔窗口,多文檔窗口(MDI),對話框。在AppWizard的第一個(gè)對話框中,就提供了選項(xiàng),讓用戶選擇應(yīng)用程序是基于單文檔、多文檔還是對話框的。MFC單文檔窗口一次只能打開一個(gè)文檔框架窗口,而MDI應(yīng)用程序運(yùn)行時(shí),在應(yīng)用程序的一個(gè)實(shí)例中打開多個(gè)文檔框架窗口,這些窗口稱作子窗口(Child Window)。這些文檔可以是同一類型的,也可以是不同類型的。如Visual Studio就可以打開資源文件窗口和源程序窗口等不同類型的窗口。此時(shí),激活不同類型的MDI子窗口,菜單也將相應(yīng)變化。
            MFC提供了三個(gè)類CFrameWnd、CMDIFrameWnd、CMDIChildWnd和CDialog 分別用于支持單文檔窗口、多文檔窗口和對話框。

          CFrameWnd
            用于SDI框架窗口,形成單個(gè)文檔及其視的邊框。框架窗口既是應(yīng)用程序的主框架窗口,也是當(dāng)前文檔對應(yīng)的視圖的邊框。

          CMDIFrameWnd
            用于MDI應(yīng)用程序的主框架窗口。主框架窗口是所有MDI文檔窗口的容器,并與它們共享菜單條。MDI框架窗口是出現(xiàn)在桌面中的頂層窗口。

          CMDIChildWnd
            用于在MDI主框架窗口中顯示打開的各個(gè)文檔。每個(gè)文檔及其視都有一個(gè)MDI子框架窗口,子框架窗口包含在MDI主框架窗口中。子框架窗口看起來類似一般的框架邊框窗口,但它是包含在主框架窗口中,而不是位于桌面的,并且為主窗口所裁剪。而且MDI子窗口沒有自己的菜單,它與主MDI框架窗口共享菜單。

          CDialog
            對話框是一種特殊類型的窗口,它的邊框一般不可以調(diào)整,而且內(nèi)部包含一些控件窗口。有關(guān)對話框作為主窗口的技術(shù)可以參見下一章。

            要生成一個(gè)單文檔窗口,主窗口就必須從CFrameWnd派生;要生成一個(gè)多文檔窗口,主窗口就必須從CMDIFrameWnd派生,而且其中的子窗口必須從CMDIChildWnd派生出來;而基于對話框的窗口程序就要從CDialog派生出主窗口類。

          子窗口
            子窗口就是具有WS_CHILD風(fēng)格的窗口,且一定有一個(gè)父窗口。所有的控件都是子窗口。子窗口可以沒有邊框。子窗口被完全限制在父窗口內(nèi)部。

          父窗口
            父窗口就是擁有子窗口的窗口。
          彈出式窗口
            具有WS_POPUP風(fēng)格,它可以沒有父窗口。這種窗口幾乎什么都沒有,可看作一個(gè)矩形區(qū)域。
          3.5.2窗口的創(chuàng)建

          窗口的創(chuàng)建分為兩步:第一步是用new創(chuàng)建一個(gè)C++的窗口對象,但是此時(shí)只是初始化窗口的數(shù)據(jù)成員,并沒有真正創(chuàng)建窗口(這一點(diǎn)與一般的對象有所不同)。

          //第一步:創(chuàng)建一個(gè)C++對象,其中CMainFrame是從CFrameWnd派生的對象。

          CMainFrame* pMyFrame=new CMainFrame();//用new操作符創(chuàng)建窗口對象

          CMainFrame MyFrame;//定義一個(gè)窗口對象,自動(dòng)調(diào)用其構(gòu)造函數(shù)

          第二步是創(chuàng)建窗口。CFrameWnd的Create成員函數(shù)把窗口給做出來,并將其HWND保存在C++對象的公共數(shù)據(jù)成員m_hWnd中。

          //第二步:創(chuàng)建窗口

          pMyFrame->Create(NULL,“My Frame Window”);

          MyFrame.Create(NULL,“My Frame Window”);

          Create函數(shù)的原形如下:

          BOOL Create( LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle = WS_OVERLAPPEDWINDOW, const RECT& rect = rectDefault, CWnd* pParentWnd = NULL, LPCTSTR lpszMenuName = NULL, DWORD dwExStyle = 0, CCreateContext* pContext = NULL );

            Create函數(shù)第一個(gè)參數(shù)為窗口注冊類名,它指定了窗口的圖標(biāo)和類風(fēng)格。這里我們使用NULL做為其值,表明使用缺省屬性。第二個(gè)參數(shù)為窗口標(biāo)題。其余幾個(gè)參數(shù)指定了窗口的風(fēng)格、大小、父窗口、菜單名等。

            這個(gè)函數(shù)看起來比較復(fù)雜,對于CFrameWnd派生出來的窗口,我們可以使用LoadFrame從資源文件中創(chuàng)建窗口,它只需要一個(gè)參數(shù)。

          pMyFrame->LoadFrame(IDR_FRAME);

          LoadFrame使用該參數(shù)從資源中獲取許多默認(rèn)值,包括主邊框窗口的標(biāo)題、圖標(biāo)、菜單、加速鍵等。但是,在使用LoadFrame時(shí),必須確保標(biāo)題字符串、圖標(biāo)、菜單、加速鍵等資源使用同一個(gè)ID標(biāo)識(shí)符(在本例中,我們使用IDR_FRAME)。

          提示:在Hello程序的InitInstance中我們看不到創(chuàng)建窗口的過程。實(shí)際上,在

          pDocTemplate = new CSingleDocTemplate(

          IDR_MAINFRAME,

          RUNTIME_CLASS(CHelloDoc),

          RUNTIME_CLASS(CMainFrame), // main SDI frame window

          RUNTIME_CLASS(CHelloView));

            AddDocTemplate(pDocTemplate); 程序片段中,我們看到,CSingleDocTemplate構(gòu)造函數(shù)的第二個(gè)參數(shù)就是IDR_MAINFRAME。在構(gòu)造函數(shù)內(nèi)部,已經(jīng)通過調(diào)用m_pMainWnd->LoadFrame(IDR_MAINFRAME),完成了應(yīng)用程序主窗口的創(chuàng)建過程。
            在InitInstance中,創(chuàng)建完窗口后,窗口調(diào)用ShowWindow成員函數(shù)來顯示窗口。ShowWindow帶一個(gè)參數(shù),指示窗口以何種方式顯示(最大化、最小化或一般)。缺省方式為SW_SHOW,但實(shí)際上我們經(jīng)常希望應(yīng)用程序啟動(dòng)時(shí)窗口最大化,此時(shí)可以將該參數(shù)該為SW_SHOWMAXMIZED,即調(diào)用

          m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);

            在MainFrm.cpp中,我們還看到CMainFrame類有一個(gè)OnCreate方法。OnCreate成員函數(shù)定義如清單3.3。當(dāng)調(diào)用Create或CreateEx時(shí),操作系統(tǒng)會(huì)向窗口發(fā)送一條WM_CREATE消息。這一函數(shù)就是用來響應(yīng)WM_CREATE消息的。

          清單3.3 OnCreate成員函數(shù)定義

          int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

          {

          if (CFrameWnd::OnCreate(lpCreateStruct) == -1)

          return -1;

           

          if (!m_wndToolBar.Create(this) ||

          !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))

          {

          TRACE0("Failed to create toolbar\n");

          return -1; // fail to create

          }

          if (!m_wndStatusBar.Create(this) ||

          !m_wndStatusBar.SetIndicators(indicators,

          sizeof(indicators)/sizeof(UINT)))

          {

          TRACE0("Failed to create status bar\n");

          return -1; // fail to create

          }

          // TODO: Remove this if you don't want tool tips or a resizeable toolbar

          m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |

          CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);

          // 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;

          }

            在OnCreate函數(shù)中,首先調(diào)用CFrameWnd的缺省處理方法OnCreate完成窗口創(chuàng)建工作。后面是應(yīng)用程序主窗口的特定工作,在上面程序中,創(chuàng)建了工具條和狀態(tài)欄(有關(guān)工具條和狀態(tài)欄編程參見下一章有關(guān)內(nèi)容)。可以在此處加入一些初始化工作,如從INI文件中載入設(shè)置,顯示Splash Window(啟動(dòng)畫面)等。

          3.5.3 注冊窗口

            在傳統(tǒng)的Windows C程序中,送給一個(gè)窗口的所有消息是在它的窗口函數(shù)中處理的。把一個(gè)窗口同它的窗口函數(shù)聯(lián)系起來的過程稱為注冊窗口類。注冊窗口包括對窗口指定一個(gè)窗口函數(shù)(給出窗口函數(shù)的指針)以及設(shè)定窗口的光標(biāo)、背景刷子等內(nèi)容。一個(gè)注冊窗口類可以被多個(gè)窗口共享。注冊窗口通過調(diào)用API函數(shù)RegisterClass來完成。
            在MFC下,框架提供了缺省的自動(dòng)窗口注冊過程。框架仍然使用傳統(tǒng)的注冊類,而且提供了幾個(gè)標(biāo)準(zhǔn)的注冊類,它們在標(biāo)準(zhǔn)的應(yīng)用程序初始化函數(shù)中注冊。調(diào)用AfxRegisterWndClass全局函數(shù)就可以注冊附加的窗口類,然后把已經(jīng)注冊的類傳給CWnd的Create成員函數(shù)。用戶可以定制自己的注冊過程,以提供一些附加的特性。比如設(shè)置窗口的圖標(biāo)、背景、光標(biāo)等。下面是注冊窗口的例子。

          BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)

          {

          // TODO: Modify the Window class or styles here by modifying

          // the CREATESTRUCT cs

          UINT ClassStyle=CS_VREDRAW|CS_HREDRAW;

          cs.style=cs.style&(~FWS_ADDTOTITLE);

          cs.lpszClass = AfxRegisterWndClass(ClassStyle,

          AfxGetApp()->LoadStandardCursor(IDC_ARROW),

          (HBRUSH)(COLOR_WINDOW+1),//for brush

          AfxGetApp()->LoadIcon(IDR_MAINFRAME));

          return TRUE;

          }

            注冊窗口在CFrameWnd的PreCreateWnd方法中完成。從成員函數(shù)名字PreCreateWindow中就可以看出來,注冊窗口的工作必須在調(diào)用Create函數(shù)創(chuàng)建窗口之前完成。其中cs.style=cs.style&(~FWS_ADDTOTITLE)指定窗口標(biāo)題風(fēng)格,關(guān)閉自動(dòng)添加文檔標(biāo)題的功能。AfxRegisterWndClass指定窗口使用箭頭光標(biāo)、背景刷子使用比窗口顏色標(biāo)號(hào)大一的顏色、圖標(biāo)使用IDR_MAINFRAME標(biāo)識(shí)符指定的圖標(biāo)(當(dāng)然也可以使用其它圖標(biāo))。用上面的程序段替換Hello程序MainFrm.cpp中的PreCreateWindow成員函數(shù)定義,并重新編譯和運(yùn)行程序。此時(shí),窗口標(biāo)題變成了Hello,原來令人討厭的“Untitled-”沒有了,因?yàn)榇翱陲L(fēng)格中關(guān)閉自動(dòng)添加當(dāng)前文件名的風(fēng)格。

          3.5.4 關(guān)閉和銷毀窗口

            框架窗口不僅維護(hù)窗口的創(chuàng)建,還管理著窗口的關(guān)閉和銷毀過程。關(guān)閉窗口時(shí),操作系統(tǒng)依次向被關(guān)閉的窗口發(fā)送WM_CLOSE和WM_DESTROY消息。WM_CLOSE消息的缺省處理函數(shù)OnClose將調(diào)用DestroyWindow,來銷毀窗口;最后,框架調(diào)用窗口的析構(gòu)函數(shù)作清理工作并刪除C++窗口對象。
            不要使用C++的delete操作符來銷毀框架窗口,而應(yīng)當(dāng)采用CWnd的DestroyWindow成員函數(shù)來銷毀。DestroyWindow首先刪除子窗口,再刪除窗口本身。若窗口以變量方式產(chǎn)生(即在堆棧上分配內(nèi)存),該窗口對象會(huì)被自動(dòng)清除。若對象是用new操作符創(chuàng)建的(也就是在堆上分配內(nèi)存的),則需要用戶自己處理。有關(guān)DestroyWindow問題在第五章對話框技術(shù)中還要作進(jìn)一步解釋。

          OnClose()常用功能:保存窗口的一些狀態(tài)、工具條狀態(tài),提示保存未保存的數(shù)據(jù)等等。

          void CMainFrame::OnClose()

          {

          SaveBarState( "MyDockState" );//保存工具條狀態(tài)

          CFrameWnd::OnClose();

          }3.5.5 窗口激活

            活動(dòng)窗口必定是一個(gè)沒有父窗口的頂層窗口,包括框架窗口和對話框。當(dāng)頂層窗口被激活時(shí),Windows向窗口發(fā)送WM_ACTIVATE消息,對此消息的缺省處理是將活動(dòng)窗口設(shè)為有輸入焦點(diǎn)。
            輸入焦點(diǎn)用于表示哪個(gè)窗口有資格接收鍵盤輸入消息。帶有輸入焦點(diǎn)的窗口或是一個(gè)活動(dòng)窗口,或者是該活動(dòng)窗口的子窗口。當(dāng)一個(gè)頂層窗口獲得輸入焦點(diǎn)時(shí),Windows向該窗口發(fā)送WM_SETFOCUS消息,此窗口可將輸入焦點(diǎn)重定位到它的子窗口上。子窗口不會(huì)自動(dòng)獲得輸入焦點(diǎn)。失去輸入焦點(diǎn)的窗口會(huì)收到WM_KILLFOCUS消息。當(dāng)子窗口擁有輸入焦點(diǎn)時(shí),父窗口就不會(huì)處理鍵盤輸入了。

          主站蜘蛛池模板: 舟山市| 济南市| 肇东市| 周口市| 岱山县| 西丰县| 石狮市| 荔浦县| 道孚县| 江口县| 承德市| 通道| 汉沽区| 怀来县| 馆陶县| 彰化市| 同仁县| 青龙| 桂平市| 县级市| 南溪县| 乌拉特中旗| 丰宁| 临武县| 桓台县| 绥中县| 西宁市| 合山市| 黔西| 芜湖市| 双峰县| 桦南县| 重庆市| 绥化市| 屯昌县| 遂宁市| 桂平市| 眉山市| 唐河县| 兴文县| 梁河县|