Чтение онлайн

ЖАНРЫ

Программирование на Visual C++. Архив рассылки

Jenter Алекс

Шрифт:

);

 }

 return hr;

}

HRESULT DrawImg(HDC hdc, RECT& rcBounds) {

 if (m_pImage) {

// Check download state

DWORD dwState = 0;

HRESULT hr = m_pImage->GetStateInfo(&dwState, NULL, true);

if (SUCCEEDED(hr)) {

if (IMGLOAD_LOADING & dwState) {

// Still loading - wait 50 msec and request again

::DrawText(hdc, _T("Loading, please wait..."), -1, &rcBounds, DT_SINGLELINE);

::Sleep(50);

Invalidate(false);

hr = S_FALSE;

} else if (IMGLOAD_COMPLETE & dwState) {

// Download successfully complete

hr = m_pImage->Draw(

hdc, // [in] Handle of device context on which to render the image

&rcBounds // [in] Position and dimensions

);

} else {

// Download failed

hr = E_UNEXPECTED;

}

}

return hr;

 }

 return E_UNEXPECTED;

}

Достоинства:

правильно работает с прозрачными и анимированными картинками. Понимает URL (даже res:// и sysimage://).

Недостатки: не поддерживает загрузку из IStream. Не умеет загружать файлы синхронно.

ПРИМЕЧАНИЕ

Форматов, распознаваемых этим объектом, может быть меньше, например, если при установке IE4 позьзователь отключил поддержку PNG файлов.

Способ 4 (DirectXTransform)

Не смотря на название, эта технология не имеет ничего общего с DirectX. Зато является частью Internet Explorer, внутри которого даже имется набор простеньких классов, реализующих IDirectDraw для нужд DirectXTransform. Этот способ поддерживает тот же набор форматов, что и предыдущий, более того, для этого используется один и тот же код. Разве что синхронно и на выходе получается IDXSurface объект.

#include <dxtrans.h>

HRESULT DrawImg(HDC hdc, const RECT& rcBounds) {

 if (m_pDCLock) {

HDC hdcImage = m_pDCLock->GetDC;

// Get the bitmap

HGDIOBJ hObj = ::GetCurrentObject(hdcImage, OBJ_BITMAP);

BITMAP bm = {0};

// Get the size of the bitmap

if (hObj && ::GetObject(hObj, sizeof(BITMAP), &bm)) {

// Draw the image

return ::StretchBlt(hdc, rcBounds.left, rcBounds.top,

rcBounds.right - rcBounds.left, rcBounds.bottom - rcBounds.top,

hdcImage, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY

) ? S_OK : E_FAIL;

}

 }

 return E_UNEXPECTED;

}

HRESULT Load(LPCTSTR szFile) {

 CComPtr<IDXTransformFactory> pTransFact;

 CComPtr<IDXSurfaceFactory> pSurfFact;

 // Create the Transform Factory.

 HRESULT hr = ::CoCreateInstance(CLSID_DXTransformFactory, NULL,

CLSCTX_INPROC, IID_IDXTransformFactory, (void **)&pTransFact);

 if (SUCCEEDED(hr))

 hr = pTransFact->QueryService(SID_SDXSurfaceFactory,

IID_IDXSurfaceFactory, (void **)&pSurfFact);

 if (SUCCEEDED(hr)) {

CComBSTR bstrFile(szFile);

CComPtr<IDXSurface> pDXSurf;

// Load DX surface.

hr = pSurfFact->LoadImage(bstrFile, NULL, NULL,

NULL, IID_IDXSurface, (void**)&pDXSurf);

if (SUCCEEDED(hr)) {

// Get IDXDCLock object

hr = pDXSurf->LockSurfaceDC(NULL, INFINITE, DXLOCKF_READ, &m_pDCLock);

}

 }

 return hr;

}

Достоинства:

Прост в использовании. Поддерживает загрузку из IStream.

Недостатки: Медленный и ресурсоемкий. Это связянно с тем, что сначала для картинки создается обертка в виде IDirectDrawSurface, а затем еще одна для IDXSurface, которые нам совершенно не нужны.

Способ 5 (Фильтры импорта)

Многие программы (например PaintBrush или WinWord) при инсталляции кладут в каталог %ProgramFiles%\Common Files\Microsoft Shared\Grphflt некоторое количество файлов, предназначенных для чтения файлов картинок. Способ не документированный и сильно устаревший. Полный список установленных в системе фильтров находится в реестре по адресу SOFTWARE\\Microsoft\\Shared Tools\\Graphics Filters\\Import

Я не буду рассматривать этот способ подробно, поскольку он сильно устарел и очень неудобен. Тем не менее, в приложении DrawImg этот способ реализован наравне с другими.

Способ 6 (Снова Фильтры импорта)

Майкрософт Офис, начиная с версии 8.0 (97) использует новый API с теми же фильтрами.

HRESULT Load(LPCTSTR szFile) {

 HMODULE hModule = g_pMapExtToFilter->LoadFilter(szFile);

 if (NULL == hModule) return E_FAIL;

 struct NameStruct {

DWORD dwHead[2];

char szName[MAX_PATH];

DWORD dwTail[2];

 };

 typedef DWORD (__stdcall *GetFilterInfo_t)

 (DWORD dwVersion, DWORD dwReserved, HGLOBAL *phFilterData, DWORD dwReserved2);

 typedef DWORD (__stdcall *SetFilterPref_t)

(HGLOBAL hFilterData, LPCSTR szOption, LPCSTR szValue, DWORD dwReserved2, DWORD dwReserved1);

Поделиться с друзьями: