16,471
社区成员
不是MFC。Win32Api 编程。
直接上代码,代码上带注释
//如果支持LVS_OWNERDRAWFIXED 则不见了复选框,去掉则收不到WM_MEASUREITEM 消息。
//请教大神们,这个如何拯救
BOOL CTaskDialog::OnInitListCrtl(HWND hwnd)
{
HWND taskhwnd = GetDlgItem(hwnd, IDC_LIST_TASK);
//这里添加复选框 LVS_EX_CHECKBOXES
ListView_SetExtendedListViewStyle(taskhwnd, LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES | LVS_EX_GRIDLINES| LVS_EX_HEADERDRAGDROP| LVS_EX_BORDERSELECT);
LVCOLUMN lvcolum;
lvcolum.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_FMT | LVCF_SUBITEM;
lvcolum.fmt = LVCFMT_CENTER |LVCFMT_LEFT;
RECT rect;
int cols = (sizeof(taskhead) / sizeof(TCHAR)) / (sizeof(taskhead[0]) / sizeof(TCHAR));
GetClientRect(hwnd, &rect);
int vlen = (rect.right - rect.left) / (cols-1);
int llen = vlen + (rect.right - rect.left) % (cols - 1);
int halfflen = vlen * 2/3;
int halfslen = vlen - halfflen;
int idx = 0;
lvcolum.cx = 0;
lvcolum.pszText = taskhead[idx];
lvcolum.iSubItem = idx;
ListView_InsertColumn(taskhwnd, idx++, &lvcolum); //将idx=0,插入后,再将idx +1
lvcolum.cx = vlen + 2* halfslen;
lvcolum.pszText = taskhead[idx];
lvcolum.iSubItem = idx;
ListView_InsertColumn(taskhwnd, idx++, &lvcolum); //将idx=0,插入后,再将idx +1
for (; idx < cols-1; ++idx)
{
lvcolum.cx = halfflen;
lvcolum.pszText = taskhead[idx];
lvcolum.iSubItem = idx;
ListView_InsertColumn(taskhwnd, idx, &lvcolum);
}
lvcolum.cx = llen + 2* halfslen;
lvcolum.pszText = taskhead[idx];
lvcolum.iSubItem = idx;
ListView_InsertColumn(taskhwnd, idx, &lvcolum);
SendMessage(taskhwnd, LVM_DELETECOLUMN, WPARAM(0), 0);
std::map<wcomm::charstring, Task> vmap = CTaskManger::Instance()->gettasktab();
std::map<wcomm::charstring, Task>::iterator iter = vmap.begin();
cols = cols - 1;//删除首列
for (; iter != vmap.end(); ++iter)
{
int irow = ListView_GetItemCount(taskhwnd);
AddListCtrlRow(taskhwnd, irow, iter->second.vec);
}
return FALSE;
}
BOOL CALLBACK CTaskDialog::DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CTaskDialog *_this = (CTaskDialog *)GetWindowLong(hwnd, GWL_USERDATA);
switch (uMsg)
{
case WM_INITDIALOG:
{
//SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
//_this->SetCenter(hwnd);
SetWindowLong(hwnd, GWL_USERDATA, lParam);
_this = (CTaskDialog *)(lParam);
_this->m_bShow = TRUE;
_this->SetCenter(hwnd);
_this->OnInitListCrtl(hwnd);
}
break;
case WM_MEASUREITEM://ODT_LISTBOX
if ((UINT)wParam == IDC_LIST_TASK)
{
LPMEASUREITEMSTRUCT lpmis = (LPMEASUREITEMSTRUCT)lParam;
lpmis->itemHeight = abs(m_nFontHeight1 - 10);
}
break;
case WM_DRAWITEM:
if ((UINT)wParam == IDC_LIST_TASK)
{
HWND hList;
HDC hdc;
RECT rt;
LVCOLUMN LvColumn;
int SubItemNum;
int SubItem;
char Text[4096] = { 0 };
LPDRAWITEMSTRUCT lpDraw = (LPDRAWITEMSTRUCT)lParam;
hList = lpDraw->hwndItem;
hdc = lpDraw->hDC;
SaveDC(hdc);
SetTextColor(hdc, RGB(0, 0, 0));
SelectObject(hdc, m_HFont1);
ZeroMemory(&LvColumn, sizeof(LvColumn));
LvColumn.mask = LVCF_FMT;
SubItemNum = Header_GetItemCount(ListView_GetHeader(hList)) - 1;
for (SubItem = 0; SubItem <= SubItemNum; SubItem++) {
ListView_GetSubItemRect(hList, lpDraw->itemID, SubItem, LVIR_BOUNDS, &rt);
ListView_GetColumn(hList, SubItem, &LvColumn);
ListView_GetSubItemRect(hList, lpDraw->itemID, SubItem, LVIR_LABEL, &rt);
ListView_GetItemText(hList, lpDraw->itemID, SubItem, Text, sizeof(Text));
DrawText(hdc, Text, -1, &rt, DT_VCENTER | DT_CENTER | DT_SINGLELINE);
}
RestoreDC(hdc, -1);
}
break;
case WM_NOTIFY:
{
switch (((LPNMHDR)lParam)->code)
{
case LVN_ITEMCHANGED:
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(lParam);
if ((pNMLV->uChanged & LVIF_STATE) && (pNMLV->uNewState & 0x2000) && (pNMLV->uOldState & 0x1000))
{
HWND taskhwnd = GetDlgItem(hwnd, IDC_LIST_TASK);
int count = ListView_GetItemCount(taskhwnd);
for (int nItem = 0; nItem < count; nItem++)
if (nItem != pNMLV->iItem)
{
ListView_SetCheckState(taskhwnd, nItem, FALSE);
}
}
}
break;
case NM_CUSTOMDRAW:
{
WORD wItem = LOWORD(wParam);
if (wItem == IDC_LIST_TASK)
{
LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam;
int result = CDRF_DODEFAULT;
switch (lplvcd->nmcd.dwDrawStage)
{
case CDDS_PREPAINT:
result = CDRF_NOTIFYITEMDRAW;
break;
case CDDS_ITEMPREPAINT:
lplvcd->clrTextBk = RGB(240, 240, 240);
result = CDRF_NEWFONT;
break;
}
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, result);
return TRUE;
}
}
break;
}
}
break;
case WM_PAINT:
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDCANCEL:
_this->m_bShow = FALSE;
EndDialog(hwnd, IDCANCEL);
break;
case IDC_BUTTON_TASKADD:
{
time_t time = std::time(0);
std::vector < wcomm::charstring> vec;
CTaskManger::Instance()->getruntask(time, vec);
_this->showEditFram(hwnd, 0);
}
break;
case IDC_BUTTON_TASKUPD:
{
HWND listctrl = GetDlgItem(hwnd, IDC_LIST_TASK);
if (_this->selectedrow(listctrl) != INVALIDROW)
{
_this->showEditFram(hwnd, 1);
}
}
break;
case IDC_BUTTON_TASKDEL:
{
HWND listctrl = GetDlgItem(hwnd, IDC_LIST_TASK);
size_t row = _this->selectedrow(listctrl);
if (row != INVALIDROW)
{
char buffer[256] = { 0 };
HWND listctrl = GetDlgItem(hwnd, IDC_LIST_TASK);
ListView_GetItemText(listctrl, row, 0, buffer, 256);
wcomm::charstring strtip;
strtip.Format("确定删除 %s", buffer);
if (MessageBox(hwnd, strtip, "删除提示", MB_YESNO)==IDYES)
{
ListView_DeleteItem(listctrl, row);
CTaskManger::Instance()->deletetask(buffer);
}
}
}
break;
case IDC_BUTTON_TASKEXEC:
{
HWND listctrl = GetDlgItem(hwnd, IDC_LIST_TASK);
size_t row = _this->selectedrow(listctrl);
if (row != INVALIDROW)
{
if (!wcomm::CTaskInterruptManager::Instance()->IsHotSignal())
{
char buffer[256] = { 0 };
ListView_GetItemText(listctrl, row, 3, buffer, 256); //任务状态
if (taskstate::instance()->getindex(buffer) == 0)
{
MessageBox(hwnd, "不能执行处于停用状态任务", "温馨提示", 0);
}
else
{
std::vector<wcomm::charstring> vec;
ListView_GetItemText(listctrl, row, 0, buffer, 256); //任务名称
vec.push_back(buffer);
ListView_GetItemText(listctrl, row, 1, buffer, 256); //任务类型
vec.push_back(buffer);
ListView_GetItemText(listctrl, row, 2, buffer, 256); //任务优先级
vec.push_back(wcomm::charstring().Format("%d", tasklevel::instance()->getindex(buffer)));
ListView_GetItemText(listctrl, row, 3, buffer, 256); //任务状态
vec.push_back(wcomm::charstring().Format("%d", taskstate::instance()->getindex(buffer)));
ListView_GetItemText(listctrl, row, 4, buffer, 256); //任务日志
vec.push_back(wcomm::charstring().Format("%d", logstate::instance()->getindex(buffer)));
vec.push_back("手工执行");
SimuData data;
SetSimData(vec, &data);
PushWatiQueue(data);
}
}
else
{
MessageBox(hwnd, "值守已暂停,不执行任何任务", "温馨提示", 0);
}
}
else
{
MessageBox(hwnd, "选择要执行的任务", "温馨提示", 0);
}
}
break;
}
break;
}
return FALSE;
}
HWND m_hListCtrl = NULL;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case(WM_CREATE):
{
RECT rcRect;
GetClientRect(hWnd, &rcRect);
m_hListCtrl = CreateWindowW(WC_LISTVIEWW, L"TestList",
0 | WS_CHILD|WS_VISIBLE
| LVS_REPORT|LVS_SINGLESEL
| LVS_OWNERDRAWFIXED
| 0,
0, 0, rcRect.right - rcRect.left, rcRect.bottom - rcRect.top,
hWnd, (HMENU)0x1000, hInst, NULL);
_ASSERT(m_hListCtrl != NULL);
if(m_hListCtrl != NULL)
{
//修改扩展风格
{
DWORD dwStyleEx = ListView_GetExtendedListViewStyle(m_hListCtrl);
dwStyleEx |= LVS_EX_CHECKBOXES | LVS_EX_GRIDLINES;
ListView_SetExtendedListViewStyle(m_hListCtrl, dwStyleEx);
}
//No.
{
LVCOLUMNW lvCol = {0};
lvCol.mask = LVCF_WIDTH|LVCF_TEXT;
lvCol.cx = 100;
lvCol.pszText = L"No.";
ListView_InsertColumn(m_hListCtrl, 0, &lvCol);
}
//Col1
{
LVCOLUMNW lvCol = {0};
lvCol.mask = LVCF_WIDTH|LVCF_TEXT;
lvCol.cx = 260;
lvCol.pszText = L"Col1";
ListView_InsertColumn(m_hListCtrl, 1, &lvCol);
}
//添加行
for(int iRow=0; iRow<10; iRow++)
{
LV_ITEMW vItem = {0};
vItem.mask = LVIF_TEXT;
vItem.iItem = iRow;
vItem.pszText = L"";
int n = ListView_InsertItem(m_hListCtrl, &vItem);
_ASSERT(n == iRow);
for(int iCol=0; iCol<2; iCol++)
{
WCHAR wChBuff[64];
swprintf_s(wChBuff, L"C%dR%d", iCol, iRow);
ListView_SetItemText(m_hListCtrl, iRow, iCol, wChBuff);
}
}
ListView_SetCheckState(m_hListCtrl, 5, TRUE);
}
break;
}
case(WM_NOTIFY):
{
int nCtrlID = (int)wParam;
NMHDR *pNmhdr = (NMHDR *)lParam;
if(pNmhdr->hwndFrom == m_hListCtrl)
{
//处理单击消息
if(pNmhdr->code == NM_CLICK)
{
NMLISTVIEW phdr = (NMLISTVIEW)pNmhdr;
int iItem = phdr->iItem;
if(phdr->iSubItem == 0)
{
BOOL bChk = ListView_GetCheckState(m_hListCtrl, iItem);
ListView_SetCheckState(m_hListCtrl, iItem, !bChk);
}
}
}
return 0;
break;
}
case(WM_DRAWITEM):
{
int nCtrlID = (int)wParam;
DRAWITEMSTRUCT *lpDrawItemStruct = (DRAWITEMSTRUCT *)lParam;
if(lpDrawItemStruct && lpDrawItemStruct->hwndItem == m_hListCtrl)
{
int nItem = lpDrawItemStruct->itemID;
HDC hDC = lpDrawItemStruct->hDC;
RECT rcItem = lpDrawItemStruct->rcItem;
UINT uState = lpDrawItemStruct->itemState;
//填充背景色
HBRUSH hbr = CreateSolidBrush((uState&ODS_FOCUS)? /*选中状态*/
RGB(100,100,200) : RGB(220, 220, 220) );
FillRect(hDC, &rcItem, hbr);
DeleteObject(hbr);
//绘制复选框
if(ListView_GetExtendedListViewStyle(m_hListCtrl) & LVS_EX_CHECKBOXES)
{
RECT rcBox;
rcBox.left = rcItem.left + 2;
rcBox.top = rcItem.top + 2;
rcBox.bottom = rcItem.bottom -2;
rcBox.right = rcBox.left + (rcBox.bottom - rcBox.top);
BOOL bChked = ListView_GetCheckState(m_hListCtrl, nItem);
DrawFrameControl(hDC, &rcBox, DFC_BUTTON,
DFCS_BUTTONCHECK | (bChked? DFCS_CHECKED:0));
}
}
break;
}
case WM_DESTROY:
{
if(m_hListCtrl != NULL)
{
DestroyWindow(m_hListCtrl);
m_hListCtrl = NULL;
}
PostQuitMessage(0);
break;
}
case WM_COMMAND:
{
UINT wmId = LOWORD(wParam);
UINT wmEvent = HIWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
}
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意绘图代码...
EndPaint(hWnd, &ps);
break;
}
default:
{
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
return 0;
}
自绘 就得自己绘制
DrawText 前可以用 DrawFrameControl 绘制复选框 DFC_BUTTON, DFCS_BUTTONCHECK