Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "KOL";
Текущий архив: 2014.09.21;
Скачать: [xml.tar.bz2];

Вниз

Контекстное меню и ComboBox   Найти похожие ветки 

 
igg ©   (2009-06-03 16:15) [0]

Возникла проблема с контекстным меню для комбобокса.

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

Я так понимаю, что проблема в том, что комбобокс реализован действительно как комбинированная конструкция из строки ввода и выпадающего списка. По идее, если получить ссылку на саму строку ввода, то можно будет назначить контекстное меню и на строку ввода комбобокса. Вот только не соображу, как до нее добраться?


 
igg ©   (2009-06-03 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++ с комбобоксом.

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


 
Дмитрий К ©   (2009-06-03 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 ©   (2009-06-04 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 ©   (2009-06-04 01:09) [4]

P.S. Прошу прощения, Дмитрий К, за этими мыслями об ошибках компиляции забыл самое главное - спасибо за помощь!


 
igg ©   (2009-06-04 01:24) [5]

Поправка: вторая часть проблемы оказалась тривиальной. Извиняюсь, это я просто скопировал приведенный код в файл, а надо было добавить {$mode delphi}, и всё стало под Win32 компилироваться, спасибо!

Осталась только проблема отсутствия описания TComboBoxInfo.


 
igg ©   (2009-06-04 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...


 
Дмитрий К ©   (2009-06-04 02:09) [7]

Скорее всего, в WinCE нет GetComboBoxInfo. Нужно просто послать комбобоксу CB_GETCOMBOBOXINFO


 
igg ©   (2009-06-04 09:40) [8]

Что-то не получается. Поставил вместо вызова GetComboBoxInfo такую строку:

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

Компилируется, запускается... Контекстного меню нет :(


 
igg ©   (2009-06-04 10:18) [9]

Самое неприятное заключается в том, что код с CB.Perform() под Win32 запускается и работает... Такое впечатление, что WinCE вообще не поддерживает сообщение GETCOMBOBOXINFO.

Нужен какой-то другой способ получения хэндла поля ввода комбобокса...


 
igg ©   (2009-06-04 10:35) [10]

Попробовал в вызове SetWindowLong поставить первым параметром конструкцию
GetWindow(CB.GetWindowHandle, GW_CHILD)

Издевается - опять под Win32 работает, под WinCE точки не появляются.


 
Дмитрий К ©   (2009-06-04 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 ©   (2009-06-04 14:21) [12]

А так работает. Спасибо огромное!


 
имя   (2009-09-27 02:36) [13]

Удалено модератором


 
имя   (2009-10-03 05:01) [14]

Удалено модератором



Страницы: 1 вся ветка

Форум: "KOL";
Текущий архив: 2014.09.21;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.002 c
15-1392050673
petr
2014-02-10 20:44
2014.09.21
Что-нить похожее на DevExpress, но на java


2-1382260841
dis12345
2013-10-20 13:20
2014.09.21
предопределенные константы в DrawFrameControl


2-1382155371
Павел
2013-10-19 08:02
2014.09.21
Звук при нажатие хоткея


15-1390288445
JohnKorsh
2014-01-21 11:14
2014.09.21
Не по Delphi (поиск алгорима)


4-1264472887
SPeller
2010-01-26 05:28
2014.09.21
Проблема с Read/WriteProcessMemory из разных модулей





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский