HOWTO: Find Out Which Listview Column Was Right-Clicked
ID: Q125694
|
The information in this article applies to:
-
Microsoft Win32 Software Development Kit (SDK)
-
Microsoft Windows 2000
SUMMARY
You can use the technique described in this article to find out which
column was clicked after right-clicking the listview column header.
MORE INFORMATION
LVN_COLUMNCLICK notifies a listview's parent window when a column is
clicked using the left mouse button, but no such notification occurs when a
column is clicked with the right mouse button.
Windows 95 sends an NM_RCLICK notification to the listview's parent window
when a column is clicked with the right mouse button, but the message sent
does not contain any information as to which column was clicked, especially
if the window is sized so that the listview is scrolled to the right.
The correct way to determine which column was clicked with the right mouse
button, regardless of whether the listview is scrolled, is to send the
header control an HDM_HITTEST message, which returns the index of the
column that was clicked in the iItem member of the HD_HITTESTINFO struct.
In sending this message, make sure the point passed in the HD_HITTESTINFO
structure is relative to the header control's client coordinates. Do not
pass it a point relative to the listview's client coordinates; if you do,
it will return an incorrect column index value.
The header control in this case turns out to be a child of the listview
control of LVS_REPORT style.
The following code demonstrates this method. Note that while the code
processes the NM_RCLICK notification on a WM_NOTIFY message, you also
process the WM_CONTEXTMENU message, which is also received as a
notification when the user clicks the right mouse button.
Sample Code
case WM_NOTIFY:
{
if ((((LPNMHDR)lparam)->code == NM_RCLICK))
{
HWND hChildWnd;
POINT pointScreen, pointLVClient, pointHeader;
DWORD dwpos;
dwPos = GetMessagePos();
pointScreen.x = LOWORD (dwPos);
pointScreen.y = HIWORD (dwPos);
pointLVClient = pointScreen;
// Convert the point from screen to client coordinates,
// relative to the listview
ScreenToClient (ghwndLV, &pointLVClient);
// Because the header turns out to be a child of the
// listview control, we obtain its handle here.
hChildWnd = ChildWindowFromPoint (ghwndLV, pointLVClient);
// NULL hChildWnd means R-CLICKED outside the listview.
// hChildWnd == ghwndLV means listview got clicked: NOT the
// header.
if ((hChildWnd) && (hChildWnd != ghwndLV))
{
char szClass [50];
// Verify that this window handle is indeed the header
// control's by checking its classname.
GetClassName (hChildWnd, szClass, 50);
if (!lstrcmp (szClass, "SysHeader32"))
{
HD_HITTESTINFO hdhti;
char szBuffer [80];
// Transform to client coordinates
// relative to HEADER control, NOT the listview!
// Otherwise, incorrect column number is returned.
pointHeader = pointScreen;
ScreenToClient (hChildWnd, &pointHeader);
hdhti.pt = pointHeader;
SendMessage (hChildWnd,
HDM_HITTEST,
(WPARAM)0,
(LPARAM) (HD_HITTESTINFO FAR *)&hdhti);
wsprintf (szBuffer, "Column %d got clicked.\r\n",
hdhti.iItem);
MessageBox (NULL, szBuffer, "Test", MB_OK);
}
}
}
return 0L;
}
Additional query words:
Keywords : kbcode kbCtrl kbListView kbNTOS351 kbNTOS400 kbWinOS2000 kbSDKWin32 kbGrpUser kbWinOS95 kbWinOS98
Version : WINDOWS:
Platform : WINDOWS
Issue type : kbhowto