新建乙個就有mfc應用程式的project專案,在彈出的mfc應用程式嚮導中選擇「基於對話方塊」,取消「使用unicode庫」,單擊完成。在「資源檢視」裡面新增乙個對話方塊,預設id為idd_dialog1。
雙擊idd_dialog1對話方塊,在彈出的mfc類嚮導中,類名填寫csondialog,基類選擇cdialog,單擊完成。這樣我們就將新建的idd_dialog1關聯上乙個基於cdialog的類了。
在父視窗上新增乙個按鈕,雙擊,便可進入這個按鈕的訊息響應函式。在最上面包含csondialog的標頭檔案#include 「sondialog.h」。如果在訊息響應函式中寫入如下**:
csondialog sonwnd;
sonwnd.domodal();
執行之後按下父視窗上的按鈕,可以發現彈出了idd_dialog1,但是只能在idd_dialog1上操作,無法操作父視窗。如果想要在彈出子視窗後還可以操作父視窗的話,需要採用非模態對話方塊的模式彈出子視窗。
mfc在cdialog類中有乙個create(uint nidtemplate, cwnd *pparentwnd = 0),這個函式可以建立乙個dialog,其中引數nidtemplate為需要建立的dialog的id。同時還有乙個函式showwindow(int ncmdshow),用來顯示建立的這個dialog。在訊息響應函式中寫入如下**:
csondialog sonwnd;
sonwnd.create(idd_dialog1);
sonwnd.showwindow(sw_show);
執行之後按下父視窗上的按鈕發現視窗閃了一下,然後就消失了。這是因為物件sonwnd是乙個區域性物件,在執行完sonwnd.showwindow(sw_show)這條語句之後便退出了訊息響應函式,因此sonwnd物件也就被銷毀了。如果想要退出訊息響應函式之後視窗依然存在,則需要將sonwnd定義為乙個全域性變數。因此在projectdlg.h中新增乙個csondialog sonwnd的定義,同時由於vc++在編譯的時候預編譯標頭檔案,因此還需要在projectdlg.h中包含csondialog的標頭檔案#include 「sondialog.h」,這樣在projectdlg.cpp中,便可以把sondialog.h刪掉了。然後在按鈕的訊息響應函式中新增如下**:
sonwnd.create(idd_dialog1);
sonwnd.showwindow(sw_show);
我們發現idd_dialog1被建立出來,並且一直保留著。但是還是無法和父視窗進行資料交流。根據查詢資料我們發現在c++中有乙個指標很特別,它指向的是當前視窗,這個指標就是this指標。我們通過傳遞this指標來相互呼叫對方的資料。
在csondialog類中,我們新增乙個指向父視窗的全域性指標變數cprojectdlg *m_pfaher,同時新增乙個函式wndcreate(cprojectdlg *pparent),**如下:
void csondialog::wndcreate(cprojectdlg *pparent)
這個函式中呼叫了cdialog類中的create()和showwindow()函式來建立和顯示對話方塊,同時採用引數傳遞的辦法將父視窗的指標傳遞到子視窗中。而在父視窗projectdlg.cpp的訊息響應函式中,我們新增如下**:
sonwnd.wndcreate(this);
編譯執行之後發現有錯,因為在projectdlg.h的標頭檔案中包含了sondialog.h,而在sondialog.h中又包含了projectdlg.h,這樣程式在進行編譯的時候就會出現標頭檔案重複包含的錯誤,有兩種辦法可以解決此問題。
第一種辦法是在兩個標頭檔案中分別加入預編譯命令#ifndef #define #endif命令,在sondialog.h最上面加入
#ifndef sondialog
#define sondialog
最下面加入
#endif
在projectdlg.h最上面加入
#ifndef rpojectdlg
#define projectdlg
最下面加入
#endif
以上語句塊的意思是如果sondialog/projectdlg沒有被定義的話,那麼就定義sondialog/projectdlg,如果sondialog/projectdlg被定義的話,直接跳轉到#endif,這樣就可以很好的避免被重複定義的情況。這種方法我在以前程式設計的時候很好用,但是不知道為什麼最近幾次寫程式這種方法都失效了,於是我又想出了另外一種辦法。
第二種辦法的原理是採取避免在標頭檔案中定義具體型別的指標變數,用定義空指標的方法繞過標頭檔案重複包含的問題。由於在父視窗中,指向子視窗的物件必須是全域性變數,這樣才能保證子視窗在銷毀之前一直有顯示。因此在父視窗projectdlg.h中不得不包含sondialog.h的標頭檔案,這樣就只能在sondialog.h中想辦法了。其實仔細想來我們發現在sondialog.h中只要定義乙個空指標就可以解決問題。具體方法如下:
在sondialog.h不包含projectdlg.h標頭檔案,也不定義cprojectdlg的物件,而是定義乙個空指標lpvoid m _pfather,將wndcreate()函式的引數改為lpvoid ppaernt,然後在wndcreate()函式中新增如下**:
void csondialog::wndcreate(lpvoid pparent)
這樣,父視窗的this指標傳遞進來之後到m_pfather還是乙個指向任意物件的指標,只要在sondialog.cpp的函式中需要呼叫父視窗中的函式或者是改動父視窗的某些變數時,在cpp檔案中包含標頭檔案projectdlg.h,在函式開始時加入**:
cprojectdlg *main;
main = (cprojectdlg *)m_pfather; //強制將lpvoid型別轉換
main->
就可以通過指標main來對父視窗進行操作。這樣就可以實現兩個對話方塊中的資訊相互傳遞了。
另外在建立非模態對話方塊的時候要注意,重寫onok()和oncancel()兩個函式,要在裡面加入destorywindow()函式,onok()和oncancel()函式裡面並沒有銷毀視窗,而是使得視窗不可見,如果不銷毀視窗,在下一次再次開啟子視窗時,就會出現錯誤。
python中函式值傳遞與引用傳遞
簡單理解,值傳遞就是在乙個引數傳入到函式中後,函式中對該引數的操作不會影響函式外該引數的變數的值 而引用傳遞,則是引數傳遞進來的相當於記憶體位址,對該引數的操作會直接影響到外部指向其值的變數。python中的變數沒有型別,變數相當於乙個指標,可以指向任何型別的物件,也就是變數引用了某個物件 pyth...
MFC在不同的類窗體之間傳遞訊息
接收訊息窗體,cmainframe 1 首先在頭中定義訊息 例如 indefine wm mymessage wm user 100 wm mymessage是定義的巨集 定義訊息處理函式。訊息處理函式為訊息目標類的成員函式。首先應該在.h 檔案中宣告。這裡以主視窗類為例,主視窗類名 cmainfr...
JS中函式引數值傳遞和引用傳遞
也許大家對於函式的引數都不會太在意,簡單來說,把函式外部的值複製給函式內部的引數,就和把值從乙個變數複製到另乙個變數一樣。深入研究,你會發現其實沒那麼簡單,這個傳參是要分倆種情況 其實這是個錯誤的說法,ecmascript中所有函式的引數都是按值傳遞的 高程3 原話,之所以這裡說倆種,是因為結合引用...