免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開(kāi)通VIP
VC中視圖(view)是怎樣隨著主窗口的大小改變而改變的
在一般用MFC編寫的程序的窗口客戶區(qū)中,可能有好幾個(gè)子窗口(具有WM_CHILD風(fēng)格的窗口)。上邊是工具欄,中間是視圖窗口,下邊是狀態(tài)欄。三個(gè)窗口在框架的客戶區(qū)里和平共處,互不重疊。主框架窗口的尺寸改變了,別的子窗口都能及時(shí)調(diào)整自己的尺寸以便保持相互位置關(guān)系不變,例如狀態(tài)條窗口總能保持在主框架客戶區(qū)底部,并且其寬度總能和主框架客戶區(qū)寬度一致。工具欄窗口總能??吭谥骺蚣艿哪骋贿叢蛔?,其寬度或高度總能和主框架客戶區(qū)的寬度或高度一致,視圖窗口總能填滿主框架客戶區(qū)的剩余空間。    
   
  假如我們自己從CWnd類派生一個(gè)窗口類并生成一個(gè)窗口,在它的客戶區(qū)里要生成若干個(gè)子窗口,我們想使這些子窗口排列得規(guī)規(guī)矩矩,互不重疊,當(dāng)父窗口的尺寸變了時(shí)各個(gè)子窗口能適時(shí)調(diào)整自己的尺寸和位置,使各個(gè)子窗口之間的位置大小比例關(guān)系不變。當(dāng)移動(dòng)其中一個(gè)或幾個(gè)子窗口時(shí),別的子窗口能及時(shí)為這個(gè)移動(dòng)了的子窗口讓位。當(dāng)然我們可以利用api函數(shù)里管理窗口的函數(shù)來(lái)編寫自己的管理子窗口的方法。可是如果在父窗口的客戶區(qū)里有了工具欄,狀態(tài)條等等子窗口時(shí),你自己加進(jìn)來(lái)的子窗口還能和這些mfc提供的子窗口融洽相處嗎?你如何保證你的子窗口不會(huì)覆蓋了能夠四處??康墓ぞ邫冢慨?dāng)工具欄和狀態(tài)條消失后你的子窗口如何才能知道,以便及時(shí)調(diào)整自己的大小從而覆蓋工具欄和狀態(tài)條騰出的空間?基于文檔視圖構(gòu)架的窗口的客戶區(qū)內(nèi)還有個(gè)視圖,你自己硬加上的子窗口能不和視圖窗口爭(zhēng)地盤嗎?    
   
  所以必須了解mfc的窗口管理它的客戶區(qū)的方法。其實(shí),mfc的窗口管理它的客戶區(qū)的方法是非常簡(jiǎn)單的:父窗口調(diào)用一個(gè)函數(shù),子窗口響應(yīng)一個(gè)消息,就這么多。  
   
  CWnd::RepositionBars函數(shù)和WM_SIZEPARENT消息  
   
  先簡(jiǎn)述一下mfc的窗口為子窗口分配客戶區(qū)空間的過(guò)程:這一過(guò)程是父窗口與子窗口共同協(xié)調(diào)完成的。父窗口先提供它的客戶區(qū)內(nèi)的一塊區(qū)域,叫做起始可用區(qū)域。然后調(diào)用一個(gè)函數(shù),在這個(gè)函數(shù)里,父窗口把這片區(qū)域通過(guò)一個(gè)消息提交給它的第一個(gè)子窗口,該子窗口決定自己要占用多大一塊,然后在可用區(qū)域里把它將占據(jù)的部分劃出去,這樣可用區(qū)域就被切去了一塊。父窗口再把這塊剩下的可用區(qū)域通過(guò)同樣的消息提交給第二個(gè)子窗口,第二個(gè)子窗口再根據(jù)自己的需要切掉一塊。如此這般,每個(gè)子窗口都切去自己所需的一塊。最后剩下的可用區(qū)域就給最后的子窗口使用。可以看出,除了最后一個(gè)子窗口外,其它子窗口都得在消息響應(yīng)函數(shù)里有自己的算法來(lái)決定自己將在可用區(qū)域里占據(jù)多大一塊,最后一個(gè)子窗口由于別無(wú)選擇,所以不需要這樣的算法。    
   
  當(dāng)然,初始的可用區(qū)域是一個(gè)矩形,每次被切割后剩下的可用區(qū)域還是一個(gè)矩形,不可能是別的形狀的。    
   
  舉例說(shuō)來(lái),在一個(gè)典型單文檔程序中,父窗口就是從CFrameWnd派生的主框架窗口,最后一個(gè)子窗口就是視圖窗口,如果用了CSplitterWnd生成分隔條的話,最后一個(gè)子窗口就是擁有分隔條的那個(gè)窗口。其它子窗口就是工具欄窗口和狀態(tài)條窗口,以及可能有的別的控件窗口。    
   
  在典型多文檔界面程序中,父窗口就是主框架窗口,最后一個(gè)子窗口就是覆蓋在主窗口客戶區(qū),背景為黑灰色,擁有包含文檔的子框架窗口的那個(gè)窗口,這是個(gè)預(yù)定義了窗口類的窗口,它的窗口類名是“MDIClient”。如果用了CSplitterWnd生成分隔條的話,最后一個(gè)子窗口就是擁有分隔條的那個(gè)窗口。其它窗口就是工具欄窗口,狀態(tài)條窗口以及可能有的別的控件窗口。    
   
  這個(gè)函數(shù)和消息是:函數(shù)CWnd::RepositionBars()以及消息WM_SIZEPARENT。這個(gè)消息是mfc自定義的,不是windows自有的。    
   
  先簡(jiǎn)單說(shuō)明一下這個(gè)函數(shù)和消息。    
   
  1。函數(shù)CWnd::RepositionBars()  
   
  這個(gè)函數(shù)不是虛函數(shù),所以就無(wú)法在派生類里通過(guò)覆蓋來(lái)編制自己的版本了,只能搞懂它的功能,以便能靈活使用。    
   
  簡(jiǎn)單而言,這個(gè)函數(shù)的功能是將可用的客戶區(qū)區(qū)域信息放到消息WM_SIZEPARENT的消息參數(shù)里,然后枚舉本窗口的所有子窗口,給每個(gè)子窗口   (除掉一個(gè)特定的子窗口,相當(dāng)于上文提到的最后一個(gè)子窗口)都發(fā)送這個(gè)消息,每個(gè)響應(yīng)這個(gè)消息的子窗口都會(huì)把可用客戶區(qū)切去一塊。最后把那個(gè)特定的子窗口的尺寸和位置調(diào)整到剛好放在最后剩下的可用區(qū)域里。    
   
  2。消息WM_SIZEPARENT    
   
  每個(gè)欲參與分配客戶區(qū)的子窗口都要響應(yīng)這個(gè)消息,除非這個(gè)子窗口是那個(gè)特定的子窗口。    
   
  響應(yīng)這個(gè)消息的子窗口至少要做兩件事:1,將可用的父窗口客戶區(qū)切去自己所占據(jù)的一塊。2,根據(jù)消息參數(shù)的指示,將自己的大小和位置調(diào)整到剛好容納到自己所占據(jù)的區(qū)域里或不做調(diào)整。    
   
  下面詳細(xì)介紹一下函數(shù)CWnd::RepositionBars()和消息WM_SIZEPARENT。    
   
  1。函數(shù)CWnd::RepositionBars()   void   RepositionBars(   UINT   nIDFirst,   UINT   nIDLast,   UINT   nIDLeftOver,   UINT   nFlag   =   CWnd::reposDefault,   LPRECT   lpRectParam   =   NULL,   LPCRECT   lpRectClient   =   NULL,   BOOL   bStretch   =   TRUE   );    
   
  參數(shù)比較多,但還是比較好懂的。    
   
  (1)nIDFirst和nIDLast    
   
  參與分配父窗口客戶區(qū)的子窗口的id范圍。    
   
  每個(gè)WM_CHILD風(fēng)格的窗口都有個(gè)id,這是在窗口創(chuàng)建過(guò)程中指定的。函數(shù)CWnd::Create()的第六個(gè)參數(shù)就是這個(gè)id。api函數(shù)CreateWindow和   CreateWindowEx里的那個(gè)HMENU類型的參數(shù),當(dāng)窗口的風(fēng)格里有WM_CHILD時(shí),它不是指的菜單句柄,而是該窗口的id。    
   
  nIDFirst和nIDLast參數(shù)指明了:如果一個(gè)子窗口的id值大于等于nIDFirst并且小于等于nIDLast,在這個(gè)函數(shù)中才會(huì)給這個(gè)子窗口發(fā)送   WM_SIZEPARENT消息,這個(gè)子窗口才能參與父窗口客戶區(qū)的分配。    
   
  (2)nIDLeftOver    
   
  前面說(shuō)過(guò),有一個(gè)特定的子窗口,它不響應(yīng)WM_SIZEPARENT消息。只有當(dāng)其它的子窗口都分配完了,它才來(lái)?yè)烊「复翱诳蛻魠^(qū)里剩下的那塊。   nIDLeftOver正是這個(gè)子窗口的id。它也必須大于等于nIDFirst并且小于等于nIDLast。    
   
  (3)lpRectClient    
   
  這是一個(gè)指向RECT結(jié)構(gòu)數(shù)據(jù)的指針。這個(gè)RECT結(jié)構(gòu)里存放的正是父窗口客戶區(qū)的初始可用區(qū)域。隨著在該函數(shù)里依次給各個(gè)子窗口發(fā)送   WM_SIZEPARENT消息,每個(gè)響應(yīng)這個(gè)消息的子窗口都會(huì)切去自己所占據(jù)的部分。最后剩下的部分,就是id為nIDLeftOver的子窗口將要占據(jù)的區(qū)域了。這個(gè)參數(shù)可以為NULL,這時(shí)初始的可用區(qū)域就是整個(gè)父窗口客戶區(qū)。    
   
  (4)nFlag和lpRectParam    
   
  這兩個(gè)參數(shù)放在一起講比較好。nFlag是該函數(shù)的功能標(biāo)志,它可以有三個(gè)值:reposDefault,reposQuery   和reposExtra。    
   
  當(dāng)nFlag等于reposDefault時(shí),RepositionBars函數(shù)的功能是這樣的:依次給id介于nIDFirst和nIDLast之間并且不等于nIDLeftOver的子窗口發(fā)送WM_SIZEPARENT消息,每個(gè)響應(yīng)這個(gè)消息的子窗口從lpRectClient所指的結(jié)構(gòu)里切去自己所占據(jù)的部分,并且將自己的大小和位置調(diào)整到自己所占據(jù)的區(qū)域的大小,最后RepositionBars函數(shù)還將id為nIDLeftOver的子窗口的大小和位置調(diào)整到被其他子窗口切剩的可用區(qū)域內(nèi),使這個(gè)子窗口正好完全覆蓋最后的可用區(qū)域。這種情況下lpRectParam不用,可以為NULL。    
   
  當(dāng)nFlag等于reposQuery   時(shí),RepositionBars函數(shù)的功能是這樣的:依次給id介于nIDFirst和nIDLast之間并且不等于nIDLeftOver的子窗口發(fā)送WM_SIZEPARENT消息,每個(gè)響應(yīng)這個(gè)消息的子窗口從lpRectClient所指的結(jié)構(gòu)里切去自己所占據(jù)的部分,但是他們并不調(diào)整自己的大小和位置,最后RepositionBars函數(shù)并不調(diào)整將id為nIDLeftOver的子窗口的大小和位置,而是根據(jù)bStretch的值來(lái)做動(dòng)作:如果bStretch為TRUE,那么   RepositionBars函數(shù)把最后剩下的可用區(qū)域拷貝到lpRectParam指向的RECT結(jié)構(gòu)里;如果bStretch為FALSE,那么RepositionBars函數(shù)把所有其他子窗口占用掉的可用區(qū)域的高和寬(要所有的子窗口都緊排在一起,形成一個(gè)大的矩形,這個(gè)值才有意義)拷貝到lpRectParam指向的RECT結(jié)構(gòu)的bottom   和right成員里,其top和left成員被置零。使用這個(gè)nFlag值來(lái)調(diào)用RepositionBars的目的不是要重排子窗口,而是要看看,假如重排子窗口的話,這些子窗口將占去多大一塊,最后剩下的可用區(qū)域在什么位置等等信息。    
   
  當(dāng)nFlag等于reposExtra時(shí),該函數(shù)的功能和nFlag等于reposDefault時(shí)差不多,有點(diǎn)小小的區(qū)別。此時(shí)需要用到lpRectParam。前面說(shuō)過(guò),當(dāng)   nFlag等于reposDefault時(shí),RepositionBars函數(shù)將在最后把id為nIDLeftOver的子窗口的大小和位置調(diào)整到被其他子窗口切剩的可用區(qū)域內(nèi),使這個(gè)子窗口正好完全覆蓋最后的可用區(qū)域。而當(dāng)nFlag等于reposExtra時(shí),RepositionBars在調(diào)整id為nIDLeftOver的子窗口的大小和位置前,還要用   lpRectParam來(lái)對(duì)最后剩下的可用區(qū)域做修正。假設(shè)lpRect指向的是最后的可用區(qū)域,那么這個(gè)修正是這樣進(jìn)行的:    
   
     
                lpRect->top+=lpRectParam->top;  
                lprect->left+=lpRectParam->left;  
                lpRect->right-=lpRectParam->right;  
                lpRect->bottom-=lpRectParam->bottom;  
   
  通過(guò)這樣的修正,可以使最后剩下的可用區(qū)域不被id為nIDLeftOver的子窗口占滿,而是空出一些地方來(lái)留作他用。    
  (5)bStretch    
   
  這個(gè)參數(shù)上面已經(jīng)提到一點(diǎn)它的作用。它主要是提供給各個(gè)響應(yīng)WM_SIZEPARENT消息的子窗口用的,子窗口例如工具欄,狀態(tài)條等在決定自己將從父窗口客戶區(qū)的可用空間里劃走多少時(shí),這個(gè)參數(shù)也是個(gè)判斷的依據(jù)。詳細(xì)可以參閱工具欄和狀態(tài)條響應(yīng)WM_SIZEPARENT的函數(shù)OnSizeParent()。    
   
  2。消息WM_SIZEPARENT    
   
  這是個(gè)mfc自定義的消息。在msdn里的TN024這篇技術(shù)文章里有關(guān)于這個(gè)消息的說(shuō)明。    
   
  該消息的兩個(gè)參數(shù)中wParam不用,lParam是指向一個(gè)AFX_SIZEPARENTPARAMS結(jié)構(gòu)變量的指針,這個(gè)結(jié)構(gòu)變量是在RepositionBars函數(shù)里定義的:    
   
  AFX_SIZEPARENTPARAMS   layout;    
   
  AFX_SIZEPARENTPARAMS結(jié)構(gòu)定義如下:    
   
  struct   AFX_SIZEPARENTPARAMS  
  {  
          HDWP   hDWP;                
          RECT   rect;                
          SIZE   sizeTotal;      
          BOOL   bStretch;        
  };  
  這個(gè)結(jié)構(gòu)變量的成員是在RepositionBars函數(shù)里填寫的:它的bStretch成員就是RepositionBars的參數(shù)bStretch,它的sizeTotal成員的兩個(gè)成員cx和cy都被設(shè)置為零,它的rect成員就是從RepositionBars的參數(shù)lpRectClient里拷貝過(guò)來(lái)的,就是父窗口客戶區(qū)的初始可用區(qū)域嘛。每個(gè)響應(yīng)這個(gè)消息的子窗口都必須修改rect成員的值,以便切去自己所占據(jù)的部分。    
  成員hDWP是什么?這得知道三個(gè)api函數(shù):BebinDeferWindowPos(),DeferWindowPos()和EndDeferWindowPos()。這三個(gè)api函數(shù)是用來(lái)成批設(shè)置窗口的位置和尺寸的。BebinDeferWindowPos()先通知windows分配一個(gè)將用來(lái)存貯窗口的位置和尺寸信息的結(jié)構(gòu),它不是返回這個(gè)結(jié)構(gòu)的指針,而是返回代表這個(gè)結(jié)構(gòu)的句柄,句柄的類型是HDWP。然后每個(gè)需要重新設(shè)置位置和尺寸的窗口都要調(diào)用DeferWindowPos()函數(shù)(該函數(shù)需要那個(gè)HDWP   類型的句柄為參數(shù)),以便往那個(gè)結(jié)構(gòu)里填寫各自的窗口位置和大小信息。最后,在某個(gè)合適的時(shí)候調(diào)用EndDeferWindowPos(),windows就會(huì)根據(jù)那個(gè)結(jié)構(gòu)里的信息把有關(guān)的窗口的位置和大小一次性設(shè)置好。比起針對(duì)每個(gè)窗口分別用SetWindowPos()等函數(shù)逐個(gè)設(shè)置來(lái)說(shuō),這種方法速度快。    
   
  好了,在RepositionBars函數(shù)里正是調(diào)用了BebinDeferWindowPos(),獲得一個(gè)HDWP類型的句柄,這個(gè)句柄就被填寫到了上面那個(gè)結(jié)構(gòu)變量   layout的成員hDWP里。然后RepositionBars函數(shù)給每個(gè)符合條件的子窗口發(fā)送WM_SIZEPARENT消息。在每個(gè)響應(yīng)WM_SIZEPARENT消息的子窗口里,要調(diào)用DeferWindowPos()來(lái)設(shè)置位置和尺寸信息。當(dāng)所有的子窗口都響應(yīng)完畢WM_SIZEPARENT消息后,RepositionBars函數(shù)再調(diào)用   EndDeferWindowPos()函數(shù),這一來(lái),除了那個(gè)id為nIDLeftOver的子窗口外,所有的子窗口都一次性排好了位置了。    
   
  至于該結(jié)構(gòu)的sizeTotal成員的意義,它累計(jì)每個(gè)子窗口所占據(jù)掉的可用區(qū)域的長(zhǎng)寬尺寸和。每個(gè)子窗口在響應(yīng)WM_SIZEPARENT消息時(shí)一般都要把自己所占據(jù)的區(qū)域的高和寬分別累加到sizeTotal結(jié)構(gòu)的cy和cx成員里。這有什么意義呢?當(dāng)每個(gè)子窗口所占據(jù)的區(qū)域都是挨在一起的時(shí)候,這個(gè)   sizeTotal結(jié)構(gòu)就有意義了,主框架窗口可以使nFlag等于reposQuery,使bStretch等于FALSE來(lái)調(diào)用RepositionBars函數(shù),RepositionBars函數(shù)會(huì)把   sizeTotal結(jié)構(gòu)的兩個(gè)成員值拷貝到lpRectParam參數(shù)里返回給主框架類(前面也提到過(guò)),這樣主框架類就知道它的客戶區(qū)內(nèi)的子窗口占去了客戶區(qū)內(nèi)多大的一塊空間。如果你的主框架窗口沒(méi)有利用這個(gè)信息,那么響應(yīng)WM_SIZEPARENT消息的子窗口就可以不理睬sizeTotal成員。    
   
  ID的分配    
   
  可以看到,每個(gè)子窗口都有個(gè)id,同一個(gè)父窗口的子窗口的id不能重復(fù)。mfc的一些現(xiàn)成的控件子窗口都有預(yù)定義的id:    
   
            id名                                 id值             意義  
   
  AFX_IDW_TOOLBAR                   0xE800     //   主窗口的工具欄的id  
  AFX_IDW_STATUS_BAR             0xE801     //   狀態(tài)欄的id  
  AFX_IDW_PREVIEW_BAR           0xE802     //   PrintPreview   Dialog   Bar  
  AFX_IDW_RESIZE_BAR             0xE803     //   OLE   in-place   resize   bar  
  AFX_IDW_REBAR                       0xE804     //   COMCTL32   "rebar"   Bar  
  AFX_IDW_DIALOGBAR               0xE805     //   CDialogBar  
   
  還有象單文檔程序的視圖窗口,多文檔程序的那個(gè)MDIClient窗口,分隔條窗口,他們的id值介于下面兩個(gè)id值之間:    
  AFX_IDW_PANE_FIRST             0xE900     //  
  AFX_IDW_PANE_LAST               0xE9FF  
   
  你要給你自己的子窗口分配id的話,別和上面的重復(fù)了。一般如果用IDE的菜單view/resource   symbols項(xiàng)來(lái)加入自己的id的話,是不會(huì)重復(fù)的。有關(guān)id,還可以看看msdn里的TN020文章,那是專講id的。    
   
  實(shí)例分析    
   
  1。CFrameWnd類是如何調(diào)用RepositionBars函數(shù)的    
   
  前面介紹了RepositionBars的各個(gè)參數(shù)和意義,現(xiàn)在看看CFrameWnd類是如何調(diào)用這個(gè)函數(shù)的,從中可以學(xué)習(xí)RepositionBars函數(shù)的使用方法。    
   
  CFrameWnd類及其派生類生成的窗口的客戶區(qū)內(nèi)可以有工具欄,狀態(tài)條和視圖窗口等子窗口。當(dāng)父窗口的尺寸發(fā)生變化時(shí),這些子窗口的各自的位置和大小比例關(guān)系保持不變,這就需要父窗口一旦在它自己的尺寸發(fā)生變化時(shí)就調(diào)用RepositionBars函數(shù)。CFrameWnd類是集中在函數(shù)   RecalcLayout里調(diào)用RepositionBars函數(shù)的。該類保證了在窗口尺寸發(fā)生變化時(shí)函數(shù)RecalcLayout都被調(diào)用,從而RepositionBars函數(shù)也能被及時(shí)調(diào)用,確保了各個(gè)子窗口都能及時(shí)調(diào)整自己的位置和大小。    
   
  RecalcLayout是個(gè)虛函數(shù)。該函數(shù)的功能就是在主框架的客戶區(qū)內(nèi)提供一個(gè)初始的可用區(qū)域,并把這個(gè)區(qū)域放在一個(gè)CRect類型的變量里。該函數(shù)大致是這樣的:    
   
  void   CFrameWnd::RecalcLayout(BOOL   bNotify)  
  {  
          if   (m_bInRecalcLayout)  
                    return;//這大概是在防止該函數(shù)重入  
          m_bInRecalcLayout   =   TRUE;  
  ....  
  ....  
  ....  
  ....  
          if   (GetStyle()   &   FWS_SNAPTOBARS)  
          {  
                  CRect   rect(0,   0,   32767,   32767);  
                  RepositionBars(0,   0xffff,   AFX_IDW_PANE_FIRST,   reposQuery,  
                              &rect,   &rect,   FALSE);  
                  RepositionBars(0,   0xffff,   AFX_IDW_PANE_FIRST,   reposExtra,  
                              &m_rectBorder,   &rect,   TRUE);  
                  CalcWindowRect(&rect);  
                  SetWindowPos(NULL,   0,   0,   rect.Width(),   rect.Height(),  
                          SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER);  
          }  
          else  
                  RepositionBars(0,   0xffff,   AFX_IDW_PANE_FIRST,   reposExtra,   &m_rectBorder);  
          m_bInRecalcLayout   =   FALSE;  
  }         可以看出,mfc認(rèn)為這個(gè)函數(shù)是不能重入的。在編制自己的RecalcLayout()函數(shù)時(shí)也得用同樣的方法來(lái)防止重入。  
          后面的if語(yǔ)句檢查框架窗口是否具有風(fēng)格FWS_SNAPTOBARS,這個(gè)風(fēng)格用在什么時(shí)候呢?我是這樣認(rèn)為的:通常都是在主框架窗口的尺寸改變  
  時(shí),子窗口在響應(yīng)WM_SIZEPARENT消息時(shí)調(diào)整自己的尺寸以便跟上框架窗口的尺寸變化。有這樣的情況:父窗口的客戶區(qū)內(nèi)的子窗口的數(shù)目是動(dòng)態(tài)變  
  化的,而且這些子窗口互相不能重疊,他們的尺寸由于某種原因不好改變。那么當(dāng)子窗口的數(shù)目發(fā)生增減時(shí),如不調(diào)整父窗口自己的尺寸,就會(huì)導(dǎo)  
  致客戶區(qū)留下空白或新增加的子窗口沒(méi)有多余空間安排。FWS_SNAPTOBARS風(fēng)格就是用在這種情況下,使父窗口能調(diào)整自己的大小以便容納子窗口。  
  看這個(gè)分支里的語(yǔ)句,似乎是這樣的。  
          一般都不會(huì)有FWS_SNAPTOBARS風(fēng)格的,所以一般是執(zhí)行else分支。在這個(gè)分支里簡(jiǎn)單地調(diào)用RepositionBars去重排所有的子窗口,它的參數(shù)  
  lpRectClient   使用默認(rèn)的NULL值,意思就是初始可用區(qū)域是父窗口的整個(gè)客戶區(qū)。  
          可以在自己的派生類里編寫自己的RecalcLayout函數(shù),以便用自己的方法調(diào)用RepositionBars函數(shù)。要注意的是在CFrameWnd類的窗口剛被創(chuàng)建  
  時(shí)RecalcLayout函數(shù)也被調(diào)用,此時(shí)可能某些用戶自己加的子窗口還未被創(chuàng)建出來(lái),所以在這個(gè)函數(shù)內(nèi)如果要引用某個(gè)用戶自己加的子窗口的句柄  
  的話必須先用::IsWindow()函數(shù)判斷一下該窗口句柄是否可用。否則的話就會(huì)出現(xiàn)非法操作了。  
   
   
  實(shí)戰(zhàn)演練  
  由于精力有限,只提供一個(gè)實(shí)戰(zhàn)例子:將視圖,工具欄和狀態(tài)欄趕到右邊  
  我們要生成這樣的界面:視圖窗口,工具欄和狀態(tài)條統(tǒng)統(tǒng)在右邊,左邊是個(gè)自己加的窗口。  
  第一步:?jiǎn)?dòng)AppWizard生成一個(gè)單文檔程序,全部使用默認(rèn)設(shè)置。  
  第二步:在CMainFrame類里增加一個(gè)成員   CWnd   m_mywnd。  
  第三步:在CMainFrame::OnCreate()函數(shù)里增加這幾行:  
          m_mywnd.CreateEx  
          (  
                  WS_EX_CLIENTEDGE,  
                  AfxRegisterWndClass  
                (  
                          CS_HREDRAW|CS_VREDRAW,  
                          ::LoadCursor(NULL,IDC_ARROW),  
                          ::CreateSolidBrush(RGB(190,190,190))  
                  ),  
                "",  
                WS_VISIBLE|WS_CHILD,  
                CRect(0,0,0,0),  
                this,  
                IDC_MYPANE   //用IDE的菜單view/resource   symbols項(xiàng)加入的id。  
          );  
   
  第四步:?jiǎn)?dòng)ClassView,在CMainFrame里加上虛函數(shù)RecalcLayout(),函數(shù)體這樣寫:  
  void   CMainFrame::RecalcLayout(BOOL   bNotify)  
  {  
          if   (m_bInRecalcLayout)  
                  return;  
          m_bInRecalcLayout   =   TRUE;  
   
          //rect1是新加的窗口將占據(jù)的區(qū)域  
          //rect2就是提供給工具欄,狀態(tài)條和視圖窗口的初始可用區(qū)域。  
          CRect   rect1,rect2;  
          GetClientRect(&rect1);  
          rect1.right=rect1.right/3;  
          GetClientRect(&rect2);  
          rect2.left=rect2.right/3;  
   
          if(::IsWindow(m_mywnd.m_hWnd))   //這句是不能少的  
                  m_mywnd.MoveWindow(&rect1);  
          RepositionBars(0,   0xffff,   AFX_IDW_PANE_FIRST,   reposExtra,   CRect(0,0,0,0),&rect2);  
          m_bInRecalcLayout   =   FALSE;  
  }  
   
  第五步:用IDE的菜單view/resource   symbols項(xiàng)加入一個(gè)id:IDC_MYPANE。  
  第六步:編譯并運(yùn)行程序。  
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
理解MFC控制條窗口布局原理之一
VC++更改對(duì)話框背景色和字體顏色
VC添加自定義消息
單文檔多視圖
MFC中OnDraw與OnPaint的區(qū)別
OnDraw()和OnPaint()
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服