第一篇:總結幾種用于DLL資源模塊切換的方法
方法一):
AFX_MANAGE_STATE(AfxGetStaticModuleState());//模塊切換方法一
CMyDialog dlg;
dlg.DoModal();
方法二):
HINSTANCE Save_hInstance=AfxGetResourceHandle();//模塊切換方法二
AfxSetResourceHandle(theApp.m_hInstance);
CMyDialog dlg;
dlg.DoModal();AfxSetResourceHandle(Save_hInstance);//方法二的模塊狀態還原
方法三):
HMODULE hDLL=GetModuleHandle(“CMyDialog.dll”);HINSTANCE hEXE=AfxGetResourceHandle();//或者用:GetModuleHandle(NULL)獲取EXE模塊句柄。
AfxSetResourceHandle((HINSTANCE)hDLL);//設定資源模塊句柄,指定為DLL模塊。
CMyDialog dlg;
dlg.DoModal();
AfxSetResourceHandle(hEXE);//還原到應用程序(EXE)模塊。
其它函數:
<<深入淺出MFC>>P283:
HINSTANCE hInst=AfxFindResourceHandle(lpszMenuName,RT_MENU);//lpszMenuName:為一個指定的菜單名。
HMENU hMenu=::LoadMenu(hInst,lpszMenuName);
《VC開發 典型模塊大全》P670
HBITMAP m_hBitmap=LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURCE(資源ID號));
《模塊大全》P661
HMODULE hMod=LoadLibrary(“SkinDll.dll”)
第二篇:MFC規則DLL總結
MFC規則DLL總結
1、創建MFC規則DLL工程,生成XX.h, XX.cpp, XX.def文件,插入資源(對話框),生成類。
2、在XX.cpp 中添加ShowDlg函數,在該函數中定義對話框,顯示對話框,對話框所需要的參數由ShowDlg的形參傳遞。
3、在XX.def中添加:
EXPORTS
;此處可以是顯式導出
ShowDlg @14、編譯生成XX.dll文件
5、新建測試工程,在需要調用該DLL處,添加類如下代碼:
CString strName=_T(“王朋”);
double dScore=89;
HINSTANCE hdll;
typedef void(*dllfun)(CString,double);
dllfun thefunc;
hdll=LoadLibrary(_T(“RegularMFCDLL.dll”));
if(hdll!=NULL)
{
thefunc=(dllfun)GetProcAddress(hdll,“ShowScore”);
}
else
{
AfxMessageBox(_T(“加載DLL失敗!”));return;} thefunc(strName,dScore);FreeLibrary(hdll);
6、靜態調用
頭文件中添加如下代碼:
#pragma comment(lib,“RegularMFCDLL.lib”)
extern void ShowScore(CString,double);
在源文件中需要調用該DLL的函數處添加:
CString strName=_T(“王a?朋¨?”);
double dScore=90;
ShowScore(strName,dScore);
7、可見,窗口等MFC對象是被定義在一個函數中,再導出這個函數來顯示這些資源對象的。
第三篇:matlab生成dll方法的心得體會
將MATLAB函數編譯成dll 供VC調用的方法
1簡介
1.1 MATLAB簡介
MATLAB名字是由MATrix和 LABoratory 兩詞的前三個字母組合而成。是美國新墨西哥大學計算機科學系主任的Cleve Moler教授出于減輕學生編程負擔的動機,為學生設計了一組調用LINPACK和EISPACK庫程序的“通俗易用”的接口,此即用FORTRAN編寫的萌芽狀態的MATLAB。
經幾年的校際流傳,在Little的推動下,由Little、Moler、Steve Bangert合作,于1984年成立了MathWorks公司,并把MATLAB正式推向市場。
目前,MATLAB己經成為應用最廣泛的科學工程計算軟件,它廣泛的應用于自動控制、數學運算、信號分析、圖象處理、財務分析等各行各業。用MATLAB編寫的數學運算及圖像處理等程序十分簡單,在MATLAB里有大量的MATLAB庫函數,包括初等數學函數、線形代數函數、矩陣操作函數、數值計算函數、特殊數學函數、插值函數等等,還可以利用MATLAB的編譯工具將m文件方便的轉化為CC++語言、可執行程序(exe)、動態連接庫文件(dll)、COM組件等等,并可直接供CC++語言調用。
為什么要用VC與MATLAB接口?
既然MATLAB擁有強大的數值計算功能,利用VC與MATLAB接口可以充分發揮它的數值計算功能,并且可以不依賴MATLAB軟件運行,在VC下做出漂亮的界面,把復雜的數據處理交給MATLAB去做。
1.2 MATLAB函數編譯為dll與VC之間的通訊方式
1、使用自帶的MATLAB Compiler
2、使用MATcom工具
3、在MATLAB下做com組件,在VC中調用com組件(出現了點問題,目前還沒找到解決方法,這種方法在m文件較大、用matcom、調用math library或使用mcc方式無法實現的時候,推薦使用)2使用Matcom工具
2.1 MATcom簡介
MATcom是MATHworks公司推出的第一個由MATLAB到C++的編譯開發軟件平臺,其最新版本為4.5,集成調試編譯環境為MIDEVA。
這個軟件可厲害了,他生成的exe可執行文件可以在沒有安裝MATLAB的地方運行,只是需要幾個 dll文件而已。如果用MATLAB的Deployment Tool來生成的exe可執行文件,在沒有安裝MATLAB的機子上運行時需要安裝MCR,而MCR現在有200M 多,所以很不方便。
通過MATcom連接MATLAB m文件 有以下三種方法:
(1)經過簡單的設置,由MIDEVA將m源文件轉換為C/C++,然后添加到VC工程中。
(2)由MIDEVA直接生成EXE文件,然后在VC中通過Shell調用。這種方法簡單方便,但運行時出現一個控制臺窗口,而且由于VC和MATLAB之間不能交互,通用性差,僅適用于VC調用MATLAB實現圖形顯示的場合。
(3)通過Visual MATcom工具條,使用Add-in,這種方法提供了MATLAB和VC直接集成的途徑,且可快速集成m文件到VC工程中創建獨立的C/C++應用程序、C MEX DLL,在調試過程中可以查看矩陣變量的值,可直接修改m源文件而不是修改生成的C/C++文件。
2.2 MATcom的安裝
a)安裝之前,首先在matlab的安裝目錄下建立文件夾:MATLAB7.0bintoolboxmatlabgeneral。matcom4.5在安裝時需要你輸入口令,Matcom4.5的口令為FREE-4.5-1193046-80295111。
b)之后啟動MATLAB,運行以下命令: cd c:matcom45 % MATcom的安裝路徑 diary mpath matlabpath diary off c)復
制%MATcom45%binusertype.dat文件到%VC%CommonMSDev98bin目錄。
d)運行Visual C++,并從菜單中選擇Tools->Customize->Add-ins and Macro Files,選擇Browse,改變文件類型為
Add-in(.dll),選擇%MATcom45%binmvcide.dll文件,確定。
e)在Visual C++的開發環境中可以看到一個Visual MATcom工具條,安裝成功。
2.3 Matcom的工作原理
Matcom編譯.m文件是先將.m文件按照與Matcom的Cpp庫的對應關系,翻譯為CPP源代碼,然后用對應版本的C編譯器將該CPP文件編譯為exe或dll文件,所以,在第一次運行時讓指定C Complier的路徑是必需的,否則將無法編譯。指定好的C Complier的信息寫在Matcom/bin/matcom.ini文件中。但也有不足之處:比如,對struct等類的支持有缺陷,部分繪圖語句無法實現或得不到準確圖象,尤其是三維圖象。
2.4使用Matcom將.m文件翻譯為C++文件
a)在MIDEVA下新建一個.m文件
function Test1()x=-10:0.1:10;y=sin(x);plot(x,y);
在matcom安裝路徑Debug文件夾下將會產生以下文件:
從這里可以看出,MIDEVA己經將.m文件轉化成c++代碼,放在Test1.cpp中。
b)在VC中用MFC Wizard(exe)創建一個基于對話框名為Example的工程。在面板上添加一個ID為IDC_BUTTON1按扭。
c)將C:matcom45Debug目錄下的Test1.cpp文件的內容拷貝到
void CExamleDlg::OnButton1()下;
d)將C:matcom45lib下的matlib.h 和v4501v文件和C:matcom45debug下的Test1.h文件拷貝到工程Example目錄下,然后在VC中將庫文件和頭文件加入到工程中:工程->添加工程->Files,選擇剛剛拷貝到Example目錄下的matlib.h、v4501v和Test1.h文件。
e)在ExampleDlg.cpp中加入如下代碼: #include “matlib.h” #include “Test1.h” f)
2.5使用Matcom工具編譯為dll文件供VC調用
在MIDEVA中新建一個.m文件,然后將其編譯為.dll文件,新建工程,File->New Project…,設置組件屬性,在“Component name”項中填寫組件名稱“component”,這時候會自動生成類“component”,在“Class name”項中填寫類名稱“huatu”,為了便于區分,選中“Classes”中的“component”,點擊“remove”按鈕,將類component移除,再點擊“Add>>”添加新類huatu,結果如圖5。點擊“OK”,接下來出現一個對話框,選擇“Yes”.添加文件:選中左邊工作區的“huatu”,點擊Project->Add File?,選擇已經編輯好的函數文件huatu.m,如圖所示。需要注意的是m文件必須是m函數,否則會報錯,如果是m腳本文件的話,只需要改為無輸入輸出參數的m函數即可。
生成 com組件:點擊Build->COM Object?,在這里出現了點問題,目前還不知道解決辦法。使用MATLAB 自帶的Matlab Compiler MATLAB Compiler 是MATLAB自帶的一個編譯器,它能將m文件轉化成 C、C++或p等各種類型的源代碼,并根據需要生成可執行文件、lib文件(庫文件)、dll文件或S函數文件等。Matlab所使用的編譯器包括了MATLAB 的CC++數學庫函數以及圖形庫。
必須保證編譯器的正確配置,因為編譯器使用了CC++庫函數,所以在使用前需要使用 mex-setup 和 mbuild-setup兩個命令對編譯器進行配置。步驟如下:
1.設置Matlab的編譯器,使用外部的VC或者gcc等編譯器。2.編譯m文件成dll 3.設置VC等的繼承環境,設置C需要用到的靜態庫和動態庫 4.編寫C調用dll 3.1設置Matlab編譯器
首先要安裝Matlab 編譯器,一般來說,在安裝了Matlab后編譯器就己經安裝了,所在就只需要對Matlab編譯器進行設置。3.1.1 編譯環境設置
首先設置系統的環境變量,點擊“我的電腦”屬性-?系統特性--?高級-?環境變量-?添加系統變量Matlab值為Matlab的安裝路徑:G:matlab7.0binwin32,重啟電腦即可。
3.1.2 Matlab7.0 編譯器設置
(a)為編譯后產生的MEX文件進行預配置
運行 Matlab,在 Matlab 的命令窗口(Command Window)鍵入“ mex-setup ”命令后,按回車鍵,安裝 Matlab 編譯器;
(b)為產生獨立外部應用程序進行預配置
對Matlab編譯器mbuild應用程序進行設置,運行 Matlab,在 Matlab 的命令窗口(Command Window)鍵入“ mbuild-setup ”命令后,按回車鍵,安裝 Matlab 編譯器;
編寫 Matlab文件 huatu_test.m,一個很簡單的程序,function [X1,Y1]=huatu_test(x1,x2)x=x1:0.1:x2;y=sin(x);X1=rand(1);Y1=rand(1);plot(x,y,X1,Y1,'*');end
3.2 將Matlab函數轉成dll函數
在 Matlab的 Command Window /下輸入命令: 命令 1 : mcc-W lib:dlltest-T link:lib huatu_test.m 或
命令 2 : mcc-W cpplib: dlltest-T link:lib huatu_test.m 其中,mcc是matlab提供的編譯命令(可以理解為gcc),對于這一點,matlab的幫助說明如下:
-W lib:string link:lib 其中-W是控制編譯之后的封裝格式,cpplib,是指編譯成C++的lib,cpplib冒號后面是指編譯的庫的名字,-T表示目標,link:lib表示要連接到一個庫文件的目標,目標的名字是后面的你寫的m函數的名字。生成的文件將會保存在當前目錄下,默認的當前目錄為:MATLAB根目錄work,找到dlltest.h、dlltest.lib和dlltest.dll文件,這三個文件是我們需要的。
3.3 M函數文件編譯成DLL文件問題解決
1、Warning: No matching builtin function available for C:MATLAB6.5toolboxsimulinksimulinkset_param.bi 解決方法:
1)將 MATLAB6.5toolboxcompilerdeploymatlabrc.m 中的 81行 set_param(0,'PaperType',defaultpaper);82行 set_param(0,'PaperUnits',defaultunits);注釋掉,或者干脆刪掉。
2)在 Matlab6.5 的命令窗口運行 rehash toolboxcache 3)重新編譯文件后即可運行。
2、mbuild –setup的錯誤
Error: Could not find the compiler “cl”on the DOS path,use mbuild to configure your environment properly.由于VC安裝有誤而導致此錯誤,在安裝時必須選擇默認路徑,否則matlab檢測不到VC編譯器的物理位置 3.4 dll 文件載入
在VC中新建一個名為ceshi基于對話框的工程,在工程中添加一個名為“測試”的button按鈕。將dlltest.h、dlltest.lib和dlltest.dll文件拷貝到當前工程目錄下,并通過Project->Add To Project->Files 選擇拷貝到當前目錄下的三個文件,將文件引入工程。
在ceshiDlg.cpp文件中添加頭文件dlltest.h #include “dlltest.h” 打開dlltest.h文件,里面有有關函數的定義,找到其中三個函數:
extern mxArray * mlfHuatu_test(void);extern void dlltestInitialize(void);extern void dlltestTerminate(void);
從函數意思不難知道它們的作用,dlltestInitialize用來初始化dll庫,dlltestTerminate用來結束調用dll, mlfHuatu_test為主程序執行函數。將三個函數拷貝到button響應代碼中,進行修改:
void CCeshiDlg::OnButton1(){ dlltestInitialize();mlfHuatu_test();dlltestTerminate();} 在MATLAB下做com組件,在VC中調用com組件
COM(Component Object Model)組件對象模型,在Matcom里做 COM組件,步驟如下:
1、在matlab command window 輸入如下命令:
>> comtool 出現com編輯界面,兩種方法比較
其實兩種方法大致思路都一樣,但是各自都有局限:
用Matlab 自帶的Compiler 將.m文件轉換成c++代碼功能有很多限制:
1、不能轉換腳本m文件,只能轉換m函數;
2、不能使用matlab對象;
3、不能用input或者eval操作matlab空間變量;
4、不能動態地命名變量,然后用load或者save命令來操作;
5、不能處理具有嵌套調用其他m文件的m文件;
6、不能使用MATLAB內聯函數;
另外用Matlab自帶的編譯器有版本限制,MATLAB6.5的編譯器為3.0版本,MATLAB7.0的編譯器為4.0版本,4.0版本的編譯器對原編譯器進行了很多改進,3.0很多方法都不再使用,如果在7.0版本上使用會出現錯誤。
問題:在VC6.0下怎樣調用Matlab7.0下編譯生成的dll文件? 問題:在Matcom里生成了dll文件,在VC中該怎樣調用它? 問題:在Matlab7.0下生不成dll組件?
第四篇:任務欄里的中英文切換找不到的方法
輸入法圖標不見了?
使用電腦中,常常有意想不到的事情發生,比如某天你正想寫點什么,突然發現,哎,我的輸入法圖標哪兒去了?怎么辦?
如果你用的還是Windows 98、Windows Me的系統,有時輸入法圖標不見了,一般可以在輸入法設置中找回來。依次單擊“開始”→“設置”→“控制面板”,打開控制面板,在控制面板中雙擊“輸入法”圖標,在彈出的對話框下部,有一個“啟動任務欄上的指示器”的選項,看看它前面的選擇框內有沒有一個對勾,沒有就選上,然后用鼠標單擊下方的“確定”按鈕,輸入法圖標就會失而復得了。
如果你用的是Windows XP中,輸入法圖標也會莫名其妙地丟失,但在控制面板中卻沒有“輸入法”,這時可以按以下方法嘗試:
方法1:在任務欄單擊鼠標右鍵,彈出快捷菜單,把鼠標移動到“工具欄”上,會彈出子菜單,看看其中的“語言欄”有沒有被選中,如果沒有選中,單擊選中“語言欄”,一般會顯示輸入法圖標。
方法2:依次單擊“開始→設置→控制面板”,打開控制面板,在控制面板中單擊“日期、時間、語言和區域設置”,單擊“語言和區域設置”,彈出“語言和區域設置”對話框,單擊“語言”標簽,在“文字服務和輸入語言”下單擊“詳細信息”按鈕,彈出“文字服務和輸入語言”對話框,單擊“高級”標簽,在“系統配置”下,把“關閉高級文字服務”前面的對號取消(看到下面的注釋了沒有,選中“會關閉語言欄”),單擊“確定”按鈕,輸入法圖標就回來了。
方法3:點“開始→運行”,鍵入“msconfig”,單擊“確定”或回車,運行“系統配置實用程序”,在“啟動”里把“Ctfmon.exe”選中,單擊“確定”,然后注銷或重新啟動應該就可以了。這是因為Ctfmon.exe控制Alternative User Input Text Processor(TIP)和Microsoft Office語言條,提供語音識別、手寫識別、鍵盤、翻譯和其它用戶輸入技術的支持。這個程序沒有啟動也會造成輸入法圖標不顯示。
最后提示一下,沒有輸入法圖標,用快捷鍵一樣可以操作輸入法。Ctrl+Space(空格鍵)是在中、英文輸入法之間切換;按Ctrl+Shift組合鍵可以依次顯示系統安裝的輸入法。
第五篇:MFC視圖切換全總結
MFC視圖切換全總結
交流的朋友請加我QQ:451072182 我的百度空間:http://hi.baidu.com/%BB%B6stephen/home 單純視圖之間的切換
單文檔多視圖切換是我在學習MFC中遇到的一個老大難問題,在今天總算是一一破解了。我覺得視圖切換分為三個等級,第一是在未切分窗格的情況下切換視圖類;第二是在分割窗格的一個窗格內實行視圖切換;第三是在分割窗格和未分割之間的切換和視圖切換。
在MFC創建SDI的伊始,MFC默認的視圖類是CView,如果CView滿足你的需求,可以直接單擊finish,如果你不想讓CView成為你的默認視圖類,你可以在下圖這個地方修改。
如果你忘記了修改默認的視圖類這也沒關系,我們可以在代碼中改變: 在App類里面有個函數叫InitInstance(),在這里面有一段代碼
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(IDR_MAINFRAME,RUNTIME_CLASS(Cprogram8Doc),RUNTIME_CLASS(CMainFrame),RUNTIME_CLASS(CView1));
//這里更改你的默認視圖類,注意不要忘記包含頭文件哦
if(!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);
說完了默認視圖類的更改,我們現在進入主題。
1、首先創建你需要切換的視圖類,AddClass進入或者創建一個控件然后AddClass創建控件關聯類,后者適用于Form之類的控件。
2、控制之處,比如菜單項單擊、單擊鼠標什么的,我是使用菜單項來切換窗口的
void CMainFrame::OnView1(){
// TODO: Add your command handler code here
SwitchToForm(IDD_FORMVIEW1);}
void CMainFrame::OnView2(){
// TODO: Add your command handler code here
SwitchToForm(IDD_FORMVIEW2);}
3、SwitchToForm這個函數主要用于視圖切換 在這個函數中主要做以下幾個動作:
1、獲得當前視圖類指針和需要轉換的視圖類指針,如果是第一次使用需要New一個,并且與文檔類關聯;
2、改變活動視圖;
3、顯示新視圖和隱藏舊視圖;
4、設置控件ID;
5、調整框架視圖。
void CMainFrame::SwitchToForm(int nForm){
CView *pOldActiveView=GetActiveView();
//1
CView *pNewActiveView=(CView*)GetDlgItem(nForm);
if(NULL==pNewActiveView)
{
switch(nForm)
{
case IDD_FORMVIEW1:
pNewActiveView=(CView*)new CView1;
break;
case IDD_FORMVIEW2:
pNewActiveView=(CView*)new CView2;
break;
case IDD_FORMVIEW3:
pNewActiveView=(CView*)new CView3;
break;
case IDD_FORMVIEW4:
pNewActiveView=(CView*)new CView4;
break;
default:
break;
}
CCreateContext context;
context.m_pCurrentDoc=pOldActiveView->GetDocument();
pNewActiveView->Create(NULL,NULL,WS_CHILD | WS_BORDER,CFrameWnd::rectDefault,this,nForm,&context);
pNewActiveView->UpdateData();
}
SetActiveView(pNewActiveView);
//2
pNewActiveView->ShowWindow(SW_SHOW);
//
3pOldActiveView->ShowWindow(SW_HIDE);
if(pOldActiveView->GetRuntimeClass()==RUNTIME_CLASS(CView1))
//4
pOldActiveView->SetDlgCtrlID(IDD_FORMVIEW1);
else if(pOldActiveView->GetRuntimeClass()==RUNTIME_CLASS(CView2))
pOldActiveView->SetDlgCtrlID(IDD_FORMVIEW2);
else if(pOldActiveView->GetRuntimeClass()==RUNTIME_CLASS(CView3))
pOldActiveView->SetDlgCtrlID(IDD_FORMVIEW3);
else if(pOldActiveView->GetRuntimeClass()==RUNTIME_CLASS(CView4))
pOldActiveView->SetDlgCtrlID(IDD_FORMVIEW4);
pNewActiveView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
RecalcLayout();//5 }
在看網上其他人的帖子的時候發現在RecalcLayout();前面還要加一句delete pOldActiveView;我自己覺得這樣有些浪費資源,視圖類創建完成了隱藏起來,用的時候重新顯示。這樣的方法應該比每次使用都要創建好一些。小弟不才,有討論的朋友可以聯系我。帶有分割窗格的視圖切換
切換視圖第二層就是帶有分割窗格的視圖切換
分割窗格的視圖切換,我覺得難點是不容易在有限區域進行視圖切換。
1、首先分割窗格,這里我不多解釋,詳情看下面鏈接;
2、再給每個視圖一個唯一的ID號;
m_splitter.CreateStatic(this,1,2);
m_splitter.CreateView(0,0,RUNTIME_CLASS(CTree1),CSize(100,100),pContext);
m_splitter.CreateView(0,1,RUNTIME_CLASS(CForm1),CSize(100,100),pContext);
CWnd *pWnd=m_splitter.GetPane(0,1);
m_pViews[0]=(CView*)m_splitter.GetPane(0,1);
pWnd->SetDlgCtrlID(IDD_FORM1);
pWnd->ShowWindow(SW_HIDE);
m_splitter.CreateView(0,1,RUNTIME_CLASS(CForm2),CSize(100,100),pContext);
pWnd=m_splitter.GetPane(0,1);
m_pViews[1]=(CView*)m_splitter.GetPane(0,1);
pWnd->SetDlgCtrlID(m_splitter.IdFromRowCol(0,1));
pWnd->ShowWindow(SW_SHOW);
RedrawWindow();
return true;
注:我這里CreateView一個新視圖,就覆蓋掉前一個視圖,最終顯示的是最后一個視圖,前面的視圖只是隱藏起來,等到使用的時候顯示出來就好了。返回值要覆蓋返回到基類的語句
return CFrameWndEx::OnCreateClient(lpcs, pContext);將這句話注解,然后return true;
3、在哪里激活切換功能自己設計,我使用的是菜單;
4、響應主要包括下面幾個步驟:
1、首先獲得窗格中的當前視圖;
2、使用IsKindOf判斷這個類是否是將要切換到的類;
3、獲得框架長寬和窗格長寬;
CView *pView=(CView*)m_splitter.GetPane(0,1);
//1
m_bTest=pView->IsKindOf(RUNTIME_CLASS(CForm2));
//
2CRect rcFrame,rcClient;
//3
m_splitter.GetClientRect(&rcClient);
GetClientRect(&rcFrame);
上面的全部是準備工作,下面才是真正的切換;
4、刪除原有視圖
5、創建當前視圖
6、調整框架
if(m_bTest)
{
m_splitter.DeleteView(0,1);
m_splitter.CreateView(0,1,RUNTIME_CLASS(CForm1),CSize(rcClient.Width(),rcFrame.Height()),NULL);
m_splitter.RecalcLayout();
}
else
{
m_splitter.DeleteView(0,1);
m_splitter.CreateView(0,1,RUNTIME_CLASS(CForm2),CSize(rcClient.Width(),rcFrame.Height()),NULL);
m_splitter.RecalcLayout();
}
仔細一看,貌似這個還要比單純視圖切換還要簡單一些,這也沒辦法,CSplitterWnd提供了這么一個便捷的方法。
帶分割視圖與未分割視圖之間的切換
這個是三部曲中我認為最難的,并不是說程序有多么難,只是想到這個切分方式真的不容易,今天就把這三部曲的最后一曲分享給大家,也為互聯網做一點貢獻。
首先說一下程序的思想,為分割窗口層專門獨立創建一個基于CFrameWnd的類,然后在這里面寫分割視圖的代碼,再與其他未分割的視圖類進行切換。
下面我們來看一下實現的過程:
1、創建一個基于CFrameWnd的派生類CSplitterFrame;
2、添加要填充分割窗口的視圖類和與分割視圖切換的視圖類;
3、為這個派生類重載OnCreateClient函數,構造分割視圖
m_Splitter.CreateStatic(this,1,2);
m_Splitter.CreateView(0,0,RUNTIME_CLASS(CLeftTree),CSize(300,0),pContext);
m_Splitter.CreateView(0,1,RUNTIME_CLASS(CRightList),CSize(300,0),pContext);return true;這里我不解釋了,想必大家都很熟悉了,這里我要說一點我自己犯過的錯誤。我本來想在這里GetClientRect獲得窗口大小,但失敗了,左思右想不明白,后來才發現,這又不是CMainFrame,所以根本不能獲得,要是用API函數。
4、在CMainFrame類里面添加框架和視圖類指針變量
CSplitterFrame *m_pSplitterFrame;
//分割視圖框架指針
CView *m_pView;
//單獨視圖類,基于CView類
CView *m_pForm;
//單獨視圖類,基于CFormView類
int m_nCurrentID;
//記錄當前視圖
5、在CMainFrame類里面重載OnCreateClient函數,創建視圖及分割框架
CRect rcClient;GetClientRect(&rcClient);m_pView=new CViewShow;m_pView->Create(NULL,NULL,AFX_WS_DEFAULT_VIEW &~WS_BORDER,rcClient,this,NULL,pContext);m_pView->ShowWindow(SW_SHOW);m_pView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);pContext->m_pNewViewClass=(CRuntimeClass*)m_pView;
//設置默認視圖類
m_pForm=new CFormShow;m_pForm->Create(NULL,NULL,AFX_WS_DEFAULT_VIEW &~WS_BORDER,rcClient,this,IDD_FORMSHOW,pContext);m_pForm->ShowWindow(SW_HIDE);m_pSplitterFrame=new CSplitterFrame;m_pSplitterFrame->Create(NULL,NULL,AFX_WS_DEFAULT_VIEW &~WS_BORDER,rcClient,this,NULL,0,pContext);m_pSplitterFrame->ShowWindow(SW_HIDE);return true;
6、創建視圖切換函數
bool CMainFrame::Switch(int nID){ if(nID==m_nCurrentID)
return false;switch(nID){ case IDD_FORMSHOW:
m_pForm->ShowWindow(SW_SHOW);
m_pForm->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
m_pView->ShowWindow(SW_HIDE);
m_pView->SetDlgCtrlID(AFX_IDW_PANE_FIRST+2);
m_pSplitterFrame->ShowWindow(SW_HIDE);
m_pSplitterFrame->SetDlgCtrlID(AFX_IDW_PANE_FIRST+1);
m_nCurrentID=IDD_FORMSHOW;
break;case AFX_IDW_PANE_FIRST+1:
m_pSplitterFrame->ShowWindow(SW_SHOW);
m_pSplitterFrame->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
m_pForm->ShowWindow(SW_HIDE);
m_pForm->SetDlgCtrlID(IDD_FORMSHOW);
m_pView->ShowWindow(SW_HIDE);
m_pView->SetDlgCtrlID(AFX_IDW_PANE_FIRST+2);
m_nCurrentID=AFX_IDW_PANE_FIRST+1;
break;case AFX_IDW_PANE_FIRST+2:
m_pView->ShowWindow(SW_SHOW);
m_pView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
m_pForm->ShowWindow(SW_HIDE);
m_pForm->SetDlgCtrlID(IDD_FORMSHOW);
m_pSplitterFrame->ShowWindow(SW_HIDE);
m_pSplitterFrame->SetDlgCtrlID(AFX_IDW_PANE_FIRST+1);
m_nCurrentID=AFX_IDW_PANE_FIRST+2;
break;default:
break;} RecalcLayout();return true;}
7、創建調用方法
void CMainFrame::OnForm(){ // TODO: Add your command handler code here Switch(IDD_FORMSHOW);} void CMainFrame::OnView(){ // TODO: Add your command handler code here Switch(AFX_IDW_PANE_FIRST+2);} void CMainFrame::OnSplitter(){ // TODO: Add your command handler code here Switch(AFX_IDW_PANE_FIRST+1);}