AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi -> SingleInstance - Parameter an Form1 übergeben
Thema durchsuchen
Ansicht
Themen-Optionen

-> SingleInstance - Parameter an Form1 übergeben

Offene Frage von "ZelltoD"
Ein Thema von ZelltoD · begonnen am 12. Okt 2008 · letzter Beitrag vom 12. Okt 2008
Antwort Antwort
Seite 1 von 2  1 2      
ZelltoD

Registriert seit: 1. Jul 2008
40 Beiträge
 
RAD-Studio 2009 Arc
 
#1

-> SingleInstance - Parameter an Form1 übergeben

  Alt 12. Okt 2008, 13:20
Servus,

Um zu erreichen, dass mein Programm nur einmal Startet und die Parameter an die erste Instanz des Programms weitergegeben werden, hab ich die Unit "Single instance" von Hagen benutzt:
Delphi-Quellcode:
unit SingleInstance;

interface

implementation

uses Windows, SysUtils, Controls, Messages, Dialogs, Forms;

type
  TSingleInstance = class
    class procedure WndProc(var Msg: TMessage);
    class procedure Start;
    class procedure Stop;
    class function GetParamStr(P: PChar; var Param: string): PChar;
    class function ParamCount: Integer;
    class function ParamStr(Index: Integer): string;

    class procedure OnStartup;
  end;

const
  sTitle = 'TESTPROGRAMM'; // dieser Wert MUSS individuell angepasst werden

class procedure TSingleInstance.OnStartup;
// diese Methode muß mit eigenen Inhalt gefüllt werden,
// als Beispiel wird hier die 1. Instance sichtbar gemacht
// und der ParamStr() der 2. Instance angezeigt.
var
  S: String;
  I: Integer;
begin
  Application.Minimize;
  Application.Restore;

  S := '';
  for I := 0 to ParamCount do
    S := S + ParamStr(I) + #10;
  ShowMessage(S);
end;

// ab hier Implementierung

const
  cMagic = $BADF00D; // dient zur Idententifizierung der Message wm_CopyData
  cResult = $DAED;

var
  WndHandle: hWnd = 0; // die 1. Instance erzeugt ein Fensterhandle
  CmdLine: PChar = nil; // ParamStr() der 2. Instance per wm_CopyData transportiert

class function TSingleInstance.GetParamStr(P: PChar; var Param: string): PChar;
// diese funktion musste aus System.pas kopiert werden für unser
// ParamStr() udn ParamCount() nötig
var
  Len: Integer;
  Buffer: array[0..4095] of Char;
begin
  while True do
  begin
    while (P[0] <> #0) and (P[0] <= ' ') do Inc(P);
    if (P[0] = '"') and (P[1] = '"') then Inc(P, 2) else Break;
  end;
  Len := 0;
  while (P[0] > ' ') and (Len < SizeOf(Buffer)) do
    if P[0] = '"then
    begin
      Inc(P);
      while (P[0] <> #0) and (P[0] <> '"') do
      begin
        Buffer[Len] := P[0];
        Inc(Len);
        Inc(P);
      end;
      if P[0] <> #0 then Inc(P);
    end else
    begin
      Buffer[Len] := P[0];
      Inc(Len);
      Inc(P);
    end;
  SetString(Param, Buffer, Len);
  Result := P;
end;

class function TSingleInstance.ParamCount: Integer;
// diese Funktion musste aus System.pas kopiert werden für unser
// ParamStr() und ParamCount() nötig da System.pas NICHT auf die
// globale Variable System.CmdLine zugreift sondern per Funktion GetCommandLine() arbeitet.
var
  P: PChar;
  S: string;
begin
  P := GetParamStr(CmdLine, S); // CmdLine statt GetCommandLine
  Result := 0;
  while True do
  begin
    P := GetParamStr(P, S);
    if S = 'then Break;
    Inc(Result);
  end;
end;

class function TSingleInstance.ParamStr(Index: Integer): string;
// siehe ParamCount
var
  P: PChar;
  Buffer: array[0..260] of Char;
begin
  if Index = 0 then
    SetString(Result, Buffer, GetModuleFileName(0, Buffer, SizeOf(Buffer)))
  else
  begin
    P := CmdLine; // CmdLine statt GetCommandLine
    while True do
    begin
      P := GetParamStr(P, Result);
      if (Index = 0) or (Result = '') then Break;
      Dec(Index);
    end;
  end;
end;

class procedure TSingleInstance.WndProc(var Msg: TMessage);
// das ist die Fensterprocedure von WndHandle, sie empfängt innerhalb
// der 1. Instance die wm_CopyData Message mit der CommandLine der
// 2. Instance
begin
  with Msg do
    if (Msg = wm_CopyData) and (PCopyDataStruct(lParam).dwData = cMagic) then
    begin
      Result := cResult;
      CmdLine := PCopyDataStruct(lParam).lpData;
      OnStartup;
    end else Result := DefWindowProc(WndHandle, Msg, wParam, lParam);
end;

class procedure TSingleInstance.Start;
var
  PrevWnd: hWnd;
  Data: TCopyDataStruct;
begin
  if MainInstance = GetModuleHandle(nil) then // nur in EXE's möglich, nicht in DLL's oder packages
  begin
    PrevWnd := FindWindow('TPUtilWindow', sTitle); // suche unser Fenster
    if IsWindow(PrevWnd) then
    begin
    // 1. Instance läuft also schon, sende CommandLine an diese
      Data.dwData := cMagic;
      Data.cbData := StrLen(GetCommandLine) +1;
      Data.lpData := GetCommandLine;
      if SendMessage(PrevWnd, wm_CopyData, 0, Integer(@Data)) = cResult then Halt;
    end;
   // keine 1. Instance gefunden, wir sind also die 1. Instance
    WndHandle := AllocateHWnd(WndProc);
    SetWindowText(WndHandle, sTitle);

// falls auch bei der 1. Instance OnStartup aufgerufen werden soll
// CmdLine := System.CmdLine;
// OnStartup;
  end;
end;

class procedure TSingleInstance.Stop;
begin
  if IsWindow(WndHandle) then DeallocateHWnd(WndHandle);
end;

initialization
  TSingleInstance.Start;
finalization
  TSingleInstance.Stop;
end.



Doch mit dem weiter geben der Parameter hab ich so meine Probleme...

Delphi-Quellcode:
[...] class procedure TSingleInstance.OnStartup;
// diese Methode muß mit eigenen Inhalt gefüllt werden,
// als Beispiel wird hier die 1. Instance sichtbar gemacht
// und der ParamStr() der 2. Instance angezeigt.
var
  S: String;
  I: Integer;
begin
  Application.Minimize;
  Application.Restore;

  S := '';
  for I := 0 to ParamCount do
    S := S + ParamStr(I) + #10;
  ShowMessage(S); //ANSTATT SCHOWMESSAGE WÜRDE ICH DIE PARAMETER GERN IN EIN MEMOFELD ÜBERTRAGEN
end; [...]
Auf dem Hauptformular (Bei mir noch Form1), hab ich ein Memo-Feld und selbst nach stundenlangen Versuchen, hab ich es nicht, hinbekommen, dass die Parameter, die eigendlich die zweite Instanz bekommen sollte in das Memo-Feld der Form1 transportiert werden.

Versuche wie Form1.memo1.lines.add sind elends fehlgeschlagen.

lg ZelltoD
  Mit Zitat antworten Zitat
dominikkv

Registriert seit: 30. Sep 2006
Ort: Gundelfingen
1.109 Beiträge
 
Delphi 2007 Professional
 
#2

Re: -> SingleInstance - Parameter an Form1 übergeben

  Alt 12. Okt 2008, 14:16
Wird bei dem Showmessage das richtige angezeigt?
Dominik
Wer anderen eine Grube gräbt, hat ein Gruben-Grab-Gerät!
  Mit Zitat antworten Zitat
ZelltoD

Registriert seit: 1. Jul 2008
40 Beiträge
 
RAD-Studio 2009 Arc
 
#3

Re: -> SingleInstance - Parameter an Form1 übergeben

  Alt 12. Okt 2008, 14:32
Ja, Showmessage zeigt das Korrekte an.
  Mit Zitat antworten Zitat
dominikkv

Registriert seit: 30. Sep 2006
Ort: Gundelfingen
1.109 Beiträge
 
Delphi 2007 Professional
 
#4

Re: -> SingleInstance - Parameter an Form1 übergeben

  Alt 12. Okt 2008, 14:40
Dann musst du unter den uses in SingleInstance deine Unit 1 angeben (oder wie du die halt genannt hast) und dann kannst du einfach über Form1.Memo1.lines.Add(S) deine parameter übergeben
Dominik
Wer anderen eine Grube gräbt, hat ein Gruben-Grab-Gerät!
  Mit Zitat antworten Zitat
ZelltoD

Registriert seit: 1. Jul 2008
40 Beiträge
 
RAD-Studio 2009 Arc
 
#5

Re: -> SingleInstance - Parameter an Form1 übergeben

  Alt 12. Okt 2008, 14:49
Das hab ich scon versucht -> die einzige Resonanz die ich dadurch bekomme:

[DCC Fehler] SingleInstance.pas(41): E2003 Undefinierter Bezeichner: 'Memo1'
  Mit Zitat antworten Zitat
dominikkv

Registriert seit: 30. Sep 2006
Ort: Gundelfingen
1.109 Beiträge
 
Delphi 2007 Professional
 
#6

Re: -> SingleInstance - Parameter an Form1 übergeben

  Alt 12. Okt 2008, 15:03
Zitat von ZelltoD:
Das hab ich scon versucht -> die einzige Resonanz die ich dadurch bekomme:

[DCC Fehler] SingleInstance.pas(41): E2003 Undefinierter Bezeichner: 'Memo1'
- gibt es ein memo mit dem namen mome1memo1?
- wie ist die sichtbarkeit von dem memo?
Dominik
Wer anderen eine Grube gräbt, hat ein Gruben-Grab-Gerät!
  Mit Zitat antworten Zitat
ZelltoD

Registriert seit: 1. Jul 2008
40 Beiträge
 
RAD-Studio 2009 Arc
 
#7

Re: -> SingleInstance - Parameter an Form1 übergeben

  Alt 12. Okt 2008, 15:53
Memo ist sichtba und enabled, und es ist das einzige mit dem Namen Memo1.
Das Andere Memo-Feld, heißt log_31 und hat mit diesem nichts zu tun.

g
  Mit Zitat antworten Zitat
dominikkv

Registriert seit: 30. Sep 2006
Ort: Gundelfingen
1.109 Beiträge
 
Delphi 2007 Professional
 
#8

Re: -> SingleInstance - Parameter an Form1 übergeben

  Alt 12. Okt 2008, 16:16
Zitat von ZelltoD:
Memo ist sichtba und enabled, und es ist das einzige mit dem Namen Memo1.
Ich meinte damit eigendlich unter welcher Sichtbarkeit das Memo deklariert ist also private oder public etc

ansonsten probiere mal das:
Delphi-Quellcode:
// in unit1:

type
  TForm1 = class(TForm)
  public
    procedure ShowParams(Params: TStringList); // diese zeile hinzufügen
  end;

//

procedure TForm1.ShowParams(Params: TStringList);
begin
  Application.Minimize;
  Application.Restore;

  Memo1.Lines := Params.Text;

  // Damit man direkt auf den n-ten Parameter zugreifen kann hab ich das als TStringList deklariert
end;



// in SingleInstance:

uses
  Unit1;

[...] class procedure TSingleInstance.OnStartup;
// diese Methode muß mit eigenen Inhalt gefüllt werden,
// als Beispiel wird hier die 1. Instance sichtbar gemacht
// und der ParamStr() der 2. Instance angezeigt.
var
  I: Integer;
  Params: TStringList;
begin
  Params := TStringList.Create;

  for I := 0 to ParamCount do
    Params.Add(ParamStr(I));

  try
    Form1.ShowParams(Params);
  finally
    Params.free;
  end;
end; [...]
Dominik
Wer anderen eine Grube gräbt, hat ein Gruben-Grab-Gerät!
  Mit Zitat antworten Zitat
ZelltoD

Registriert seit: 1. Jul 2008
40 Beiträge
 
RAD-Studio 2009 Arc
 
#9

Re: -> SingleInstance - Parameter an Form1 übergeben

  Alt 12. Okt 2008, 16:33
[DCC Fehler] SingleInstance.pas(45): E2003 Undefinierter Bezeichner: 'ShowParams' bei
Delphi-Quellcode:
try
    Form1.ShowParams(Params);
ich bin am verzweifeln...

Achja -> Mein Memo1 war schon in public deklariert.. ohne Erfolg

und -> Memo1.Text := Params.Text;....


gruß
  Mit Zitat antworten Zitat
dominikkv

Registriert seit: 30. Sep 2006
Ort: Gundelfingen
1.109 Beiträge
 
Delphi 2007 Professional
 
#10

Re: -> SingleInstance - Parameter an Form1 übergeben

  Alt 12. Okt 2008, 16:54
sicher das du in der SingleInstance uses Unit1; stehen hast? Wobei wenn das fehlen würde müsste die Fehlermeldung so lauten:
Zitat:
[DCC Fehler] SingleInstance.pas(45): E2003 Undeklarierter Bezeichner: 'Form1'
Zeig einfach mal die gesammte SingleInstance, so wie du sie momentan verwendest.
Dominik
Wer anderen eine Grube gräbt, hat ein Gruben-Grab-Gerät!
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:32 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz