ATL:OnDrawThumbnail hDrawDC 在 IThumbnailProvider 中似乎是单色的
ATL: OnDrawThumbnail hDrawDC seems to be monochrome in IThumbnailProvider
我正在处理一个 C++ ATL COM thumbnail/preview/search 项目,但它的位图显示代码行为在缩略图过程中是单色的,而不是彩色的。使用相同的功能,预览过程按预期着色。
我使用 ATL 向导创建了 IThumbnailProvider
和他的朋友们。我的小改动是:我将 document::OnDrawThumbnail
中的颜色从黑色替换为粉红色,并将 document::OnDrawThumbnail 写入 CPreviewCtrl::DoPaint
。我已经阅读了 MS 规范中的“新 DC 始终是单色”的内容,但即使更改了原始 ATL 代码 OnDrawThumbnail(GetDC(NULL), &rcBounds);
,我也无法获得彩色 DC。 CreateCompatibleDC(NULL)
和 CreateCompatibleDC(hDrawDC)
也是死胡同。
document.cpp(已更改)
// Almost the default sample code, but hDrawBrush is changed to pink
void document::OnDrawThumbnail(HDC hDrawDC, LPRECT lprcBounds)
{
HBRUSH hDrawBrush = CreateSolidBrush(RGB(255, 0, 255)); // pink
FillRect(hDrawDC, lprcBounds, hDrawBrush);
HFONT hStockFont = (HFONT) GetStockObject(DEFAULT_GUI_FONT);
LOGFONT lf;
GetObject(hStockFont, sizeof(LOGFONT), &lf);
lf.lfHeight = 34;
HFONT hDrawFont = CreateFontIndirect(&lf);
HFONT hOldFont = (HFONT) SelectObject(hDrawDC, hDrawFont);
CString strText = _T("TODO: implement thumbnail drawing here");
DrawText(hDrawDC, strText, strText.GetLength(), lprcBounds, DT_CENTER | DT_WORDBREAK);
SelectObject(hDrawDC, hDrawFont);
SelectObject(hDrawDC, hOldFont);
DeleteObject(hDrawBrush);
DeleteObject(hDrawFont);
}
PreviewHandler.h(已更改,由预览调用)
// CPreviewCtrl implementation
class CPreviewCtrl : public CAtlPreviewCtrlImpl
{
protected:
virtual void DoPaint(HDC hdc)
{
// you can obtain a pointer to IDocument as follows
// CMyDoc* pDoc = (CMyDoc*)m_pDocument;
/*
CString strData = _T("Draw Rich Preview content here.");
TextOut(hdc, 10, 20, strData, strData.GetLength());
*/
RECT rc{};
rc.right = 290;
rc.bottom = 290;
dynamic_cast<document*>(m_pDocument)->OnDrawThumbnail(hdc, &rc);
}
};
atlhandlerimpl.h(未更改,来自 VS SDK \atlmfc\include\ 称为缩略图提供程序)
ATLPREFAST_SUPPRESS(6101)
_Success_(return != FALSE) BOOL GetThumbnail(
_In_ UINT cx,
_Out_ HBITMAP* phbmp,
_Out_ WTS_ALPHATYPE* /* pdwAlpha */)
{
HDC hdc = ::GetDC(NULL);
RECT rcBounds;
SetRect(&rcBounds, 0, 0, cx, cx);
HDC hDrawDC = CreateCompatibleDC(hdc);
if (hDrawDC == NULL)
{
ReleaseDC(NULL, hdc);
return FALSE;
}
HBITMAP hBmp = CreateCompatibleBitmap(hDrawDC, cx, cx);
if (hBmp == NULL)
{
ReleaseDC(NULL, hdc);
DeleteDC(hDrawDC);
return FALSE;
}
HBITMAP hOldBitmap = (HBITMAP) SelectObject(hDrawDC, hBmp);
// Here you need to draw the document's data
OnDrawThumbnail(hDrawDC, &rcBounds);
SelectObject(hDrawDC, hOldBitmap);
DeleteDC(hDrawDC);
ReleaseDC(NULL, hdc);
*phbmp = hBmp;
return TRUE;
}
ATLPREFAST_UNSUPPRESS()
Sample thumbnail in the File Explorer
Github 帮助了我。这绝对是一个 ATL SDK 错误。
BUG report on the VS developer community
Solution on the www.patthoyts.tk
And the github repo which helped me: abhimanyusirohi/ThumbFish
在atlhandlerimpl.h
中提供的GetThumbnail
必须被覆盖:
BOOL document::GetThumbnail(
_In_ UINT cx,
_Out_ HBITMAP * phbmp,
_Out_ WTS_ALPHATYPE* /* pdwAlpha */)
{
BOOL br = FALSE;
HDC hdc = ::GetDC(NULL);
HDC hDrawDC = CreateCompatibleDC(hdc);
if (hDrawDC != NULL)
{
void* bits = 0;
RECT rcBounds;
SetRect(&rcBounds, 0, 0, cx, cx);
BITMAPINFO bi = { 0 };
bi.bmiHeader.biWidth = cx;
bi.bmiHeader.biHeight = cx;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biSizeImage = 0;
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biClrUsed = 0;
bi.bmiHeader.biClrImportant = 0;
HBITMAP hBmp = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, &bits, NULL, 0);
if (hBmp != NULL)
{
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hDrawDC, hBmp);
OnDrawThumbnail(hDrawDC, &rcBounds);
SelectObject(hDrawDC, hOldBitmap);
*phbmp = hBmp;
br = TRUE;
}
DeleteDC(hDrawDC);
}
ReleaseDC(NULL, hdc);
return br;
}
我正在处理一个 C++ ATL COM thumbnail/preview/search 项目,但它的位图显示代码行为在缩略图过程中是单色的,而不是彩色的。使用相同的功能,预览过程按预期着色。
我使用 ATL 向导创建了 IThumbnailProvider
和他的朋友们。我的小改动是:我将 document::OnDrawThumbnail
中的颜色从黑色替换为粉红色,并将 document::OnDrawThumbnail 写入 CPreviewCtrl::DoPaint
。我已经阅读了 MS 规范中的“新 DC 始终是单色”的内容,但即使更改了原始 ATL 代码 OnDrawThumbnail(GetDC(NULL), &rcBounds);
,我也无法获得彩色 DC。 CreateCompatibleDC(NULL)
和 CreateCompatibleDC(hDrawDC)
也是死胡同。
document.cpp(已更改)
// Almost the default sample code, but hDrawBrush is changed to pink
void document::OnDrawThumbnail(HDC hDrawDC, LPRECT lprcBounds)
{
HBRUSH hDrawBrush = CreateSolidBrush(RGB(255, 0, 255)); // pink
FillRect(hDrawDC, lprcBounds, hDrawBrush);
HFONT hStockFont = (HFONT) GetStockObject(DEFAULT_GUI_FONT);
LOGFONT lf;
GetObject(hStockFont, sizeof(LOGFONT), &lf);
lf.lfHeight = 34;
HFONT hDrawFont = CreateFontIndirect(&lf);
HFONT hOldFont = (HFONT) SelectObject(hDrawDC, hDrawFont);
CString strText = _T("TODO: implement thumbnail drawing here");
DrawText(hDrawDC, strText, strText.GetLength(), lprcBounds, DT_CENTER | DT_WORDBREAK);
SelectObject(hDrawDC, hDrawFont);
SelectObject(hDrawDC, hOldFont);
DeleteObject(hDrawBrush);
DeleteObject(hDrawFont);
}
PreviewHandler.h(已更改,由预览调用)
// CPreviewCtrl implementation
class CPreviewCtrl : public CAtlPreviewCtrlImpl
{
protected:
virtual void DoPaint(HDC hdc)
{
// you can obtain a pointer to IDocument as follows
// CMyDoc* pDoc = (CMyDoc*)m_pDocument;
/*
CString strData = _T("Draw Rich Preview content here.");
TextOut(hdc, 10, 20, strData, strData.GetLength());
*/
RECT rc{};
rc.right = 290;
rc.bottom = 290;
dynamic_cast<document*>(m_pDocument)->OnDrawThumbnail(hdc, &rc);
}
};
atlhandlerimpl.h(未更改,来自 VS SDK \atlmfc\include\ 称为缩略图提供程序)
ATLPREFAST_SUPPRESS(6101)
_Success_(return != FALSE) BOOL GetThumbnail(
_In_ UINT cx,
_Out_ HBITMAP* phbmp,
_Out_ WTS_ALPHATYPE* /* pdwAlpha */)
{
HDC hdc = ::GetDC(NULL);
RECT rcBounds;
SetRect(&rcBounds, 0, 0, cx, cx);
HDC hDrawDC = CreateCompatibleDC(hdc);
if (hDrawDC == NULL)
{
ReleaseDC(NULL, hdc);
return FALSE;
}
HBITMAP hBmp = CreateCompatibleBitmap(hDrawDC, cx, cx);
if (hBmp == NULL)
{
ReleaseDC(NULL, hdc);
DeleteDC(hDrawDC);
return FALSE;
}
HBITMAP hOldBitmap = (HBITMAP) SelectObject(hDrawDC, hBmp);
// Here you need to draw the document's data
OnDrawThumbnail(hDrawDC, &rcBounds);
SelectObject(hDrawDC, hOldBitmap);
DeleteDC(hDrawDC);
ReleaseDC(NULL, hdc);
*phbmp = hBmp;
return TRUE;
}
ATLPREFAST_UNSUPPRESS()
Sample thumbnail in the File Explorer
Github 帮助了我。这绝对是一个 ATL SDK 错误。
BUG report on the VS developer community
Solution on the www.patthoyts.tk
And the github repo which helped me: abhimanyusirohi/ThumbFish
在atlhandlerimpl.h
中提供的GetThumbnail
必须被覆盖:
BOOL document::GetThumbnail(
_In_ UINT cx,
_Out_ HBITMAP * phbmp,
_Out_ WTS_ALPHATYPE* /* pdwAlpha */)
{
BOOL br = FALSE;
HDC hdc = ::GetDC(NULL);
HDC hDrawDC = CreateCompatibleDC(hdc);
if (hDrawDC != NULL)
{
void* bits = 0;
RECT rcBounds;
SetRect(&rcBounds, 0, 0, cx, cx);
BITMAPINFO bi = { 0 };
bi.bmiHeader.biWidth = cx;
bi.bmiHeader.biHeight = cx;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biSizeImage = 0;
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biClrUsed = 0;
bi.bmiHeader.biClrImportant = 0;
HBITMAP hBmp = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, &bits, NULL, 0);
if (hBmp != NULL)
{
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hDrawDC, hBmp);
OnDrawThumbnail(hDrawDC, &rcBounds);
SelectObject(hDrawDC, hOldBitmap);
*phbmp = hBmp;
br = TRUE;
}
DeleteDC(hDrawDC);
}
ReleaseDC(NULL, hdc);
return br;
}