Как реализовать масштабирование списка с помощью Win32 / WTL

Некоторое время назад я реализовал облегченный просмотрщик логов в WTL / C ++. Недавно решили расширить пользовательский интерфейс с возможностью увеличения / уменьшения масштаба. Я добавил деривацию из CZoomScrollImpl, как показано ниже:

class CLogView
: public CWindowImpl<CLogView, CListViewCtrl>
, public CZoomScrollImpl<CLogView>
, public CCustomDraw<CLogView>
{
CLogReader m_logReader;

public:
DECLARE_WND_SUPERCLASS(_T("ZoomWTL"), CListViewCtrl::GetWndClassName())

CLogView(){}

BOOL PreTranslateMessage(MSG* /*pMsg*/){return FALSE;}

BEGIN_MSG_MAP(CLogView)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel)
CHAIN_MSG_MAP_ALT(CCustomDraw<CLogView>, 1)
CHAIN_MSG_MAP(CZoomScrollImpl<CLogView>);
END_MSG_MAP()

LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
LRESULT OnMouseWheel(UINT uMsg, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/);

DWORD OnPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/)
{
return CDRF_NOTIFYITEMDRAW;
}

void DoPaint(CDCHandle /*dc*/)
{
/// TODO: Implement!
}

DWORD OnItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw);
LRESULT OnGetdispinfo(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/);
};

И тогда возник вопрос: как сделать просмотр списка? Ранее он был нарисован на заказ, т. Е. Я только указывал текст и цвет для элементов. Как правильно вызывать рендеринг по умолчанию из DoPaint? Или я должен написать весь код рендеринга?

Вот фрагмент файла CPP:

// Columns definitions
LVCOLUMN SQLLOG_COLUMNS[] = {
{ LVCF_FMT|LVCF_WIDTH|LVCF_TEXT, LVCFMT_LEFT, 100, L"Time", -1, 0,0,0 },
{ LVCF_FMT|LVCF_WIDTH|LVCF_TEXT, LVCFMT_LEFT, 140, L"Type", -1, 1,0,0 },
{ LVCF_FMT|LVCF_WIDTH|LVCF_TEXT, LVCFMT_LEFT, 500, L"Message", -1, 2,0,0 },
{ LVCF_FMT|LVCF_WIDTH|LVCF_TEXT, LVCFMT_LEFT, 150, L"Application", -1, 3,0,0 },
};

const int SQLLOG_COLUMNS_CNT = _countof(SQLLOG_COLUMNS);

LRESULT CLogView::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
LRESULT lResult = DefWindowProc(uMsg, wParam, lParam);

ModifyStyle(0, LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | LVS_ALIGNTOP | LVS_OWNERDATA);
SetExtendedListViewStyle(LVS_EX_HEADERDRAGDROP | LVS_EX_FULLROWSELECT /*| LVS_EX_FLATSB | LVS_EX_TRACKSELECT | LVS_EX_GRIDLINES*/);

while (DeleteColumn(0));

int iCol = 0;
for (int i = 0; i < SQLLOG_COLUMNS_CNT; i++)
{
LVCOLUMN lvc(SQLLOG_COLUMNS[i]);
InsertColumn(iCol++, (LVCOLUMN*)&lvc);
}

//?not needed: SetScrollSize(1000, 10000, FALSE, false);

return lResult;
}

LRESULT CLogView::OnGetdispinfo(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
LV_ITEM* pItem = &((LV_DISPINFO*)pnmh)->item;

if (pItem->mask & LVIF_TEXT)
{
const LOG_MESSAGE* msg = m_logReader.GetMessageData(pItem->iItem);
switch (pItem->iSubItem)
{
case 0:
switch (msg->msgType)
{
default:
case 0:
wcscpy(pItem->pszText, L"Normal");
break;
case 1:
wcscpy(pItem->pszText, L"Error");
break;
case 2:
wcscpy(pItem->pszText, L"Notification");
break;
case 3:
wcscpy(pItem->pszText, L"Alert");
break;
case 4:
wcscpy(pItem->pszText, L"Comment");
break;
}
break;
case 1:
{
SYSTEMTIME sysTime, locTime;
FileTimeToSystemTime((FILETIME*)&msg->timestamp, &sysTime);
SystemTimeToTzSpecificLocalTime(NULL, &sysTime, &locTime);
swprintf(pItem->pszText, _CVTBUFSIZE, L"%04d/%02d/%02d %02d:%02d:%02d.%03d", locTime.wYear, locTime.wMonth, locTime.wDay, locTime.wHour, locTime.wMinute, locTime.wSecond, locTime.wMilliseconds);
break;
}
case 2:
wcscpy(pItem->pszText, msg->message);
break;
case 3:
wcscpy(pItem->pszText, msg->source);
break;
}
}

return 0;
}

DWORD CLogView::OnItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw)
{
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(lpNMCustomDraw);

const LOG_MESSAGE* msg = m_logReader.GetMessageData((size_t)pLVCD->nmcd.dwItemSpec);

switch (msg->msgType)
{
default:
case 0: pLVCD->clrTextBk = 0xFFFFFF/*White*/; break;
case 1: pLVCD->clrTextBk = 0x0045FF/*OrangeRed*/; break;
case 2: pLVCD->clrTextBk = 0xFFFF00/*Cyan*/; break;
case 3: pLVCD->clrTextBk = 0x00FFFF/*Yellow*/; break;
case 4: pLVCD->clrTextBk = 0xD3D3D3/*LightGray*/; break;
}

// Tell Windows to paint the control itself.
return CDRF_DODEFAULT;
}

// Returns TRUE if number of messages changed in the ListView; otherwise - FALSE.
BOOL CLogView::ShowMessages()
{
BOOL msgCountChanged = FALSE;

size_t numMessages = m_logReader.GetNumMessages();
if (m_numMessages == numMessages)
{   // number of messages haven't changed - nothing to do.
return FALSE;
}

if (numMessages == 0)
{   // messages were cleared
m_numMessages = 0;
DeleteAllItems();
return TRUE;
}

int nItemLast = GetItemCount() + numMessages - m_numMessages;
SetItemCountEx(nItemLast, LVSICF_NOINVALIDATEALL | LVSICF_NOSCROLL);

m_numMessages = numMessages;

if (nItemLast > 0)
EnsureVisible(nItemLast-1, FALSE);

return TRUE;
}

LRESULT CLogView::OnMouseWheel(UINT uMsg, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
{
if (MK_CONTROL & wParam)
{
int zDelta = (int)GET_WHEEL_DELTA_WPARAM(wParam);
float scale = this->GetZoomScale();
if (zDelta < 0)
scale *= 0.91f;
else
scale *= 1.1f;

this->Zoom(0, 0, scale);

return 0;
}

bHandled = FALSE;
return 1;
}

0

Решение

Ответ пришел неожиданно от родственника, который не является программистом. Она сказала мне, чтобы изменить шрифт listview !!! Просто и легко … почему я не задумывался об этом с самого начала?

1

Другие решения


По вопросам рекламы [email protected]