В данной статье мы рассмотрим проблему внедрения динамической библиотеки (DLL) в другой процесс с целью изменения главного меню этого процесса и обработки событий клика по добавленному элементу меню. Мы будем использовать язык программирования Object Pascal, который является основным для среды разработки Delphi.
Проблема
Разработчик столкнулся с проблемой, при которой внедрение DLL в другой процесс для добавления элемента в главное меню приводило к сбою этого процесса, если не комментировать строку, отвечающую за установку нового обработчика сообщений окна. В случае комментирования этой строки, элемент меню добавлялся, но его обработчик событий клика не вызывался.
Контекст
Данный код представляет собой попытку внедрения DLL, где используется функция SetWindowLong для замены стандартного обработчика сообщений окна на пользовательский. Однако, в коде присутствует ошибка, связанная с неправильной работой функции CallWindowProc и некорректной обработкой сообщений.
Код
library test;
uses
Winapi.Windows,
Winapi.Messages,
System.Classes,
System.Generics.Collections;
{$R *.res}
var
LSysMenu : HMenu;
OldWndProc: TFarProc;
function NewWndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): Longint; stdcall;
begin
case Msg of
WM_COMMAND:
if (LoWord(wParam) = 2000) then
MessageBox(HWND_DESKTOP, 'You pressed our new menu button!', 'Yay!', MB_OK);
Result := CallWindowProc(OldWndProc, hWnd, Msg, wParam, lParam);
end;
var
HwndWind:HWND;
begin
HwndWind := FindWindow(nil, PChar('Test App'));
if HwndWind <> 0 then
begin
LSysMenu := GetMenu(HwndWind);
LSysMenu := GetSubMenu(LSysMenu, 3);
AppendMenu(LSysMenu, MF_STRING, 2000, 'test');
DrawMenuBar(HwndWind);
OldWndProc := TFarProc(SetWindowLong(HwndWind, GWL_WNDPROC, LONG(@NewWndProc)));
end;
end.
Подтвержденный ответ
Проблема заключается в неправильной работе с функцией CallWindowProc и обработке сообщений. В функции NewWndProc необходимо правильно обрабатывать сообщение WM_COMMAND и идентификатор команды. Также, при вызове SetWindowLong необходимо корректно привести возвращаемое значение к типу TFarProc.
Исправленный код функции NewWndProc должен выглядеть следующим образом:
function NewWndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): Longint; stdcall;
begin
case Msg of
WM_COMMAND:
if (LoWord(wParam) = 2000) then
begin
// Обработка события клика по элементу меню
MessageBox(HWND_DESKTOP, 'You pressed our new menu button!', 'Yay!', MB_OK);
end;
Result := CallWindowProc(OldWndProc, hWnd, Msg, wParam, lParam);
end;
end;
Заключение
После внесения исправлений в код, добавление элемента в меню и обработка событий клика по нему должны работать корректно. Важно помнить о корректной обработке сообщений и правильном использовании функций для работы с окнами и сообщениями в Windows API.
Решение состоит в исправлении ошибок при внедрении DLL и настройке обработчика сообщений для изменения меню процесса в Delphi.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS