Einzelnen Beitrag anzeigen

henrik

Registriert seit: 25. Nov 2003
36 Beiträge
 
Delphi 2007 Professional
 
#1

Comment-Tool gebastelt, aber beim Clipboard knallts noch....

  Alt 12. Aug 2007, 20:12
hallo,

leider gibt es bis Delphi 2005 keine automatische Kommentarfunktion ( markierten Quelltext mit einem Klick oder Tastenkombi mit "//" versehen). Auch eine Codeblock - Einrückfunktion werden sicherlich viele Benutzer von Delphi < 2005 vermissen.

Folgender Code realisiert dies im Prinzip. Leider macht das Clipboard -Objekt manchmal Probleme (zB. nach mehreren Einrückoperationen hintereinander) :

"Zwischenablage kann nicht geöffnet werden". Das passiert in der Funktion "copyMarkedTextToClipBoard()".


Habe diesbezuglüch schon mehrere Zugriffs-Varianten auf das Clipboard ausprobiert - ohne dauerhaften Erfolg.

Vielleicht fällt euch dazu was ein !?


Wenn das Ding dann mal fehlerfrei funktioniert, könnte man es zB. zu den Delphi Editor Tools hinzufügen und im Hintergrund laufen lassen und sich so manch stupides Codegeschubse ersparen.


Der markierte Text wird sich übrigens per Tastendrucksimulation STRG C / V besorgt. Könnte man evtl. auch mit WM_COPY o.ä. realisieren. Ansonsten wird im onTimer -event geprüft ob die entsprechende Tastenkombination vorliegt:


TODO wäre u.a. noch ,den zuvor in der Zwischenablage enthaltenen Code zu sichern und nach dem Paste-Vorgang wieder zuzuweisen.



Gruss
Henrik


STRG + # = comment marked codeblock
STRG + SHIFT+ # = uncomment marked codeblock
STRG + "+"/"-" = shift marked codeblock right/left

(Benötigt wird eine TTimer -komponente.)


Delphi-Quellcode:
unit UComment;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Clipbrd, ExtCtrls;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  blocked, releasedFunctionKey : boolean;
  FunctionKey: integer; // + , - , #

  lastMouseUp, lastMouseDown: TPoint;//Var. um Markierung im Editor wdhzustellen
  lastMouseVal: integer;

implementation

{$R *.dfm}

//##############################################################################
function copyMarkedTextToClipBoard(): string;
var
  i: integer;
  MyHandle: THandle;
  TextPtr: PChar;

  clipb: TClipboard;

begin
  clipb := TClipboard.Create;

  Result := '';

  keybd_event(VK_CONTROL, 0, 0, 0); // STRG + C
  keybd_event(67, 0, 0, 0);

  sleep(5);

  keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0); // Tasten loslassen
  keybd_event(67, 0, KEYEVENTF_KEYUP, 0);

  Result := clipb.AsText; // Hier knallts ab und zu ...


// MyHandle := clipb.GetAsHandle(CF_TEXT);
// TextPtr := GlobalLock(MyHandle);
// Result := StrPas(TextPtr);
// GlobalUnlock(MyHandle);

   clipb.Free; // ...oder hier

end;
//##############################################################################
procedure pasteClipBoardTextInEditor();
begin
  sleep(5);

            keybd_event(VK_CONTROL, 0, 0, 0);
            keybd_event(86, 0, 0, 0);

  sleep(5);

            keybd_event(86, 0, KEYEVENTF_KEYUP, 0);
end;
//##############################################################################
procedure reSelectText();
begin
 // die durch den Paste-Vorgang verlorengegangene Selektierung wiederherstellen

       SetCursorPos(lastMouseDown.X, lastMouseDown.Y);
       Mouse_Event(MOUSEEVENTF_LEFTDOWN, lastMouseDown.X, lastMouseDown.Y, 0, 0);
       SetCursorPos(lastMouseUp.X, lastMouseUp.Y);
       Mouse_Event(MOUSEEVENTF_LEFTUP, lastMouseUp.X, lastMouseUp.Y, 0, 0);

end;
//##############################################################################
procedure TForm1.Timer1Timer(Sender: TObject);
var
  strings: TStringList;
  i: integer;
begin

  if (ABS(GetKeyState(VK_ESCAPE)) > 1) then
  begin
    Timer1.Enabled := False;

    Application.Terminate;
  end;


  if blocked then exit;



  if NOT (ABS(GetKeyState(FunctionKey)) > 1) then
        releasedFunctionKey:=true; // zB. "+" losgelassen

  if not releasedFunctionKey Then exit;

  // wurde die linke maustaste gerade gedrückt oder losgelassen und wenn WO ? :

  if (ABS(GetKeyState(VK_LBUTTON)) >= 127) then //gerade gedrückt
  begin
    if (lastMouseVal <= 1) then // zuletzt nicht gedrückt
    begin
      GetCursorPos(lastMouseDown);
    end;

  end
  else
   if (ABS(GetKeyState(VK_LBUTTON)) <= 1) then //gerade nicht gedrückt
   begin
     if (lastMouseVal > 1) then // zuletzt gedrückt
     begin
       GetCursorPos(lastMouseUp);
     end;
   end;

    lastMouseVal := ABS(GetKeyState(VK_LBUTTON));



  // die eigentlichen Textoperationen :




  // Kommentare setzen/entfernen -----STRG + # ---------------------------------
  if (ABS(GetKeyState(VK_CONTROL)) > 1) and (ABS(GetKeyState(191)) > 1) then
  begin
    blocked := True;
    FunctionKey:=191;
    releasedFunctionKey:=false;
    // Text kopieren

    strings := TStringList.Create;
    strings.Text := copyMarkedTextToClipBoard();


    // SHIFT gedrückt ?:

    if (ABS(GetKeyState(VK_SHIFT)) > 1) then //ja : Kommentar entfernen:
    begin
      for i := 0 to strings.Count - 1 do
      begin
        strings.Strings[i] := StringReplace(strings.Strings[i], '//', '', []);
      end;

      keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0); // shift wieder hoch
    end
    else // mit Kommentar versehen :
    begin

      for i := 0 to strings.Count - 1 do
      begin
        strings.Strings[i] := '//' + strings.Strings[i];
      end;

    end;


    Clipboard.AsText := strings.Text;

    // und in editor einfügen:

    pasteClipBoardTextInEditor();
    strings.Free;

  end
  else
  //Textblock einrücken rechts -----> -----STRG + "+" -----------------------:

  if (ABS(GetKeyState(VK_CONTROL)) > 1) and (ABS(GetKeyState(187)) > 1) then
  begin
    blocked := True;
    FunctionKey:=187;
    releasedFunctionKey:=false;

    //markierten Text im Editor kopieren

    strings := TStringList.Create;
    strings.Text := copyMarkedTextToClipBoard();



    for i := 0 to strings.Count - 1 do
    begin
      strings.Strings[i] := ' ' + strings.Strings[i];
    end;



    Clipboard.AsText := strings.Text;

    // und einfügen
    pasteClipBoardTextInEditor();

    //Markierung wiederherstellen:
    reSelectText();

    strings.Free;


  end
  else
  //Textblock einrücken left <----- ------STRG + "-" ----------------------:
                                                    
  if (ABS(GetKeyState(VK_CONTROL)) > 1) and (ABS(GetKeyState(189)) > 1) then
  begin
    blocked := True;
    FunctionKey:=189;
    releasedFunctionKey:=false;
    // Text kopieren

    strings := TStringList.Create;
    strings.Text := copyMarkedTextToClipBoard();



    for i := 0 to strings.Count - 1 do
    begin
      if copy(strings.Strings[i], 1, 1) = ' then
        strings.Strings[i] := copy(strings.Strings[i], 2, length(strings.Strings[i]));
    end;


    Clipboard.AsText := strings.Text;

    // und einfügen
    pasteClipBoardTextInEditor();

    //Markierung wiederherstellen:

    reSelectText();


    strings.Free;


  end;

  blocked := False;


end;
//##############################################################################
procedure TForm1.FormCreate(Sender: TObject);
begin
  lastMouseVal := 1;
  releasedFunctionKey:=true;
  timer1.Interval:=50;
  timer1.OnTimer:=Timer1Timer;
  timer1.Enabled:=true;
end;
//##############################################################################
end.
  Mit Zitat antworten Zitat