![]() |
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. |
AW: Programmübergreifend Steuerelemente aktualisieren
Beim Aufrufen warten, bis das Programm fertig ist (SuFu:
![]() 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) |
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 ![]() .... If you can hardcoded then it is the best, but GetExitCodeProcess is my preferred method to check without blocking on not-my-own applications. |
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; |
AW: Programmübergreifend Steuerelemente aktualisieren
Wieso muss ich bei dieser Lösung
![]() |
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. |
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. |
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 |
AW: Programmübergreifend Steuerelemente aktualisieren
<OT>
Zitat:
Zitat:
Aber einfach einen Quelltext hinzurotzen, der auch noch größtenteils am Ziel vorbeigeht, ist einfach unnötig. </OT> |
AW: Programmübergreifend Steuerelemente aktualisieren
Zitat:
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. |
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