Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Компоненты Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.08.2012, 12:23   #1
mansuetudo
Пользователь
 
Регистрация: 08.11.2011
Сообщений: 46
По умолчанию Отловить клик правой кнопкой мыши в ComboBox

Добрый день. Есть необходимость выполнять некоторые действия, кликнув правой кнопкой мыши по элементу выпавшего списка ComboBox'а. Что-то никак не могу ни сама сообразить, ни найти в инете подсказку, может, неправильно формулирую запрос. Событие OnClick замечательно отлавливает левую и никак не реагирует на правую. Подскажите пожалуйста, как можно поймать этот самый "правый" клик?
Заранее спасибо.
mansuetudo вне форума Ответить с цитированием
Старый 04.08.2012, 11:12   #2
volvo877
Форумчанин
 
Аватар для volvo877
 
Регистрация: 01.06.2009
Сообщений: 108
По умолчанию

Получай хендл выпадающего списка в OnDropDown через GetComboboxInfo, подменяй его оконную процедуру своей, в которой лови WM_RBUTTON<...>, и делай с ним всё, что нужно. По закрытию выпадающего списка - восстанавливай оконную функцию (насколько я помню, при открытии списка он может создаваться заново, поэтому нельзя сделать один раз его сабклассинг и постоянно с ним работать, есть вероятность нарваться на проблемы). Вот примерный код:

Код:
type
  TForm1 = class(TForm)
    ComboBox1: TComboBox;
    Memo1: TMemo;
    procedure ComboBox1DropDown(Sender: TObject);
    procedure ComboBox1CloseUp(Sender: TObject);
  private
    { Private declarations }
    CbxInstance: Pointer;
    OldCbxProc: Pointer;
  public
    { Public declarations }
    procedure NewCbxProc(var msg: TMessage);
  end;
+

Код:
function GetHandle(cbx : TComboBox) : HWND;
var
   Info: TComboBoxInfo;
begin
   ZeroMemory(@Info, SizeOf(Info));
   Info.cbSize := SizeOf(Info);
   GetComboBoxInfo(cbx.Handle, Info);
   Result := Info.hwndList;
end;

procedure TForm1.NewCbxProc(var msg : TMessage);
begin
   case msg.Msg of
      WM_RBUTTONDOWN:
      begin
         Memo1.Lines.Add('Right click detected !'); // Обрабатывай как нужно
      end;
   end;
   msg.Result := CallWindowProc(OldCbxProc, GetHandle(ComboBox1),
                                msg.Msg, msg.WParam, msg.LParam);
end;

procedure TForm1.ComboBox1CloseUp(Sender: TObject);
begin
   SetWindowLong(GetHandle(ComboBox1), GWL_WNDPROC, Integer(OldCbxProc));
   FreeObjectInstance(CbxInstance);
end;

procedure TForm1.ComboBox1DropDown(Sender: TObject);
begin
    CbxInstance := MakeObjectInstance(NewCbxProc);
    OldCbxProc := Pointer(SetWindowLong(GetHandle(ComboBox1),
        GWL_WNDPROC, Integer(CbxInstance)));
end;
volvo877 вне форума Ответить с цитированием
Старый 06.08.2012, 13:58   #3
mansuetudo
Пользователь
 
Регистрация: 08.11.2011
Сообщений: 46
По умолчанию

Спасибо, буду разбираться.

P.S. Офф - кошка шикарная, давно таких не видела
mansuetudo вне форума Ответить с цитированием
Старый 07.08.2012, 13:37   #4
artemavd
Старожил
 
Аватар для artemavd
 
Регистрация: 05.06.2008
Сообщений: 4,206
По умолчанию

Именно на самом компоненте? Если нет, то ответ дан выше. Если да, то у каждого компонента есть свойство OnContextPopup, которое срабатывает как раз, когда на компоненте нажали правую кнопку мыши.
Не стоит смеяться над человеком делающим шаг назад, возможно он делает разбег.
artemavd вне форума Ответить с цитированием
Старый 07.08.2012, 14:59   #5
mansuetudo
Пользователь
 
Регистрация: 08.11.2011
Сообщений: 46
По умолчанию

OnContextPopup у меня срабатывает почему-то только при клике на самом компоненте и не срабатывает на выпавшем списке. Пробовала определять координаты выпавшего списка, преобразовывать в оконные и вызывать выполнение нужных функций при клике в заданном прямоугольнике - не работает. Возможно, просто не туда привязываю вызов.
mansuetudo вне форума Ответить с цитированием
Старый 07.08.2012, 18:23   #6
volvo877
Форумчанин
 
Аватар для volvo877
 
Регистрация: 01.06.2009
Сообщений: 108
По умолчанию

Цитата:
OnContextPopup у меня срабатывает почему-то только при клике на самом компоненте и не срабатывает на выпавшем списке.
OnContextPopup и не должен срабатывать на выпадающем списке. Только на поле ввода/стрелке. Потому что только там можно вызвать правой кнопкой мыши контекстное меню. Для отлова при выпавшем списке - только подменять его оконную функцию.

Тебе чего сделать-то надо? Найти айтем, на котором кликнули правой кнопкой? Так спроси у hwndList-а, вышли ему LB_GETCURSEL, он тебе вернет индекс выделенного на данный момент элемента. Это и будет индекс элемента, над которым была нажата правая кнопка мыши
volvo877 вне форума Ответить с цитированием
Старый 08.08.2012, 10:58   #7
mansuetudo
Пользователь
 
Регистрация: 08.11.2011
Сообщений: 46
По умолчанию

Пока что у меня вообще не получалось выполнить действие при клике на выпавшем списке. Не было никакой реакции вообще. Удалось решить при помощи такого кода (нашла в инете и скорректировала под себя):

Код:
procedure TForm1.AppMessage(var Msg:TMsg; var Handled:Boolean);
var
 C:TWinControl;
begin
 if Msg.message=WM_RBUTTONUP then begin
  C:=Screen.ActiveControl;
  if C is TComboBox then
    with TComboBox(C), Items do
     if DroppedDown and (ItemIndex>=0) then PopupMenu1.Popup(Msg.pt.X,Msg.pt.Y)
 end;
end;
+ в OnCreate для формы прописала
Код:
Application.OnMessage:=AppMessage;
Клик ловится, надо допрописать по мелочам (определить элемент, над которым кликнули и выполнить действия по клику). Ваш последний совет как раз в тему
Спасибо всем, думаю, нужные ответы у меня есть
mansuetudo вне форума Ответить с цитированием
Старый 08.08.2012, 11:50   #8
volvo877
Форумчанин
 
Аватар для volvo877
 
Регистрация: 01.06.2009
Сообщений: 108
По умолчанию

Цитата:
Пока что у меня вообще не получалось выполнить действие при клике на выпавшем списке. Не было никакой реакции вообще.
Вообще-то я копировал код (который приведен во втором посте) из работающего приложения. Клик в нем прекрасно ловится. Что уж там можно было сделать не так, чтобы клик НЕ ловился - непонятно.
volvo877 вне форума Ответить с цитированием
Старый 08.08.2012, 12:05   #9
mansuetudo
Пользователь
 
Регистрация: 08.11.2011
Сообщений: 46
По умолчанию

Я имела в виду, что клик не ловился раньше, до того, как я обратилась сюда с вопросом. В приведённом выше коде я толком ещё не разобралась по разным причинам - недостаток знаний, недостаток времени (аудит приехал), ну и то, что программирование, в общем-то, не есть моя основная работа. Пока по мере возможности буду проверять всё, что удалось по теме найти, чтоб возможные подводные камни найти и обойти. За помощь большое спасибо!
mansuetudo вне форума Ответить с цитированием
Старый 10.05.2013, 13:40   #10
Ruslan_9977
Новичок
Джуниор
 
Регистрация: 12.03.2013
Сообщений: 1
По умолчанию

Спасибо за хороший пример, очень помог.
Ruslan_9977 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
C# Работа ПРАВОЙ кнопкой мыши back1919 Помощь студентам 0 04.11.2010 15:18
На рабочем столе нельзя правой кнопкой мыши создать новый файл тхт Kapitann Операционные системы общие вопросы 10 09.08.2010 15:49
Выделение ячейки в DBGrid правой кнопкой мыши RIO БД в Delphi 2 20.08.2009 17:53
Косяки с правой кнопкой мыши joker Общие вопросы Delphi 4 12.11.2008 13:25
Как работать с правой кнопкой мыши? ZeRRon Помощь студентам 4 28.12.2007 18:45