본문 바로가기
컴퓨터/MFC_API

CListCtrl의 Report 형식에서 각 Cell 의 배경과 글자색을 변경하기

by adnoctum 2016. 1. 4.




   CListCtrl 을 report 형식으로 하면 grid 처럼 사용할 수 있다. 이 때, 각 Cell 의 배경색과 글자색을 변경할 수 있으면 좀 더 알아 보기 좋게 표현할 수 있다. 아래 설명할 코드의 실제 결과는 다음과 같다.






기본적으로 CUSTOMDRAW 메세지 핸들러를 작성해 주면 되는데, MSDN 에 그 설명이 약간은 모호하게 나와 있는데, 자세히 풀어 보자면 다음과 같다. 



환경 : Visual Studio 2010 on Windows 7  Professional SP1, English, 64-bit. 



ITEM 이나 subitem 이 그려질 때는 CUSTOMDRAW 구조체의 값 중 dwDrawStage 값이 CDDS_ITEMPREPAINT, 또는 CDDS_SUBITEM | CDDS_ITEMPREPAINT 값으로 설정이 된 후 custom draw message 가 호출이 된다. 따라서 이 값을 확인해서 작업을 하면 된다. 또한, 결과 중 LRESULT *pResult 값이 있는데, 만약 배경색이나 글자색 등 font 를 변경했을 때는 이 값에 그것을 알려 주는 값을 반환해 주어야 한다. 실제 코드를 보면 다음과 같다.



void CNormStateMonitorDlg::OnNMCustomdrawLstDir(NMHDR *pNMHDRLRESULT *pResult) { LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR); // TODO: Add your control notification handler code here if(pNMCD->dwDrawStage == CDDS_PREPAINT){ *pResult = (LRESULT)CDRF_NOTIFYITEMDRAWreturn; // 여기서 함수를 빠져 나가야 *pResult 값이 유지된다. } if(pNMCD->dwDrawStage == CDDS_ITEMPREPAINT){ 

// 한 줄 (row) 가 그려질 때. 여기서만 설정하면 한 줄이 모두 동일하게 설정이 된다. if(_lstDir.GetItemData(pNMCD->dwItemSpec) == 0){//dwItemSpec 이 현재 그려지는 row index NMLVCUSTOMDRAW *pDraw = (NMLVCUSTOMDRAW*)(pNMHDR);    pDraw->clrText = 0xffffff;  pDraw->clrTextBk = 0x0//*pResult = (LRESULT)CDRF_NEWFONT;//여기서 나가면 sub-item 이 변경되지 않는다. *pResult = (LRESULT)CDRF_NOTIFYSUBITEMDRAW;//sub-item 을 변경하기 위해서.  return;//여기서 중단해야 *pResult 값이 유지된다. } else// When all matrices are already made.  NMLVCUSTOMDRAW *pDraw = (NMLVCUSTOMDRAW*)(pNMHDR);    pDraw->clrText = 0x0;  pDraw->clrTextBk = RGB(255,255,196);   *pResult = (LRESULT)CDRF_NEWFONTreturn;  } } else if(pNMCD->dwDrawStage == (CDDS_SUBITEM | CDDS_ITEMPREPAINT)){ // sub-item 이 그려지는 순간. 위에서 *pResult 에 CDRF_NOTIFYSUBITEMDRAW 를 해서 여기로

// 올 수 있었던 것이다.

NMLVCUSTOMDRAW *pDraw = (NMLVCUSTOMDRAW*)(pNMHDR);  CString text= _lstDir.GetItemText(pNMCD->dwItemSpec, pDraw->iSubItem);  if(text == _T("x")){   pDraw->clrText = 0xff;  pDraw->clrTextBk = 0xf0fff0;  } else{   pDraw->clrText = 0x0;  pDraw->clrTextBk = 0xffffff;  } *pResult = (LRESULT)CDRF_NEWFONT; // 이렇게 해야 설정한 대로 그려진다. return; } *pResult = 0; }


기본적으로 list control 이 그려질 때 custom draw 가 여러 번 호출이 되고, 각각의 경우 어떠한 것을 그리려는 상황인지가 dwDrawStage 로 넘어 오는 것이다. 또한 dwItemSpec 이 현재 그려지는 row index 이다.