Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > WM_LBUTTONDBCLK


Автор: AlikV 5.12.2005, 12:08
У меня на главном окне есть ListView
В нем соответственно записи
Каким оразом чере двойной счелчек на оной из записи запустить
PropertySheet
Как отловить позицию мыши и какие флаги надо ставить
(еси надо)На WinAPI

Автор: 2133 5.12.2005, 12:48
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/listview/listview.asp

Автор: Aleksandor 5.12.2005, 13:02
Придется субклассировать ListView smile
В процедуре субклассирования обрабатываем сообщение WM_LBUTTONDBLCLICK

С передачей параметров в PropertySheet
Код

LRESULT APIENTRY ListSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
 static  MYSTRUCTURE param;
 LV_ITEM lvI;
 LVHITTESTINFO hittest;
 // другие переменные.......

 switch (uMsg) {
 case WM_LBUTTONDBLCLK:
    hittest.pt.x=GET_X_LPARAM(lParam); 
    hittest.pt.y=GET_Y_LPARAM(lParam); 
    member=ListView_HitTest(hwnd,&hittest);
              if (member==-1) return 0;
           lvI.iSubItem=0;              // узнаем имя выбранного элемента
           lvI.pszText =szName;
           lvI.cchTextMax=MAX_PATH;
        SendMessage(hwnd,LVM_GETITEMTEXT,(WPARAM)member,(LPARAM)&lvI);
        strcpy(param.szSearch,szName);
        // другое-флаги и т.п.
           pABookPage[0].lParam  = (LPARAM)&param;
           pABookPage[1].lParam  = (LPARAM)&param;
           pABookPage[2].lParam  = (LPARAM)&param;
        PropertySheet(&pABookHeader);
        break;
//  other processing
//............................
 }
    return CallWindowProc(wpListProc, hwnd, uMsg, wParam, lParam); 
} 

Без передачи параметров
Код

 case WM_LBUTTONDBLCLK:
    hittest.pt.x=GET_X_LPARAM(lParam); 
    hittest.pt.y=GET_Y_LPARAM(lParam); 
    member=ListView_HitTest(hwnd,&hittest);
              if (member==-1) return 0;

       PropertySheet(&pABookHeader);
       break;


Автор: AlikV 5.12.2005, 14:22
Какого типа олжно быть member,
и что-то ругаеться на

Код

 static  MYSTRUCTURE param;


Цитата

error C2146: syntax error : missing ';' before identifier 'param'
error C2065: 'param' : undeclared identifier


Да и самое главное это в процедуре обработке всех сообщений надо описать или отделно создавать(если да то где вызывать)?

Автор: Aleksandor 5.12.2005, 14:43
static int member;

на param будет ругаться, это моя структура, у Вас не определена smile
надо определить ее как свою структуру, например

typedef struct _myparams {
char szSearch[250];
//BOOL bSMode;
//BOOL bAbook;
//DWORD index;
// может еще чего что нужно
} MYSTRUCTURE;


ListView надо субклассировать, т.е написать свою процедуру обработки для нужных сообщений, остальные передавать в default процедуру внутри Windows

для субклассирования помимо процедуры нужно сначала объявить саму процедуру и переменную WNDPROC хранящую адрес "настоящей" процедуры в недрах windows

WNDPROC wpListProc;
LRESULT APIENTRY ListSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

потом когда у нас есть дескриптор окна ListView указываем адрес нашей процедуры-

wpListProc=(WNDPROC)SetWindowLong(hwndListView,GWL_WNDPROC,(LONG)ListSubclassProc);

собственно все... теперь вызывается сначала наша процедура, а потом та которая в Windows
( в конце нашей пишем - return CallWindowProc(wpListProc, hwnd, uMsg, wParam, lParam); )
для обработки остальных сообщений smile

Автор: Earnest 5.12.2005, 16:46
Цитата(Aleksandor @ 5.12.2005, 13:02)
Придется субклассировать ListView

"Придется" - слишком сильно сказано.
Т.е. так тоже можно, но проще ловить уведомление WM_NOTIFY::MN_DBLCLK, которое приходит паренту, и в обработчике делать то, что Aleksandor предложил. В параметрах уведомления будет и точка клика, и итем.

Ловить уведомление лучше еще и потому, что существует некая стандартная обработка кликов, дабл-кликов и прочая, в зависимости от стилей контрола. И это надо учитывать, перехватывая эти сообщения. Тогда как ловля уведомлений ничем не грозит в смысле нарушения стандартного поведения.

Автор: rsm 5.12.2005, 20:00
Кусок вполне рабочего кода из моей программы:
Код

// hKeys - хэндл окна ListView
// nCurSel - порядковый номер выделенной строки

case WM_NOTIFY:
    if(((LPNMHDR)lParam)->hwndFrom != hKeys)
        break;
    nCurSel = SendMessage(hKeys, LVM_GETNEXTITEM, -1, LVIS_SELECTED);
    if(nCurSel < 0)
        break;
    switch(((LPNMHDR)lParam)->code)
    {
        case NM_DBLCLK: // двойной клик мышью
            SendMessage(hDlg, WM_COMMAND, IDC_BTEDIT, 0);
            break;

Автор: GremlinProg 6.12.2005, 16:09
Про подклассы писать не буду, слишком много, скажу лишь, что проще всего подставить процедуру окна можно на примере всем известной Delphi, а если про двойной щелчок, то NOTIFY переопределять необязательно, достаточно переопределить WM_LBUTTONDBLCLK

Автор: Earnest 8.12.2005, 21:28
Цитата(GremlinProg @ 6.12.2005, 16:09)
NOTIFY переопределять необязательно, достаточно переопределить WM_LBUTTONDBLCLK

Фишка-то как раз в том, что для перехвата WM_LBUTTONDBLCLK требуется сабклассить контрол, а для обработки WM_NOTIFY достаточно добавить case (или отдельный обработчик - уж как кто пишет) - в оконную процедура парента, которая по-любому должна быть своя. Понимаешь разницу? Для обработки двойного клика не нужно добавлять новых сущностей - нового класса ListView.

Автор: GremlinProg 10.12.2005, 15:45
...да, верно, согласен, я просто обычно переадресовываю уведомления самому себе, для удобства, и все мои контролы уже изначально вкючают сукклассинг. Считаю этот метод самым гибким.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)