home *** CD-ROM | disk | FTP | other *** search
/ Softwarová Záchrana 3 / Softwarova-zachrana-3.bin / ArsClip / source.zip / UnitPaste.pas < prev    next >
Pascal/Delphi Source File  |  2004-09-02  |  20KB  |  712 lines

  1. unit UnitPaste;
  2. {
  3.     Purpose:
  4.         Move the Pasting logic into it's own class. The FrmMainPopup unit
  5.         was getting a little bloated.
  6.     NOTES;
  7.         Use EmptyClipboard (or Clipboard.Clear) before pasting - this marks
  8.         clips as "ours" so the ClipboardManager can ignore them
  9.  
  10.     Updates:
  11.         Don't use Simple Text version when pasting CF_DIBs
  12.         --------------------
  13.         Pasting complex items will now also include a plain text (for programs
  14.         that don't understand what, for example, CF_HTML is)
  15.         --------------------
  16.         New option to alter the clipboard (and trigger the Clipboard Manager)
  17.         Win9x Mimic characters shift keys didn't work
  18.         -----------
  19.         Clear the clipboard before pasting
  20.         This is the only place an item may be placed on the clipboard
  21.  
  22.         ------
  23.         Another fix for SHIFT+Insert on Win2k
  24.         --------------------
  25.         - New support for pasting with keystrokes embedded in the text
  26.         - Fix for SHIFT+Insert on Win2k
  27. }
  28. interface
  29. uses UnitClipQueue, INIFiles;
  30.  
  31. type TPasteMethod = (
  32.     PASTE_CTRL_V=0,
  33.     PASTE_SHIFT_INS=1,
  34.     PASTE_MIMIC=2,
  35.     PASTE_CLIPBOARD=3,
  36.     PASTE_DEFAULT=4
  37. );
  38.  
  39. type TPaste = class(TObject)
  40.     private
  41.         {Configurations for pasting method}
  42.         UseKeyboardMimic,
  43.         UsePastingSI,
  44.         UsePastingCV,
  45.         UseClipboardOnly,
  46.  
  47.         {single time use overrides for pasting}
  48.         PasteCVOnce,
  49.         PasteSIOnce,
  50.         ClipboardOnlyOnce,
  51.         KeyboardMimicOnce : boolean;
  52.  
  53.         EXEPasteList : THashedStringList;
  54.  
  55.         procedure ClearMethods;
  56.     public
  57.         constructor Create;
  58.         destructor Destroy; override;
  59.         procedure SendText(s: string; ci  : TClipItem = nil);
  60.         procedure SendTextWithKeystrokes(s : string);
  61.         procedure PlaceOnClipboardDontBypassClipboardManager(s : string);
  62.         procedure SendSHIFT_INSERT;
  63.         procedure SendCTRL_V;
  64.         procedure SendTAB;
  65.         procedure SendENTER;
  66.         procedure SendINSERT;
  67.         procedure SendDELETE;
  68.         procedure SendBACKSPACE;
  69.         procedure SendHOME;
  70.         procedure SendEND;
  71.         procedure SendUP;
  72.         procedure SendDOWN;
  73.         procedure SendLEFT;
  74.         procedure SendRIGHT;
  75.  
  76.         {Used by FrmCONFIG to set pasting method}
  77.         procedure SetClipboardOnly;
  78.         function GetClipboardOnly : boolean;
  79.         procedure SetMimicTyping;
  80.         procedure SetUsePaste;
  81.         procedure SetUsePasteSI;
  82.  
  83.         {Used by FrmMainPopup}
  84.         procedure SetClipboardOnlyOnce;
  85.         procedure SetKeyboardMimicOnce;
  86.         function GetKeyboardMimicOnce : boolean;
  87.         procedure SetUsePasteCVOnce;
  88.         procedure SetUsePasteSIOnce;
  89.         procedure ClearOnceFlags;
  90.  
  91.         procedure AssignPaste(EXEName : string; method : TPasteMethod);
  92.         function GetPasteMethod(EXEName : string) : TPasteMethod;
  93.         function GetDefaultPasteMethod : TPasteMethod;
  94. end;
  95.  
  96. var Paste : TPaste;
  97.  
  98. implementation
  99.  
  100. uses Windows, SysUtils, StrUtils, UnitFrmMainPopup, clipbrd,
  101.     UnitFrmClipboardManager, UnitOtherQueue, UnitMisc, UnitToken, Forms, Dialogs;
  102.  
  103. const  EXEPASTE_FILE = 'exepaste.ini';
  104. { TPaste }
  105.  
  106. procedure TPaste.PlaceOnClipboardDontBypassClipboardManager(s: string);
  107. begin
  108.     // No clearing, do not prevent the Clipboard from detecting the change
  109.     clipboard.SetTextBuf(PChar(s));
  110. end;
  111.  
  112.  
  113. //
  114. // Either send text S or use ClipItem if specificed
  115. //
  116. procedure TPaste.SendText(s: string; ci : TClipItem = nil);
  117.     procedure SendUsingKeyboardMimic(s : string);
  118.     var c : char;
  119.         w : word;
  120.         i : integer;
  121.         ShiftPressed, EnterPressed : boolean;
  122.     begin
  123.         UnitMisc.AppendLog('mimic typing');
  124.         for i := 1 to length(s) do begin
  125.             c := s[i];
  126.             w := VkKeyScan(c);
  127.             ShiftPressed := (hi(w) and 1) > 0;
  128.             EnterPressed := (byte(c) = VK_RETURN);
  129.             {VkKeyScan: The first bit of the hi byte set means shift is pressed}
  130.             {Ditch LF - assume CR came first}
  131.             if (c <> #10) then begin
  132.                 if ShiftPressed and (not EnterPressed) then begin
  133.                     //keybd_event(VK_RSHIFT, 0, 0, 0);
  134.                     keybd_event(VK_SHIFT, Lo(MapVirtualKey(VK_SHIFT,0)),0,0);
  135.                 end;
  136.  
  137.                 {Press and release key}
  138.                 keybd_event(lo(w), w, 0, 0);
  139.                 keybd_event(lo(w), w, KEYEVENTF_KEYUP, 0);
  140.  
  141.                 if ShiftPressed and (not EnterPressed) then begin
  142.                     //keybd_event(VK_RSHIFT, 0, KEYEVENTF_KEYUP, 0);
  143.                      keybd_event(VK_SHIFT, Lo(MapVirtualKey(VK_SHIFT,0)), KEYEVENTF_KEYUP, 0);
  144.                 end;
  145.             end;
  146.  
  147.             if (i mod 10 = 0) then sleep(1); // give the keyboard buffer a little break
  148.         end;
  149.     end;
  150.  
  151.     procedure PutOnClipboard;
  152.     begin
  153.         clipboard.Clear; // <-- Makes use OWNER and flags the data
  154.                          // to be ignored by us
  155.         clipboard.SetTextBuf(PChar(s));
  156.     end;
  157.  
  158.     procedure SendUsingPaste(s : string);
  159.     begin
  160.         //
  161.         // place text on clipboard and paste via CTRL+P
  162.         //
  163.  
  164.         UnitMisc.AppendLog('clearing and placing selected text on clipboard');
  165.         UnitMisc.AppendLog('---"' + s + '"---');
  166.         PutOnClipboard;
  167.  
  168.         sleep(10);
  169.         if (self.PasteSIOnce) then begin
  170.             Self.SendSHIFT_INSERT;
  171.         end else if (self.PasteCVOnce) then begin
  172.             Self.SendCTRL_V;
  173.         end else if (self.UsePastingCV)  then begin
  174.             Self.SendCTRL_V;
  175.         end else if (self.UsePastingSI) then begin
  176.             Self.SendSHIFT_INSERT;
  177.         end;
  178.     end;
  179.  
  180.     function PutClipOnCLipboard(ci : TClipItem; Format : word = 0) : boolean;
  181.     var duph : THandle;
  182.         dups : cardinal;
  183.         pc : PChar;
  184.         s : string;
  185.     begin
  186.         result := false;
  187.  
  188.         if (Format = CF_TEXT) then begin
  189.             s := ci.GetAsText;
  190.             dups := length(s) + 1;
  191.             duph := Windows.GlobalAlloc(GMEM_MOVEABLE or GMEM_ZEROINIT, dups);
  192.             pc := Windows.GlobalLock(duph);
  193.             Windows.MoveMemory(pc, pchar(s), dups);
  194.             Windows.GlobalUnlock(duph);
  195.             Windows.SetClipboardData(CF_TEXT, duph);
  196.         end else begin
  197.             duph := UnitMisc.DupHandle(ci.GetHandle, dups);
  198.             if (duph <> 0) then begin
  199.                 Windows.SetClipboardData(ci.GetFormat, duph);
  200.             end else begin
  201.                 UnitMisc.AppendLog('SendText: Unable to dup ClipItem to place on clipboard');
  202.                 EXIT;
  203.             end;
  204.         end;
  205.  
  206.         result := true;
  207.     end;
  208. begin
  209.     if (s = '') and (ci = nil) then EXIT;
  210.  
  211.     UnitMisc.AppendLog('[Paste Start]');
  212.  
  213.     // send text using configured method
  214.     // Update: ClipboardOnlyWindow will override and force
  215.     //          a clipboard only operation
  216.     if (ci = nil) then begin
  217.         UnitMisc.AppendLog('Plain text version');
  218.         if (self.ClipboardOnlyOnce) then begin
  219.             self.ClipboardOnlyOnce := false;
  220.             PutOnClipboard;
  221.         end else if (self.UseKeyboardMimic or self.KeyboardMimicOnce) then begin
  222.             SendUsingKeyboardMimic(s);
  223.             self.KeyboardMimicOnce := false;
  224.         end else if (self.UsePastingCV or self.UsePastingSI
  225.             or self.PasteCVOnce or self.PasteSIOnce) then  begin
  226.             SendUsingPaste(s);
  227.             self.PasteCVOnce := false;
  228.             self.PasteSIOnce := false;
  229.         end else begin
  230.             // send clipboard only
  231.             PutOnClipboard;
  232.         end;
  233.     end else begin
  234.         UnitMisc.AppendLog('complex text version');
  235.         //
  236.         // No calls to unit Clipbrd can be used to in this section
  237.         // since it will try to open and already open clipboard.
  238.         // Place both the plain text version and the complex item on the clipboard
  239.         //
  240.         Windows.OpenClipboard(0);
  241.         Windows.EmptyClipboard;
  242.         //Clipboard.Clear; // <- Makes use owner
  243.         if ci.HasText and (ci.GetFormat <> Windows.CF_DIB)  then begin
  244.             if not PutClipOnCLipboard(ci, CF_TEXT) then begin
  245.                 Windows.CloseClipboard;
  246.                 EXIT;
  247.             end;
  248.         end;
  249.         if not PutClipOnCLipboard(ci) then begin
  250.             Windows.CloseClipboard;
  251.             EXIT;
  252.         end;
  253.         Windows.CloseClipboard;
  254.  
  255.         //ci.PlaceOnClipboard;
  256.  
  257.         if (self.ClipboardOnlyOnce) then begin
  258.             self.ClipboardOnlyOnce := false;
  259.         end else if (self.UseKeyboardMimic or self.KeyboardMimicOnce) then begin
  260.             if (ci.HasText) then begin
  261.                 SendUsingKeyboardMimic(ci.GetAsText);
  262.             end else begin
  263.                 // I can't mimic the clipitem - default to ctrl+v
  264.                 self.SendCTRL_V;
  265.             end;
  266.             self.KeyboardMimicOnce := false;
  267.         end else if (self.UsePastingCV or self.PasteCVOnce) then  begin
  268.             self.SendCTRL_V;
  269.             self.PasteCVOnce := false;
  270.         end else if (self.UsePastingSI or self.PasteSIOnce) then  begin
  271.             self.SendSHIFT_INSERT;
  272.             self.PasteSIOnce := false;
  273.         end;
  274.  
  275.     end;
  276.  
  277.  
  278.  
  279.     UnitMisc.AppendLog('[Paste End]');
  280.     //frmClipboardManager.InformOfPaste;
  281.     //frmClipboardManager.SetIgnoreClipboard(false);
  282. end;
  283.  
  284.  
  285. //
  286. // used by SendText and OtherItemClickEvent to simulate the user
  287. // pressing CTRL+V to paste
  288. //
  289. procedure TPaste.SendCTRL_V;
  290. var w : word;
  291. begin
  292.     UnitMisc.AppendLog('sending CTRL+V');
  293.  
  294.     // clear any phantom keystrokes
  295.     keybd_event(VK_SHIFT, VkKeyScan(char(VK_SHIFT)), KEYEVENTF_KEYUP, 0);
  296.     keybd_event(VK_CONTROL , VkKeyScan(char(VK_control)), KEYEVENTF_KEYUP, 0);
  297.     sleep(10);
  298.  
  299.     // press CTRL, press V, release V, release CTRL
  300.     keybd_event(VK_CONTROL , VkKeyScan(char(VK_control)), 0, 0);
  301.     sleep(10);
  302.             w := VkKeyScan('V');
  303.             keybd_event(lo(w), w, 0, 0);
  304.             sleep(10);
  305.  
  306.             keybd_event(lo(w), w, KEYEVENTF_KEYUP, 0);
  307.             sleep(10);
  308.     keybd_event(VK_CONTROL , VkKeyScan(char(VK_control)), KEYEVENTF_KEYUP, 0);
  309.     sleep(10);
  310.     UnitMisc.AppendLog('sent CTRL+V');
  311. end;
  312.  
  313. procedure TPaste.SendSHIFT_INSERT;
  314. begin
  315.     UnitMisc.AppendLog('sending SHIFT+INSERT');
  316.  
  317.     // clear any phantom keystrokes
  318.     keybd_event(VK_SHIFT, VkKeyScan(char(VK_SHIFT)), KEYEVENTF_KEYUP, 0);
  319.     keybd_event(VK_CONTROL , VkKeyScan(char(VK_control)), KEYEVENTF_KEYUP, 0);
  320.     sleep(10);
  321.  
  322.     // press SHIFT, press INSERT, release INSERT, release SHIFT
  323.  
  324.     // Label VK_INSERT as extended, othewise it freaks out when combined with SHIFT
  325.  
  326.     keybd_event(VK_SHIFT, Lo(MapVirtualKey(VK_SHIFT,0)),0,0);  // win9x
  327.     sleep(1);
  328.             keybd_event(VK_INSERT, Lo(MapVirtualKey(VK_INSERT,0)),KEYEVENTF_EXTENDEDKEY, 0);
  329.             sleep(1);
  330.  
  331.             keybd_event(VK_INSERT, Lo(MapVirtualKey(VK_INSERT,0)),KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP,0);
  332.             sleep(1);
  333.  
  334.     keybd_event(VK_SHIFT, Lo(MapVirtualKey(VK_SHIFT,0)), KEYEVENTF_KEYUP, 0);
  335.     sleep(5);
  336.     UnitMisc.AppendLog('sent SHIFT+INSERT');
  337. end;
  338.  
  339. procedure TPaste.SendTAB;
  340. begin
  341.     UnitMisc.AppendLog('sending tab');
  342.     keybd_event(VK_TAB , 0, 0, 0);
  343.     sleep(50);
  344.  
  345.     keybd_event(VK_TAB, 0, KEYEVENTF_KEYUP, 0);
  346.     sleep(10);
  347.     UnitMisc.AppendLog('sent tab');
  348. end;
  349. procedure TPaste.SendDELETE;
  350. begin
  351.     UnitMisc.AppendLog('sending del');
  352.     keybd_event(VK_DELETE, 0, 0, 0);
  353.     sleep(50);
  354.  
  355.     keybd_event(VK_DELETE, 0, KEYEVENTF_KEYUP, 0);
  356.     sleep(10);
  357.     UnitMisc.AppendLog('sent del');
  358.  
  359. end;
  360. procedure TPaste.SendINSERT;
  361. begin
  362.     UnitMisc.AppendLog('sending INSERT');
  363.     keybd_event(VK_INSERT, 0, 0, 0);
  364.     sleep(50);
  365.  
  366.     keybd_event(VK_INSERT, 0, KEYEVENTF_KEYUP, 0);
  367.     sleep(10);
  368.     UnitMisc.AppendLog('sent INSERT');
  369. end;
  370.  
  371. procedure TPaste.SendENTER;
  372. begin
  373.     UnitMisc.AppendLog('sending insert');
  374.     keybd_event(VK_RETURN, MapVirtualKey(VK_RETURN,0), 0, 0);
  375.     sleep(50);
  376.  
  377.     keybd_event(VK_RETURN, MapVirtualKey(VK_RETURN,0), KEYEVENTF_KEYUP, 0);
  378.     sleep(10);
  379.     UnitMisc.AppendLog('sent insert');
  380. end;
  381.  
  382.  
  383.  
  384. procedure TPaste.ClearMethods;
  385. begin
  386.     self.UseKeyboardMimic := false;
  387.     self.UsePastingSI := false;
  388.     self.UsePastingCV := false;
  389.     self.UseClipboardOnly := false;
  390. end;
  391.  
  392.  
  393. procedure TPaste.SetClipboardOnly;
  394. begin
  395.     self.ClearMethods;
  396.     self.UseClipboardOnly := true;
  397. end;
  398. procedure TPaste.SetMimicTyping;
  399. begin
  400.     self.ClearMethods;
  401.     self.UseKeyboardMimic := true;
  402. end;
  403. procedure TPaste.SetUsePaste;
  404. begin
  405.     self.ClearMethods;
  406.     self.UsePastingCV := true;
  407. end;
  408. procedure TPaste.SetUsePasteSI;
  409. begin
  410.     self.ClearMethods;
  411.     self.UsePastingSI := true;
  412. end;
  413.  
  414.  
  415.  
  416. procedure TPaste.SetKeyboardMimicOnce;
  417. begin
  418.     self.KeyboardMimicOnce := true;
  419. end;
  420. procedure TPaste.SetUsePasteCVOnce;
  421. begin
  422.     self.PasteCVOnce := true;
  423. end;
  424. procedure TPaste.SetUsePasteSIOnce;
  425. begin
  426.     self.PasteSIOnce := true;
  427. end;
  428. procedure TPaste.SetClipboardOnlyOnce;
  429. begin
  430.     self.ClipboardOnlyOnce := true;
  431. end;
  432.  
  433. function TPaste.GetClipboardOnly: boolean;
  434. begin
  435.     result := self.UseClipboardOnly;
  436. end;
  437.  
  438.  
  439.  
  440. {
  441. //
  442. // Not used, but may need to be refered to later
  443. //
  444. procedure TFrmMainPopup.PlaceTextOnClipboard(s : string);
  445.     procedure SetBuffer(format: Word; var buffer; Size: Integer);
  446.     var Data: THandle;
  447.         DataPtr: Pointer;
  448.     begin
  449.         clipboard.Open;
  450.         try
  451.             Data := Windows.GlobalAlloc(GMEM_MOVEABLE+GMEM_DDESHARE, Size);
  452.             try
  453.                 DataPtr := GlobalLock(Data);
  454.                 try
  455.                     Move(Buffer, DataPtr^, Size);
  456.                     clipboard.Clear;
  457.                     Windows.SetClipboardData(Format, Data);
  458.                 finally
  459.                     Windows.GlobalUnlock(Data);
  460.                 end;
  461.             except
  462.                 Windows.GlobalFree(Data);
  463.                 raise;
  464.             end;
  465.         finally
  466.             clipboard.Close;
  467.         end;
  468.     end;
  469.  
  470. begin
  471.  
  472.     s := s + #0 + 'ArsClip' + #0;
  473.     SetBuffer(CF_TEXT, PChar(s)^, length(s) + 1);
  474. end;
  475. }
  476.  
  477.  
  478.  
  479. function TPaste.GetKeyboardMimicOnce: boolean;
  480. begin
  481.     result := self.UseKeyboardMimic;
  482. end;
  483.  
  484. type TKeyProc = procedure;
  485.  
  486. procedure TPaste.SendTextWithKeystrokes(s: string);
  487. var str : string;
  488.     key : string;
  489. const SLEEPMS = 60;
  490.  
  491.     procedure PreKey;
  492.     begin
  493.         self.SendText(str);
  494.         sleep(SLEEPMS);
  495.     end;
  496.     procedure PostKey;
  497.     begin
  498.         Application.ProcessMessages;
  499.         str := '';
  500.     end;
  501. begin
  502.     // key rid of '[KEYS]'
  503.     s := rightstr(s,length(s) - 6);
  504.  
  505.     str := '';
  506.     while (s <> '') do begin
  507.         if (pos('[',s) <> 0) and (pos(']',s) <> 0) then begin
  508.             str := str + TokenString(s, '[');
  509.             if (s <> '') then begin
  510.                 key := Uppercase(TokenString(s, ']'));
  511.                 if (key = 'TAB') then begin
  512.                     prekey; self.SendTAB; PostKey;
  513.                 end else if (key = 'ENTER') then begin
  514.                     prekey; self.SendENTER; PostKey;
  515.                 end else if (key = 'DEL') then begin
  516.                     prekey; self.SendDELETE; PostKey;
  517.                 end else if (key = 'HOME') then begin
  518.                     prekey; self.SendHOME; PostKey;
  519.                 end else if (key = 'BACK') then begin
  520.                     prekey; self.SendBACKSPACE; PostKey;
  521.                 end else if (key = 'END') then begin
  522.                     prekey; self.SendEND; PostKey;
  523.                 end else if (key = 'INS') then begin
  524.                     prekey; self.SendINSERT; PostKey;
  525.                 end else if (key = 'UP') then begin
  526.                     prekey; self.SendUP;PostKey;
  527.                 end else if (key = 'DOWN') then begin
  528.                     prekey; self.SendDOWN; PostKey;
  529.                 end else if (key = 'LEFT') then begin
  530.                     prekey;self.SendLEFT; PostKey;
  531.                 end else if (key = 'RIGHT') then begin
  532.                    prekey; self.SendRIGHT; PostKey;
  533.                 end else begin
  534.                     // not a key, just add it to they string to
  535.                     // send buffer
  536.                     str := str + '['+ key + ']';
  537.                 end;
  538.             end;
  539.         end else begin
  540.             str := s;
  541.             s := '';
  542.         end;
  543.     end;
  544.     
  545.     if (s = '') then begin
  546.         if (str <> '') then begin
  547.             self.SendText(str);
  548.         end;
  549.     end;
  550.  
  551. end;
  552.  
  553.  
  554.  
  555.  
  556.  
  557. procedure TPaste.SendBACKSPACE;
  558. begin
  559.     UnitMisc.AppendLog('sending back');
  560.     keybd_event(VK_BACK , 0, 0, 0);
  561.     sleep(50);
  562.  
  563.     keybd_event(VK_BACK, 0, KEYEVENTF_KEYUP, 0);
  564.     sleep(10);
  565.     UnitMisc.AppendLog('sent back');
  566. end;
  567.  
  568. procedure TPaste.SendEND;
  569. begin
  570.     UnitMisc.AppendLog('sending end');
  571.     keybd_event(VK_END  , 0, 0, 0);
  572.     sleep(50);
  573.  
  574.     keybd_event(VK_END, 0, KEYEVENTF_KEYUP, 0);
  575.     sleep(10);
  576.     UnitMisc.AppendLog('sent end');
  577. end;
  578.  
  579. procedure TPaste.SendHOME;
  580. begin
  581.     UnitMisc.AppendLog('sending VK_HOME');
  582.     keybd_event(VK_HOME  , 0, 0, 0);
  583.     sleep(50);
  584.  
  585.     keybd_event(VK_HOME, 0, KEYEVENTF_KEYUP, 0);
  586.     sleep(10);
  587.     UnitMisc.AppendLog('sent VK_HOME');
  588. end;
  589.  
  590. procedure TPaste.SendDOWN;
  591. begin
  592.      UnitMisc.AppendLog('sending VK_DOWN');
  593.     keybd_event(VK_DOWN   , 0, 0, 0);
  594.     sleep(50);
  595.  
  596.     keybd_event(VK_DOWN, 0, KEYEVENTF_KEYUP, 0);
  597.     sleep(10);
  598.     UnitMisc.AppendLog('sent VK_DOWN');
  599. end;
  600.  
  601. procedure TPaste.SendLEFT;
  602. begin
  603.   UnitMisc.AppendLog('sending VK_LEFT');
  604.     keybd_event(VK_LEFT   , 0, 0, 0);
  605.     sleep(50);
  606.  
  607.     keybd_event(VK_LEFT, 0, KEYEVENTF_KEYUP, 0);
  608.     sleep(10);
  609.     UnitMisc.AppendLog('sent VK_LEFT');
  610. end;
  611.  
  612. procedure TPaste.SendRIGHT;
  613. begin
  614.    UnitMisc.AppendLog('sending VK_RIGHT');
  615.     keybd_event(VK_RIGHT   , 0, 0, 0);
  616.     sleep(50);
  617.  
  618.     keybd_event(VK_RIGHT, 0, KEYEVENTF_KEYUP, 0);
  619.     sleep(10);
  620.     UnitMisc.AppendLog('sent VK_RIGHT');
  621. end;
  622.  
  623. procedure TPaste.SendUP;
  624. begin
  625.    UnitMisc.AppendLog('sending VK_UP');
  626.     keybd_event(VK_UP   , 0, 0, 0);
  627.     sleep(50);
  628.  
  629.     keybd_event(VK_UP, 0, KEYEVENTF_KEYUP, 0);
  630.     sleep(10);
  631.     UnitMisc.AppendLog('sent VK_UP');
  632. end;
  633.  
  634.  
  635.  
  636.  
  637.  
  638. procedure TPaste.ClearOnceFlags;
  639. begin
  640.     PasteCVOnce := false;
  641.     PasteSIOnce := false;
  642.     ClipboardOnlyOnce := false;
  643.     KeyboardMimicOnce := false;
  644. end;
  645.  
  646.  
  647. //
  648. // Assigned Paste Methods
  649. //
  650. constructor TPaste.Create;
  651. var s : string;
  652. begin
  653.     self.EXEPasteList := THashedStringList.Create;
  654.     s := IncludeTrailingPathDelimiter(ExtractFilePath(application.ExeName));
  655.     s := s + EXEPASTE_FILE;
  656.     if FileExists(s) then begin
  657.         self.EXEPasteList.LoadFromFile(s);
  658.     end;
  659. end;
  660.  
  661. destructor TPaste.Destroy;
  662. var s : string;
  663. begin
  664.     s := IncludeTrailingPathDelimiter(ExtractFilePath(application.ExeName));
  665.     s := s + EXEPASTE_FILE;
  666.     self.EXEPasteList.SaveToFile(EXEPASTE_FILE);
  667.     MyFree(EXEPasteList);
  668. end;
  669.  
  670.  
  671. procedure TPaste.AssignPaste(EXEName: string; method: TPasteMethod);
  672. begin
  673.     EXEPasteList.Values[EXEName] := IntToStr(Integer(method));
  674. end;
  675.  
  676. function TPaste.GetPasteMethod(EXEName : string) : TPasteMethod;
  677. var s : string;
  678. begin
  679.     result := PASTE_DEFAULT;
  680.     s := EXEPasteList.Values[EXEName];
  681.  
  682.     if (s <> '') then begin
  683.         result := TPasteMethod(StrToInt(s));
  684.     end;
  685. end;
  686.  
  687.  
  688. function TPaste.GetDefaultPasteMethod: TPasteMethod;
  689. begin
  690.     result := PASTE_DEFAULT; // this case should never fire
  691.  
  692.     if self.UseKeyboardMimic then begin
  693.         result := PASTE_MIMIC;
  694.     end else if self.UsePastingSI then begin
  695.         result := PASTE_SHIFT_INS;
  696.     end else if self.UsePastingCV then begin
  697.         result := PASTE_CTRL_V;
  698.     end else if self.UseClipboardOnly then begin
  699.         result := PASTE_CLIPBOARD
  700.     end;
  701. end;
  702.  
  703. initialization
  704. begin
  705.     Paste := TPaste.Create;
  706. end;
  707. finalization
  708. begin
  709.     MyFree(Paste);
  710. end;
  711. end.
  712.