AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi AV "Kann Zwischenablage nicht öffnen"
Thema durchsuchen
Ansicht
Themen-Optionen

AV "Kann Zwischenablage nicht öffnen"

Ein Thema von jensw_2000 · begonnen am 23. Aug 2004 · letzter Beitrag vom 24. Aug 2004
Antwort Antwort
jensw_2000
(Gast)

n/a Beiträge
 
#1

AV "Kann Zwischenablage nicht öffnen"

  Alt 23. Aug 2004, 14:57
Hallo,

ich habe ein Verständnisproblem beim verwenden der Zwischenablage ...
Ich experimentiere schon seit Tagen erfolglos herum und hoffe, das jemand von euch einen Tip für mich hat ...

Ich habe eine kleine Anwendung, die nach dem drücken eines globalen Hotkeys ein CTRL+C an die aktive Anwendung sendet um den dort selektierten Text in die Zwischenablage zu kopieren.

In meiner Anwendung verarbeite ich die Zwischenablage und möchte diese anschliessend leeren, um zu verhindern, das der User beim Drücken des Hotkeys (ohne vorheriges markieren des Textes) die alte Zwischenablage noch einmal verwendet.


Hier ein kleines Codebeispiel ...

Code:
 
public
   function VerarbeiteClipboardText(ClipboardText:String):Boolean;



procedure TMain."onHotkeyPress";
begin
  // selektierten Text aus aktivem Fenster in die Zwischenablage kopieren
  // beim 2. Drücken des Hotkeys wird der selektierte Text nicht mehr in die ZA kopiert :-(
  keybd_event(VK_CONTROL, 0, 0, 0);
  keybd_event(Ord('C'), 0, 0, 0);
  keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
  Sleep(10);

  if Clipboard.HasFormat(CF_TEXT) then
  begin
    // die nächste Codezeile funktioniert nur beim ersten Drücken des Hotkeys.
    // bbeim 2. Drücken des Hotkeys wird die Exception "kann Zwischenablage nicht öffnen" ausgelöst
    if VerarbeiteClipboardText( Clipboard.AsText )=true then
      showmessage('Clipoard verarbeitet') else
      showmessage('Fehler');
  end;

end;

function TMain.VerarbeiteClipboardText(ClipboardText:String):Boolean;
begin


  // Hier mache ist was mit ClipboardText
  //.............
  //.............

  // Zwischenablage leeren
  try
    clipboard.clear;
    result:=true;
  except
    result:=false;
  end;

end;

{
Variante 2 - funtioniert auch nicht
function TMain.VerarbeiteClipboardText(ClipboardText:String):Boolean;
begin



  // Hier mache ist was mit ClipboardText
  //.............
  //.............

  // Zwischenablage leeren
  try

    try  
      clipboard.open
      clipboard.clear;
    finally
      clipboard.close;
    end;

    result:=true;
  except
    result:=false;
  end;

end;
}

Der Hotkey kopiert nur einmal den selektierten Text in die Zwischenablage und Clipboard.asText löst beim 2. drücken des Hotkeys die Exception "Kann Zwischenalage nicht öffnen" aus.
Wenn ich die Zwischenablage nicht leere funktioniert alles super.


Ich babe auch schon versucht mit SetClipboardTextSetClipboardText die Zwischenablage mit SetClipboardText(Pchar('<bereits übernommen>')) zu überschreiben.

Der Fehler bleibt der Selbe ...
Sobald ich die Zwischenablage in meinem Programm schreibe oder leere kommt beim 2. Drücken des Hotkeys "Kann Zwischenalage nicht öffnen".

Hat jemand eine Idee ?

Danke .....
Jens
  Mit Zitat antworten Zitat
Blutiger Anfänger
(Gast)

n/a Beiträge
 
#2

Re: AV "Kann Zwischenablage nicht öffnen"

  Alt 23. Aug 2004, 15:48
Könnte es sein, daß es Konflikte zwischen dem, für andere Anwendungen durchaus wichtigen Hotkey Strg+C, und deinem Hotkey (auch Strg+C) gibt??? Beide machen ja schließlich Clipboardaktionen und nur einer darf das Clipboard zu einem Zeitpunkt öffnen. Eine kleine Schleife würde sich da eventuell lohnen ...
  Mit Zitat antworten Zitat
jensw_2000
(Gast)

n/a Beiträge
 
#3

Re: AV "Kann Zwischenablage nicht öffnen"

  Alt 23. Aug 2004, 17:43
Das denke ich nicht.
Der Global Hotkey in meinem Prog ist [ALTGR+F9].
Nach dem alle Tasten der Hotkeykombination losgelassen wurden, wird die Ereignisbehandnung aufgerufen, die ich im Samplecode "onHotkeyPress" genannt habe.

Die Ereignisbehandlung simuliert dann in der aktiven Anwendung das Drücken von [STRG+C] um den dort markierten Text in die Zwischenablage zu kopieren ...

Das funktioniert ja auch super (mindestens 1000 mal hintereinander ... ), wenn ich nicht am Ende versuche, die Zwischenablage mit clipboard.clear zu löschen bzw. mit clipboard.astext:='<irgendwas'> zu überschreiben ...

Hast das eventuell auch was mit Rechten zu tun ?
Zitat:
EmptyClipboard; // !Wichtig! Nur so kann das oben angegebene Fenster der "Besitzer" des Clipboards werden



Gruss,
Jens
  Mit Zitat antworten Zitat
Blutiger Anfänger
(Gast)

n/a Beiträge
 
#4

Re: AV "Kann Zwischenablage nicht öffnen"

  Alt 23. Aug 2004, 17:53
Komisch eigentlich, aber PSDK gibt deiner Theorie recht. Ist also systembedingt:

Zitat:
The EmptyClipboard function empties the clipboard and frees handles to data in the clipboard. The function then assigns ownership of the clipboard to the window that currently has the clipboard open.
  Mit Zitat antworten Zitat
jensw_2000
(Gast)

n/a Beiträge
 
#5

Re: AV "Kann Zwischenablage nicht öffnen"

  Alt 23. Aug 2004, 21:18
Neue Erkenntnisse ...

Bei mir tritt das Clipboard-Problem wahrscheinlich dadurch auf, dass ich mit dem simulierten [CTRL+C] die Clipboard unter dem Application Handle der jeweils aktiven Anwendung fülle. Diese Anwendung wird (wenn die Owner-Theorie stimmt) demnach als Eigentümer der Clipboard eingetragen.

Mein Programm darf die Zwischenablage lesen, aber nicht schreiben oder leeren.

Sobald ich einen "schreibenden" Befehl wie z.B. Clipboard.clear oder Clipboard.asText:='1234' verwende hat dieser keine Auswirkung auf den Inhalt der Zwischenablage "!!!" und der nächste Clipbaord.irgendwas Befehl löst die Exception "Kann Zwischenablage nicht öffnen" aus.

Um die Owner-Theorie zu untermauern habe ich testweise in der clipbrd.pas bei "TClipboard.open" ein Showmessage() eingebaut, damit die Clipbrd.pas zwingend mein Application.Handle an die Windows.OpenClipboard(hwnd) übergibt.

Schon funktioniert alles wieder problemlos ....


Hier die betreffende Stelle aus der clipbrd.pas

Code:
procedure TClipboard.Open;
begin
  if FOpenRefCount = 0 then
  begin

    // Test... Öffne die Clipboard immer unter meinem Application Handle !!!
    Showmessage('Öffne die Zwischenablage für alle Schreib+Leseoperationen unter meinem ApplicationHandle !' );
    // ENDE Test... Öffne die Clipboard immer unter meinem Application Handle !!!

    FClipboardWindow := Application.Handle;
    if FClipboardWindow = 0 then
    begin
{$IFDEF MSWINDOWS}
      FClipboardWindow := Classes.AllocateHWnd(MainWndProc);
{$ENDIF}
{$IFDEF LINUX}
      FClipboardWindow := WinUtils.AllocateHWnd(MainWndProc);
{$ENDIF}
      FAllocated := True;
    end;
    if not OpenClipboard(FClipboardWindow) then
      raise Exception.CreateRes(@SCannotOpenClipboard);
    FEmptied := False;
  end;
  Inc(FOpenRefCount);
end;

Jetzt kommt der Frageteil :

1. Wie kann ich ohne Änderungen an der Clipbrd.pas sicherstellen, dass die Zwischenablage unter meinem Application Handle geöffnet wird ?

2. Warum können alle anderen Programme die Zwischenablage schreiben (auch wenn da schon was aus einer anderen Anwendung drin stand) ?


Hilfe .... !!!!!!!

Schöne Grüße,
Jens
  Mit Zitat antworten Zitat
Blutiger Anfänger
(Gast)

n/a Beiträge
 
#6

Re: AV "Kann Zwischenablage nicht öffnen"

  Alt 23. Aug 2004, 21:22
War es nicht so, daß das Clipboard innerhalb eines Prozesses nur von einem Thread und/oder Fenster besessen werden kann?
  Mit Zitat antworten Zitat
jensw_2000
(Gast)

n/a Beiträge
 
#7

Re: AV "Kann Zwischenablage nicht öffnen"

  Alt 23. Aug 2004, 21:36
Scheint so ...

Ich werde jetzt einfach eine MyClipboard.pas basteln, in der ich bei allen Aufrufen von TClipboard.open mein ApplicationHandle übergebe. Dann wird's wahrscheinlich funktionieren ...

Ich werde dann kurz Bescheid was dabei herausgekommen ist.


Bis dahin...
Danke, Jens
  Mit Zitat antworten Zitat
Blutiger Anfänger
(Gast)

n/a Beiträge
 
#8

Re: AV "Kann Zwischenablage nicht öffnen"

  Alt 23. Aug 2004, 21:51
Jut, sowas gehört schon fast in die CodeLib (IMO)
  Mit Zitat antworten Zitat
jensw_2000
(Gast)

n/a Beiträge
 
#9

Re: AV "Kann Zwischenablage nicht öffnen"

  Alt 24. Aug 2004, 00:16
Jetzt klapps ...

In TClipboard.open darf FClipboardWindow nicht das Application.Handle zugewiesen werden.
Wenn FClipboardWindow = 0 ist und somit AllocateHWnd(MainWndProc) verwendet wird, dann kann man die Zwischenablage mit anderen Anwendungen lesend und schreibend teilen ...


Da ich definitiv nicht genug von der Materie verstehe, habe ich die Clipbrd.pas im Originalzustand belassen, in myClipbrd.pas kopiert und dann in mein Project eingebunden.

In die CodeLib möchte ich das nicht posten, bevor sich das jemand angesehen hat der mehr davon versteht als ich. Der Code den man da findet funktioniert ...
Den Ruf will ich versauen ...

Die myclipbrd.pas hänge ich hier einfach an den Thread.

Kurz zu den Veränderungen:

1. Prvate Variable FNullhandle definiert

Code:
type
  TClipboard = class(TPersistent)
  private
    FOpenRefCount: Integer;
    FClipboardWindow: HWND;
    FAllocated: Boolean;
    FEmptied: Boolean;
    FNullHandle:HWND; //---- Edit (hinzugefügt) ----
2. constructor überschrieben, FNullHandle:=0 definiert
Code:
constructor TClipboard.create; //---- Edit (hinzugefügt) ----

begin

  FNullHandle:=0;
  inherited Create;

end;
3. in TClipboard.open FClipboardWindow:=FNullHandle definiert damit Zwischenablage dem Owner AllocateHWnd(MainWndProc) zugewiesen wird

Code:
procedure TClipboard.Open;
begin

  if FOpenRefCount = 0 then
  begin
    FClipboardWindow := FNullHandle;  //---- Edit (von Application.Handle in FNullHandle geändert) ----
    if FClipboardWindow = 0 then
    begin
{$IFDEF MSWINDOWS}
      FClipboardWindow := Classes.AllocateHWnd(MainWndProc);
{$ENDIF}
{$IFDEF LINUX}
      FClipboardWindow := WinUtils.AllocateHWnd(MainWndProc);
{$ENDIF}
      FAllocated := True;
    end;
    if not OpenClipboard(FClipboardWindow) then
      raise Exception.CreateRes(@SCannotOpenClipboard);
    FEmptied := False;
  end;
  Inc(FOpenRefCount);
end;


Schöne Grüße,
Jens
Angehängte Dateien
Dateityp: pas myclipbrd.pas (13,3 KB, 17x aufgerufen)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es 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

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:19 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz