WINAPI:在列表框中捕获鼠标单击以添加新项目

WINAPI:在列表框中捕获鼠标单击以添加新项目,winapi,listbox,click,mouse,Winapi,Listbox,Click,Mouse,我有一个Windows应用程序,在对话框中有一个列表框。 我想做的是,当用户单击列表框的空白区域时,会收到通知,然后添加我将从新对话框中获得的项目。 如何做到这一点? 提前感谢您的帮助 更新1:我添加了子类化,现在我在Listboxproc中得到了点击。 但我只想点击现有项目之外的内容,在列表框的空白部分。我怎样才能检查呢? Update2:我试图调用LBItemFromPt()来确定单击是否在某个项目上,但函数始终返回-1。 LRESULT CALLBACK ListboxProc (HWND

我有一个Windows应用程序,在对话框中有一个列表框。
我想做的是,当用户单击列表框的空白区域时,会收到通知,然后添加我将从新对话框中获得的项目。
如何做到这一点?
提前感谢您的帮助

更新1:我添加了子类化,现在我在Listboxproc中得到了点击。
但我只想点击现有项目之外的内容,在列表框的空白部分。我怎样才能检查呢?

Update2:我试图调用LBItemFromPt()来确定单击是否在某个项目上,但函数始终返回-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?
LRESULT回调ListboxProc(HWND-HWND,UINT-msg,WPARAM-WPARAM,LPARAM-LPARAM,
UINT_PTR uIdSubclass,DWORD_PTR dwRefData)
{
开关(msg)
{
案例WM_LBUTTONDOWN:
//已单击列表框
长x=低ORD(LPRAM);
长y=HIWORD(LPRAM);
点p={x,y};
int pos=LBItemFromPt(hWnd,p,0);//始终为-1!!!!
返回TRUE;
} 
返回def子类proc(hWnd、uMsg、wParam、lParam);
}
LRESULT回调DlgProc(HWND hDlg、UINT消息、WPARAM WPARAM、LPARAM LPARAM)
{
案例WM_初始化对话框:
{
HWND hListBox=GetDlgItem(hDlg、IDC\u列表框);
//子类化
SetWindowsSubClass(按钮,ListboxProc,0,0);
SendMessage(hListBox,LB_RESETCONTENT,0,0);

对于(int i=0;i您需要将
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);

控件和句柄的子类
WM_LBUTTONDOWN
。您是否考虑过在列表框中添加一个特殊项,并在用户单击时添加一个项?有点像许多web浏览器显示的特殊选项卡,允许用户通过单击它来打开一个新选项卡。当然,但我觉得这没有那么优雅,因为我有几个这样的列表框,不希望每个列表框都有一个按钮。
如果用户单击现有的列表框项目I get pos>=0并处理此项目,如果用户单击外部I get pos,则会更简单。太好了!在找到此解决方案之前,我已经很接近了。谢谢!