Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Заставить выпасть подпункт контекстного меню


Автор: StayAtHome 8.7.2005, 02:26
Возникла необходимость програмно отобразить PopupMenu, а потом раскрыть один из его подпунктов. Cначала делаю PopupMenu1.Popup(...), а что потом?
Пробовал и нажатия клавиш посылать и DispatchCommand... Видимо торможу, т. к. нифига не вышло.

Автор: _hunter 8.7.2005, 11:51
а ничего потом smile
потому как Popup() аналогичен ShowModal() формы
или просто показывай меню или сразу показывай подменю...

Автор: SoWa 8.7.2005, 18:17
А ничего типа:
Код

PopupMenu1.Подкатегория.Popup; 

нету?
Т.е. обращаться не к главной менюшке, а ниже.

Автор: StayAtHome 9.7.2005, 02:06
SoWa Вот-вот, похоже что нету. Недоработки у борланда, однако smile

Автор: StayAtHome 28.11.2005, 17:36
Вопрос все еще актуален. Неужели никому такой изврат не требовался? smile Может как-то обойти это можна?

Автор: ~FoX~ 28.11.2005, 17:46
Ну товарисчи.... субитнмыменю - есть Item-ы от Item-ов...... т.е. Они являются свойствами итемов верхнего уровня...
Код

PopupMenu1.items[1].Items[1].Popup
PopupMenu1.items[1].Items[1].Items[1].Popup
PopupMenu1.items[1].Items[1].Items[1].Items[1].Popup
// и т.д. в зависимости от степени вложенности итемеов


Автор: sexton 28.11.2005, 17:49
Имхо никак smile

Автор: StayAtHome 28.11.2005, 18:04
~FoX~
Сам проверял? У меня такое не работало

Автор: Girder 28.11.2005, 20:02
http://forum.vingrad.ru/index.php?showtopic=68777&view=findpost&p=550085

Автор: StayAtHome 30.11.2005, 03:21
Girder
Че-то не очень получается... smile Если не влом -- большая просьба кинуть в меня рабочим куском кода (не лентяй я, торможу наверное).

Автор: Girder 30.11.2005, 14:42
Если надо именно отобразить...

Код
procedure TForm1.Button1Click(Sender: TObject);
var p:TPoint;
begin
 GetCursorPos(p);
 Timer1.Enabled:=true;
 PopupMenu1.Popup(p.X,p.Y);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var p:TPoint;
    R:TRect;
    i,k:integer;
    j:DWord;
    M:HMenu;
    V:HWND;
begin
 Timer1.Enabled:=false;
 for i:=0 to GetMenuItemCount(PopupMenu1.Handle)-1 do
  begin
   j:=GetMenuItemID(PopupMenu1.Handle,i);
   if j=$FFFFFFFF then
    begin
     M:=GetSubMenu(PopupMenu1.Handle,i);
     if M<>0 then
      begin
       while (FindWindow('SysShadow',nil)=0) do;
       v:=FindWindow('#32768',nil);
       GetWindowRect(v,R);
       k:=Trunc((R.Bottom-R.Top)/GetMenuItemCount(PopupMenu1.Handle));
       p.Y:=R.Top-(k div 2)+GetMenuItemCount(PopupMenu1.Handle)*k;
       p.X:=R.Left+(R.Right-R.Left) div 2;
       SetCursorPos(p.X,p.Y);
      end;
    end;
  end;
end;


PS: Если у тебя нет тени у меню... то строчки
Код
while (FindWindow('SysShadow',nil)=0) do;
v:=FindWindow('#32768',nil);
надо заменить на
Код
//pID,tID:DWord;
tID:=0;
GetWindowThreadProcessId(Form1.Handle,@tID);
v:=0;
while (v=0) do
 begin
 v:=FindWindow('#32768',nil);
 pID:=0;
 GetWindowThreadProcessId(v,@pID);
 if tID<>pID then v:=0
 end;


PS: Хотя... лудше сдалать перечисление окон и сверять наше... не наше... smile

Автор: StayAtHome 2.12.2005, 04:08
Спасиб! Ларчик просто открывался -- переместить курсор на родительскй пункт меню -- подменю само откроется. Работает. Напрягаю дальше: а без перемещения курсора нельзя?
smile Обьясняю, зачем понадобился такой изврат. Контекстное меню -- в DBGrid'е. В одном из его пунктов -- выпадающее меню со списком отображаемых колонок. По моему скромному мнению, такое решение было бы весьма удобным -- нажал на пункт меню -- колонка спряталась/отобразилась, а меню снова раскрылось под курсором. И не надо открывать лишнее диалоговое окно.

Автор: Girder 6.12.2005, 00:46
Хм... для одного процесса может быть отображен только одно PopUp а субменю просто даже если и удастья вывести то оно тут же погаснет(если курсора не будет в нужном месте).

PS: Но можно запустить несколько процессов, а тогда можеш отобразить и несколько Popup за раз(ну а субменю надо просто будут вызывать из другого процесса(его экземпляр)... т.е. делать имитацию... плюс придется организовывать обмен инфы между процессами.

Автор: StayAtHome 6.12.2005, 07:53
Girder
Не, это уже перебор. smile Второй процесс создавать я не буду smile
Спасибо за помощь!

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