![]() |
|
|
#1
|
|||
|
|||
|
Уважаемые,
пытаюсь сделать: при попытке пользователя запустить второй экземпляр программы, отобразить первый, несмотря на его состояние (свернут, не активен..) получаю:результат успешен, однако после проведенных операций фигурирует баг. баг: после восстановления окна первого экземпляра не работает функция сворачивания окна. При этом закрыть окно и максимизировать его возможно. Код:
h := FindWindow('TfrmMain','%form_title%');
if h <> 0 then
begin
//если окно не отображено на экране
//то максимизировать его
if not IsWindowVisible(h) then
ShowWindow(h,sw_showmaximized);
//выставляем окно на передний план
SetForeGroundWindow(h);
end
else
begin
Application.Initialize;
...
Application.Run;
end; |
|
#2
|
||||
|
||||
|
Код:
procedure BringToFront(AHandle: HWND); var AThreadId: Cardinal; AProcessId: Cardinal; begin AThreadId:=GetCurrentThreadId; AProcessId:=GetWindowThreadProcessId(GetForegroundWindow, nil); AttachThreadInput(AThreadId, AProcessId, True); ShowWindow(AHandle, SW_RESTORE); SetForegroundWindow(AHandle); AttachThreadInput(AThreadId, AProcessId, False); end; |
|
#3
|
|||
|
|||
|
Не помогло
![]() |
|
#4
|
||||
|
||||
|
это работает? http://zalil.ru/34833170
Последний раз редактировалось NumLock, 02.12.2013 в 15:38. |
|
#5
|
|||
|
|||
|
А нельзя закинуть на нормальный файлообменник? А то мне не скачать.
|
|
#6
|
||||
|
||||
|
|
|
#7
|
|||
|
|||
|
Программа запускается (DownloaderLite.exe). В ней всё прекрасно работает.
|
|
#8
|
||||
|
||||
|
Мое мнение - все дело в параметре sw_showmaximized в ShowWindow. Используй вместо него sw_Restore или т.п. Наверное, система просто показывает окно, не давая себе отчет, что оно развернутое, считая его и дальше свернутым.
|
|
#9
|
|||
|
|||
|
По вышеуказанному примеру NumLock'a выполнял SW_RESTORE, однако изменений не заметил.
|
|
#10
|
||||
|
||||
|
А так?
Код:
Application.Initialize;
h := FindWindow('TForm1','ABCD');
if h <> 0 then
begin
if not IsWindowVisible(h) then
ShowWindow(h,SW_RESTORE);
setWindowPos(h, HWND_TOPMOST, 0, 0, 0, 0,SWP_SHOWWINDOW or SWP_NOMOVE or SWP_NOSIZE);
end
else
begin
Application.CreateForm(TForm1, Form1);
Application.Run;
end;
Последний раз редактировалось YVitaliy, 02.12.2013 в 16:39. |
|
#11
|
||||
|
||||
|
на самом деле все зависит от версии Delphi. либо от VCL или API.
|
|
#12
|
|||
|
|||
|
У меня вот такой код работает, вроде, стабильно:
Код:
function TMainForm.HookMessageProc(var Message: TMessage): Boolean;
begin
Result := False;
If Message.Msg = WndMessage Then
Begin
TrayIcon.ShowMainForm;
Application.BringToFront;
SetForegroundWindow(Self.Handle);
Result := True;
End;
end;TrayIcon - это, на самом деле, TCoolTrayIcon. Собственно, там есть только одна закавыка. Под Vista и 7 надо что бы второй экземпляр отдал разрешение на всплытие окна другого процесса, иначе операционка откажется его активировать. |
|
#13
|
||||
|
||||
|
Такой глюк возникает из-за того, что в ShowWindow нужно указывать хэндл не "главной" формы, а главного окна, т.е. Application.
У себя я делал проще - создавал собственное сообщение - примерно так: Код:
const
MY_RESTORE = WM_APP + 1;
type
TfrmMain = class(TForm)
.....
private
{ Private declarations }
procedure MyRestore(var Message: TMessage); message MY_RESTORE;
.....
implementation
.....
procedure TfrmMain.MyRestore(var Message: TMessage);
begin
Application.Restore;
end;тогда в файле проекта будет примерно так: Код:
var
h: HWND;
begin
h := FindWindow('TfrmMain', '%form_title%');
if h <> 0 then
begin
SendMessage(h, MY_RESTORE, 0, 0);
SetForeGroundWindow(h);
end else
begin
Application.Initialize;
Application.CreateForm(TfrmMain, frmMain);
Application.Run;
end;
end. |
|
#14
|
||||
|
||||
|
Вариантов существует множество, я использую Mutex.
|
|
#15
|
||||
|
||||
|
Присоединяюсь к варианту poli-smen, много раз делал при помощи обработки Message - всё работало прекрасно.
P.S. Рекламу из подписи таки стоит убрать, ибо Цитата:
Последний раз редактировалось PhoeniX, 03.12.2013 в 00:07. |