|
Registriert seit: 24. Sep 2022 Ort: Planet Erde 356 Beiträge Delphi 11 Alexandria |
#8
sodele.
Nach mehrmaligen experimentieren, habe ich es dann doch hinbekommen - außer die Geschichte, das ich den in der Zwischenablage befindlichen (formatierten) Text für EichEdit, nicht in die RichEdit1 Komponente in meiner Anwendung kopiert bekommen. In den unten beschriebenen, kostenlosen Tool kann ich aber ersehen, das Daten, die das RichEdit Text-Format aufweisen, sehen und daraus auch wieder kopieren kann. Also muss es doch irgendwie möglich sein, die Zwischenablage so zu Nutzen, das man den RichEdit Text in eine TRichEdit bekommt... ? Für die Interessen-Schaft habe ich mal hier den Code offen gelegt, damit Ihr sehen könnt, wie man in modernen Zeiten von Windows 10 und 11 Zwischen Fenstern wechseln, und Text mittels simulieren von Tastendrücken richtig vollzieht. Damit meine ich auch das SendInput, das anstelle der SendMessage Funktion verwendet werden sollte. Falls, neben meinen Fragen, Fragebedarf besteht, stehe ich gerne zur Verfügung, sofern der Fragende keine Frage stellt, die ich nicht beantworten kann... (naja genug gegaggert ![]() Nachtrag: Ich kann ja den Text selbst, mittels CTRL+V in meine Eigene Anwendung kopieren - ist mir gerade eingefallen - Problem so gut wie fast gelöst. Naja, nicht nur schreiben, sondern aich denken beim schreiben kann helfen. Sagt Bitte zu mir: "Ich bin ein GNU" ![]()
Delphi-Quellcode:
// ---------------------------------------------------------------------
// File: copyTest.pas // Author: (c) 2023 by Jens Kallup - paule32 // all rights reserved. // // only free for education, and non-profit ! // --------------------------------------------------------------------- unit Unit2; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, TLHelp32, Clipbrd, System.Generics.Collections, Vcl.ComCtrls; type TForm2 = class(TForm) Button1: TButton; RichEdit1: TRichEdit; procedure Button1Click(Sender: TObject); private public end; var Form2: TForm2; type HWNDArray = array of THandle; PEnumData = ^TEnumData; TEnumData = record ProcessID: DWORD; Handles: HWNDArray; WindowHandle: HWND; WindowText: string; end; implementation {$R *.dfm} // convert a dynamic "Array of Char" to "String" function ArrayToString(const a: array of Char): string; begin if Length(a)>0 then SetString(Result, PChar(@a[0]), Length(a)) else Result := ''; end; // simply, copy the text from an edit component to a text buffer function GetRichViewText(hWnd: HWND): string; var textLength: Integer; text: String; begin // create buffer for the text: textLength := SendMessage(hWnd, WM_GETTEXTLENGTH, 0, 0); SetLength(text, textLength + 1); // get text from window hwnd: SendMessage(hWnd, WM_GETTEXT, textLength + 1, LPARAM(PChar(text))); Result := String(text); end; procedure TForm2.Button1Click(Sender: TObject); var hSnap : THandle; hProc : THandle; procWin : THandle; priClass : DWORD; procEntry: TProcessEntry32; childWindowHandles: HWNDArray; counter, i : Integer; s1, s2, s3: string; found, flagged: Boolean; Input: TInput; InputList: TList<TInput>; // get the caption of the window, and return // it as string: function GetWindowCaption(hWnd: HWND): string; var len: Integer; begin len := GetWindowTextLength(hWnd); if len > 0 then begin SetLength(Result, len); GetWindowText(hWnd, PChar(Result), len + 1); end else Result := ''; end; // window callback, that iterate through the processes windows, // and fill TEnumData with Informations: function EnumWindowsCallback(hwnd: HWND; lParam: LPARAM): BOOL; stdcall; var data: PEnumData; windowProcessID: DWORD; begin data := PEnumData(lParam); GetWindowThreadProcessId(hwnd, @windowProcessID); if windowProcessId = data.ProcessID then begin SetLength(data.Handles, Length(data.Handles) + 1); data.Handles[ High(data.Handles) ] := hwnd; end; Result := True; end; // find the window hwnd's, starting at processID: function FindChildWindowHandles(processID: DWORD): HWNDArray; var data: TEnumData; begin inc(counter); data.ProcessID := processID; SetLength(data.Handles, 0); EnumWindows(@EnumWindowsCallback, LPARAM(@data)); Result := data.Handles; end; begin RichEdit1.Lines.Clear; counter := -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); // only for information debug: // [.. s1 := '' + #10 + 'Process Name : = ' + ProcEntry.szExeFile + #10 + 'Process ID : = 0x' + IntToHex(ProcEntry.th32ProcessID) + #10 + 'Thread Count : = ' + IntToStr(ProcEntry.cntThreads); if priClass > 0 then s1 := s1 + #10 + 'Priority class : = ' + IntToStr(priClass); ShowMessage(s1); // ..] // fill the sub-hwnd container: childWindowHandles := FindChildWindowHandles(ProcEntry.th32ProcessID); flagged := false; // 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: RichEdit1.Perform(WM_SETTEXT, 0, PWChar(Clipboard.AsText)); finally InputList.Free; end; // at end, switch back to applicatiin Winapi.Windows.SetForegroundWindow(self.Handle); end; end; CloseHandle(hSnap); end; end.
Frag doch einfach
Alles was nicht programmiert werden kann, wird gelötet Geändert von paule32.jk (14. Okt 2023 um 15:03 Uhr) Grund: mögliche Problemlösung gefunden |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs 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
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |