程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 使用GDI+的MFC應用程序的文件打開和保存對話框

使用GDI+的MFC應用程序的文件打開和保存對話框

編輯:關於VC++

(譯注:原文代碼的Demo_VC7沒有在同Demo_VC6一樣顯示滾動條視圖,修改之)

開發環境:Windows XP/Server 2003/2000/NT4.0-SP6/98/Me, MS Visual Sudio 6.0/2003, GDI+

介紹

CGdiplusFileOpenDialog和CGdiplusFileSaveAsDialog類提供了一個在GDI+的MFC應用程序輕松實現文件打開和保存對話框的方法。

主要特點是:

它們可以動態地裝入關於支持圖像的解碼器/編碼器和構建文件過濾清單。

它們可以獲得當前圖像編碼器標識碼(CLSID)以供需要將其作為一個參數的GDI+函數使用。

它們可以檢查和驗證文件名和擴展名。

你可以在類的描述和demo應用程序中找到更多的詳情。

(類的)層次表

CGdiplusFileDialog類

CGdiplusFileDialog繼承於MFC CFileDialog類,同時也是CGdiplusFileOpenDialog和CGdiplusFileSaveAsDialog的抽象基類。

封裝一個包含所支持的解碼器/編碼器的數組(m_arrCodecInfo)

實現基函數TranslateFilter:轉換一個MFC-like文件過濾器(使用一個''|''作為分隔符)到一個OPENFILENAME結構文件過濾器(使用''\0''作為分隔符)

聲明兩個純虛函數:FillCodecInfoArray 和ConstructMFCStyleFilte;在派生類中,覆寫函數實現特定操作。

覆寫CFileDialog::DoModal;在調用基類函數之前調用,它

o 檢查GDI+庫是否被初始化

o 調用FillCodecInfoArray、 ConstructMFCStyleFilter 和 TranslateFilter函數

CGdiplusFileOpenDialog類

CGdiplusFileOpenDialog實現文件打開命令對話框。

覆寫CGdiplusFileDialog::FillCodecInfoArray並調用Gdiplus::GetImageDecoders填充關於可用譯碼器的信息數組。

o 文件格式的名稱(如:"JPEG")

o 已用擴展名(如:"*.JPG、*.JPEG、*.JPE、*.JFIF")

o 在打開對話框(譯注:原文為Save As dialog,應該是Open dialog,筆誤了)中使用的缺省擴展名(如:"JPG")

o 解碼器標識碼

覆寫CGdiplusFileDialog::ConstructMFCStyleFilter構建一個"MFC 樣式"的過濾器(使用一個''|''作為分隔符);一個附加的"All GDI+ supported"(所有GDI+支持)的過濾項被添入

舉例

#include "GdiplusFileOpenDialog.h"
// ...
bool CFoo::LoadImage(Image*& pImage)
{
bool bLoaded = false;
CGdiplusFileOpenDialog dlgFile;
if(IDOK == dlgFile.DoModal())
{
CString strPathName = dlgFile.GetPathName();
pImage = Image::FromFile(strPathName.AllocSysString());
Status status = pImage->GetLastStatus();
if(Ok == status)
{
bLoaded = true;
}
}
return bLoaded;
}

CGdiplusFileSaveAsDialog類

CGdiplusFileSaveAsDialog實現文件保存的通用型對話框。

覆寫CGdiplusFileDialog::FillCodecInfoArray並調用Gdiplus::GetImageEncoders來填充關於可用編碼器的信息數組。

o 文件格式的名稱(如:" BMP ")

o 已用擴展名(如:"*. BMP、*. DIB、*. RLE ")

o 在保存對話框中使用的缺省擴展名(如:" BMP ")

覆寫CGdiplusFileDialog::ConstructMFCStyleFilter構建"MFC 樣式"的過濾器(使用一個''|''作為分隔符)

覆寫CFileDialog::OnInitDone 和 CFileDialog::OnTypeChange來設置缺省擴展名並裝入缺省編碼器標識碼(m_clsid成員變量)

實現public方法GetCodecCLSID;codec(編碼器/譯碼器)CLSID進一步被傳遞到Gdiplis::Image::Save函數

覆寫CFileDialog::OnFileNameOK以實現文件擴展名檢查:

o 如果文件名沒有擴展名,使用缺省擴展名和CLSID

o 如果文件名有一個擴展名並且可以被codec信息數組找到,擴展名和相應的CLSID將用來代替缺省值

o 如果文件名有一個擴展名同時不能被codec信息數組找到,它返回TRUE同時對話框保持顯示以便用戶輸入另一個文件名

舉例

#include "GdiplusFileSaveAsDialog.h"
// ...
bool CFoo::SaveImage(Image* pImage)
{
bool bSaved = false;
CGdiplusFileSaveAsDialog dlgFile;
if(IDOK == dlgFile.DoModal())
{
CLSID clsid = dlgFile.GetCodecCLSID();
CString strPathName = dlgFile.GetPathName();
Status status = pImage->Save(strPathName.AllocSysString(),
&clsid);
if(Ok == status)
{
bSaved = true;
}
}
return bSaved;
}

Demo應用程序

Demo應用程序是一個建立在MDI框架上的簡單的圖像浏覽器。它演示了如何使用CGdiplusFileOpenDialog 和 CGdiplusFileSaveAsDialog.

StdAfx.h 中的包含和聲明

typedef unsigned __int32 ULONG_PTR;
#include <afxtempl.h>
#include <gdiplus.h>
#pragma comment(lib, "gdiplus.lib")
using namespace Gdiplus;

注意

對於比VC++6.0更新的版本,或如果你已安裝了platform SDK更新,請移去ULONG_PTR的定義。

(僅在VC++ 6.0下)確保gdiplus.lib 的位置應在Tools/Option/Directories/Library文件夾下;抑或你可以在pragma comment指示中提供其完全路徑和文件名稱。

初始化和發布GDI+

你必須在做如何GDI+調用前調用GdiplusStartup,同時在你結束使用GDI+時調用GdiplusShutdown。

class CDemoApp : public CWinApp
{
// ...
// Attributes
protected:
ULONG_PTR m_gdiplusToken;
// ...
// Implementation
protected:
bool InitGdiplus();
void TermGdiplus();
// ...
};
// Called from CDemoApp::InitInstance
bool CDemoApp::InitGdiplus()
{
GdiplusStartupInput gdiplusStartupInput;
Status status = GdiplusStartup(&m_gdiplusToken,
&gdiplusStartupInput,
NULL);
return (Ok == status);
}
// Called from CDemoApp::ExitInstance
void CDemoApp::TermGdiplus()
{
GdiplusShutdown(m_gdiplusToken);
}

使用CGdiplusFileOpenDialog

去掉調用基類信息處理器的ID_FILE_OPEN命令的缺省映射並將該命令映射到在一個CWinApp派生類中處理(譯注:即Demo程序中的CDemoApp類)。

void CDemoApp::OnFileOpen()
{
CGdiplusFileOpenDialog dlgFile;
if(IDOK == dlgFile.DoModal())
{
OpenDocumentFile(dlgFile.GetPathName());
}
}

覆寫CDocument::OnOpenDocument虛函數。

class CDemoDoc : public CDocument
{
// ...
// Attributes
protected:
Image* m_pImage;
// Operations
public:
Image* GetImage() {return m_pImage;}
// ...
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDemoDoc)
public:
virtual BOOL OnOpenDocument(LPCTSTR pszPathName);
//}}AFX_VIRTUAL
// ...
};

BOOL CDemoDoc::OnOpenDocument(LPCTSTR pszPathName)
{
SafeDeleteImage();
m_pImage = Image::FromFile(CString(pszPathName).AllocSysString());
return (Ok == m_pImage->GetLastStatus());
}

使用CGdiplusFileSaveAsDialog

在CDocument派生類(譯注:即Demo程序中的CDemoDoc類)中映射ID_FILE_SAVE_AS命令。在CGdiplusFileSaveAsDialog::DoModal返回後,調用GetPathName和GetCodecCLSID以傳遞(路徑、文件名、Codec CLSID)到Image::Save方法。

void CDemoDoc::OnFileSaveAs()
{
CGdiplusFileSaveAsDialog dlgFile;
if(IDOK == dlgFile.DoModal())
{
CLSID clsid = dlgFile.GetCodecCLSID();
CString strPathName = dlgFile.GetPathName();
Status status = m_pImage->Save(strPathName.AllocSysString(),
&clsid);
if(Ok != status)
{
TRACE2(_T("\nFailed to save image in ''%s'' file\n")
_T("GDI+ Error: %u"),
strPathName,
status);
}
}
}

繪圖

在CDemoView::OnDraw中,使用一個Gdiplus::Graphics對象來繪圖。

注意這只是一個例子並且設計得盡可能的簡單。

void CDemoView::OnDraw(CDC* pDC)
{
CDemoDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
Image* pImage = pDoc->GetImage();
if(NULL != pImage)
{
Graphics graphics(*pDC);
Status status = graphics.GetLastStatus();
if(Ok == status)
{
graphics.DrawImage(pImage, 0, 0,
pImage->GetWidth(), pImage->GetHeight());
}
}
}

結束提示:

gdiplus.dll已經包含在Windows XP 和 Windows Server 2003中

對於運行在Microsoft Windows NT 4.0-SP6/2000/98/Me之上應用程序的可再分發,gdiplus.dll是必需的。

如果你再分發gdiplus.dll,推薦你將之放入應用程序的文件夾。

下載

Platform SDK Update(http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm):包含GDI+頭文件,gdiplus.lib, 和 gdiplus.dll(VC++ 6.0所需)

Platform SDK Redistributable: GDI+(http://www.microsoft.com/downloads/details.aspx?FamilyID=6a63ab9c-df12-4d41-933c-be590feaa05a&DisplayLang=en):可再分發gdiplus.dll,對於Windows NT 4.0-SP6/2000/98/Me

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved