绘制错误的 CListCtrl 项
Wrong CListCtrl items drawing
我的 CListCtrlEx 派生自 CListCtrl。此列表的样式为 LVS_REPORT、LVS_OWNERDRAWFIXED 和 LVS_EX_GRIDLINES。我添加了更改此列表字体的可能性。这工作正常,但有一件坏事 - 如果我更改字体并且在此之前我没有滚动列表,那么所有列表项都会正确重绘,但如果我在字体更改之前完成滚动,那么列表项会重绘一点或低于列表网格水平线,i。 e.项目文本被网格线重叠。
这是我更改列表字体的方法:
LRESULT CListCtrlEx::OnSetFont(WPARAM wParam, LPARAM)
{
LRESULT res = Default();
CRect rc;
GetWindowRect(&rc);
WINDOWPOS wp;
wp.hwnd = m_hWnd;
wp.cx = rc.Width();
wp.cy = rc.Height();
wp.flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER;
SendMessage(WM_WINDOWPOSCHANGED, 0, (LPARAM)&wp);
return res;
}
void CListCtrlEx::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
HDC hDC = ::GetDC(NULL);
CFont* pFont = GetFont();
HFONT hFontOld = (HFONT)SelectObject(hDC, pFont->GetSafeHandle());
CRect rect;
DrawText(hDC, _T(" "), 1, rect, DT_SINGLELINE | DT_CALCRECT);
lpMeasureItemStruct->itemHeight = rect.bottom - rect.top;
SelectObject(hDC, hFontOld);
::ReleaseDC(NULL, hDC);
}
更新:
三个人都点击了 UP 按钮,但没人知道它会是什么? :(
更新 1:
这是 class 代码
http://pastebin.com/UdXYEpF7.h
http://pastebin.com/2HYe5AEd.cpp
我试过你的代码,看起来 ListView 正在与滚动条交换消息,header 也在调整大小,这真的不值得研究。如果你把位置设置为零就好了,你可以保存旧位置并放回去。
void CListCtrlEx::SetupFont(int nSize, const CString& strName)
{
int saveIndex = GetTopIndex();
EnsureVisible(0, 0);
if (m_pFont.get()) m_pFont.get()->DeleteObject();
VERIFY(m_pFont.get()->CreatePointFont(nSize, strName));
SetFont(m_pFont.get());
//This scrolls to bottom, it ensures saveIndex will end up on top
//once the next EnsureVisible is called
if (GetItemCount())
EnsureVisible(GetItemCount() - 1, 1);
EnsureVisible(saveIndex, 1);
}
我的 CListCtrlEx 派生自 CListCtrl。此列表的样式为 LVS_REPORT、LVS_OWNERDRAWFIXED 和 LVS_EX_GRIDLINES。我添加了更改此列表字体的可能性。这工作正常,但有一件坏事 - 如果我更改字体并且在此之前我没有滚动列表,那么所有列表项都会正确重绘,但如果我在字体更改之前完成滚动,那么列表项会重绘一点或低于列表网格水平线,i。 e.项目文本被网格线重叠。
这是我更改列表字体的方法:
LRESULT CListCtrlEx::OnSetFont(WPARAM wParam, LPARAM)
{
LRESULT res = Default();
CRect rc;
GetWindowRect(&rc);
WINDOWPOS wp;
wp.hwnd = m_hWnd;
wp.cx = rc.Width();
wp.cy = rc.Height();
wp.flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER;
SendMessage(WM_WINDOWPOSCHANGED, 0, (LPARAM)&wp);
return res;
}
void CListCtrlEx::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
HDC hDC = ::GetDC(NULL);
CFont* pFont = GetFont();
HFONT hFontOld = (HFONT)SelectObject(hDC, pFont->GetSafeHandle());
CRect rect;
DrawText(hDC, _T(" "), 1, rect, DT_SINGLELINE | DT_CALCRECT);
lpMeasureItemStruct->itemHeight = rect.bottom - rect.top;
SelectObject(hDC, hFontOld);
::ReleaseDC(NULL, hDC);
}
更新: 三个人都点击了 UP 按钮,但没人知道它会是什么? :(
更新 1: 这是 class 代码 http://pastebin.com/UdXYEpF7.h http://pastebin.com/2HYe5AEd.cpp
我试过你的代码,看起来 ListView 正在与滚动条交换消息,header 也在调整大小,这真的不值得研究。如果你把位置设置为零就好了,你可以保存旧位置并放回去。
void CListCtrlEx::SetupFont(int nSize, const CString& strName)
{
int saveIndex = GetTopIndex();
EnsureVisible(0, 0);
if (m_pFont.get()) m_pFont.get()->DeleteObject();
VERIFY(m_pFont.get()->CreatePointFont(nSize, strName));
SetFont(m_pFont.get());
//This scrolls to bottom, it ensures saveIndex will end up on top
//once the next EnsureVisible is called
if (GetItemCount())
EnsureVisible(GetItemCount() - 1, 1);
EnsureVisible(saveIndex, 1);
}