Алекс Jenter - Программирование на Visual C++. Архив рассылки
- Название:Программирование на Visual C++. Архив рассылки
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Алекс Jenter - Программирование на Visual C++. Архив рассылки краткое содержание
РАССЫЛКА ЯВЛЯЕТСЯ ЧАСТЬЮ ПРОЕКТА RSDN, НА САЙТЕ КОТОРОГО ВСЕГДА МОЖНО НАЙТИ ВСЮ НЕОБХОДИМУЮ РАЗРАБОТЧИКУ ИНФОРМАЦИЮ, СТАТЬИ, ФОРУМЫ, РЕСУРСЫ, ПОЛНЫЙ АРХИВ ПРЕДЫДУЩИХ ВЫПУСКОВ РАССЫЛКИ И МНОГОЕ ДРУГОЕ.
Программирование на Visual C++. Архив рассылки - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
// Create new Gdiplus::Image object
m_pImage = new Gdiplus::Image(T2CW(szFile));
ATLASSERT(m_pImage);
// Check for success
if (Gdiplus::Ok == m_pImage->GetLastStatus()) return S_OK;
// Cleanup on failure
Destroy();
return E_FAIL;
}
HRESULT DrawImg(HDC hdc, RECT& rcBounds) {
if (m_pImage) {
// Create Gdiplus::Graphics object from HDC
Gdiplus::Graphics graphics(hdc);
// Create Gdiplus::Rect object from RECT
Gdiplus::Rect rc(rcBounds.left, rcBounds.top, rcBounds.right, rcBounds.bottom);
// Draw the image
return Gdiplus::Ok == graphics.DrawImage(
m_pImage, // [in] Gdiplus::Image object
rc // [in] Position and dimensions
) ? S_OK : E_FAIL;
}
return E_UNEXPECTED;
}
Достоинства: понимает множество форматов, в том числе анимированный GIF, правильно работает с прозрачными картинками.
Недостатки: На сегодняшний момент реализован только в WindowsXP. Хотя простое копирование gdiplus.dllв system32 делает ее доступной, как минимум, в Windows2000. Скорее всего, в обозримом будущем ожидаются версии и для Win9x.
Не так давно Майкрософт предоставила заголовочные и библиотечные файлы к объекту ImgCtx, появившемуся еще в internet explorer 4.0. Он умеет заргужать картинки в формате BMP, GIF, JPEG, ICO, WMF, EMF, PNG, XBM, ICO, TIFF и, возможно, некоторых других:
#include
HRESULT Load(LPCTSTR szFile) {
// Create IImgCtx object
HRESULT hr = ::CoCreateInstance(CLSID_IImgCtx, NULL, CLSCTX_ALL, IID_IImgCtx, (void**)&m_pImage);
if (SUCCEEDED(hr)) {
// Load URL
USES_CONVERSION;
hr = m_pImage->Load(
T2COLE(szFile), // [in] URL
0 // [in] Flags and preffered color format
);
}
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 файлов.
Не смотря на название, эта технология не имеет ничего общего с DirectX. Зато является частью Internet Explorer, внутри которого даже имется набор простеньких классов, реализующих IDirectDraw для нужд DirectXTransform. Этот способ поддерживает тот же набор форматов, что и предыдущий, более того, для этого используется один и тот же код. Разве что синхронно и на выходе получается IDXSurfaceобъект.
#include
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 pTransFact;
CComPtr 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 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, которые нам совершенно не нужны.
Многие программы (например PaintBrush или WinWord) при инсталляции кладут в каталог %ProgramFiles%\Common Files\Microsoft Shared\Grphfltнекоторое количество файлов, предназначенных для чтения файлов картинок. Способ не документированный и сильно устаревший. Полный список установленных в системе фильтров находится в реестре по адресу SOFTWARE\\Microsoft\\Shared Tools\\Graphics Filters\\Import
Я не буду рассматривать этот способ подробно, поскольку он сильно устарел и очень неудобен. Тем не менее, в приложении DrawImg этот способ реализован наравне с другими.
Майкрософт Офис, начиная с версии 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);
typedef DWORD (__stdcall *ImportGr_t)
(DWORD dwReserved, NameStruct *pFile, ImgInfo *pInfo, HGLOBAL hFilterData);
GetFilterInfo_t pGetFilterInfo = (GetFilterInfo_t)::GetProcAddress(hModule, "GetFilterInfo");
SetFilterPref_t pSetFilterPref = (SetFilterPref_t)::GetProcAddress(hModule, "SetFilterPref");
ImportGr_t pImportGr = (ImportGr_t)::GetProcAddress(hModule, "ImportGr");
if (NULL == pImportGr) pImportGr = (ImportGr_t)::GetProcAddress(hModule, "ImportGR");
if (pImportGr) {
NameStruct name = {0};
HGLOBAL hFilterData = NULL;
if (pGetFilterInfo) {
DWORD dwVer = pGetFilterInfo(2, 0, &hFilterData, 0x00170000);
ATLASSERT(2 == dwVer);
if (2 != dwVer) {
::FreeLibrary(hModule);
return E_UNEXPECTED;
}
}
// PB 01/26/2001 Turn off dialogs
if (pSetFilterPref) {
pSetFilterPref(hFilterData, "ShowProgressDialog", "No", 2, 1);
pSetFilterPref(hFilterData, "ShowOptionsDialog", "No", 2, 1);
}
USES_CONVERSION;
::lstrcpynA(name.szName, T2CA(szFile), MAX_PATH);
DWORD dwRet = pImportGr(0, &name, &m_Image, hFilterData);
if (hFilterData) ::GlobalFree(hFilterData);
if (0 != dwRet || NULL == m_Image.hObj) {
::FreeLibrary(hModule);
return E_FAIL;
}
if (OBJ_METAFILE != ::GetObjectType(m_Image.hObj)) {
HGLOBAL hObj = (HGLOBAL)m_Image.hObj;
LPBYTE pObj = (LPBYTE)::GlobalLock(hObj);
m_Image.hObj = ::SetMetaFileBitsEx(::GlobalSize(hObj), pObj);
::GlobalUnlock(hObj);
::GlobalFree(hObj);
}
if (NULL == m_Image.hObj) {
::FreeLibrary(hModule);
return E_FAIL;
Интервал:
Закладка: