2015-01-28 4 views
1

У меня есть приложение Windows со списком в диалоговом окне.
Что я хочу сделать, так это получить уведомление, когда пользователь заходит в пустую область списка, а затем добавляет элемент, который я получаю из нового диалогового окна.
Как это можно сделать?
Заранее благодарим за помощь!
WINAPI: захват щелчка мыши в ListBox для добавления новых элементов

Update1: Я добавил подклассы, и теперь получаю щелчки в 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? 
+1

Подкласс управления и ручкой 'WM_LBUTTONDOWN'. –

+0

Рассматривали ли вы добавление специального элемента в список и добавление элемента, когда пользователь нажимает на него? Похоже на специальную вкладку, отображаемую многими веб-браузерами, чтобы пользователь мог открыть новую вкладку, щелкнув по ней. – Stuart

+0

Конечно, но я не считаю это настолько элегантным, так как у меня есть несколько таких списков и не хочу, чтобы у каждого из них была кнопка .
Проще, если пользователь нажимает на существующий элемент ListBox, я получаю pos> = 0 и обрабатываю этот элемент, если он нажимает на меня, я получаю pos <0 и предлагаю диалог для добавления нового элемента. – Alfred

ответ

1

Вы должны преобразовать 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); 
+0

Отлично! Я был рядом, прежде чем найти это решение сам. Спасибо! – Alfred

Смежные вопросы