Solved

How to access selected text in other applications

Posted on 2004-10-31
434 Views
Last Modified: 2010-04-05
Hello,
Example: I am using a dictionary application "WordWebPro".  This app sits in a system tray waiting for me to select a text (typically a word) in any application (except edits on html forms) and to hit a hot key.  It then wakes up with the selected text copied into its own edit.  If the selected text comes from an application like Word, Notepad or an edit component I can make a correction and the corrected text replaces the original text.

So, how does one go about doing the same thing?  
cj
0
Question by:czechmate
    25 Comments
     
    LVL 12

    Expert Comment

    by:Ivanov_G
    http://www.delphi.about.com/library/weekly/aa060303a.htm

    You can find this useful for reading information from other applications.
    0
     
    LVL 1

    Author Comment

    by:czechmate
    It is an interesting article, but I cannot imagine this would be the solution for accessing text in any editable window.  I guess the way to access text in other apps must be via finding focused control in foreground window.  As I say it is just a guess:)
    cj
    0
     
    LVL 5

    Expert Comment

    by:Hypoviax
    Use keyboard events:

    This example copies the selected text in edit1 to the richeditbox when enter key is pressed (normally your hotkey)

    unit Unit1;

    interface

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

    type
      TForm1 = class(TForm)
        Edit1: TEdit;
        RichEdit1: TRichEdit;
        procedure Edit1KeyDown(Sender: TObject; var Key: Word;
          Shift: TShiftState);
      private
        { Private declarations }
      public
        { Public declarations }
      end;

    var
      Form1: TForm1;

    implementation

    {$R *.dfm}

    procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    begin
    if key=vk_return then
    begin
    keybd_event(VK_CONTROL,0,0,0);
    keybd_event(ord('C'),0,0,0);
    keybd_event(VK_CONTROL,0,KEYEVENTF_KEYUP,0);
    keybd_event(ord('C'),0,KEYEVENTF_KEYUP,0);
    richedit1.Clear;
    richedit1.PasteFromClipboard;
    end;

    end;

    end.

    Then depending on what you want to do with the collected data you eventually paste something back (modify contents of richedit):

    richedit.copytoclipboard;
    keybd_event(VK_CONTROL,0,0,0); //paste back into field.
    keybd_event(ord('V'),0,0,0);
    keybd_event(VK_CONTROL,0,KEYEVENTF_KEYUP,0);
    keybd_event(ord('V'),0,KEYEVENTF_KEYUP,0);

    You must not lose the focus of the application.

    For a hotkey control the Jedi JVCL free component library is good. If you use it the control is located under the JvWin32 tab : http://sourceforge.net/project/showfiles.php?group_id=45786

    Regards,

    Hypoviax
    0
     
    LVL 5

    Expert Comment

    by:Hypoviax
    Here is a complete working one i coded. It uses a different method for the hotkey rather than a component (reads for a key state). You need 2 richedit controls. :

    unit Unit1;

    interface

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

    type
      TForm1 = class(TForm)
        Timer1: TTimer;
        RichEdit1: TRichEdit;
        RichEdit2: TRichEdit;
        procedure Timer1Timer(Sender: TObject);
        procedure RichEdit1Change(Sender: TObject);
      private
        { Private declarations }
      public
        control:string;
      end;

    var
      Form1: TForm1;

    implementation

    {$R *.dfm}

    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
    if ((GetAsyncKeyState(VK_F12) and 1) = 1) then //if the user presses F12
      begin
        keybd_event(VK_CONTROL,0,0,0);
        keybd_event(ord('C'),0,0,0);
        keybd_event(VK_CONTROL,0,KEYEVENTF_KEYUP,0);
        keybd_event(ord('C'),0,KEYEVENTF_KEYUP,0);
        richedit1.Clear;
        richedit1.PasteFromClipboard; //load contents
        control:=richedit1.Text;
      end;
    end;

    procedure TForm1.RichEdit1Change(Sender: TObject);
    begin
    if richedit2.Text=control then
    exit
    else
    richedit2.Text:='NEW TEXT'; //Process word here
    richedit2.SelectAll;
    richedit2.CopyToClipboard; //Copy processed data
    keybd_event(VK_CONTROL,0,0,0); //paste back into field.
    keybd_event(ord('V'),0,0,0);
    keybd_event(VK_CONTROL,0,KEYEVENTF_KEYUP,0);
    keybd_event(ord('V'),0,KEYEVENTF_KEYUP,0);
    end;

    end.

    One little bug seems to be you need to press F12 twice - probably something to do with the richedit control

    Best Regards,

    Hypoviax
    0
     
    LVL 5

    Expert Comment

    by:Hypoviax
    Get rid of the control variable you don't need it:

    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
    if ((GetAsyncKeyState(VK_F12) and 1) = 1) then
      begin
        keybd_event(VK_CONTROL,0,0,0);
        keybd_event(ord('C'),0,0,0);
        keybd_event(VK_CONTROL,0,KEYEVENTF_KEYUP,0);
        keybd_event(ord('C'),0,KEYEVENTF_KEYUP,0);
        richedit1.Clear;
        richedit1.PasteFromClipboard;

      end;
    end;

    procedure TForm1.RichEdit1Change(Sender: TObject);
    begin
    richedit2.Text:='NEW TEXT';
    richedit2.SelectAll;
    richedit2.CopyToClipboard;
    keybd_event(VK_CONTROL,0,0,0); //paste back into field.
    keybd_event(ord('V'),0,0,0);
    keybd_event(VK_CONTROL,0,KEYEVENTF_KEYUP,0);
    keybd_event(ord('V'),0,KEYEVENTF_KEYUP,0);
    end;

    Hypoviax
    0
     
    LVL 2

    Accepted Solution

    by:
    Slight change here.
    Register a global hot key
    then grab send a message to the forground window to copy the selected text to the clipboard.
    I have used the insert key here for capture. you could useany key, do a search on virtual key codes.
    This works accross all running applications.

    If you want to avoid the clipboard then you will have to use a WM_COPY command. but this is only really stable in edit boxes.


    //run it, minimize it, start up any program, highlight some text, then press insert to see it working
    unit Unit1;

    interface

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

    type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
         procedure WMHotKey(var Msg : TWMHotKey); message WM_HOTKEY;
      public
        { Public declarations }
      end;


    var
      Form1: TForm1;

    implementation

    {$R *.dfm}
    procedure TForm1.WMHotKey (var Msg : TWMHotKey);
    var
      thewnd : hwnd;
    begin
       if Msg.HotKey = 101 then begin
         thewnd := getforegroundwindow;
         if thewnd <> nil then begin //probably no reason to do this, but why not
           keybd_event( VK_Control,MapVirtualKey(VK_Control, 0),0, 0);
           keybd_event( ord('C'), MapvirtualKey( ord('C'), 0 ), 0, 0 );
           keybd_event( ord('C'), MapvirtualKey( ord('C'), 0 ), KEYEVENTF_KEYUP, 0 );
           keybd_event( VK_Control,MapVirtualKey(VK_Control, 0),KEYEVENTF_KEYUP, 0);
           Sleep(250); //give windows time to catchup
          //do what you want with the text here.
           showmessage('in the clipboard is: '+ clipboard.AsText);
           end;
         end;

    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    RegisterHotKey(Form1.Handle,101,0,VK_INSERT);
    end;

    end.
    0
     
    LVL 1

    Author Comment

    by:czechmate
    Sorry guys I have not come back earlier, down with flu and not enjoying it.

    Hypoviax, I thought your solution was about accessing text betweeen two controls in a single application.  Anyway it is almost the same as the Molando's comment.  I based my test on Molando's code.  I think it is the right way to go about it, but I get these bugs with HotKeys.  

    If I have a combination of any keys with an Alt key then copy from foreground app does not work at all.  The other combinations copy text OK, that is until I paste the text back to foreground window.  It does it once then the copy and paste stops working altogether.

    Here's my code, can you have a look at it?  My system, D5 on Win98se, is a bit shaky right now and I thought maybe that was the reason but when I ran the Dictionary App it works happily with Alt/Ctrl/W key combination.

    I also put the RegisterHotKey function into if/then statement, it always registers without problem.

    Here's the code anyway:

    ~~~~~~~~~~~~~~~~~~~~~~~~~~
    unit Unit1;

    interface

    uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
      Dialogs,  StdCtrls, clipbrd, ComCtrls, Buttons, ExtCtrls;

    type
      TForm1 = class(TForm)
        Panel1: TPanel;
        SpeedButton1: TSpeedButton;
        Memo1: TMemo;
        procedure FormCreate(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure SpeedButton1Click(Sender: TObject);
      private
        { Private declarations }
         procedure WMHotKey(var Msg : TWMHotKey); message WM_HOTKEY;
      public
        { Public declarations }
      end;


    var
      Form1: TForm1;
      FgWND : HWND;
    implementation

    {$R *.dfm}

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    RegisterHotKey(Handle, 101, 0, VK_INSERT);
    //works until and including the 1st Paste back thereafter
    //the foreground window does not copy.
    //-------------
    //RegisterHotKey(Handle, 101, 0, ord('E'));
    //same as above
    //-------------
    //RegisterHotKey(Handle, 101, MOD_ALT,     ord('E'))
    //does not work - foreground window does not copy
    //-------------
    //RegisterHotKey(Handle, 101, MOD_CONTROL, ord('E'));
    //works until 1st Pasteback....as above
    //-------------
    //RegisterHotKey(Handle, 101, MOD_SHIFT,   ord('E'));
    //works until 1st Pasteback....as above
    //-------------
    //RegisterHotKey(Handle, 101, MOD_CONTROL or MOD_ALT,   ord('E'))
    //does not work - foreground window does not copy
    //-------------
    //RegisterHotKey(Handle, 101, MOD_CONTROL OR MOD_SHIFT, ord('E'));
    //works until 1st Pasteback....as above
    //-------------
    //RegisterHotKey(Handle, 101, MOD_SHIFT OR MOD_ALT,     ord('E'));
    //does not work - foreground window does not copy
    //-------------
    end;

    procedure TForm1.WMHotKey (var Msg : TWMHotKey);
    begin
       if Msg.HotKey = 101 then
       begin
          FgWND := GetForegroundWindow;
          if FgWND <> 0 then
          begin //probably no reason to do this, but why not
             keybd_event(VK_Control,MapVirtualKey(VK_Control, 0), 0, 0);
             keybd_event(ord('C'),  MapvirtualKey( ord('C'), 0 ), 0, 0 );
             keybd_event(ord('C'),  MapvirtualKey( ord('C'), 0 ), KEYEVENTF_KEYUP, 0);
             keybd_event(VK_Control,MapVirtualKey(VK_Control, 0), KEYEVENTF_KEYUP, 0);
             Sleep(500); //give windows time to catchup

             Memo1.Clear;
             Memo1.PasteFromClipBoard;
             If IsIconic(Application.Handle) Then
                Application.Restore
             else
                Application.BringToFront;
          end;
       end;
    end;


    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      UnRegisterHotkey(Handle, 101);
    end;

    procedure TForm1.SpeedButton1Click(Sender: TObject);
    begin
       Memo1.SelectAll;
       Memo1.CopyToClipboard;
       Memo1.Clear;
       SetForeGroundWindow(FgWND);
       sleep(250);

       keybd_event(VK_Control,MapVirtualKey(VK_Control, 0), 0, 0);
       keybd_event(ord('V'),  MapvirtualKey( ord('V'), 0 ), 0, 0 );
       keybd_event(ord('V'),  MapvirtualKey( ord('V'), 0 ), KEYEVENTF_KEYUP, 0);
       keybd_event(VK_Control,MapVirtualKey(VK_Control, 0), KEYEVENTF_KEYUP, 0);
    end;

    end.
    0
     
    LVL 5

    Expert Comment

    by:Hypoviax
    No, you misunderstood me. My code:

    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
    if ((GetAsyncKeyState(VK_F12) and 1) = 1) then //if the user presses F12
      begin
        keybd_event(VK_CONTROL,0,0,0);
        keybd_event(ord('C'),0,0,0);
        keybd_event(VK_CONTROL,0,KEYEVENTF_KEYUP,0);
        keybd_event(ord('C'),0,KEYEVENTF_KEYUP,0);
        richedit1.Clear;
        richedit1.PasteFromClipboard; //load contents
        control:=richedit1.Text;
      end;
    end;

    effectively is another way of detecting a keypress. My code works globally. I tested it with notepad etc.
    0
     
    LVL 5

    Expert Comment

    by:Hypoviax
    I'll explain my logic. The hotkey section (Molando's or mine) detects the key press. The data selected is copied and pasted into the richedit1 control. This is the data. The OnChange event starts and you manipulate the data that is in richedit1 and put it in richedit2. The data in richedit2 is copied back to the clipboard and pasted where the selected text is.

    Regards,

    Hypoviax
    0
     
    LVL 5

    Expert Comment

    by:Hypoviax
    I'll have a look at your code

    Hypoviax
    0
     
    LVL 1

    Author Comment

    by:czechmate
    Ok, Hypoviax I'll try it your way.  One thing though, isn't the GetAsyncKeyState function using lot of resources?  How often does your timer time out?
    cj
    0
     
    LVL 5

    Expert Comment

    by:Hypoviax
    The problem occurs whether you use the hotkey or my detection method. For some reason you need to press it twice for it to work. The following code illustrates using both methods, the hotkey and the detection.

    unit Unit1;

    interface

    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ExtCtrls, StdCtrls, ComCtrls,clipbrd, Buttons;

    type
      TForm1 = class(TForm)
        Timer1: TTimer;
        RichEdit1: TRichEdit;
        RichEdit2: TRichEdit;
        Button1: TButton;
        SpeedButton1: TSpeedButton;
        procedure Timer1Timer(Sender: TObject);
        procedure RichEdit1Change(Sender: TObject);
        procedure Button1Click(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure FormCreate(Sender: TObject);
      private
         procedure WMHotKey(var Msg : TWMHotKey); message WM_HOTKEY;
      public
        Fgwnd:hwnd;
      end;

    var
      Form1: TForm1;

    implementation

    {$R *.dfm}

    procedure TForm1.WMHotKey (var Msg : TWMHotKey);   //insert the key
    begin
       if Msg.HotKey = 101 then
       begin
          FgWND := GetForegroundWindow;
          if FgWND <> 0 then
          begin //probably no reason to do this, but why not
             keybd_event(VK_Control,MapVirtualKey(VK_Control, 0), 0, 0);
             keybd_event(ord('C'),  MapvirtualKey( ord('C'), 0 ), 0, 0 );
             keybd_event(ord('C'),  MapvirtualKey( ord('C'), 0 ), KEYEVENTF_KEYUP, 0);
             keybd_event(VK_Control,MapVirtualKey(VK_Control, 0), KEYEVENTF_KEYUP, 0);
             Sleep(500); //give windows time to catchup

             richedit1.Clear;
             richedit1.PasteFromClipBoard;
             If IsIconic(Application.Handle) Then
                Application.Restore
             else
                Application.BringToFront;
          end;
       end;
    end;


    procedure TForm1.Timer1Timer(Sender: TObject); //f12 the key
    begin
    if ((GetAsyncKeyState(VK_F12) and 1) = 1) then
      begin
    fgwnd:=GetForegroundWindow;
        keybd_event(VK_CONTROL,0,0,0);
        keybd_event(ord('C'),0,0,0);
        keybd_event(VK_CONTROL,0,KEYEVENTF_KEYUP,0);
        keybd_event(ord('C'),0,KEYEVENTF_KEYUP,0);
        richedit1.Clear;
        richedit1.PasteFromClipboard;
        application.BringToFront;
      end;
    end;

    procedure TForm1.RichEdit1Change(Sender: TObject);
    var manipulatedtext:string;
    begin
    if richedit1.Text='' then
    exit
    else
     begin
     richedit2.text:=richedit1.Text + 'ADDED';   //modify text
     clipboard.SetTextBuf(pansichar(richedit2.text));
     end;
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    begin
    SetForeGroundWindow(FgWND);
    keybd_event(VK_CONTROL,0,0,0); //paste back into field.
    keybd_event(ord('V'),0,0,0);
    keybd_event(VK_CONTROL,0,KEYEVENTF_KEYUP,0);
    keybd_event(ord('V'),0,KEYEVENTF_KEYUP,0);
    end;

    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      UnRegisterHotkey(Handle, 101);
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    RegisterHotKey(Handle, 101, 0, VK_INSERT);
    end;

    end.

    This problem would not really be a problem if you did not require the application to setfocus to view the text as you could just press the keys twice. Will look into it.

    Regards,

    Hypoviax
    0
     
    LVL 5

    Expert Comment

    by:Hypoviax
    With the timer i set it to 1ms ;). I'll have a look at the resources.
    0
     
    LVL 5

    Expert Comment

    by:Hypoviax
    Doesn't appear to be on my pc , 3364 kb and no movement in the CPU usage. I agree the hotkey is better, but  the problem is not in the hotkey it has something to do with either setting the apps window focus or something to do with the keyboard event. In my original i required to press it twice in order for it to work. I found i needed to do this with Molando's too

    Regards,

    Hypoviax
    0
     
    LVL 5

    Expert Comment

    by:Hypoviax
    Hang on i found this:

    Function ReadFromNotepad:string;
    var h:hwnd;
        Text:string;
        NumCaracters:integer;
    begin
    h:=FindWindow('notepad',nil);
    h:=FindWindowex(h,0,'edit',nil);
    if h<>0 then begin
                 NumCaracters:=SendMessage(h,wm_getTextLength,0,0);
                 setlength(text,NumCaracters);
                 SendMessage(h,wm_getText,NumCaracters+1,Integer(text));
                 result:=text;
                 end
            else result:='ERROR!';
    end;

    No copy and pasting involved. I'll see if i can modify it for any window
    0
     
    LVL 5

    Expert Comment

    by:Hypoviax
    Try a slight modification of this. I ditched the last post couldn't get it to work.

    unit Unit1;

    interface

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

    type
      TForm1 = class(TForm)
        Timer1: TTimer;
        Memo1: TMemo;
        procedure Timer1Timer(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure FormCreate(Sender: TObject);
      private
        procedure WMHotKey(var Msg : TWMHotKey); message WM_HOTKEY;
      public
        fgwnd:hwnd;
      end;

    var
      Form1: TForm1;

    implementation

    {$R *.dfm}

    function GetActiveChildWindow: HWND;
    var
      h, h1: HWND;
    begin
      h := GetForegroundWindow();
      if IsWindow(h) then begin
        repeat
          h1 := GetWindow(h, GW_CHILD);
          if IsWindow(h1) then begin
            if h1 <> h then h := h1;
          end else break;
        until h1 <> 0;
      end;
      result := h;
    end;

    function GetWindowText(h:HWND) : string;
    var
     buf : string;
     len : integer;
    begin
     try
       len := SendMessage(h, WM_GETTEXTLENGTH,0,0);
       SetLength(buf,len);
       SendMessage(h, WM_GETTEXT, len+1, Integer(buf));
       result := buf;
     except
       result := '';
     end;
    end;



    procedure TForm1.WMHotKey (var Msg : TWMHotKey);   //insert the key
             var
      s: string;
      h: HWND;
      StartPos, EndPos: integer;
      res: integer;
    begin
       if Msg.HotKey = 101 then
       begin
          FgWND := GetForegroundWindow;
          if FgWND <> 0 then
          begin //probably no reason to do this, but why not

    begin
      h := GetActiveChildWindow; // get active control
      if IsWindow(h) then begin
        s := GetWindowText(h); // get the whole text
        if Length(s) > 0 then begin
          res := SendMessage(h, EM_GETSEL, 0, 0); // get selected text coordinates
          StartPos := LOWORD(res);
          EndPos := HIWORD(res);
          s := Copy(s, StartPos, EndPos - StartPos); // get the selected text
          memo1.Text:=s;
          if Length(s) > 0 then begin // there is selected text
            s:= 'Hello'; // modify it
            SendMessage(h, EM_REPLACESEL, 0, Integer(PChar(s))); // replace the selection
          end;
        end;
      end;
    end;
             If IsIconic(Application.Handle) Then
                Application.Restore
             else
                Application.BringToFront;
          end;
       end;
    end;


    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
     UnRegisterHotkey(Handle, 101);
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    RegisterHotKey(Handle, 101, 0, VK_INSERT);
    end;

    end.
    0
     
    LVL 5

    Expert Comment

    by:Hypoviax
    Better stick with the original as i can only get that to work in notepad
    0
     
    LVL 1

    Author Comment

    by:czechmate
    I'll look at this tomorrow it's getting kinda late here:)
    Thanks
    cj
    0
     
    LVL 1

    Author Comment

    by:czechmate
    Ok I am back, sorry about the delay I got sidetracked on something else.

    Hypoviax you've put a lot in this and I appreciate it.  Unfortunately the latest stuff copies only from Edit based controls, I get nothing from Outlook Express, IE nor from Word.  So I am going to go for Molando solution, it is not perfect in the present form but I will pose other questions later.

    However I don't want Hypoviax to walk empty from this, his original suggestion was not far off.  I propose to split the points at 150 each for Hypoviax and Molando.  Let me know guys if your are happy about it?
    cj
    0
     
    LVL 5

    Expert Comment

    by:Hypoviax
    That's fine by me :)

    Regards,

    Hypoviax
    0
     
    LVL 5

    Expert Comment

    by:Hypoviax
    I have more time to help now i've finished my exams. If you still need more work on it i can try later and post it here

    Regards,

    Hypoviax
    0
     
    LVL 1

    Author Comment

    by:czechmate
    I think I'll shelve it for a moment.  There are confusing variations in behaviour with different Hotkey combinations:

    -Insert key on its own works ok.  Ctrl/C copies from all apps, OE, IE, Word, Excel.
    -Any key in any combination (well, almost:) with Alt key copies from edit based apps only, eg Notebook.
    -Can't figure out all variations with Shift/Ctrl

    Clipboard behaviour:
    -keybd_event Ctrl/C:
    As long as I hit the hotkey only (doing Ctrl/C) everything's OK.     The app pops up with selected text copied every time.

    -keybd_event Ctrl/V:
    depending on Hotkey definition it may or may not work.  But..! Repeating Ctrl/C event after Ctrl/V does the following:

    1) Copies selected text to clipboard, checked with Clipboard Wiever.
    2) Getting text from Clipboard causes Delphi error message 'Cannot open Clipboard'.
    3) My application pops up empty.
    4) If I hide the app and hit the hotkey again everything works normally.

    I tried to close and open clipboard in strategic places, tried to find who's the owner and close it, lock it unlock it...to no avail.  I searched the web, nada.  So if you figure out how it works please let me know:)  My email is czechmate@fastmail.fm,  let me know when you have it, I'll pose a new question for you to answer.

    Here's the last code:

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    unit Unit1;

    interface

    uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
      Dialogs,  StdCtrls, clipbrd, ComCtrls, Buttons, ExtCtrls;

    type
      TForm1 = class(TForm)
        Panel1: TPanel;
        butPasteBack: TSpeedButton;
        Memo1: TMemo;
        procedure FormCreate(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure butPasteBackClick(Sender: TObject);
      private
        { Private declarations }
         procedure WMHotKey(var Msg : TWMHotKey); message WM_HOTKEY;
         procedure SendCtrlKey(c:char);
      public
         FgWND : HWND;
        { Public declarations }
      end;


    var
      Form1: TForm1;

    implementation

    {$R *.dfm}

    procedure TForm1.FormCreate(Sender: TObject);
    begin
          RegisterHotKey(Handle, 101, 0, VK_INSERT);
    end;

    procedure TForm1.WMHotKey (var Msg : TWMHotKey);
    var b:boolean;
    begin
       if Msg.HotKey = 101 then
       begin
          FgWND := GetForegroundWindow;
          if FgWND <> 0 then
          begin
             
             SendCtrlKey('C');
             
             Sleep(250);

             //Memo1.SetFocus;
             Memo1.clear;
             try
                Memo1.Text := Clipboard.AsText;
             except
                   // seems to suppress 'Cannot Open Clipboard'
                   // message with Debugger setting
                   //'Stop on Delphi Exception' unchecked
             end;

             If IsIconic(Application.Handle) Then
                Application.Restore;
             Application.BringToFront;
          end;
       end;
    end;


    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      UnRegisterHotkey(Handle, 101);
    end;

    procedure TForm1.butPasteBackClick(Sender: TObject);
    begin
       Memo1.SelectAll;
       Clipboard.AsText := Memo1.Text;
       SetForeGroundWindow(FgWND);//bring FgWND to foreground again
       
       SendCtrlKey('V');
       
       sleep(200);
    end;

    procedure TForm1.SendCtrlKey(c: char);
    begin
       keybd_event(VK_Control,MapVirtualKey(VK_Control, 0), 0, 0);
       keybd_event(ord(c),  MapvirtualKey( ord(c), 0 ), 0, 0 );
       keybd_event(ord(c),  MapvirtualKey( ord(c), 0 ), KEYEVENTF_KEYUP, 0);
       keybd_event(VK_Control,MapVirtualKey(VK_Control, 0), KEYEVENTF_KEYUP, 0);
    end;

    end.

    0
     
    LVL 1

    Author Comment

    by:czechmate
    Hypoviax, sorry, somehow I missed the "Assisted Answer" facility for a point split, so I am posting question for you "Points for Hypoviax", just grab it.

    Regards
    cj
    0
     
    LVL 5

    Expert Comment

    by:Hypoviax
    Thanks,

    I'll have a look at your final code to see if i can improve it in anyway ;-)

    Best Regards,

    Hypoviax
    0
     
    LVL 1

    Author Comment

    by:czechmate
    Thanks and regards
    cj:)
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How your wiki can always stay up-to-date

    Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
    - Increase transparency
    - Onboard new hires faster
    - Access from mobile/offline

    Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
    In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
    This video Micro Tutorial is the second in a two-part series that shows how to create and use custom scanning profiles in Nuance's PaperPort 14.5 (http://www.experts-exchange.com/articles/17490/). But the ability to create custom scanning profiles a…
    Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

    856 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    17 Experts available now in Live!

    Get 1:1 Help Now