MATLAB6.x & VC6.0: 將plot圖片顯示在MFC程式的視窗中
實驗環境:
Pwin2K SP3, MATLAB6.5, Visual C++ 6.0 SP?
1 問題的提出
通過調用mcc,可以將MATLAB程式編譯為C/C++或庫檔案,並嵌入到自己的VC應用程式中。該方法不僅適於純粹的運算代碼,也適於圖形函數,比如plot等等。不過遇到的問題是,每次調用plot函數,將產生一個新的視窗,這使得我們的VC程式風格不能統一,看起來很彆扭。而且,這個跳出來的視窗特徵太明顯,讓人一下子就認出來是MATLAB做的,這在有些時候會讓您的客戶、老闆、同事、同學、gg、mm覺得很不屑:偷懶呐!
那麼為了讓程式看上去更專業,能否將圖片嵌入我們的VC視窗,或者對話方塊裡面,而不讓它跳出來呢?
2 分析
實際上,在執行plot之後,執行以下命令:
set(gca)
你會發現有這樣一個屬性:Parent,它就是該視窗的父視窗,也就是在哪個父視窗中顯示。對它進行設定,可以形成複雜的GUI介面,我們看看MATLAB提供的demo就知道了。如果該屬性為空白,這個plot視窗就會以獨立視窗的形式顯示出來。
因此,MATLAB的繪圖功能本身是支援顯示在某個特定父視窗中的。然而遺憾的是,Parent屬性不是用Win32的handle指定的,而是用MATLAB的字串形式的ID。我們在VC中很難利用此功能。
3 逆向思維
既然不能直接把圖畫在指定視窗中,那麼畫好後再挪到這個視窗可以嗎?
思路就是這麼簡單,查一下Win32 API,可以找到兩個函數:FindWindow和SetParent。顧名思義,我想怎麼做,你已經猜出八九分了吧
4 代碼實現
核心代碼如下:
m_hmat = ::FindWindow(NULL, "Figure No. 1");
::SetParent(m_hmat, m_hWnd);
首先找到視窗名為"Figure No. 1"的視窗的控制代碼,然後將它的父視窗設定為某個視窗就行了。這段程式碼封裝含於個DOC/VIEW結構的MFC程式的View類中,m_hWnd就是該View的視窗控制代碼。
5 應用執行個體
應用執行個體在這裡下載:SglMFC.zip
這個程式是以《MATLAB擴充編程》第九章的例子SGLMFC為基礎改制的,在SglMFCView.cpp中加入了功能表項目Embed及其回呼函數OnSGLEmbed。至於如何對該工程進行編譯,請參考該書的相關內容。
6 其它細節
幾點說明如下:
■ 該程式是個簡單的示範程式,編程並不嚴密。內含debug版本的可執行程式,請嚴格按照下面流程運行:
(1) SGL|Start
(2) SGL|Demo,這時顯示出一個plot視窗
(3) SGL|Embed,plot視窗跑到View中
(4) 雙擊視窗欄,充滿整個View
(5) 關閉該視窗
(6) SGL-Stop
(7) 退出程式
點擊這裡看示範結果。
■ 該方法仍然會先顯示彈出式plot視窗,為了禁止在VC視窗之外顯示plot,應該先用figure命令顯示一個隱含的視窗,繪圖完畢、並挪動到VC視窗內部後在顯示出來,例如
>> figure('Visible','off')
>> plot([1:100])
>> figure(1)
■ 為了去掉plot的菜單和按鈕,在相應的MATLAB程式中應該先執行:set(gcf, 'MenuBar','none');
■ 如果顯示的圖片比較多,就不能用"Figure No. 1"唯一確定各個視窗了,應該是2或者3等等。這需要你用MATLAB代碼和VC代碼巧妙地編程加以控制
■ 用Win32API還可以將視窗的名字和表徵圖改掉,徹底去除MATLAB的痕迹
5 聲明
程式本身並不完善,如果遇到問題,請盡量自己解決
energy
2002.12.3