I have mapped the NM_CLICK notification to OnNMClickColInfo as so:
BEGIN_MESSAGE_MAP(CColInfo, CDialog)
...
ON_NOTIFY(NM_CLICK, IDC_COLINFO, OnNMClickColInfo)
ON_WM_MOUSEMOVE()
...
END_MESSAGE_MAP()
The latest 4.7 instructions (I am using IE 6.0 and XP) say that the message
signature will have an LPNMITEMACTIVATE struct pointer that will contain the
item and subitem that has been clicked on. In my case, the item seems to be
always -1 but the subitem is correct and corresponds to the column that had
been clicked.
I then tried to use the CListCtrl::HitTest(...) function but this also fails
to identify both the item (row) and subitem.
How can I determine the row and column that the user has clicked?
This is the code for the first part of the message handler that traces the
input and also tries the HitTest in two different ways. The m_lcColInfo is
the CListCtrl member:
void
CColInfo::OnNMClickColInfo(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMITEMACTIVATE pNMIA = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
TRACE(_T("NMClick: Item=%d, SubItem=%d\n")
, pNMIA->iItem, pNMIA->iSubItem);
UINT uFlags;
POINT pt = pNMIA->ptAction;
LVHITTESTINFO lvhti;
ZeroMemory(&lvhti, sizeof(lvhti));
lvhti.pt = pt;
m_lcColInfo.HitTest(&lvhti);
TRACE(_T("Hittest 1: Point %d:%d, iItem=%d, iSubItem=%d, Flags=%x\n")
, pt.x, pt.y, lvhti.iItem, lvhti.iSubItem, lvhti.flags);
int iEditItem = m_lcColInfo.HitTest(pt, &uFlags);
TRACE(_T("Hittest 2: Point %d:%d, iEditItem=%d, uFlags=%x\n")
, pt.x, pt.y, iEditItem, uFlags);
...
and the output in the debug window is as follows:
NMClick: Item=-1, SubItem=2
Hittest 1: Point 217:62, iItem=-1, iSubItem=0, Flags=1
Hittest 2: Point 217:62, iEditItem=-1, uFlags=1
...
The Flags value of one corresponds to LVHT_NOWHERE.
In another part of the test dialog, I had implemented a drag and drop of
rows. In this case the OnLVNBeginDragColInfo(...) carries a pointer to a
LPNLISTVIEW pointer and here the iItem (iSubItem is zero) is correct as in:
void
CColInfo::OnLVNBeginDragColInfo(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
TRACE(_T("BeginDrag: Item=%d, SubItem=%d\n")
, pNMLV->iItem, pNMLV->iSubItem);
...
and the MouseMove(...) uses the HitTest() routine to obtain the drop target
successfully via:
void
CColInfo::OnMouseMove(UINT nFlags, CPoint ptClient)
{
if(m_bDragging) {
CPoint ptScreen(ptClient);
ClientToScreen(&ptScreen);
// move the drag image
VERIFY(m_pDragImage->DragShowNolock(FALSE));
CWnd* pDropWnd = WindowFromPoint(ptScreen);
// save current window pointer
m_pDropWnd = pDropWnd;
// if we are inside the main window
if(m_pDropWnd->IsKindOf(RUNTIME_CLASS(CListCtrl))) {
UINT uFlags;
// get the item that is below the cursor
int iNewDropItem = m_lcColInfo.HitTest(ptClient, &uFlags);
if(uFlags & LVHT_ONITEM) {
...
Ed
--
Edward E.L. Mitchell
Web: www.racesail.org
Phone: (239)415-7039
6707 Daniel Court
Fort Myers, FL 33908
1) goto the dialog resource in the resource view.
2) add a list control(report view) and give it a id IDC_LIST2 and populate
the list control
in OnInitDialog(...)
3) click the list control on teh fialog resource and add a variable to the
dialog class,
ClistCtrl m_ListCtrl.
4) Add the OnNotify override for the dialog
Place this code in it
5) after the ListView_SubItemHitTest call, the lvhi's iItem and iSubItem
would contain
the desired values.
BOOL CColInfo::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
if(wParam == IDC_LIST2)
{
NMITEMACTIVATE *lpnm = (NMITEMACTIVATE*)lParam;
if(lpnm->hdr.code == NM_CLICK)
{
LVHITTESTINFO lvhi;
lvhi.pt = lpnm->ptAction;
ListView_SubItemHitTest(lpnm->hdr.hwndFrom , &lvhi);
}
}
return CDialog::OnNotify(wParam, lParam, pResult);
}
--
Vipin Aravind
Microsoft MVP
"Edward Mitchell" <EELMi...@newsgroup.nospam> wrote in message
news:%23nu4Eji...@TK2MSFTNGP09.phx.gbl...
Thanks for the solution. When I implement this, I get the correct item and
subitem identified.
I went back and checked my code since the OnNMClick... was still being
activated after the OnNotify(...) message below and I could step through
with the debugger. It turns out that I was using CListCtrl::HitTest(...)
instead of CListCtrl::SubItemHitTest(...)!
When I changed my code to use the SubItemHitTest(...) everything worked as
advertised.
Ed
"Vipin" <Vi...@nospam.com> wrote in message
news:%23wPRn7n...@TK2MSFTNGP12.phx.gbl...
--
Vipin Aravind
Microsoft - MVP
"Edward Mitchell" <EELMi...@newsgroup.nospam> wrote in message
news:OyTZ9VrG...@TK2MSFTNGP14.phx.gbl...
Best Regards,
Terry Fei [MSFT]
Microsoft Community Support
Get Secure! www.microsoft.com/security
--------------------
>From: "Edward Mitchell" <EELMi...@newsgroup.nospam>
>References: <#nu4EjiG...@TK2MSFTNGP09.phx.gbl>
<#wPRn7nG...@TK2MSFTNGP12.phx.gbl>
>Subject: Re: How to Identify the Item and Subitem that has been Clicked in
a CListCtrl
>Date: Mon, 16 Jan 2006 10:56:39 -0500
>Lines: 162
>X-Priority: 3
>X-MSMail-Priority: Normal
>X-Newsreader: Microsoft Outlook Express 6.00.2900.2180
>X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2180
>X-RFC2646: Format=Flowed; Response
>Message-ID: <OyTZ9VrG...@TK2MSFTNGP14.phx.gbl>
>Newsgroups: microsoft.public.vc.mfc
>NNTP-Posting-Host: pcp01560989pcs.sftmyr01.fl.comcast.net 68.54.64.71
>Path: TK2MSFTNGXA02.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP14.phx.gbl
>Xref: TK2MSFTNGXA02.phx.gbl microsoft.public.vc.mfc:463932
>X-Tomcat-NG: microsoft.public.vc.mfc