win32 Api Listctrl 添加样式LVS_OWNERDRAWFIXED 不显示复选框

玉生香 2021-08-10 18:57:01

不是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;
}

 

...全文
474 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
zgl7903 2021-08-11
  • 打赏
  • 举报
回复

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;

}

zgl7903 2021-08-10
  • 打赏
  • 举报
回复

自绘 就得自己绘制
DrawText 前可以用 DrawFrameControl 绘制复选框 DFC_BUTTON, DFCS_BUTTONCHECK

玉生香 2021-08-11
  • 举报
回复
@zgl7903 能否给出一小段代码,含单选功能的

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧