Конференция "KOL" » Контекстное меню и ComboBox [Delphi, Windows]
 
  • igg © (03.06.09 16:15) [0]
    Возникла проблема с контекстным меню для комбобокса.

    Устанавливаю через SetAutoPopupMenu контекстное меню комбобоксу, но оно срабатывает только при нажатии правой кнопки на стрелочке, вызывающей выпадающий список. На самой строке редактирования комбобокса мое контекстное меню не вызывается.

    Я так понимаю, что проблема в том, что комбобокс реализован действительно как комбинированная конструкция из строки ввода и выпадающего списка. По идее, если получить ссылку на саму строку ввода, то можно будет назначить контекстное меню и на строку ввода комбобокса. Вот только не соображу, как до нее добраться?
  • igg © (03.06.09 22:14) [1]
    Вот код тестового проекта - самый необходимый минимум.

    program Test;
    {$mode delphi}
    uses Windows, Messages, KOL;

    var form, combobox: PControl;
         menu, ctxmenu: PMenu;

    begin
       form := NewForm(Applet, 'Test');
       combobox := NewComboBox(form, []);

       menu := NewMenu(form, 0, [], nil);
       ctxmenu := NewMenu(form, 0, ['Cut', 'Copy', 'Paste'], nil);
     
       combobox.SetAutoPopupMenu(ctxmenu);

       Run(form);
    end.



    Контекстное меню вызывается только на стрелочке, а в той части комбобокса, где можно вводить - не срабатывает.

    Пытался добавить
    form.SetAutoPopupMenu(ctxmenu);


    Не помогает. В полном соответствии с написанным появляется контекстное меню у самой формы, но на комбобоксе - нет.

    На всякий случай - версии используемого компилятора и библиотек, хотя здесь это вряд ли существенно:

    Lazarus-0.9.26.3-20365-fpc-2.2.4-20090603-cross-arm-wince-win32.exe
    Lazarus-0.9.26.3-20365-fpc-2.2.4-20090603-win32.exe
    kol-ce-2.80.3.zip



    Причем не только в контексте дельфи и KOL, та же фигня на VC++ с комбобоксом.

    Весь инет обыскал, все поисковые сервера замучил - нет ничего о контекстном меню для комбобоксов. Любой другой контрол нормально работает с контекстным меню, но мне ведь нужен комбобокс!
  • Дмитрий К © (03.06.09 22:23) [2]
    Например, с помощью
    GetComboBoxInfo

    получаем хэндл едитбокса; подменяем оконную процедуру, в которой переопределяем реакцию на WM_CONTEXTMENU, et voilà:
    program Project1;

    uses
     Windows,
     Messages,
     KOL;

    var
     Form, CB: PControl;
     Menu: PMenu;
     CBInfo: TComboBoxInfo;
     PrevWndProc: Integer;
    procedure MenuItem(Dummy, Sender: PControl; Item: Integer);
    begin
     CB.Items[CB.CurIndex] := Menu.ItemText[item];
    end;

    function CBWndProc(Wnd: HWnd; Msg: Cardinal; wParam: Integer; lParam: Integer): Integer; stdcall;
    var
     R: TRect;
    begin
     if Msg = WM_CONTEXTMENU then
     begin
       if lParam < 0 then
       begin
         GetWindowRect(Wnd, R);
         Menu.Popup((R.Left + R.Right) div 2, (R.Top + R.Bottom) div 2);
       end
       else
         Menu.Popup(LoWord(lParam), HiWord(lParam));
       Result := 0;
     end
     else
       Result := CallWindowProc(Pointer(PrevWndProc), Wnd, Msg, wParam, lParam);
    end;
    {$IFDEF FPC}
    function GetComboBoxInfo(hwndCombo:HWND;var pcbi:TCOMBOBOXINFO):BOOL; stdcall; external 'user32' name 'GetComboBoxInfo';
    {$ENDIF}
    begin
     Form := NewForm(nil, 'test');
     CB := NewComboBox(Form, []);
     CB.Add('Test');
     Menu := NewMenu(CB, 0, ['1','2','3'], TOnMenuItem(MakeMethod(nil, @MenuItem)));
     CBInfo.cbSize := SizeOf(CBInfo);
     GetComboBoxInfo(CB.GetWindowHandle, CBInfo);
     PrevWndProc := SetWindowLong(CBInfo.hwndItem, GWL_WNDPROC, Integer(@CBWndProc));
     Run(Form);
    end.

  • igg © (04.06.09 01:07) [3]
    Смысл понятен, но что-то не получается, не понравилось ей описание TComboBoxInfo:

    test.pas(6,26) Error: Identifier not found "TComboBoxInfo"
    test.pas(6,26) Error: Error in type definition


    Может, из-за того, что KOL не полностью портирована под WinCE?

    Попробовал собрать не под WinCE, а под Win32. Тоже ошибки вылезли:

    ctxtest2.pas(15,5) Error: Illegal qualifier
    ctxtest2.pas(15,5) Error: Illegal expression



    Это на строке

    CB.Items[CB.CurIndex] := Menu.ItemText[item];



    Ладно, обработка не критична сейчас, закомментировал эту строку. Опять ей не нравится:

    ctxtest2.pas(27,11) Error: Illegal qualifier
    ctxtest2.pas(27,11) Error: Illegal expression


    Это она ругается на

    Menu.Popup((R.Left + R.Right) div 2, (R.Top + R.Bottom) div 2);



    Что, у KOL'овского меню разве нет метода Popup?
  • igg © (04.06.09 01:09) [4]
    P.S. Прошу прощения, Дмитрий К, за этими мыслями об ошибках компиляции забыл самое главное - спасибо за помощь!
  • igg © (04.06.09 01:24) [5]
    Поправка: вторая часть проблемы оказалась тривиальной. Извиняюсь, это я просто скопировал приведенный код в файл, а надо было добавить {$mode delphi}, и всё стало под Win32 компилироваться, спасибо!

    Осталась только проблема отсутствия описания TComboBoxInfo.
  • igg © (04.06.09 01:39) [6]
    Еще одна попытка решить проблему. Попытался я добавить в код описание соответствующих типов, вот так:

    type
     tagCOMBOBOXINFO = record
       cbSize: DWORD;
       rcItem: TRect;
       rcButton: TRect;
       stateButton: DWORD;
       hwndCombo: HWND;
       hwndItem: HWND;
       hwndList: HWND;
     end;
     TComboboxInfo = tagCOMBOBOXINFO;
     PComboboxInfo = ^TComboboxInfo;
     LPComboboxInfo = PComboboxInfo;


    Странно, после этого программа собралась без ошибок, но... Вот только не запускается она на Windows Mobile девайсах. Издает неприятный писк при попытке запуска и не работает. Примерно такой звук, как если собрать программу под Win32, а пытаться запустить под WinCE...
  • Дмитрий К © (04.06.09 02:09) [7]
    Скорее всего, в WinCE нет GetComboBoxInfo. Нужно просто послать комбобоксу CB_GETCOMBOBOXINFO
  • igg © (04.06.09 09:40) [8]
    Что-то не получается. Поставил вместо вызова GetComboBoxInfo такую строку:

    CB.Perform(CB_GETCOMBOBOXINFO, 0, Integer(@CBInfo));


    Компилируется, запускается... Контекстного меню нет :(
  • igg © (04.06.09 10:18) [9]
    Самое неприятное заключается в том, что код с CB.Perform() под Win32 запускается и работает... Такое впечатление, что WinCE вообще не поддерживает сообщение GETCOMBOBOXINFO.

    Нужен какой-то другой способ получения хэндла поля ввода комбобокса...
  • igg © (04.06.09 10:35) [10]
    Попробовал в вызове SetWindowLong поставить первым параметром конструкцию
    GetWindow(CB.GetWindowHandle, GW_CHILD)



    Издевается - опять под Win32 работает, под WinCE точки не появляются.
  • Дмитрий К © (04.06.09 13:50) [11]

    > под WinCE точки не появляются.
    А если так?
    program test;
    {$MODE Delphi}
    uses
     windows, messages, kol, aygshell;

    var
     Form, CB: PControl;
     Menu: PMenu;
     EdtWnd: Hwnd;
     PrevWndProc: Cardinal;

    function CBWndProc(Wnd: HWnd; Msg: Cardinal; wParam: Integer; lParam: Integer): Integer; stdcall;
    var
     shrg: SHRGINFO;
     R: TRect;
    begin
     if Msg = WM_LBUTTONDOWN then
     begin
       shrg.cbSize := sizeof(shrg);
       shrg.hwndClient := Wnd;
       shrg.ptDown.x := LOWORD(lParam);
       shrg.ptDown.y := HIWORD(lParam);
       shrg.dwFlags := SHRG_RETURNCMD;
       SHRecognizeGesture(shrg);
     end;
     if Msg = WM_CONTEXTMENU then
     begin
       if lParam < 0 then
       begin
         GetWindowRect(Wnd, R);
         Menu.Popup((R.Left + R.Right) div 2, (R.Top + R.Bottom) div 2);
       end
       else
         Menu.Popup(LoWord(lParam), HiWord(lParam));
       Result := 0;
     end
     else
       Result := CallWindowProc(Pointer(PrevWndProc), Wnd, Msg, wParam, lParam);
    end;

    begin
     Form := NewForm(nil, 'test');
     CB := NewComboBox(form, []);
     Menu := NewMenu(CB, 0, ['1','2','3'], nil);
     EdtWnd := GetWindow(CB.GetWindowHandle, GW_CHILD);
     PrevWndProc := SetWindowLong(EdtWnd, GWL_WNDPROC, Integer(@CBWndProc));
     Run(Form);
    end.  

  • igg © (04.06.09 14:21) [12]
    А так работает. Спасибо огромное!
  • имя (27.09.09 02:36) [13]
    Удалено модератором
  • имя (03.10.09 05:01) [14]
    Удалено модератором
 
Конференция "KOL" » Контекстное меню и ComboBox [Delphi, Windows]
Есть новые Нет новых   [134431   +11][b:0][p:0.003]