MFC 僅原生支援 BMP,未壓縮佔用空間大,嵌入資源會嚴重膨脹執行檔。JPEG (有損高壓縮) 與 GIF (256 色高壓縮) 更適合分發與資源嵌入。
IPicture 為標準 COM 圖片介面,管理點陣圖、圖示、繪圖元等語言無關抽象。系統提供標準實現,支援 IPersistStream 從串流載入/儲存。關鍵 API:OleLoadPicture 從 IStream 載入圖片並回傳 IPicture*。
CFileDialog 過濾 *.jpg;*.gif,路徑存入 CString m_sPath。IStream* pStm = NULL;
CFile file; CFileStatus fs;
if (file.Open(m_sPath, CFile::modeRead) && file.GetStatus(fs) && fs.m_size != -1) {
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, fs.m_size);
if (hGlobal) {
LPVOID pv = GlobalLock(hGlobal);
if (pv) {
file.ReadHuge(pv, fs.m_size);
GlobalUnlock(hGlobal);
CreateStreamOnHGlobal(hGlobal, TRUE, &pStm); // 串流物件
}
}
}
IPicture* pPic = NULL;
if (SUCCEEDED(OleLoadPicture(pStm, fs.m_size, TRUE, IID_IPicture, (LPVOID*)&pPic))) {
OLE_XSIZE_HIMETRIC hmW; OLE_YSIZE_HIMETRIC hmH;
pPic->get_Width(&hmW); pPic->get_Height(&hmH);
// 轉換為裝置像素
double fx = (double)pDC->GetDeviceCaps(HORZRES) * hmW / (pDC->GetDeviceCaps(HORZSIZE) * 100.0);
double fy = (double)pDC->GetDeviceCaps(VERTRES) * hmH / (pDC->GetDeviceCaps(VERTSIZE) * 100.0);
if (FAILED(pPic->Render(*pDC, 0, 0, (DWORD)fx, (DWORD)fy,
0, hmH, hmW, -hmH, NULL)))
AfxMessageBox("渲染失敗");
pPic->Release();
} else AfxMessageBox("載入失敗");
Render 參數:目標 DC、左上角座標、寬高、來源圖片偏移/裁剪區域 (HIMETRIC 單位,1/100 公釐),負高度表示 Y 軸向下。SUCCEEDED/FAILED 巨集檢查 HRESULT。pPic->Release()、串流自動釋放 (建立時 fDeleteOnRelease=TRUE)。僅能顯示 GIF 第一幀,完整動畫需外部 ActiveX 控件支援。若需嵌入資源,可用 FindResource/LoadResource 取得資料指標建立串流,邏輯相同。