Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Меню в чужом окне  (Прочитано 6527 раз)
0 Пользователей и 1 Гость смотрят эту тему.
aMoraleZ
Гость
« : 13-12-2003 11:08 » 

Помогите разобраться! Внедряю свой пункт меню в _чужое_ приложение, делаю это так:
...
procedure TForm1.Button1Click(Sender: TObject);
var lh: Cardinal;
    pa: Pointer;
    r: integer;
begin
  {Ищем по заголовку}
  TheHWND := FindWindow(nil, PChar('Калькулятор'));
  if TheBatHWND <> 0 then
  begin
    TheMenu:= GetMenu(TheHWND);
    AppendMenu(TheMenu,MF_POPUP,PopupMenu1.Handle,'hello');
  end;
  sethook;
end;

Меню добавляется, но как теперь обрабатывать события этого меню? Делаю hook, в DLL:

function myhook(code, wParam, lParam : integer): Lresult; stdcall;
begin
  if code >= 0 then
  begin
    case code of
      MSGF_MENU:
      begin
        messagebox(0,'get it!','i get it!',mb_iconhand);
      end;
    end;
  end;
 result := CallNextHookEx(mHandle, code, wParam, lParam);
end;

procedure sethook;
begin
  mHandle:= SetWindowsHookEx(WH_SYSMSGFILTER, @myhook, hInstance, 0);
  if mHandle = 0 then
    messageBox(0,'Error','ERROR',mb_iconhand);
end;

messageBox выскакивает при нажатии на любое меню, а хотелось бы что бы на только то,
что создал я. Понимаю, что нужно смотреть lParam, но что там отслеживать?

Меню которое я добавляю имеет вид:
Мое меню
-Пункт один
-Пункт два
------------
-О программе

Нужно обрабатывать выбор каждого пункта. Прошу учесть, что меню именно в _чужом_ окне.

Спасибо.
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #1 : 13-12-2003 11:40 » 

aMoraleZ, Возникает вопрос почему ты не используешь своё TheMenu не посредственно типа того TheMenu.OnSomething = OnSomeThingDoFunction
и
другой вопрос разве нельзя навесить hook на конкретный пункт вроде каждый пункт меню отдельный объект.  Отлично  Это я так про тестить ща немогу.(под Линью сижу). Ага
Записан

Странно всё это....
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #2 : 13-12-2003 14:45 » 

можно повесить хук на WM_MEASUREITEM ему в параметрах передается структура по которой можно определить твоя кнопень нажалась или нет. Сам не пробовал.
Записан

Странно всё это....
cg_spooler
Гость
« Ответ #3 : 23-12-2003 07:43 » 

А нафига тебе каркулятор с твоим меню?
Записан
Anonymous
Гость
« Ответ #4 : 24-12-2003 11:49 » new

Цитата: cg_spooler
А нафига тебе каркулятор с твоим меню?

Конспирация батенька ) Это так для примера просто взято. А вообще, переделал так:
{*в программе: *}
...
procedure TForm1.Button1Click(Sender: TObject);
begin
  TheHWND:= FindWindow(Nil,'Калькулятор!');
    if TheHWND <> 0 then TheHMENU:= GetMenu(TheHWND)
    else MessageBox(0,'Can`t find Calc window!','Error!',mb_iconhand);
  myPopUPMenu:= CreatePopUpmenu();
  InsertMenu(myPopUpMenu,0,MF_BYPOSITION,ID_MENU_1,'MenuItem1');
  InsertMenu(myPopUpMenu,1,MF_BYPOSITION,ID_MENU_2,'MenuItem2');
  InsertMenu(myPopUpMenu,2,MF_BYPOSITION,ID_MENU_3,'MenuItem3');
  AppendMenu(TheHMENU,MF_POPUP, myPopUpMenu,'Test');
  SetMenuHandler();
end;

В DLL вынесен hook:
{*в dll: *}

function MenuHandler(nCode, wParam, lParam: integer): lResult; stdcall;
begin
  if nCode = MSGF_MENU then
  begin
    mhMSGStruct:= PMSG(lParam)^;
    case mhMSGStruct.message of
    WM_LBUTTONDOWN:
      begin
        if (GetMenu(mhMSGStruct.hwnd) = GetMenu(FindWindow(Nil,'Калькулятор'))) then
         begin
           messagebox(0,PChar(inttostr(lo(mhMSGStruct.wParam))),'foo',mb_iconhand);
           result:= CallNextHookEx(mhHandle,nCode,wParam,lParam);
           Exit;
         end;
      end;
    else
      begin
        result:= CallNextHookEx(mhHandle,nCode,wParam,lParam);
        Exit;
      end;
    end;
  end;
  result:= CallNextHookEx(mhHandle,nCode,wParam,lParam);
end;

function SetMenuHandler(): boolean; stdcall;
begin
  mhHandle:= SetWindowsHookEx(WH_MSGFILTER, @MenuHandler, hInstance,0);
  if (mhHandle <> 0) then result:= false else
  result:= true;
end;

Меню добавляется, хук ловит клики мышью, но проблема в том, что после обработки
сообщения WM_LButtonDown оно попадет и в Calc, т.е допустим мое меню открылось и
перекрыло собой пару кнопок, так вот, после щелчка по пункту моего меню, хук его ловит,
но ловит этот щелчек и Сalc, и нажимается кнопка которую перекрыло собой мой меню,
как будто оно прозрачное. Как от этого избавиться. Нужно что бы на клики по меню,
срабатывал только обработчик моего меню. )

Посмотрю  WM_MEASUREITEM, что то похоже но не знаю...
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines