WINAPI:捕获列表框中的鼠标单击以添加新项目
WINAPI: capture mouse click in a ListBox for adding new items
我有一个 Windows 应用程序,在对话框中有一个列表框。
我想要做的是当用户点击列表框的空白区域然后添加一个我会得到的项目时得到通知来自新对话框。
如何做到这一点?
预先感谢您的帮助!
更新 1:我添加了子类化,现在我在 Listboxproc 中获得了点击。
但我只想要现有项目之外的点击,在列表框的空白部分。我该如何检查?
Update2:我试图调用 LBItemFromPt() 来确定点击是否在某个项目上,但函数总是 returns -1.
LRESULT CALLBACK ListboxProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam,
UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
switch (msg)
{
case WM_LBUTTONDOWN:
// Listbox was clicked
long x = LOWORD(lParam);
long y = HIWORD(lParam);
POINT p = { x, y };
int pos = LBItemFromPt(hWnd, p, 0); // always -1 !!!!
return TRUE;
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK DlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
case WM_INITDIALOG:
{
HWND hListBox = GetDlgItem(hDlg, IDC_LISTBOX);
// Subclassing
SetWindowSubclass(button, ListboxProc, 0, 0);
SendMessage(hListBox, LB_RESETCONTENT, 0, 0);
for(int i=0; i<nItems; i++)
{
int pos = (int)SendMessage(h, LB_ADDSTRING, 0, (LPARAM) buf[i]);
SendMessage(hListBox, LB_SETITEMDATA, pos, (LPARAM) i); // item index
}
}
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDC_LISTBOX:
switch (HIWORD(wParam))
{
case LBN_DBLCLK:
{
HWND hListBox = GetDlgItem(hDlg, LOWORD(wParam));
int pos = (int)SendMessage(hListBox, LB_GETCURSEL, 0, 0);
int i =(int)SendMessage(hListBox, LB_GETITEMDATA, pos, 0);
... do something with buf[i]
SendMessage(h, LB_SETCURSEL, -1, 0);
}
break;
}
}
}
// but how to get clicks in the listbox which are not on an item?
您需要将x, y
转换为屏幕坐标:
long x = LOWORD(lParam);
long y = HIWORD(lParam);
POINT p = { x, y };
ClientToScreen(hWnd, &p); //add this line
int pos = LBItemFromPt(hWnd, p, 0);
我有一个 Windows 应用程序,在对话框中有一个列表框。
我想要做的是当用户点击列表框的空白区域然后添加一个我会得到的项目时得到通知来自新对话框。
如何做到这一点?
预先感谢您的帮助!
更新 1:我添加了子类化,现在我在 Listboxproc 中获得了点击。
但我只想要现有项目之外的点击,在列表框的空白部分。我该如何检查?
Update2:我试图调用 LBItemFromPt() 来确定点击是否在某个项目上,但函数总是 returns -1.
LRESULT CALLBACK ListboxProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam,
UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
switch (msg)
{
case WM_LBUTTONDOWN:
// Listbox was clicked
long x = LOWORD(lParam);
long y = HIWORD(lParam);
POINT p = { x, y };
int pos = LBItemFromPt(hWnd, p, 0); // always -1 !!!!
return TRUE;
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK DlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
case WM_INITDIALOG:
{
HWND hListBox = GetDlgItem(hDlg, IDC_LISTBOX);
// Subclassing
SetWindowSubclass(button, ListboxProc, 0, 0);
SendMessage(hListBox, LB_RESETCONTENT, 0, 0);
for(int i=0; i<nItems; i++)
{
int pos = (int)SendMessage(h, LB_ADDSTRING, 0, (LPARAM) buf[i]);
SendMessage(hListBox, LB_SETITEMDATA, pos, (LPARAM) i); // item index
}
}
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDC_LISTBOX:
switch (HIWORD(wParam))
{
case LBN_DBLCLK:
{
HWND hListBox = GetDlgItem(hDlg, LOWORD(wParam));
int pos = (int)SendMessage(hListBox, LB_GETCURSEL, 0, 0);
int i =(int)SendMessage(hListBox, LB_GETITEMDATA, pos, 0);
... do something with buf[i]
SendMessage(h, LB_SETCURSEL, -1, 0);
}
break;
}
}
}
// but how to get clicks in the listbox which are not on an item?
您需要将x, y
转换为屏幕坐标:
long x = LOWORD(lParam);
long y = HIWORD(lParam);
POINT p = { x, y };
ClientToScreen(hWnd, &p); //add this line
int pos = LBItemFromPt(hWnd, p, 0);