Alfred
Alfred

Reputation: 139

WINAPI: capture mouse click in a ListBox for adding new items

I have a Windows application with a ListBox inside a Dialog.
What I want to do is to get a notification when the user clicks in an empty area of the listbox and then add an item that I would get from a new dialog.
How can this be done?
Thanks in advance for your help!

Update1: I added subclassing, and now I get the clicks in Listboxproc.
But I only wanted the clicks outside of existing items, in empty part of the Listbox. How can I check that?

Update2: I tried to call LBItemFromPt() to determine if the click was over an item, but the function always 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?

Upvotes: 2

Views: 1292

Answers (1)

You need to convert x, y to screen coordinates:

long x = LOWORD(lParam);
long y = HIWORD(lParam);
POINT p = { x, y };
ClientToScreen(hWnd, &p); //add this line
int pos = LBItemFromPt(hWnd, p, 0);

Upvotes: 2

Related Questions