Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Programmübergreifend Steuerelemente aktualisieren (https://www.delphipraxis.net/214005-programmuebergreifend-steuerelemente-aktualisieren.html)

geldis 5. Nov 2023 12:04

Programmübergreifend Steuerelemente aktualisieren
 
Hoffentlich versteht das jetzt jemand:

Ich erzeuge in Programm_1 XML Dateien. Der Inhalt wird (unter anderem) in Programm_2 gebraucht. Der Zugriff von Programm_2 auf die Daten des Programms_1 ist nun keine Kunst, aber da diese Daten dort angezeigt werden sollen in einer ListView muss/müsste ich diese ListView aktualiseren, praktischerweise beim beenden von Programm_1.

Wie macht man sowas?

geldis


P.S. Programm_1 wird von Programm_2 aufgerufen.

himitsu 5. Nov 2023 12:18

AW: Programmübergreifend Steuerelemente aktualisieren
 
Beim Aufrufen warten, bis das Programm fertig ist (SuFu: Hier im Forum suchenShellExecuteAndWait und Gergleichen)
oder anschließend die Datei überwachen und nach Änderung neu laden (SuFu)
oder notfalls ein Timer, der regelmäßg guckt, ob sich die Datei geändert hat (Änderungsdatum oder Inhalt)

Kas Ob. 5. Nov 2023 12:28

AW: Programmübergreifend Steuerelemente aktualisieren
 
There is so many ways to do this

1) Run program_1 with command line and pass something like
A) Window handle for message back
B) Named or Unnamed Pipe
C) A file with path with shared write and read protection and pull status on it
... TCP ?!
Any Inter Process Communication IPC .

2) Hardcode the above in program_1 and _2

3) CreateProcess and use timer with GetExitCodeProcess https://learn.microsoft.com/en-us/wi...xitcodeprocess to know if _1 is finished.
....

If you can hardcoded then it is the best, but GetExitCodeProcess is my preferred method to check without blocking on not-my-own applications.

paule32.jk 5. Nov 2023 13:20

AW: Programmübergreifend Steuerelemente aktualisieren
 
- hier ein Beispiel, das nach einen Prozess, und dessen Unter-Prozesse sucht.
- es werden Tastenkombinationen ausgetauscht, um den Inhalt zu selektieren und zu kopieren
- uses: TLHelp32, Clipbrd

Delphi-Quellcode:
// get content of "open" hnd8.exe process content editor
procedure TForm2.Button1Click(Sender: TObject);
var
  hSnap   : THandle;
  hProc   : THandle;
  procWin : THandle;
  priClass : DWORD;
  procEntry: TProcessEntry32;
  childWindowHandles: HWNDArray;
  i : Integer;
  s1, s2, s3: string;
  found: Boolean;
  Input: TInput;
  InputList: TList<TInput>;
begin
  FEditorFrame.RichEdit1.Lines.Clear;
  FCounter := -1;

  // make a snapshot of the current system
  found := false;
  hSnap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if hSnap = INVALID_HANDLE_VALUE then
  begin
    ShowMessage('Error: CreateToolhelp32Snapshot');
    exit;
  end;

  // clean init the ProcEntry structure:
  ProcEntry.dwSize := sizeOf(ProcessEntry32);

  // if the processID > 0 ...
  if (Process32First(hSnap, ProcEntry)) then
  begin
    // ... then get the running processes
    while Process32Next(hSnap, ProcEntry) do
    begin
      // if HelpNDoc.exe (hnd8.exe) is found, then
      // internal switch to the process
      s1 := ProcEntry.szExeFile;
      if ExtractFileName(s1) = 'hnd8.exe' then
      begin
        priClass := 0;
        hProc := OpenProcess(
        PROCESS_ALL_ACCESS, FALSE,
        ProcEntry.th32ProcessID);

        // get some internal informations about the process:
        priClass := GetPriorityClass( hProc );
        if priClass < 1 then
        ShowMessage('Error: GetPriorityClass');
        CloseHandle(hProc);

        // fill the sub-hwnd container:
        childWindowHandles := FindChildWindowHandles(ProcEntry.th32ProcessID);

        // now, we can iterate the sub-windows:
        for i := 0 to High(childWindowHandles) do
        begin
          s2 := GetWindowCaption(childWindowHandles[i]);
          if System.SysUtils.AnsiPos('- HelpNDoc Personal',s2) = 0 then
          begin
            if System.SysUtils.AnsiPos('- HelpNDoc',s2) > 0 then
            begin
              procWin := childWindowHandles[i];
              s3 := Copy(s2,1,Pos(' -',s2)-1);
              found := true;
              //ShowMessage('>' + s3 + '<');
              break;
            end;
          end;
        end;
      end;
    end;
    if found = true then
    begin
      Winapi.Windows.ShowWindow(procWin,SW_RESTORE);
      Winapi.Windows.SetForegroundWindow(procWin);

      // select all: ctrl+A ...
      InputList := TList<TInput>.Create;
      try
        Input := Default(TInput);
        Input.Itype := INPUT_KEYBOARD;
        Input.ki.wScan := 0;
        Input.ki.time := 0;
        Input.ki.dwExtraInfo := 0;

        // 1. press ctrl key
        Input.ki.dwFlags := 0; // 0 for key-press
        Input.ki.wVk    := VK_CONTROL;
        InputList.Add(Input);

        // 2. press "a" key
        Input.ki.dwFlags := 0; // 0 for key-press
        Input.ki.wVk    := Ord('A');
        InputList.Add(Input);

        // 3. release "a" key
        Input.ki.dwFlags := KEYEVENTF_KEYUP;
        Input.ki.wVk    := Ord('A');
        InputList.Add(Input);

        // 4. release ctrl key
        Input.ki.dwFlags := KEYEVENTF_KEYUP;
        Input.ki.wVk    := VK_CONTROL;
        InputList.Add(Input);

        SendInput(InputList.Count, InputList.List[0], sizeof(TInput));

        //s := GetRichViewText(w2);
        //Memo1.Lines.Add(s);
      finally
        InputList.Free;
      end;

      // copy selected text: ctrl+c
      InputList := TList<TInput>.Create;
      try
        Input := Default(TInput);
        Input.Itype := INPUT_KEYBOARD;
        Input.ki.wScan := 0;
        Input.ki.time := 0;
        Input.ki.dwExtraInfo := 0;

        // 1. press ctrl key
        Input.ki.dwFlags := 0; // 0 for key-press
        Input.ki.wVk    := VK_CONTROL;
        InputList.Add(Input);

        // 2. press "c" key
        Input.ki.dwFlags := 0; // 0 for key-press
        Input.ki.wVk    := Ord('C');
        InputList.Add(Input);

        // 3. release "c" key
        Input.ki.dwFlags := KEYEVENTF_KEYUP;
        Input.ki.wVk    := Ord('C');
        InputList.Add(Input);

        // 4. release ctrl key
        Input.ki.dwFlags := KEYEVENTF_KEYUP;
        Input.ki.wVk    := VK_CONTROL;
        InputList.Add(Input);

        // copy text to clipboard, sleep could be adjusted for big text:
        SendInput(InputList.Count, InputList.List[0], sizeof(TInput));
        Sleep(250);

        // this does not work:
        FEditorFrame.RichEdit1.Perform(WM_SETTEXT, 0, PWChar(Clipboard.AsText));
      finally
        InputList.Free;
      end;

      // at end, switch back to applicatiin
      Winapi.Windows.SetForegroundWindow(self.Handle);
      FEditorFrame.RichEdit1.PasteFromClipboard;
    end;
  end;
  CloseHandle(hSnap);
end;

DeddyH 5. Nov 2023 13:43

AW: Programmübergreifend Steuerelemente aktualisieren
 
Wieso muss ich bei dieser Lösung hieran denken? :mrgreen:

paule32.jk 5. Nov 2023 14:13

AW: Programmübergreifend Steuerelemente aktualisieren
 
me?

ich nutze diesen Schnippsel Code dafür, das ich aus einen Tool, das mir XML Daten aufbereitet, dazu, um die Daten dann in HelpNDoc.com Personal zu stöpseln.

Nix schlimmes, da nach mehrmaliger Support-Anfrage bestimmte Dinge in HelpNDoc fehlen, und der Support dann spricht, das ich zusatztools verwenden soll.

Das mit den Input-Key's ist Thread-sicher, was man bei SendMessage manchmal nicht sagen kann, da es da zu überschneidungen kömmen kann.

Um bissl Werbung zu machen: HelpNDoc ist prima für Hilfe-Dokumente zu erstellen.

himitsu 5. Nov 2023 14:45

AW: Programmübergreifend Steuerelemente aktualisieren
 
SendMessage ist immer thread-safe, da es sich in den Ziel-Thread synchronisiert (der, wo das WinControl erstellt wurde)

PostMessage und PostThreadMessage können per se nur thread-safe sein, da sie in der MessageQueue des Ziel-Threads landen und jener kann nur sequentiell abgearbeitet werden.

geldis 5. Nov 2023 15:52

AW: Programmübergreifend Steuerelemente aktualisieren
 
Besten Dank an alle! :thumb:

Am einfachsten war der Timer Vorschlag. Ich bin bei dem Teil immer etwas skeptisch, aber in diesem Fall reicht das völlig aus.

geldis

Sinspin 6. Nov 2023 15:36

AW: Programmübergreifend Steuerelemente aktualisieren
 
<OT>
Zitat:

Zitat von DeddyH (Beitrag 1529069)
Wieso muss ich bei dieser Lösung hieran denken? :mrgreen:

Unrecht hast du leider nicht. Nur dass es im aktuellen Fall anders geartet ist. Ein / zwei Nutzer überziehen alles mit mehr oder weniger nutzlosen Quelltexten. Als wenn es einen Wettbewerb gäbe fürs zukleistern von Postings.
Zitat:

Zitat von paule32.jk (Beitrag 1529072)
me?

Ja, ist schön dass es dir auffällt. Du kannst gene deine Gedanken beisteuern. Jede weitere Idee ist eine Bereicherung für den TE und alle die irgendwann mal das gleiche Problem haben.
Aber einfach einen Quelltext hinzurotzen, der auch noch größtenteils am Ziel vorbeigeht, ist einfach unnötig.
</OT>

KodeZwerg 6. Nov 2023 16:35

AW: Programmübergreifend Steuerelemente aktualisieren
 
Zitat:

Zitat von geldis (Beitrag 1529082)
Besten Dank an alle! :thumb:

Am einfachsten war der Timer Vorschlag. Ich bin bei dem Teil immer etwas skeptisch, aber in diesem Fall reicht das völlig aus.

geldis

Hmmm... warum unnötig polling betreiben wenn man es bequem per SendMessage() lösen könnte oder wie der englische Kollege schrieb per CallBack als parameter deiner zweiten Anwendung.
Ich pers. würde mir einen Message Handler in Programm_B anlegen und beim Beenden von Programm_A eine Nachricht an Programm_B schicken, was dann halt alles mögliche ausführen kann ...


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:20 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz