新增大小可改變的dialogbar,建立及其銷毀

2021-05-23 02:21:34 字數 1991 閱讀 6125

我在vs2008下做的。

步驟如下:

1)新增乙個idd_dialogbar模板型別的對話方塊,使用class wizard產生類時,選擇基類為cdialog,因為沒有cdialogbar

2)把新建的類中的cdialog都改為cdialogbar,特別注意的是:該類建構函式的成員初值列的初始值為

3)給類新增三個成員變數

4)給類過載成員函式:兩個create和cbrs_size_dynamic 的響應函式calcdynamiclayout()。

之所以有兩個create函式,是因為該類的基類就有兩個版本的create函式。

這裡需要說明的是:關鍵就是這個calcdynamiclayout()函式,因為雖然mfc提供了cbrs_size_dynamic樣式,但是預設情況下並沒有呼叫相關的大小響應函式,所以要過載該函式使之生效,而也正是為了配合該過載函式,才新增了以上三個成員變數。

當然,相應的要在該類定義中新增這三個函式的宣告。

這樣,就可以讓該dialog在浮動的時候改變大小了,但是不能同時改變寬和高,所以你無法看到一般的斜著的箭頭。

可以看到,上述的dialog bar的建立是把該類物件作為cmainframe的成員變數,這樣dialogbar的生存期就等同於mainframe。這和非模態對話方塊非常類似,msdn上面也說dialogbar和modeless dialog類似。因為對話方塊有其相關的資源,不能隨便釋放,所以這裡的dialog bar物件不能是乙個區域性變數,其解決方法就是:

1)將之放入乙個生存期較長的類中或者(上述所用的方法)

2)為之申請乙個堆記憶體

後者在非模態對話方塊中似乎用的更常見:

而在後者情況下,因為申請了堆記憶體,所以當不再使用該類物件(無論是modeless dialog還是用create建立的dialog bar)都需要釋放其記憶體。而釋放的最好方式莫過於讓該類自身銷毀之。這就提示我們過載postncdestroy()函式達到該目的。因為postncdestroy()是該類呼叫的最後乙個函式。銷毀乙個視窗(該dialog自然也是繼承自cwnd的)的一般過程就是wm_close訊息呼叫destroywindow(),然後發出wm_ncdestory訊息呼叫onncdestroy()函式,在該函式中呼叫postncdestroy()虛函式。所以釋放記憶體的最好時機就是在該視窗按照規矩銷毀了一切後,最後把這些申請的資源從記憶體中釋放掉。從這個方面講,用delete myclassobj的方式直接釋放資源的方式是不好的,因為沒有正常的去銷毀對話方塊(銷毀對話方塊和釋放資源是不同的),這種方式具體的壞處我還沒有細究,我試了一下似乎還沒發現異常,應該是還沒觸發到相關異常。無論如何,還是建議過載postncdestroy()函式,在其最後delete this。

還需要說明的是,在上述兩種方法建立dialogbar或modeless dialog中,在不需要手動銷毀dialog情況下,直接將之放入別的類中即可(第一種方式),這樣就免得自己再去到堆裡面申請記憶體然後過載postncdestroy()函式什麼的,讓他和程式一起結束得了。但是如果在程式執行過程中需要手動銷毀之,比如對於dialogbar,我想在原來的dialog bar的地方將之銷毀再新建乙個dialog bar,那麼第一種方式就有點不好搞了,因為不方便確定怎麼銷毀該dialog物件,直接呼叫其析構函式?那麼下次產生乙個新的dialog怎麼產生呢?產生的就將是乙個區域性物件變數了,要麼就只能模仿第二種方式申請堆記憶體了。所以在這種情況下,還是用第二種方法合適些:只需要在要銷毀的時候呼叫該dialog的destroywindow()即可,因為正如前所述,它會一步一步呼叫postncdestroy()函式,而你,難道還沒有在其最後新增上delete this;嗎?

最後,需要注意的是:銷毀掉該對話方塊後,還是有乙個影子留在視窗裡面,那是因為沒有重繪新的客戶區的緣故。而直接使之響應wm_paint時無效的,因為它重繪的客戶區似乎還是以前的大小。所以我用了乙個折中的欺騙使用者的手法:使得視窗寬度增減1個畫素。需要指明的是,我使用movewindow()使之重繪該視窗似乎也無效,具體的參見以下**及其注釋:

參考文獻:http://kbalertz.com/143255/resizable-dialog.aspx

棋盤大小可改變的三子棋

game.h define crt secure no warnings 1 include include include include ifndef game h define game h define r 3 行 define c 3 列 define ex 0 增加量 void is b...

改變對話方塊大小和動態新增控制項

define groupbox startid 8000 code crect currentrect getwindowrect trect 得到當前對話方塊的大小 currentrect.bottom groupbox rect.height 20 movewindow trect,true 改...

改變視窗大小,恢復以前的大小

方法一。在onsize訊息事件中處理 最小化 size minimized,最大化 size maximized,還原 size restored,例如 void cmaindlg onsize uint ntype,int cx,int cy if ntype size restored 方法二 ...