Вопрос управления окнами и их активностью является актуальной задачей для разработчиков, использующих среду Delphi и язык программирования Pascal. Одной из функций, которая позволяет управлять актуальностью окон, является AllowSetForegroundWindow. Рассмотрим, как правильно использовать эту функцию для переключения фокуса на другое окно.
Проблема
Пользователь столкнулся с проблемой при попытке переключения активности между двумя приложениями, написанными на Delphi. В первом приложении есть кнопка, которая запускает второе приложение, передавая ему обработку окна и идентификатор процесса через WinExec. Во втором приложении также предусмотрена кнопка, активирующая окно первого приложения через AllowSetForegroundWindow. Однако, при попытке активации, второе приложение выдает ошибку.
Код, вызывающий проблему
procedure TForm1.Button1Click(Sender: TObject);
begin
WinExec(PChar('Second.exe ' + IntToStr(Handle) + ' ' + IntToStr(GetCurrentProcessId)), SW_SHOWDEFAULT);
end;
function AllowSetForegroundWindow(AHandle: HWND): Boolean; external 'user32.dll';
procedure TForm1.Button2Click(Sender: TObject);
begin
if not AllowSetForegroundWindow(StrToInt(ParamStr(2))) then begin
ShowMessage('ERROR');
Exit;
end;
SendMessage(StrToInt(ParamStr(1)), WM_APP + 1, 0, 0);
end;
procedure TForm1.WWAppPlusOne(var Msg: TMsg);
begin
Application.BringToFront;
end;
Ошибка в коде
Ошибка заключается в некорректной декларации функции AllowSetForegroundWindow. Не указаны необходимые параметры вызова, такие как соглашение о вызовах и корректные типы данных. Также использование WinExec считается устаревшим и не рекомендуется для новых проектов.
Правильное использование AllowSetForegroundWindow
Для корректного использования AllowSetForegroundWindow необходимо исправить декларацию функции, добавив соглашение о вызовах stdcall и корректные типы данных:
function AllowSetForegroundWindow(dwProcessId: DWORD): BOOL; stdcall; external 'user32.dll';
Кроме того, для передачи управления окном лучше использовать функцию CreateProcess вместо WinExec.
Пример корректного кода
var
StartupInfo: TStartupInfo;
ProcessInformation: TProcessInformation;
begin
with StartupInfo do
begin
cb := SizeOf(TStartupInfo);
dwFlags := STARTF_USESHOWWINDOW;
wShowWindow := SW_SHOW;
end;
if CreateProcess(nil, PChar('Second.exe ' + IntToStr(Handle) + ' ' + IntToStr(GetCurrentProcessId)), nil, nil, FALSE,
CREATE_DEFAULT_ERROR_MODE, nil, nil, @StartupInfo, ProcessInformation) then
begin
// Запуск успешный
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if not AllowSetForegroundWindow(DWORD(StrToIntDef(ParamStr(2), 0)))) then
ShowMessage('ERROR')
else
SendMessage(DWORD(StrToIntDef(ParamStr(1), 0))), WMBringToForegroundWindow, 0, 0);
end;
procedure TForm1.WMBringToForegroundWindow(var Msg: TMsg);
begin
Application.BringToFront;
end;
Эти изменения позволят корректно активировать окно другого приложения и избежать возникновения ошибок.
Заключение
Использование AllowSetForegroundWindow требует внимательности к деталям, таким как соглашение о вызовах и типы данных. Применение современных методов, таких как CreateProcess, вместо устаревших функций, таких как WinExec, повысит надежность и безопасность приложений, написанных на Delphi.
Управление актуальностью окон между приложениями на Delphi с использованием функции `AllowSetForegroundWindow`.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.