重绘LIST问题,真怪!三天了麻烦帮忙。

cici2006 2006-10-23 10:06:06
我直接用SDK(非MFC)的方式创建的LIST-VIEW控件,并在父窗口响应通知消息,能实现背景与字体色彩
改变,可不知为什么,LIST中的其它ITEM都能选择,就是第二个ITEM不能选择,所以
GetItemState(1, LVIS_SELECTED)//的时候就是返回FALSE,我直接用代码去选择第二个ITEM也不行。
怎么会这样呢?大家帮助我呀。几天了。
----------------------------------------------------------------------
case WM_NOTIFY :
{
DWORD nID = (DWORD)wParam;
if(nID == ID_LISTVIEW)
{
LRESULT lResult = S_FALSE;
NMHDR* pNMHDR = (NMHDR*)lParam;
DWORD nCode = pNMHDR->code;
m_pListCtrl->OnCustomDraw((NMHDR*)lParam, &lResult);
}
return lResult;
}

void CListCtrl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
*pResult = CDRF_DODEFAULT;
if (pLVCD->nmcd.dwDrawStage == CDDS_PREPAINT)
{
*pResult = CDRF_NOTIFYITEMDRAW;
}
else if (pLVCD->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
{
*pResult = CDRF_NOTIFYSUBITEMDRAW;
}
else if (pLVCD->nmcd.dwDrawStage == (CDDS_ITEMPREPAINT | CDDS_SUBITEM))
{
int nItem = static_cast<int> (pLVCD->nmcd.dwItemSpec);
int nSubItem = pLVCD->iSubItem;
CDC dc ;
dc.Attach(pLVCD->nmcd.hdc);
CRect rect;
COLORREF crText, crBkgnd;
GetSubItemRect(nItem, nSubItem, LVIR_BOUNDS, rect);
if (GetItemState(nItem, LVIS_SELECTED)) //选择
{
crText = m_crTextSelect;
crBkgnd = m_crTextSelectBack;
}
else
{
if(nItem == m_nCurItem)
{
crText = m_crTextCur;
}
else
crText = m_crTextNormal;
crBkgnd = nItem % 2 ? m_crTextNormalBack_0 :m_crTextNormalBack_1;
}
pLVCD->clrText = crText;
pLVCD->clrTextBk = crBkgnd;
*pResult = CDRF_DODEFAULT;
DrawText(nItem, nSubItem, &dc, crText, crBkgnd, rect);
dc.Detach();
*pResult = CDRF_SKIPDEFAULT;
}
}
...全文
258 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
hxzmm 2006-10-30
  • 打赏
  • 举报
回复
你的这个代码看不出任何问题!!!
除非你把源程序发过来看一下!!
cici2006 2006-10-30
  • 打赏
  • 举报
回复
还有人知道吗》
cici2006 2006-10-26
  • 打赏
  • 举报
回复
哪位老兄帮我看看呀。
greenabc 2006-10-26
  • 打赏
  • 举报
回复
ding
cici2006 2006-10-25
  • 打赏
  • 举报
回复
楼上谢谢你。
不过你的这个list -box
而我需要使用的是list-view 即listctrl
list-view 中是不能使用这个WM_DRAWITEM消息的。因为使用这个消息得不到subitem

麻烦你能再给看看吗?
cici2006 2006-10-24
  • 打赏
  • 举报
回复
没有人知道呀。真晕。没有人用WIN32/重新写过LIST这个控件吗?唉。
烨炜带火 2006-10-24
  • 打赏
  • 举报
回复
define XBITMAP 80
#define YBITMAP 20

#define BUFFER MAX_PATH

HBITMAP hbmpPencil, hbmpCrayon, hbmpMarker, hbmpPen, hbmpFork;
HBITMAP hbmpPicture, hbmpOld;

void AddItem(HWND hwnd, LPSTR lpstr, HBITMAP hbmp)
{
int nItem;

nItem = SendMessage(hwndList, LB_ADDSTRING, 0, lpstr);
SendMessage(hwndList, LB_SETITEMDATA, nItem, hbmp);
}

DWORD APIENTRY DlgDrawProc(
HWND hDlg, // window handle to dialog box
UINT message, // type of message
UINT wParam, // message-specific information
LONG lParam)
{
int nItem;
TCHAR tchBuffer[BUFFER];
HBITMAP hbmp;
HWND hListBox;
TEXTMETRIC tm;
int y;
HDC hdcMem;
LPMEASUREITEMSTRUCT lpmis;
LPDRAWITEMSTRUCT lpdis;
RECT rcBitmap;

switch (message)
{

case WM_INITDIALOG:

// Load bitmaps.

hbmpPencil = LoadBitmap(hinst, MAKEINTRESOURCE(700));
hbmpCrayon = LoadBitmap(hinst, MAKEINTRESOURCE(701));
hbmpMarker = LoadBitmap(hinst, MAKEINTRESOURCE(702));
hbmpPen = LoadBitmap(hinst, MAKEINTRESOURCE(703));
hbmpFork = LoadBitmap(hinst, MAKEINTRESOURCE(704));

// Retrieve list box handle.

hListBox = GetDlgItem(hDlg, IDL_STUFF);

// Initialize the list box text and associate a bitmap
// with each list box item.

AddItem(hListBox, "pencil", hbmpPencil);
AddItem(hListBox, "crayon", hbmpCrayon);
AddItem(hListBox, "marker", hbmpMarker);
AddItem(hListBox, "pen", hbmpPen);
AddItem(hListBox, "fork", hbmpFork);

SetFocus(hListBox);
SendMessage(hListBox, LB_SETCURSEL, 0, 0);
return TRUE;

case WM_MEASUREITEM:

lpmis = (LPMEASUREITEMSTRUCT) lParam;

// Set the height of the list box items.

lpmis->itemHeight = 20;
return TRUE;

case WM_DRAWITEM:

lpdis = (LPDRAWITEMSTRUCT) lParam;

// If there are no list box items, skip this message.

if (lpdis->itemID == -1)
{
break;
}

// Draw the bitmap and text for the list box item. Draw a
// rectangle around the bitmap if it is selected.

switch (lpdis->itemAction)
{
case ODA_SELECT:
case ODA_DRAWENTIRE:

// Display the bitmap associated with the item.

hbmpPicture =(HBITMAP)SendMessage(lpdis->hwndItem,
LB_GETITEMDATA, lpdis->itemID, (LPARAM) 0);

hdcMem = CreateCompatibleDC(lpdis->hDC);
hbmpOld = SelectObject(hdcMem, hbmpPicture);

BitBlt(lpdis->hDC,
lpdis->rcItem.left, lpdis->rcItem.top,
lpdis->rcItem.right - lpdis->rcItem.left,
lpdis->rcItem.bottom - lpdis->rcItem.top,
hdcMem, 0, 0, SRCCOPY);

// Display the text associated with the item.

SendMessage(lpdis->hwndItem, LB_GETTEXT,
lpdis->itemID, (LPARAM) tchBuffer);

GetTextMetrics(lpdis->hDC, &tm);

y = (lpdis->rcItem.bottom + lpdis->rcItem.top -
tm.tmHeight) / 2;

TextOut(lpdis->hDC,
XBITMAP + 6,
y,
tchBuffer,
strlen(tchBuffer));

SelectObject(hdcMem, hbmpOld);
DeleteDC(hdcMem);

// Is the item selected?

if (lpdis->itemState & ODS_SELECTED)
{
// Set RECT coordinates to surround only the
// bitmap.

rcBitmap.left = lpdis->rcItem.left;
rcBitmap.top = lpdis->rcItem.top;
rcBitmap.right = lpdis->rcItem.left + XBITMAP;
rcBitmap.bottom = lpdis->rcItem.top + YBITMAP;

// Draw a rectangle around bitmap to indicate
// the selection.

DrawFocusRect(lpdis->hDC, &rcBitmap);
}
break;

case ODA_FOCUS:

// Do not process focus changes. The focus caret
// (outline rectangle) indicates the selection.
// The IDOK button indicates the final
// selection.

break;
}
return TRUE;

case WM_COMMAND:

switch (LOWORD(wParam))
{
case IDOK:
// Get the selected item's text.

nItem = SendMessage(GetDlgItem(hDlg, IDL_STUFF),
LB_GETCURSEL, 0, (LPARAM) 0);
hbmp = SendMessage(GetDlgItem(hDlg, IDL_STUFF),
LB_GETITEMDATA, nItem, 0);

// If the item is not the correct answer, tell the
// user to try again.
//
// If the item is the correct answer, congratulate
// the user and destroy the dialog box.

if (hbmp != hbmpFork)
{
MessageBox(hDlg, "Try again!", "Oops", MB_OK);
return FALSE;
}
else
{
MessageBox(hDlg, "You're right!",
"Congratulations.", MB_OK);

// Fall through.

}

case IDCANCEL:

// Destroy the dialog box.

EndDialog(hDlg, TRUE);
return TRUE;

default:

return FALSE;
}

case WM_DESTROY:

// Free any resources used by the bitmaps.

DeleteObject(hbmpPencil);
DeleteObject(hbmpCrayon);
DeleteObject(hbmpMarker);
DeleteObject(hbmpPen);
DeleteObject(hbmpFork);

return TRUE;

default:
return FALSE;

}
return FALSE;
}
cici2006 2006-10-23
  • 打赏
  • 举报
回复
打个比方:三列
1-AAAA BBB CCC
2-AAAA BBB CCC
3-AAAA BBB CCC
----------------------
选择1-AAAA 与3-AAAA这两行都行,但选择2-AAAA就是不行。选择不中。返回值都为-1
如果我用鼠标把它们三个全部选择来,2-AAAA的背景色也不会突出显示,所以它也不会被选中了。真是郁闷。
cici2006 2006-10-23
  • 打赏
  • 举报
回复
楼上你的意思是?
我断点看了。我如果选择第二行ITEM,根本就不会进到pLVCD->nmcd.dwDrawStage == (CDDS_ITEMPREPAINT | CDDS_SUBITEM)这个状态里面来喔。
hfo38j58gt3hj 2006-10-23
  • 打赏
  • 举报
回复
不要只看现象。也许是别的问题引起的。定断点看看吧。你着程序没办法看啊。
cici2006 2006-10-23
  • 打赏
  • 举报
回复
我如果不用OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult);
直接用::DefWindowProc(hWnd, uMsg, wParam, lParam); 处理通知消息,
就可以选中第二行,并且是WINODWS默认的蓝色背景突显。
但我这个函数并没有错误呀。OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult);
我把它的内容COPY到MFC的LIST的消息回调函数中使用就可以选择第二行的呢。真是让我晕。

兄弟们帮忙呀。谢谢了。
cici2006 2006-10-23
  • 打赏
  • 举报
回复
没有人回我吗?
herrylou 2006-10-23
  • 打赏
  • 举报
回复
Up
herrylou 2006-10-23
  • 打赏
  • 举报
回复
UP

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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