На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! user posted image
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.

Соблюдайте общие правила форума

Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как запустить программу/файл? (и дождаться ее завершения)
5. Как перехватить API-функции, поставить hook? (перехват сообщений от мыши, клавиатуры - внедрение в удаленное адресное прстранство)
... (продолжение следует) ...

Внимание:
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки - бан.
Мат в разделе - бан на три месяца...

Полезные ссылки:
user posted image MSDN Library user posted image FAQ раздела user posted image Поиск по разделу user posted image Как правильно задавать вопросы


Выразить свое отношение к модераторам раздела можно здесь: user posted image Rouse_, user posted image Krid

Модераторы: Rouse_, Krid
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> Как воздействовать на контекстное меню? , "отменить","вырезать","копировать",...
    Здравствуйте. У меня такой вопрос - как "воздействовать" на стандартное меню, которое появляется при нажатии правой кнопки мыши в поле для ввода текста ("отменить","вырезать","копировать" и т.д.), например, в TEdit, TF1Book. В смысле, запретить/разрешить 1 из пуктов. По идее, надо ловить какое-то сообщение, но не знаю, какое. Думал - WM_CONTEXTMENU, WM_INITMENUPOPUP, нет, не то
      Цитата
      The EnableMenuItem function enables, disables, or grays the specified menu item.

      BOOL EnableMenuItem(

      HMENU hMenu, // handle to menu
      UINT uIDEnableItem, // menu item to enable, disable, or gray
      UINT uEnable // menu item flags
      );
        Эта функция получает хэндл меню и разрешает/запрещает его пункты. Как мне получить HMENU, если это не моё меню, т. е. в программе я его не создаю?
          vet, HMENU родного меню EDIT'а, имхо ты никак не получишь. Можешь просто задать свое PopupMenu для TEdit'а
          ExpandedWrap disabled
            Edit1.PopupMenu:=PopupMenu1;

          и делать с ним все, что душа пожелает.
            Цитата Krid @
            vet, HMENU родного меню EDIT'а, имхо ты никак не получишь.

            Да ну брось ты, нет ничего не возможного :)

            ExpandedWrap disabled
              unit Unit1;
               
              interface
               
              uses
                Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
                Dialogs, StdCtrls, Menus;
               
              type
                TForm1 = class(TForm)
                  Edit1: TEdit;
                private
                  procedure WMContextMenu(var Message: TWMContextMenu); message WM_CONTEXTMENU;
                end;
               
              var
                Form1: TForm1;
               
              implementation
               
              var
               HookHandle: DWORD = 0;
               
              {$R *.dfm}
               
              function MsgProc(Code: Integer; WParam: Integer; LParam: PCWPStruct): Integer; stdcall;
              var
                Menu: HMENU;
                ItemCount, I: Integer;
              begin
                if (Code = HC_ACTION) then
                  case LPARAM.message of
                    WM_MENUSELECT:
                    begin
                      Menu := LParam^.lParam; // Вот он хэндл меню
                      ItemCount := GetMenuItemCount(Menu);
                      for I := 0 to ItemCount - 1 do
                        EnableMenuItem(Menu, GetMenuItemID(Menu, I), MF_DISABLED or MF_GRAYED);
                      UnhookWindowsHookEx(HookHandle);
                      HookHandle := 0;
                    end;
                    $01E2: // это типа заставляем реагировать на WM_MENUSELECT до появления окна...
                      SendMessage(LPARAM.HWND, $1E5, 0, 0);
                  end;
                MsgProc := CallNextHookEx(HookHandle, Code, WPARAM, DWORD(LPARAM));
              end;
               
              procedure TForm1.WMContextMenu(var Message: TWMContextMenu);
              begin
                if HookHandle <> 0 then UnhookWindowsHookEx(HookHandle);
                HookHandle := SetWindowsHookEx(WH_CALLWNDPROC, @MsgProc, 0, GetCurrentThreadId);
              end;
               
              end.
              :yes:
              Я и сам потом понял, что поспешил с выводами. Все-таки не надо забывать про подпись Song:)
              Вот еще вариант
              ExpandedWrap disabled
                unit Unit1;
                 
                interface
                 
                uses
                  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
                  Dialogs, StdCtrls;
                 
                type
                  TForm1 = class(TForm)
                    Edit1: TEdit;
                    procedure FormCreate(Sender: TObject);
                  private
                    { Private declarations }
                  public
                    { Public declarations }
                  end;
                 
                var
                  Form1: TForm1;
                 
                implementation
                 
                {$R *.dfm}
                 
                var
                 fb:boolean=true;
                 
                function NewEditProc(wnd:HWND; uMsg:UINT; wParam:WPARAM; lParam:LPARAM):integer; stdcall;
                const
                 MN_SELECTITEM = $1E5;
                begin
                 case uMsg of
                 WM_ENTERIDLE: if (wParam=MSGF_MENU) and fb then
                               begin SendMessage(lParam, MN_SELECTITEM, 0, 0); fb:=false end;
                 WM_MENUSELECT:
                      begin
                        if (lParam=0) and (HIWORD(DWORD(wParam))=word(-1)) then fb:=true else
                        if fb then
                        begin
                         // извращаемся над меню  
                         EnableMenuItem(lParam, GetMenuItemID(lParam, 2), MF_DISABLED or MF_GRAYED);
                         DeleteMenu(lParam,1,MF_BYPOSITION);
                         DeleteMenu(lParam,5,MF_BYPOSITION);
                        end
                      end;
                 end;
                   result:=CallWindowProc(Pointer(GetWindowLong(wnd,GWL_USERDATA)),wnd,uMsg,wParam,lParam)
                end;
                 
                procedure TForm1.FormCreate(Sender: TObject);
                begin
                 SetWindowLong(Edit1.Handle,GWL_USERDATA,SetWindowLong(Edit1.Handle, GWL_WNDPROC, LPARAM(@NewEditProc)))
                end;
                 
                end.
                Цитата Krid @
                WM_ENTERIDLE: if (wParam=MSGF_MENU) and fb then
                begin SendMessage(lParam, MN_SELECTITEM, 0, 0); fb:=false end;

                во-во, это как раз та ж, о которой я так недавно говорил :lol:
                  Она самая :)
                  Это окно можно еще WinEventHook'ом достать, но это еще бОльшая ж. :)
                    Спасибо за помощь, значит, я в правильном направлении думал (WM_CONTEXTMENU). Работает, второй вариант ещё не пробовал. Ещё вопрос насчёт $01E2 - что это, в Messages такого нет?
                      А не подскажите как отследить движение мышки на компоненте PopupMenu? Интересует именно то, что нужно узнать над каким Item' ом он находится, т.к. у Item' ов нет свойства OnMouseMove.
                        Перехват сообщения WM_MENUSELECT (проще через хук как в #5), плюс код определения MenuItem по ItemID - можно взять из исходника TPopupList.WndProc в модуле menus.pas
                          Цитата leo @
                          Перехват сообщения WM_MENUSELECT (проще через хук как в #5), плюс код определения MenuItem по ItemID - можно взять из исходника TPopupList.WndProc в модуле menus.pas

                          Есть небольшой опыт, но он почему-то работает только с MainMenu, В чём проблема может быть?

                          ExpandedWrap disabled
                            unit main;
                             
                            interface
                            uses
                               Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
                               Dialogs, Menus, StdCtrls;
                             
                            type
                               TForm1 = class(TForm)
                                 lbl1: TLabel;
                                 suiPopupMenu1: TsuiPopupMenu;
                               private
                                 procedure WmMenuSelect (var Message: TMessage); message WM_MENUSELECT;
                               end;
                             
                            var
                               Form1: TForm1;
                             
                            implementation
                             
                            {$R *.dfm}
                             
                            { TForm1 }
                             
                            procedure TForm1.WmMenuSelect(var Message: TMessage);
                            var
                               Item: TMenuItem;
                               I: Integer;
                            begin
                               Item := suiPopyupMenu1.FindItem(Message.LParam, fkHandle);
                               if Assigned(Item) then
                                 for I := 0 to Item.Count - 1 do
                                   if Item.Items[I].Command = Message.WParamLo then
                                     lbl1.Caption:= Item.Items[I].Caption); //Записываем выбранный Item
                            end;
                             
                            end.
                            Цитата eclipse_99 @
                            В чём проблема может быть?

                            В том, что родительским окном для всех PopupMenu является не форма, а PopupList.Window. Поэтому нужно либо подменять его WndProc через SetWindowLong, либо проще - использовать хук SetWindowHookEx
                              Код в #5\WM_CONTEXTMENU не работает при первом ПКМ на TEdit.
                              Но работает при ПКМ на самой форме.
                              Delphi XE3...
                              Сообщение отредактировано: BugMeNot -
                                Цитата BugMeNot @
                                Код в #5\WM_CONTEXTMENU

                                Зачем тебе вообще WM_CONTEXTMENU? С ним такая же проблема, как и WM_MENUSELECT - шлется родительскому окну меню, которое не обязано быть именно формой.

                                Можно просто установить хук в FormCreate и снять в FormDestroy, а "включать\выключать" его установкой доп.глобальной переменной HookOn:boolean - если установлена, то что-то делаешь в процедуре хука, если нет, то сразу вызываешь CallNextHookEx
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0375 ]   [ 17 queries used ]   [ Generated: 19.04.24, 19:43 GMT ]