日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于VTK的MFC应用程序开发(1)

發布時間:2025/3/15 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于VTK的MFC应用程序开发(1) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

基于VTK的MFC應用程序開發(1)

分類: VTK應用示例 4195人閱讀 評論(28) 收藏 舉報 CMakeVTKMFC

目錄(?)[+]

??????? 提到MFC一般都不陌生,大部分在校學生使用最多的應該就是它了。但是相對于Qt平臺來說,MFC的機制比較復雜。當使用MFC平臺進行VTK程序開發時,許多人可能沒有頭緒。這里結合一個實例講一下如何在MFC平臺下進行VTK程序開發。

??????? 這里在MFC下實現一個基于VTK的單文檔圖像顯示程序。通過這個程序,主要演示兩個方面:一是怎樣使用CMake將MFC程序與VTK結合;二是怎樣在MFC程序中調用VTK類實現具體的功能。這個也是基于MFC和VTK進行軟件開發的基礎,搭好這個框架后,以后的工作就是壘磚了,相信通過前面的學習,壘磚已經小菜一碟了。

??????? 在開始代碼之前,這里提一下,相信許多人在網上查詢這方面的資料的時候,有許多資料會講到通過MFC中的開發環境(如Visual Studio 2008)設置VTK的包含路徑和lib庫路徑等。但是這樣配置對于一般用戶來說比較復雜,每次開發新的工程時候,都要查找和設置這些庫,既費時費力,又不利于程序的移植(例如換到另外一臺機器,如果VTK編譯路徑不一致的話就會找不到庫)。因此這里還是推薦大家使用CMake來管理程序。僅僅幾行腳本代碼就可以實現VTK庫的配置,而且便于程序移植。

??????? 現在開始一步步實現VTK和MFC的程序開發。首先建立一個單文檔的MFC工程,工程名字為vtkSDI。這里與基于Qt的VTK程序開發稍微有點不同。先建立工程的目的是我們需要把由MFC自動生成的類加入到CMakeLists.txt中,方便管理。MFC單文檔工程的建立比較簡單,過程不再演示。工程文件如下所示,主要的類為CvtkSDIApp,CMainFrame,CvtkSDIDoc,CvtkSDIView和CAboutDlg五個。由于我們使用CMake來配置和生成工程,因此將工程目錄下的工程文件刪除,主要是.ncb,.sln,.vcproj,.user文件。

?

圖1 MFC單文檔工程的建立時所包含的文件

??????? 下面編寫CMakeLists.txt文件,將工程文件寫入到CMakeLists.txt中并連接VTK動態庫。VTK根據功能不同劃分了多個不同的模塊,每個模塊都是一個庫。因此在編寫CMakeLists.txt文件的時候,可以根據需要添加相應的模塊。

[plain] view plaincopy
  • #----------------------------------------------------------------------------------??
  • ??
  • cmake_minimum_required(?VERSION?2.8?)??
  • ??
  • project(?vtkSDI?)??
  • ???
  • #----------------------------------------------------------------------------------??
  • ??
  • #?查找并包含VTK工具包??
  • ??
  • find_package(?VTK?)??
  • ??
  • if?(VTK_FOUND)??
  • ??
  • ??include?(${VTK_USE_FILE})??
  • ??
  • else?(VTK_FOUND)??
  • ??
  • ??message?(FATAL_ERROR?"Cannot?build?without?VTK.?Please?set?VTK_DIR")??
  • ??
  • endif(?VTK_FOUND?)??
  • ??
  • #----------------------------------------------------------------------------------??
  • ??
  • #?這里添加本工程的文件??
  • ??
  • #?主要分為兩部分:??
  • ??
  • #?一是新建的單文檔程序中的非工程文件??
  • ??
  • #?二是用戶后續添加的類文件??
  • ??
  • SET(?PROJECT_SRCS??
  • ??
  • ????MainFrm.h??
  • ??
  • ????MainFrm.cpp??
  • ??
  • ????stdafx.h??
  • ??
  • ????stdafx.cpp??
  • ??
  • ????vtkSDI.h??
  • ??
  • ????vtkSDI.cpp??
  • ??
  • ????vtkSDIDoc.h??
  • ??
  • ????vtkSDIDoc.cpp??
  • ??
  • ????vtkSDIView.h??
  • ??
  • ????vtkSDIView.cpp??
  • ??
  • ????targetver.h??
  • ??
  • ????Resource.h??
  • ??
  • ????vtkSDI.rc??
  • ??
  • ????res/vtkSDI.rc2??
  • ??
  • ????res/vtkSDI.ico??
  • ??
  • ????res/vtkSDIDoc.ico??
  • ??
  • ????res/Toolbar.bmp??
  • ??
  • ????res/Toolbar256.bmp??
  • ??
  • ????)???
  • #----------------------------------------------------------------------------------??
  • ??
  • #?設置工程包含的vtk模塊,這里根據需要加載對應的模塊??
  • ??
  • include("${VTK_DIR}/GUISupport/MFC/VTKMFCSettings.cmake")??
  • ??
  • set(?VTK_LIBS?${vtk_libraries}???
  • ??
  • ??????????????vtkMFC??
  • ??
  • ??????????????vtkIO??
  • ??
  • ??????????????vtkRendering???
  • ??
  • ??????????????vtkGraphics???
  • ??
  • ??????????????vtkHybrid???
  • ??
  • ??????????????vtkFiltering???
  • ??
  • ??????????????vtkCommon???
  • ??
  • ??????????????vtkImaging???
  • ???)??
  • #----------------------------------------------------------------------------------??
  • ??
  • ADD_EXECUTABLE(?vtkSDI??WIN32??${PROJECT_SRCS}?)??
  • ??
  • TARGET_LINK_LIBRARIES?(?vtkSDI??${VTK_LIBS}?)??
  • <span?style="font-size:14px;">?</span>??
  • ??????? 需要注意的是在倒數第二行中需要加入WIN32,否則生成的工程在編譯時會出現錯誤。第二個需要注意的是,由于工程是基于MFC的,需要連接vtkMFC庫。完成CMakeLists.txt文件后,利用CMake設置相應的代碼路徑(存放工程源代碼)和工程路徑(存在生成的工程和文件),配置、生成當前工程,得到工程文件vtkSDI.sln。

    ??????? 打開vtkSDI.sln并編譯,編譯后如無語法和鏈接錯誤,則可得到一個可運行的空工程。注意運行時可能會提示找不到dll文件錯誤,解決方法已在VTKQt整合的示例章節中說明,這里不再贅述。到此為止,基于MFC單文檔工程的VTK編程框架已經搭建,接下來需要做的在該框架下調用VTK實現相應的功能。下面以圖像的讀取和顯示為例進行說明。

    ??????? 首先為vtkSDI工程添加一個菜單項,通過該菜單項加載圖像。打開工程的資源視圖Resource View,雙擊Menu中IDR_MAINFRAME菜單,右鍵單擊FILE菜單下的Open項,為該項添加一個事件Add Event Handler,彈出如下窗口:

    ?

    圖2 添加MFC事件響應向導

    ??????? 這里我們將該菜單的函數響應到CvtkSDIDoc文檔類中,消息類型選擇為COMMAND,點擊Add and Edit按鈕,完成消息的響應。該函數的作用是當用戶選擇該菜單時,彈出圖像文件選擇對話框,并將用戶選擇的圖像文件加載。為此,我們需要為該類定義一個圖像數據對象接收讀入的圖像數據。在CvtkSDIDoc頭文件中添加如下代碼,定義一個圖像數據的智能指針:

    vtkSmartPointer<vtkImageData> m_pImageData;

    注意不要忘了添加頭文件。在CvtkSDIDoc構造函數中對m_pImageData進行初始化,代碼如下:

    ???????m_pImageData =vtkSmartPointer<vtkImageData>::New();

    ?????? m_pImageData =NULL;

    ??????? 然后在菜單響應函數OnFileOpen中,添加讀取圖像的代碼。這里以jpg格式的圖像為例進行說。VTK中讀取jpg圖像的類為vtkJPEGReader,代碼如下:

    [cpp] view plaincopy
  • void?CvtkSDIDoc::OnFileOpen()??
  • ??
  • {??
  • ??
  • ???????//?TODO:?Add?your?command?handler?code?here??
  • ??
  • ???????CString?FilePathName;??
  • ??
  • ???
  • ??
  • ???????CFileDialog?dlg(?TRUE,?NULL,?NULL,??
  • ??
  • ???????????????????????OFN_HIDEREADONLY?|?OFN_OVERWRITEPROMPT,??
  • ??
  • ???????????????????????(LPCTSTR)_TEXT("JPG?Files?(*.jpg)|*.jpg|All?Files?(*.*)|*.*||"),??
  • ??
  • ???????????????????????NULL?);??
  • ??
  • ???
  • ??
  • ???????if(dlg.DoModal()==IDOK)??
  • ??
  • ???????{??
  • ??
  • ??????????????FilePathName=dlg.GetPathName();??
  • ??
  • ??
  • ??????????????vtkSmartPointer<vtkJPEGReader>?reader?=?vtkSmartPointer<vtkJPEGReader>::New();??
  • ??
  • ??????????????reader->SetFileName(FilePathName.GetBuffer(0));??
  • ??
  • ??????????????reader->Update();??
  • ??
  • ??????????????m_pImageData?=?reader->GetOutput();??
  • ??
  • ???????}??
  • ??
  • ???????else??
  • ??
  • ???????{??
  • ??
  • ??????????????return;??
  • ??
  • ???????}??
  • ??
  • }??
  • ??????? 下面在CvtkSDIView類中實現圖像的顯示功能。這里我們使用VTK中的類vtkImageViewer2。該類提供了強大的圖像顯示功能,可以接受vtkImageData輸入,通過設置交互對象vtkRenderWindowInteractor實現用戶交互,如窗寬窗位調節,圖像放縮等。這里首先在CvtkSDIView頭文件中定義vtkImageViewer2對象和窗口交互對象vtkRenderWindowInteractor。

    ?????? vtkSmartPointer<vtkImageViewer2>?????????????????m_pImageViewer;

    ?????? vtkSmartPointer<vtkRenderWindowInteractor>m_pRenderWindowInteractor;

    ??????? 然后重載CvtkSDIView類的OnCreate()函數,在該函數中對定義的對象進行初始化,將MFC窗口句柄設置vtkImageViewer2的父窗口ID,以及設置vtkImageViewer2對象與vtkRenderWindowInteractor對象關聯:

    [cpp] view plaincopy
  • int?CvtkSDIView::OnCreate(LPCREATESTRUCT?lpCreateStruct)??
  • ??
  • {??
  • ??
  • ????if?(CView::OnCreate(lpCreateStruct)?==?-1)??
  • ??
  • ???????????return?-1;???
  • ??
  • ????//?TODO:??Add?your?specialized?creation?code?here??
  • ??
  • ????m_pImageViewer?=?vtkSmartPointer<vtkImageViewer2>::New();??
  • ??
  • ????m_pImageViewer->SetParentId(GetSafeHwnd());??
  • ??
  • ???
  • ????m_pRenderWindowInteractor?=?vtkSmartPointer<vtkRenderWindowInteractor>::New();??
  • ??
  • ????m_pImageViewer->SetupInteractor(m_pRenderWindowInteractor);??
  • ??
  • ????m_pRenderWindowInteractor->Start();??
  • ??
  • ????return?0;??
  • ??
  • }??
  • ??????? 為了使圖像能夠居中顯示,需要每次在窗口大小改變時,設置m_pImageViewer的大小。這里重載CvtkSDIView類的函數OnSize(),當每次響應該函數時,將當前窗口的客戶區域大小設置為m_pImageViewer的大小。

    [cpp] view plaincopy
  • void?CvtkSDIView::OnSize(UINT?nType,?int?cx,?int?cy)??
  • ??
  • {??
  • ??
  • ????CView::OnSize(nType,?cx,?cy);??
  • ??
  • ???
  • ????//?TODO:?Add?your?message?handler?code?here??
  • ??
  • ????CRect?rect;??
  • ??
  • ????GetClientRect(rect);??
  • ??
  • ????m_pImageViewer->SetSize(rect.Width(),?rect.Height());??
  • ??
  • }??
  • ??????? 最后在OnDraw函數中實現圖像渲染。在該函數中,將文檔類中讀入的圖像數據設置vtkImageViewer2的輸入,然后調用m_pImageViewerRender函數開始渲染圖像,并監聽外部消息實現交互功能。

    [cpp] view plaincopy
  • void?CvtkSDIView::OnDraw(CDC*?/*pDC*/)??
  • ??
  • {??
  • ??
  • ????CvtkSDIDoc*?pDoc?=?GetDocument();??
  • ??
  • ????ASSERT_VALID(pDoc);??
  • ??
  • ????if?(!pDoc)??
  • ??
  • ???????????return;??
  • ??
  • ????//?TODO:?add?draw?code?for?native?data?here??
  • ??
  • ????m_pImageViewer->SetInput(pDoc->m_pImageData);??
  • ??
  • ????m_pImageViewer->Render();??
  • ??
  • }??
  • ??????? 編譯鏈接后即可執行程序,運行結果如下所示。另外還可以測試交互功能,如按住鼠標右鍵拖動鼠標或者滑動滾輪,實現圖像的放縮功能;按住鼠標左鍵,拖動鼠標即可實現圖像窗寬窗位的調節。

    ?

    圖3 程序運行結果

    ??????? 從程序來看沒有編譯錯誤,而且正確顯示圖像。OK,關閉程序,這時意外出現了,在VS輸出窗口中出現許多內存溢出,如下圖所示:

    ?

    圖4 MFC&VTK程序內存溢出

    ??????? 這樣的內存溢出是因為VTK的DLL先于MFC的DLL加載。因此在CMakeLists.txt中加入下面代碼對VTK的DLL進行延遲加載,代碼如下:

    [plain] view plaincopy
  • VTK_MFC_ADD_DELAYLOAD_FLAGS(CMAKE_EXE_LINKER_FLAGS??
  • ??
  • ????vtkMFC.dll??
  • ??
  • ????vtkIO.dll??
  • ??
  • ????vtkRendering.dll??
  • ??
  • ????vtkGraphics.dll??
  • ??
  • ????vtkHybrid.dll??
  • ??
  • ????vtkFiltering.dll??
  • ??
  • ????vtkCommon.dll??
  • ??
  • ????vtkImaging.dll??
  • ??
  • ????)??
  • ?

    ??????? 添加如上代碼后,重新編譯工程(rebuild),運行然后關閉工程,觀察VS輸出窗口中的輸出信息,沒有內存溢出錯誤,正常退出。

    ?

    ==========歡迎轉載,轉載時請保留該聲明信息==========

    版權歸@東靈工作室所有,更多信息請訪問東靈工作室


    教程系列導航:http://blog.csdn.net/www_doling_net/article/details/8763686

    ================================================

    總結

    以上是生活随笔為你收集整理的基于VTK的MFC应用程序开发(1)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。