VB 的 PictureBox 輕鬆顯示 JPG/GIF,MFC 卻無對應控制項。手寫 JPEG 解碼器不現實。Windows 內建 IPicture COM 介面 (OLE 自動化) 已支援 BMP/JPG/GIF/ICO/WMF/EMF 等格式,配合 OleLoadPicture 即可輕鬆載入渲染。
IStream (檔案/資源/記憶體)OleLoadPicture(pStream, 0, FALSE, IID_IPicture, (void**)&pPicture) 載入圖片pPicture->Render(hDC, x, y, w, h, 0, hmHeight, hmWidth, -hmHeight, &rect) 繪製 (座標單位為 HIMETRIC)
class CPicture {
CComQIPtr m_spIPicture; // 智慧指標管理介面
public:
// 多重載入來源
BOOL Load(LPCTSTR pszPathName); // 檔案
BOOL Load(CFile* pFile); // CFile
BOOL Load(CArchive& ar); // 序列化/資源
BOOL Load(UINT nResID, LPCTSTR pszType=_T("IMAGE")); // 資源
// 繪製
void Render(CDC* pDC, CRect& rcRender, BOOL bStretch=TRUE);
CSize GetImageSize(); // 回傳 HIMETRIC 或像素尺寸
// 內部轉換 HIMETRIC ↔ 裝置座標
static void HMtoDP(CDC* pDC, SIZEL* psizelHM, SIZEL* psizelDP);
static void DPtoHM(CDC* pDC, SIZEL* psizelDP, SIZEL* psizelHM);
};
// Document
class CPictureDoc : public CDocument {
CPicture m_pict;
virtual void Serialize(CArchive& ar) { if (ar.IsLoading()) m_pict.Load(ar); }
CPicture* GetPicture() { return &m_pict; }
};
// View
void CPictureView::OnDraw(CDC* pDC) {
CPictureDoc* pDoc = GetDocument();
CPicture* pPic = pDoc->GetPicture();
CRect rc; GetImageRect(rc); // 依縮放比例計算目標矩形
pPic->Render(pDC, rc);
}
// 背景填充避免閃爍
BOOL CPictureView::OnEraseBkgnd(CDC* pDC) {
CRect rcClient, rcImage;
GetClientRect(&rcClient);
GetImageRect(rcImage);
pDC->ExcludeClipRect(&rcImage); // 排除圖片區域
pDC->FillSolidRect(&rcClient, RGB(0,0,0)); // 填充黑色背景
return TRUE;
}
.rc 檔加入:
IDR_MYPIC IMAGE MOVEABLE PURE "res\\MyPic.jpg"
程式碼:CPicture pic(IDR_MYPIC); pic.Render(pDC, rc);
class CPictureCtrl : public CStaticLink { // 繼承支援超連結的靜態控制項
CPicture m_pict;
CString m_strURL;
void PreSubclassWindow() {
CStaticLink::PreSubclassWindow();
ModifyStyle(0, SS_OWNERDRAW); // 自繪
}
void OnPaint() {
CPaintDC dc(this);
CRect rc; GetClientRect(&rc);
m_pict.Render(&dc, rc);
}
// 點擊圖片開啟 URL (若有設定)
void OnLButtonUp(UINT, CPoint) { if (!m_strURL.IsEmpty()) ShellExecute(...); }
};
使用:對話框放 Static 控制項 (ID=IDC_IMG),變數類型 CPictureCtrl,OnInitDialog 中 m_wndImg.SubclassDlgItem(IDC_IMG, this),同 ID 的 IMAGE 資源自動載入。
afxctl.h 中的 CPictureHolder 同樣封裝 IPicture,支援 CreateFromFile, CreateFromResource, Render。若不想引入額外類別,可直接使用。
| 方案 | 優點 | 缺點 |
|---|---|---|
| CPicture (本文) | 介面簡潔、支援檔案/資源/序列化/資源、自動座標轉換 | 需複製類別碼 |
| CPictureHolder (MFC) | 零依賴、內建 | 文件較少、介面略繁瑣 |
| GDI+ Image | 功能最強 (縮放插值、Alpha、Metafile) | 需連結 gdiplus.dll、啟動/關閉 GDI+ |
| CImage (ATL/MFC 新版) | 封裝 GDI+、介面現代 | VS2008+ 才完整支援 |
對於 VC6.0 維護專案或需零依賴部署,**CPicture + IPicture 是最佳選擇**。完整原始碼 (含 ImgView 範例) 請參考本文配套下載。