Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Zwischenablage in externes Programm benutzen (https://www.delphipraxis.net/157879-zwischenablage-externes-programm-benutzen.html)

CTest 28. Jan 2011 08:29

Zwischenablage in externes Programm benutzen
 
Hallo,

Ich versuche aus einem Programm einen markierten Wert heraus zu kopieren, diesen zu halbieren und wieder einzufügen, die Shortcuts Strg+C und Strg+V sind durch das Programm deaktiviert, deshalb führe ich einen Rechtsklick aus und kopiere, bzw. füge ein. Das klappt beim ersten Durchlauf, beim 2. Durchlauf wird dann beim lesen des kopierten Wertes der Fehler 'Die Zwischenablage kann nicht geöffnet werden.' ausgelöst.
Hab auch schon mehreres ausprobiert, clipboard.clear, open/close, create/free.
Das Problem ist vielleicht, dass bei Clipboard.GetAsText auch open/close aufgerufen wird, und somit die Zwischenablage andere Programme ignoriert, deshalb hab ich versucht GetAsText zu ersetzen mit:
Code:
{* var s : String;
Data : THandle;
PData : Pointer; *}

s := IntToStr(StrToInt(PChar(GlobalLock(GetClipboardData(CF_TEXT)))) div 2);
GlobalUnlock(GetClipboardData(CF_TEXT));

Data := GlobalAlloc(GMEM_MOVEABLE+GMEM_DDESHARE, Length(s) + 1);
PData := GlobalLock(Data);
Move(PChar(s)^, PData^, Length(s) + 1);
Clipboard.Clear;
SetClipboardData(CF_TEXT, Data);
GlobalUnlock(Data);
Danach ist die Zwischenablage aber leer, schon beim ersten Durchlauf.

Mit openClipboard/closeClipboard hab ich es noch nicht probiert, weil ich das Handle von dem Programmfenster nicht habe, aber würde da nicht auch bei GetAsText Clipboard.open aufgerufen werden und die Zwischenablage auf mein Programm einschränken?

edit1: starte das Programm mit
Code:
ShellExecute(h, 'open', 'C:\Programme\....exe', nil, nil, SW_MAX);
h ist danach aber 0, warum? Wie kann ich das Programm starten, dass das Handle gleich übergeben ist?

shmia 28. Jan 2011 10:41

AW: Zwischenablage in externes Programm benutzen
 
Das Clipboard ist ein globales Objekt; also Finger weg von Create und Free.
Eigentlich ist das Lesen und Schreiben von Text ganz einfach:
Delphi-Quellcode:
var
  s : string;
begin
  s := clipboard.AsText; // Zwischenablage lesen
  s := '*** '+s+' ***';  // Text verändern
  clipboard.AsText := s; // zurück Zwischenablage schreiben

CTest 28. Jan 2011 14:15

AW: Zwischenablage in externes Programm benutzen
 
ja, so hatte ich das auch zuerst gemacht, das klappt aber nur beim ersten Durchlauf, wenn dann dasselbe nochmal gemacht wird, kommt der Fehler 'Die Zwischenablage kann nicht geöffnet werden.' beim Zugriff auf Clipboard.AsText. obwohl der raus zu kopierende Wert dann in der Zwischenablage ist, wenn man dann das Programm abbricht.

shmia 28. Jan 2011 16:10

AW: Zwischenablage in externes Programm benutzen
 
Dann scheint hier möglicherweise ein Bug vorzuliegen.
Eine Anwendung, die mit dem Clipboard arbeiten möchte muss OpenClipboard() aufrufen, seine Arbeit tun und dann CloseClipboard() aufrufen.
OpenClipboard() und CloseClipboard() werden automatisch von der VCL aufgerufen; man braucht da selbst gar nichts tun.
Wenn nun in deinem externen Programm der Aufruf von CloseClipboard() fehlen würde, dann wäre das ein Bug.
Eine Anwendung, die nur OpenClipboard() aufruft, würde die Zwischenablage für alle anderen Programme blockieren.

Mit der Funktion GetClipboardOwner() kann man den Besitzer des Clipboards abfragen (genauer man bekommt das Fensterhandle).

Delphi-Quellcode:
var
  s : string;
  hwnd:THandle;
begin
  try
    s := clipboard.AsText; // Zwischenablage lesen
    s := '*** '+s+' ***'; // Text verändern
    clipboard.AsText := s; // zurück Zwischenablage schreiben
  except
    on E:Exception do
    begin
      // Besitzer des Clipboard ermitteln
      hwnd := GetClipboardOwner;
      ShowWindow(hwnd, SW_SHOW); // Fenster anzeigen
      E.Message := E.Message + #13#10+Format('Window-Handle %x', [hwnd]);
      raise;
    end;
  end;
end;

CTest 28. Jan 2011 20:23

AW: Zwischenablage in externes Programm benutzen
 
Folgende Message kommt dann:
"Exception Exception in Modul Digimax.exe bei 00051FB8.
Zwischenablage kann nicht geöffnet werden
Window-Handle 0."

Wenn ich GetClipboardOwner beim ersten Durchlauf aufrufe, bekomme ich noch ein Handle.

Zitat:

Zitat von shmia (Beitrag 1077981)
Wenn nun in deinem externen Programm der Aufruf von CloseClipboard() fehlen würde, dann wäre das ein Bug.
Eine Anwendung, die nur OpenClipboard() aufruft, würde die Zwischenablage für alle anderen Programme blockieren.

Da ja auch an dieser Stelle Programms das kopieren/einfügen über die Shortcuts nicht geht, könnte es ja sein, dass da irgendwas blockiert wird. Kann man die Zwischenablage nicht irgendwie resetten, dass sie wieder genau den Zustand hat, wie zum Programmstart?

CTest 16. Feb 2011 19:49

AW: Zwischenablage in externes Programm benutzen
 
Hallo,

Ich wollte es heute nochmal versuchen, hab aber erstmal den Versuch mit dem Editor gemacht. Da kommt es zum selben Fehler beim 2. Durchlauf.
...
Hab jetzt festgestellt, dass es durchläuft, wenn man die Zwischenablage nicht verändert.
Werte also jetzt nur noch den String aus und füge die Zeichen einzeln mit keybd_event ein.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:14 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-2025 by Thomas Breitkreuz