Einzelnen Beitrag anzeigen

ASM

Registriert seit: 16. Aug 2004
165 Beiträge
 
Delphi 7 Enterprise
 
#9

AW: 1. Instanz nach vorn bringen, wenn 2. geöffnet wird - fensterunabhängig!

  Alt 5. Mär 2013, 18:49
Anstelle mit Hilfe von Pipes lässt sich das Problem auch grundsätzlich anders lösen:
Man kann in den diversen Formfenstern des Programms individuelle Hooks der jeweiligen WndProc setzen. Dann ist es möglich, dort die beim Start der 2.Instanz abgesetzte HWND_BROADCAST-Message abzufangen und geeignet zu behandeln:

// in der MainForm:
Delphi-Quellcode:
Interface

const
  // z.B. mit GUI-Code zweifelsfrei individualisieren
  UniqueAppTitle = 'MyApp#21218E21-EF54-45D9-AAA0-8F4E7455D5AE';
var
  UniqueAppMsg: DWord;
  
Implementation

{...}
  
initialization
  UniqueAppMsg := RegisterWindowMessage(pChar(UniqueAppTitle));
end.
// in jeder einzelnen Form-Unit (hier exemplarisch "FormX"):
Delphi-Quellcode:
Implementation

uses Mainunit; // unit der Mainform

var
  OriginalWndProc: Pointer;
  CurrentFormHandle: hWnd;

function FormX_HookedWndProc(FormHandle: hWnd; MessageID: LongInt;
  ParamW: LongInt; ParamL: LongInt): LongInt stdcall;
begin
  if MessageID = UniqueAppMsg then
  begin
    SendMessage(Application.Handle, WM_SYSCOMMAND, SC_RESTORE, 0);
    SetForegroundWindow(Application.Handle);
    SendMessage(CurrentFormHandle, WM_SYSCOMMAND, SC_RESTORE, 0);
    Result := 0;
  end
  else
   Result := CallWindowProc(OriginalWndProc, FormHandle, MessageID, ParamW, ParamL);
end;

procedure TFormX.FormCreate(Sender: TObject);
begin
  CurrentFormHandle:=FormX.Handle;
  OriginalWndProc := Pointer(SetWindowLong(CurrentFormHandle, GWL_WNDPROC,
    LongInt(@FormX_HookedWndProc)));
end;

procedure TFormX.FormDestroy(Sender: TObject);
begin
  SetWindowLong(CurrentFormHandle, GWL_WNDPROC, LongInt(OriginalWndProc));
end;
// im Projektfile:
Delphi-Quellcode:
Uses Windows, ...;
var
  Mutex: THandle;

begin
  Mutex := CreateMutex(nil, True, UniqueAppTitle);
  if (Mutex = 0) or (GetLastError = ERROR_ALREADY_EXISTS) then
  begin
    SendMessage(HWND_BROADCAST, UniqueAppMsg, 0, 0);
    Halt(0);
  end
  else
  try
    Application.Initialize;
    {...}
  finally
    if Mutex <> 0 then CloseHandle(Mutex);
  end;
  Mit Zitat antworten Zitat