Autor Beitrag
JacFab
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 111



BeitragVerfasst: Sa 25.01.03 16:55 
Ich hab mein Programm für den Dateityp *.bmp registriert, aber möchte, dass alle im Explorer markierten Dateien in der selben Instanz des Programms geöffnet werden. Zur Zeit öffnet jede Datei ein eigenes Fenster. Wie vermeide ich das??
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 25.01.03 17:09 
Am besten, indem du

1. einen Mutex für dein Programm schreibst, der nur eine Instanz zulässt
2. mit Hilfe der Nachricht WM_COPYDATA den Parameter jeder weiteren, geladenen Instanz an die bereits laufende weiterreichst
Andreas Pfau
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 997



BeitragVerfasst: Sa 25.01.03 17:14 
Ohne DDE gar nicht (oder nur mit extremem Aufwand). DDE geht so:

Du hast ja in der Registry einen Kea angelegt, sagen wir mal, "HKCR\Paint.Picture\Shell\MeinProg". Dort ist dein Command-Ordner. Im Ordner "MeinProg" (oder so ähnlich) legst du den Ordner "DdeExec" an. Der Standard-String hat den Wert "%1". Unterordner "Application" anlegen, Standard-String = "MeinProg". Zurück in "DdeExec" Unterordner "Topic" anlegen, Standard="OpenFile".

Jetzt lädtst Du dein Delphi-Projekt. Den Code zum auswerten der Parameters löschen, den brauchst du für DDe nicht. Dann fügst du die Komponente "TDDEServerConv" ein, Name = "OpenFile". Im Event "OnExecuteMacro" das hier eintragen:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
var
 I: Integer;
begin
 For I := 0 To Msg.Count - 1 Do begin
  If FileExists(Msg[I]) Then
   OpenFile(Msg[I]);
 end;

wobei du OpenFile() delbst deklarieren musst. Die Prozedur lädt ganz einfach die angegebene Datei.
JacFab Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 111



BeitragVerfasst: Sa 25.01.03 18:11 
ja, dann wird das prog nur einmal geöffnet, aber die parameter kommen nur einmal an!
Andreas Pfau
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 997



BeitragVerfasst: Sa 25.01.03 18:24 
Immer, wenn das Ereignis von TDDEServerConv aufgerufen wird, kommen neue Dateinamen. Konsolenparameter gibt's keine mehr, läuft alles über DDE. Evtl. kommen mehrere Dateiamen auf einmal, daher ja auch die Schleife.

Noch fragen? :wink:
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 25.01.03 18:52 
Andreas Pfau hat folgendes geschrieben:
Ohne DDE gar nicht (oder nur mit extremem Aufwand).

Sagen wir als Beispiel: ein VCL-Projekt. Eine neue Nachricht und eine Zeile in der Unit bezeichnest du als extremen Aufwand? Dazu kommen im Projektquelltext noch ein paar Zeilen zum Senden des Parameters. :)

Mutex-Code und WM_COPYDATA; als Beispiel im Projektquelltext (*.dpr):
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
var
  cpydata : TCopyDataStruct;
begin
  hm := CreateMutex(nil,false,'MeinProgramm_Version1.0');
  if(GetLastError = ERROR_ALREADY_EXISTS) then begin

    // Parameter übermitteln
    if(paramcount = 1) then begin
      cpydata.dwData := 0;
      cpydata.cbData := length(paramstr(1)) + 1;
      cpydata.lpData := @paramstr(1)[1];

      // Fenster der alten Instanz suchen
      // (als Beispiel die VCL-Version)
      aWnd := findwindow('TForm1','Form1');
      if(aWnd <> 0) then
        SendMessage(aWnd,WM_COPYDATA,0,LPARAM(@cpydata));
    end;

    // diese Instanz beenden!
    Halt;
  end;

  // der Rest vom DPR-Quelltext
  { ... }

  CloseHandle(hm);
end.

Abfrage des Parameters:
  • Non-VCL (am Beispiel einer Dialogprozedur):
    ausblenden Quelltext
    1:
    2:
    3:
    4:
    5:
    6:
    7:
    8:
    9:
    10:
    11:
    12:
    13:
    14:
    15:
    16:
    17:
    18:
    function dlgproc(hwndDlg: HWND; uMsg: UINT; wp: WPARAM; lp: LPARAM): bool; stdcall;
    var
      buf : array[0..MAX_PATH]of char;
    begin
      Result := true;

      case uMsg of
        WM_COPYDATA:
          begin
            ZeroMemory(@buf,sizeof(buf));
            lstrcpyn(buf,PCopyDataStruct(lp)^.lpData,PCopyDataStruct(lp)^.cbData);

            MessageBox(hwndDlg,buf,'Empfangen ->',0);
          end;
        else
          Result := false;
      end;
    end;

  • VCL:
    ausblenden Quelltext
    1:
    2:
    3:
    4:
    5:
    6:
    7:
    8:
    9:
    10:
    11:
    12:
    13:
    14:
    15:
    type
      TForm1 = class(TForm)
        { ... }
      private
        procedure WmCopyData(var Msg: TWMCopyData); message WM_COPYDATA;
      { ... }


    procedure TForm1.WmCopyData(var Msg: TWMCopyData);
    var
      buf    : array[0..MAX_PATH]of char;
    begin
      StrLCopy(buf,Msg.CopyDataStruct.lpData,Msg.CopyDataStruct.cbData);
      MessageBox(Form1.Handle,buf,'Empfangen ->',0);
    end;


Gruß.
Andreas Pfau
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 997



BeitragVerfasst: Sa 25.01.03 19:40 
Na ja, @Mathias, so geht's auch. Aber eines ist mir ein Dorn im Auge: Wenn ich weder Die caption noch die Klasse kenne (z.B. habe ich ja bei jedem Delphi-Programm "TForm", und Die Caption kann je nach geöffneter Datei anders sein), wie kann ich dann das Fenster-Handle rausfinden? Ich würde das auch so machen wie Du, aber wie kann ich das Handle global speichern? Klar, Registry, aber gibt es auch eine professionelle Lösung???
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Sa 25.01.03 20:02 
Andreas Pfau hat folgendes geschrieben:
Klar, Registry

Da würde ich dann lieber MMFs einsetzen.


Du könntest deinem Formular eine Botschaft hinzufpgen (RegisterWindowMessage) und dann alle Formulare mit EnumWindows durchlaufen. Das Formular, dass eine bestimmte Antwort auf diese Botschaft gibt, ist dann das gesuchte.

Diese Komponente dürfte etwas für dich sein.

_________________
Ist Zeit wirklich Geld?
Andreas Pfau
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 997



BeitragVerfasst: Sa 25.01.03 22:00 
Danke, @Andy, aber was ist eine MMF? Ehrlich gesagt, das habe ich noch nie gehört und kann mir rein gar nix drunter vorstellen.
Rool
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 211



BeitragVerfasst: So 02.02.03 18:48 
Titel: Irgendwas funzt nicht!!!
Hab die Methode von MathiasSimmack mal ausprobiert, vom Kontext-Menu des Dateityps funktionierts ja, aber wie übergebe ich diese Parameter per Code (ShellExecute) oder mit Start->Ausführen ???
Habs so versucht: "C:\Prog.exe" "Datei1" "Datei2" usw. aber das geht nicht!!!
Was muss ich aufrufen???

_________________
MFG Rool
GSE
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 740

Win 2k, Win XP Pro
D5 Prof, D6 Ent, D2k5 PE
BeitragVerfasst: So 02.02.03 20:28 
Hab´ was bei Torry gefunden:
www.torry.net/samples_software.htm

->How to prevent a second instance
By Theodoros Bebekis. Example on How to prevent a second instance of application and take its parameters.

Funktioniert (verwende es selbst in meinen Programmen)!

mfg
GSE

_________________
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs
and the universe trying to produce bigger and better idiots. So far, the universe is winning. (Richard Cook)
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 02.02.03 21:24 
Titel: Re: Irgendwas funzt nicht!!!
Rool hat folgendes geschrieben:
aber wie übergebe ich diese Parameter per Code (ShellExecute) oder mit Start->Ausführen ???
Habs so versucht: "C:\Prog.exe" "Datei1" "Datei2" usw. aber das geht nicht!!!
Was muss ich aufrufen???

Da ich via WM_COPYDATA nur den ersten Parameter an die laufende Instanz weiterreiche, sollte der Aufruf von
ausblenden Quelltext
1:
prog.exe Datei1					

erfolgreich sein. Die zweite Variante wäre eine for-Schleife, die sich durch die übergebenen Parameter "loopt" und jeden nacheinander an die laufende Instanz weiterreicht. Dann, und wirklich erst dann!, kannst du auch
ausblenden Quelltext
1:
prog.exe Datei1 Datei2 ...					

aufrufen.
Rool
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 211



BeitragVerfasst: Mo 03.02.03 13:58 
Titel: Jau...
Ok, alles klar, wenn mans dann noch mit Anführungszeiczhen macht, kann man auch Dateinamen mit Leertasten übergeben!

Danke vielmals!!!

_________________
MFG Rool
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 03.02.03 15:03 
Na ja meine Taste wollte ich schon noch behalten :mrgreen:. Du redest wohl von Leerzeichen :wink:
Rool
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 211



BeitragVerfasst: Mo 03.02.03 15:33 
Titel: ;-)))
Ja logo, sorry natürlich meine ich ZEICHEN!!! :D

_________________
MFG Rool