Avatar billede kastermester Nybegynder
22. december 2002 - 00:34 Der er 30 kommentarer og
1 løsning

Hvis program er åben send paramenter der åbner fil og luk sig sel

Ja, emnet siger jo næsten sig selv.

Jeg er som så mange andre ved at kode en web-editor. Og det jeg ønsker er i min mainforms oncreate event skal der chekkes for om programmet er åbn en gang i forvejen. Er det det så skal der sendes en paramenter til programmet som åbner den fil man forsøgte at åbne (altså, kun hvis man da forsøgte at åbne det) laver "SetForegroundWindow(hwnd) og lukker sig selv. Indtil videre er jeg ikke nået længere end noget alla det her:

var
  Hwnd: integer;
  CaptionName: string;
begin
  CaptionName := 'Smart Edit';
  Hwnd := FindWindow(nil, PChar(CaptionName));
  If Hwnd > 0 then
  begin
      SetForegroundWindow(Hwnd);
      Close;
  end;
end;

Så det jeg ønsker er altså at sende paramenter til mit program og behandle dem, jeg har forsøgt mig lidt med SendMessage og Så lave en Application.OnMessage event i min mainform, nogen der har en løsning?

Kastermester
Avatar billede dkn Nybegynder
22. december 2002 - 03:29 #1
//    .........
  private
    { Private declarations }
//    .........
    procedure WMCopyData(var msg:TWMCopyData); message WM_COPYDATA;
  public
    { Public declarations }
//    .........
  end;


implementation


procedure TfrmDinMainForm.WMCopyData(var msg: TWMCopyData);
var s:string;
begin
  s := PChar(msg.CopyDataStruct.lpData);
  Application.BringToFront;
  showmessage('Besked modtaget:'+s);
end;


//I din project fil (DPR)


uses
  Windows, messages;


var handle: THandle;
    cds: TCopyDataStruct;
    fMutex: THandle;
    s:string;
    i:integer;
begin
  // Ser om dit program kører vedhjælp af mutex

  fMutex := CreateMutex(nil,false,'DitUnikeMutexNavn');    // <-- Skift den til noget langt og unikt :)
  if ( GetLastError() = ERROR_ALREADY_EXISTS ) or
    ( WaitForSingleObject(fMutex,100) = WAIT_TIMEOUT ) or
    ( fMutex = 0 ) then
    begin
      // Fandt et kørende program...
      handle := FindWindow('TfrmDinMainForm','Program title'); // <-- Det er nok med classen hvis du er sikker på at der ikke er andre programmer der har den samme

      if handle <> 0 then
        begin
          //Laver en stor paramstr
          s := '';
          for i:= 1 to ParamCount do
            s:=s+ParamStr(i)+#$0d;

          with cds do
            begin
              dwData := 0;
              cbData := length(s);
              lpData := PChar(s);
            end;
          // Sender besked og stopper dette program
          SendMessage(handle,WM_COPYDATA,Application.Handle,integer(@cds));
          exit;
        end;
    end;

  Application.Initialize;
  // ... autocreate og hvad du ellers har
  Application.Run;
end.


held og lykke
dkn
Avatar billede kastermester Nybegynder
04. februar 2003 - 16:55 #2
Undskyld at jeg ikke har svaret endnu, men havde lige glemt tråden, jeg kigger lige på det og vender tilbage senere.
Avatar billede kastermester Nybegynder
04. februar 2003 - 17:07 #3
Egentlig virker det meget godt, men hvordan "afkoder" jeg den der s streng til noget brugbart, der står noget med "besked modtaget: araber/kineser tegn", det kommer jo fra den der showmessage, det er jeg med på, men hvordan afkoder jeg de andre tegn så det bliver til noget jeg kan bruge til evt. at åbne nogle filer.
Avatar billede dkn Nybegynder
04. februar 2003 - 17:28 #4
kan ikke lige huske det, men skal nok finde ud af det, hvis ikke det er det her:
SendMessage(handle,WM_COPYDATA,Application.Handle,longint(@cds));
Avatar billede kastermester Nybegynder
04. februar 2003 - 17:30 #5
Desværre, føler mig stadig strandet i chinatown.
Avatar billede kastermester Nybegynder
07. februar 2003 - 22:57 #6
dkn?
Avatar billede dkn Nybegynder
08. februar 2003 - 01:54 #7
ja skal nok se på det...
Avatar billede kastermester Nybegynder
08. februar 2003 - 01:56 #8
Lyder rart, sidder nemlig og venter på at kan få det her løst så jeg kan udgive en ny udgave af min editor :-D, bare sig til hvis der skal flere point til, jeg vil gøre (næsten) alt.
Avatar billede kastermester Nybegynder
09. februar 2003 - 00:59 #9
Jeg har nu fået det til at virke (næsten) af en eller anden mystisk grund så VIL det kun virke hvis jeg ikke allerede har et MDI vindue åben (editoren kan findes her: www.smartware.dk/software/download/smartedit/), derfor vil jeg gerne høre om du har nogle forslag, når jeg får det sidste her løst skal du nok få dine velfortjente point.
Avatar billede kastermester Nybegynder
14. februar 2003 - 14:14 #10
Ok som sagt, jeg har næsten fået det til at virke, men det virker ikke hvis et MDI vindue allerede er åbn, der modtager min MainForm, simpelthen ikke messagen som den ny åbnet (og lukket) application sender til den. Her er mine koder som de ser ud nu:

procedure TMainForm.WMCopyData(var msg: TWMCopyData);
var
s:string;
r: TRegExpr;
Params: TStringList;
FileName: string;
I: integer;
begin
  s := PChar(msg.CopyDataStruct.lpData);
  r := TRegExpr.Create;
  Params := TStringList.Create;
  r.Expression := ' ';
  r.Split(s, Params);
  FileName := '';
  For I := 0 to Params.Count - 2 do
  begin
        FileName := FileName + ' ' + Params.Strings[I];
  end;
  Delete(FileName, 1, 1);
  ShowMessage('"' + FileName + '"');
  If FileExists(FileName) then
  begin
        NumsOpen := NumsOpen + 1;
        CreateMDIChild(FileName);
        TChildWin(ActiveMDIChild).SynMemo.Lines.LoadFromFile(FileName);
  end;
  ShowWinNoAnimate(Application.Handle, SW_MINIMIZE);
  ShowWinNoAnimate(Application.Handle, SW_RESTORE);

end;

Og:

var
        IniFile: TIniFile;
        handle: THandle;
        cds: TCopyDataStruct;
        fMutex: THandle;
        s:string;
        i:integer;
begin
fMutex := CreateMutex(nil,false,'MinsupersmarteSmartEditunikkemutextsomderikkeerandrederhar');    // <-- Skift den til noget langt og unikt :)
  if ( GetLastError() = ERROR_ALREADY_EXISTS ) or
    ( WaitForSingleObject(fMutex,100) = WAIT_TIMEOUT ) or
    ( fMutex = 0 ) then
    begin
      // Fandt et kørende program...
      handle := FindWindow('TMainForm',PChar('Smart Edit')); // <-- Det er nok med classen hvis du er sikker på at der ikke er andre programmer der har den samme

      if handle <> 0 then
        begin
          //Laver en stor paramstr
          s := '';
          for i:= 1 to ParamCount do
            s:=s+ParamStr(i)+ ' ';
            ShowMessage(s + ' ' + BoolToStr(FileExists(s), True));
          if FileExists(s) = False then
                s := '';

          with cds do
            begin
              dwData := 0;
              cbData := length(s);
              lpData := PChar(s);
            end;
          // Sender besked og stopper dette program
          SendMessage(handle,WM_COPYDATA,Application.Handle,longint(@cds));
          exit;
        end;
    end;

Og ud fra de showmessages som der skal vises kan jeg se at den ikke modtager nogen besked når et MDI vindue allerede er åben, jeg håber at du er der til at hjælpe mig med mit sidste spørgsmål dkn, så skal jeg nok give dig dine point, plus lidt exstra ;-).
Avatar billede dkn Nybegynder
15. februar 2003 - 23:12 #11
ja skal nok se på det, men det bliver nok først på mandag. Har en del lektier som skal laves inden vinterferien er helt slut.
Avatar billede kastermester Nybegynder
29. marts 2003 - 21:21 #12
dkn?
Avatar billede dkn Nybegynder
29. marts 2003 - 22:19 #13
yep sorry....
Stadig ikke fået det til at virke ordentligt?
Avatar billede kastermester Nybegynder
29. marts 2003 - 22:20 #14
Nej, det virker ikke hvis der er et MDI vindue åbent, ellers virker det fint.
Avatar billede dkn Nybegynder
29. marts 2003 - 22:30 #15
Ok vil lige teste det med det samme, og se om jeg kan finde fejlen....
Avatar billede kastermester Nybegynder
29. marts 2003 - 22:31 #16
Ok, mange tak.
Avatar billede kastermester Nybegynder
29. marts 2003 - 22:35 #17
Nu hvor jeg kiggede det hele igennem tror jeg jeg ved hvorfor fejlen opstår.
FindWindow('TMainForm',PChar('Smart Edit')) Her ligger skidtet, når man åbner et mdi vindue bliver dens caption jo også tilføjet, derfor holder den ikke helt. Er der ikke andre måder jeg kan finde mit vindue på?
Avatar billede dkn Nybegynder
29. marts 2003 - 22:49 #18
ja netop er også kommet frem til det problem!
Ja man kunne evt bruge en enumwindows. Kan lave noget kode til dig hvis det skulle være
Avatar billede kastermester Nybegynder
29. marts 2003 - 22:50 #19
Jo tak. Hvis du kan fikse det, så vil det være skønt.
Avatar billede dkn Nybegynder
29. marts 2003 - 23:05 #20
var
  Form1: TForm1;
  Proglist : TStringlist;

implementation

{$R *.dfm}

function EnumWindowsProc(Wnd: HWnd; Form: TForm1): Boolean; export;
{$IFDEF Win32} stdcall; {$ENDIF}
var
  Buffer: array[0..99] of char;
begin
  GetWindowText(Wnd, Buffer, 100);
  if StrLen(Buffer) <> 0 then
  Proglist.Add(Buffer);
  Result := True;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  handle: THandle;
  cds: TCopyDataStruct;
  s: string;
  i: integer;
begin
  Proglist := TStringlist.Create;
  EnumWindows(@EnumWindowsProc, LongInt(Self));

  handle := 0;
  for I := 0 to Proglist.Count - 1 do
    if pos('Smart Edit', Proglist.Strings[I]) <> 0 then
      handle := findwindow(nil, Pchar(Proglist.Strings[I]));

  if handle <> 0 then
  begin
    s := 'Test String';
    with cds do
    begin
      dwData := 0;
      cbData := length(s);
      lpData := PChar(s);
    end;
    SendMessage(handle, WM_COPYDATA, Application.Handle, longint(@cds));
    exit;
  end else
    showmessage('debug: fandt ikke prog'); 
end;




Ok ser ud til at virke nu, efter at mdi er blevet maximeret.
Måske ikke den smarteste måde, men jeg desvære ikke lige komme på andet :)
Avatar billede dkn Nybegynder
29. marts 2003 - 23:05 #21
husk at free Proglist :)
Avatar billede kastermester Nybegynder
29. marts 2003 - 23:36 #22
Hader når folk selv stiller det her spørgsmål, men du vil ikke lige være venlig at lave et eksempel som jeg næsten selv kan bruge, ligesom det første du oprettede?
Avatar billede dkn Nybegynder
29. marts 2003 - 23:40 #23
hmm hvis ikke du har noget personlig i din dpr fil kan du jo sende den til

dkn @pc.dk (uden space)
Avatar billede kastermester Nybegynder
30. marts 2003 - 00:11 #24
Jamen, det der er jo skrevet som en button event, jeg er lidt forvirret :-s.
Avatar billede dkn Nybegynder
30. marts 2003 - 00:27 #25
Ok dette skulle være til at forstå :)


program Project1;

uses
  Forms,
  Classes,
  windows,
  SysUtils,
  messages,
  cli in 'cli.pas' {Form1};

{$R *.res}

var
  Proglist : TStringlist;
  handle: THandle;
  cds: TCopyDataStruct;
  s: string;
  i: integer;
 
function EnumWindowsProc(Wnd: HWnd): Boolean; export;
{$IFDEF Win32} stdcall; {$ENDIF}
var
  Buffer: array[0..99] of char;
begin
  GetWindowText(Wnd, Buffer, 100);
  if StrLen(Buffer) <> 0 then
  Proglist.Add(Buffer);
  Result := True;
end;

begin
  Proglist := TStringlist.Create;
  EnumWindows(@EnumWindowsProc, 0);

  handle := 0;
  for I := 0 to Proglist.Count - 1 do
    if pos('Smart Edit', Proglist.Strings[I]) <> 0 then
      handle := findwindow(nil, Pchar(Proglist.Strings[I]));

  if handle <> 0 then
  begin
    s := 'Test String';
    with cds do
    begin
      dwData := 0;
      cbData := length(s);
      lpData := PChar(s);
    end;
    SendMessage(handle, WM_COPYDATA, Application.Handle, longint(@cds));
    exit;
  end;

  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.
Avatar billede dkn Nybegynder
30. marts 2003 - 14:45 #26
kan du ikke får det til at virke eller hvad?
Avatar billede kastermester Nybegynder
30. marts 2003 - 17:57 #27
Skulle lige sove :-) prøver den nu.
Avatar billede kastermester Nybegynder
30. marts 2003 - 18:06 #28
Nej jeg kan ikke få det til at virke. Mit program lukker uformelt ned. Jeg prøvede dog at lave nogle ændringer. 1. handle gik jeg ud fra blev til application.handle, derfor skiftede jeg det til hwnd, dernæst fik jeg atvide at HWnd (i funktionen) ikke var en type, så jeg skiftede den ud med cardinal, men det hjalp heller ikke, har du nogen idee'er?
Avatar billede dkn Nybegynder
30. marts 2003 - 18:27 #29
det virker ihvertefald i min lille test. Så du skal bare lige tilpasse det dit projekt jo
Avatar billede kastermester Nybegynder
30. marts 2003 - 18:32 #30
Doh ved hvorfor det ikke virkede.
Jeg havde jo en anden version af min editor løbende :-O.

Mange tak, nu skal du vist også have de point.
Avatar billede dkn Nybegynder
30. marts 2003 - 19:26 #31
hehe mange tak :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester

IT-JOB