트리컨트롤의 글자색을 마음대로 바꾸기
페이지 정보
본문
common control이 4.7 이상이 되면서 NM_CUSTOMDRAW라는 메시지가 생겼습니다.
공통 컨트롤들은 각 아이템을 그리기 전에 이 메시지를 부모 윈도우에 보내줘서 직접 그릴 수 있는 기회를 줍니다.
가장 쉽게 사용할 수 있는 예가 트리 컨트롤에서 글자의 색을 바꾸는 것입니다.
(리스트 컨트롤이나 NM_CUSTOMDRAW를 보내는 다른 컨트롤들이 다 비슷한 방법을 사용하면 됩니다.)
일단 소스를 보죠. 제 경우에는 CTreeCtrl을 계승해서 새로운 트리 컨트롤을 만들고 notify 메시지가 reflect되는 걸 받아서 처리했습니다.
XXXTreeCtrl.h
class CXXXTreeCtrl
{
...
//}}AFX_MSG
afx_msg void OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult);
....
};
XXXTreeCtrl.cpp
...
BEGIN_MESSAGE_MAP(CXXXTreeCtrl, CBaseTree)
//{{AFX_MSG_MAP(CNewsTree)
...
//}}AFX_MSG_MAP
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
...
END_MESSAGE_MAP()
...
void CNewsTree::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult) {
NMTVCUSTOMDRAW* pcd = (NMTVCUSTOMDRAW*)pNMHDR;
HTREEITEM hItem;
switch ( pcd->nmcd.dwDrawStage ) {
case CDDS_PREPAINT:
*pResult = CDRF_NOTIFYITEMDRAW;
break;
case CDDS_ITEMPREPAINT :
hItem = (HTREEITEM)pcd->nmcd.dwItemSpec;
if (hItem에 따른 적당한 조건) {
pcd->clrText = RGB(0, 0, 204);
pcd->clrTextBk = RGB(255, 255, 255);
} else {
...
}
*pResult = CDRF_DODEFAULT;// do not set *pResult = CDRF_SKIPDEFAULT
break;
}
}
1. CDDS_PREPAINT가 오면 진짜로 아이템 그리기 전에 알켜줘라는 플랙을 설정합니다.
2. CDDS_ITEMPREPAINT가 오면 해당 아이템의 HTREEITEM 핸들을 얻어서 원하는 색으로 설정해줍니다.
참고로 말씀드리자면...
1. 위의 예처럼 하면 배경색을 바꿀 수 있지만 fullrow select일 경우가 아니면 그다지입니다... -_-;
2. 그리고 pcd->iLevel 값은 각 트리의 차수를 표시합니다. 0이면 루트 노드와 그 형제노드, 1이면 0인 노드들의 자식 노드들... 등등.
3. 폰트를 바꾸는 것도 가능합니다. 아이콘을 안그리게 할 수도 있습니다. CDDS_ITEMPREPAINT의 결과를 바꾸면 됩니다. 자세한 내용은 MSDN을 보세요...
4. 참고로 글씨를 굵게 하는 정도만 필요하다면
CTreeCtrl::SetItemState(hItem, TVIS_BOLD, TVIS_BOLD); 으로도 가능합니다.
5. 그러나 OE5처럼 일부만 굵게하고 색도 두가지이상으로 하려면 NM_CUSTOMDRAW에서 다 그려줘야 할겁니다. 아마도...
공통 컨트롤들은 각 아이템을 그리기 전에 이 메시지를 부모 윈도우에 보내줘서 직접 그릴 수 있는 기회를 줍니다.
가장 쉽게 사용할 수 있는 예가 트리 컨트롤에서 글자의 색을 바꾸는 것입니다.
(리스트 컨트롤이나 NM_CUSTOMDRAW를 보내는 다른 컨트롤들이 다 비슷한 방법을 사용하면 됩니다.)
일단 소스를 보죠. 제 경우에는 CTreeCtrl을 계승해서 새로운 트리 컨트롤을 만들고 notify 메시지가 reflect되는 걸 받아서 처리했습니다.
XXXTreeCtrl.h
class CXXXTreeCtrl
{
...
//}}AFX_MSG
afx_msg void OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult);
....
};
XXXTreeCtrl.cpp
...
BEGIN_MESSAGE_MAP(CXXXTreeCtrl, CBaseTree)
//{{AFX_MSG_MAP(CNewsTree)
...
//}}AFX_MSG_MAP
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
...
END_MESSAGE_MAP()
...
void CNewsTree::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult) {
NMTVCUSTOMDRAW* pcd = (NMTVCUSTOMDRAW*)pNMHDR;
HTREEITEM hItem;
switch ( pcd->nmcd.dwDrawStage ) {
case CDDS_PREPAINT:
*pResult = CDRF_NOTIFYITEMDRAW;
break;
case CDDS_ITEMPREPAINT :
hItem = (HTREEITEM)pcd->nmcd.dwItemSpec;
if (hItem에 따른 적당한 조건) {
pcd->clrText = RGB(0, 0, 204);
pcd->clrTextBk = RGB(255, 255, 255);
} else {
...
}
*pResult = CDRF_DODEFAULT;// do not set *pResult = CDRF_SKIPDEFAULT
break;
}
}
1. CDDS_PREPAINT가 오면 진짜로 아이템 그리기 전에 알켜줘라는 플랙을 설정합니다.
2. CDDS_ITEMPREPAINT가 오면 해당 아이템의 HTREEITEM 핸들을 얻어서 원하는 색으로 설정해줍니다.
참고로 말씀드리자면...
1. 위의 예처럼 하면 배경색을 바꿀 수 있지만 fullrow select일 경우가 아니면 그다지입니다... -_-;
2. 그리고 pcd->iLevel 값은 각 트리의 차수를 표시합니다. 0이면 루트 노드와 그 형제노드, 1이면 0인 노드들의 자식 노드들... 등등.
3. 폰트를 바꾸는 것도 가능합니다. 아이콘을 안그리게 할 수도 있습니다. CDDS_ITEMPREPAINT의 결과를 바꾸면 됩니다. 자세한 내용은 MSDN을 보세요...
4. 참고로 글씨를 굵게 하는 정도만 필요하다면
CTreeCtrl::SetItemState(hItem, TVIS_BOLD, TVIS_BOLD); 으로도 가능합니다.
5. 그러나 OE5처럼 일부만 굵게하고 색도 두가지이상으로 하려면 NM_CUSTOMDRAW에서 다 그려줘야 할겁니다. 아마도...
댓글목록
등록된 댓글이 없습니다.