A Google Csoportok már nem támogatja az új Usenet-bejegyzéseket és -feliratkozásokat. A korábbi tartalmak továbbra is megtekinthetők.

Sending Keys in Delphi? How?

10 megtekintés
Ugrás az első olvasatlan üzenetre

Philippe Ranger

olvasatlan,
1999. jan. 2. 3:00:001999. 01. 02.
Andre: >>. In VBA we
have the instruction SendKeys; does Delphi has a way to implement something
equivalent?
<<

SendKeys is a wrapper around the Win32 API function keybd_event, which of
course is accessible from Delphi (use Windows.pas). See the Help for
Keybd_event. If you have trouble with the parameters, ask again. You can
leave dwExtraInfo at 0.

But first look at the answer to the same question from Joe C. Hecht, in the
"Anything Like VB's SendKeys?" thread. It's very clear and very detailed.


Like SendKeys, keybd_event feeds whatever window happens to have the focus —
just as if you were typing on the keyboard. You can also, with some
limitations, feed keys to a specific window, but that uses another route,
and it's more complicated.

Re: Anything Like VB's SendKeys?
PhR

Andre Luis

olvasatlan,
1999. jan. 3. 3:00:001999. 01. 03.
Hi,

As a VBA Excel programmer trying to go to Delphi, I'd like to know, first,
how
to run and external application from my own one and most important if there
is a way to SendKeys (keystrokes) from my own application - in Delphi - to
this
another external running application. I want to control an external
program sending keystrokes to
it, because first I am quite sure it does not have DDE or OLE automation
and, second, if it had, it would be more dificult to use it . In VBA we


have the instruction SendKeys; does Delphi has a way to implement something
equivalent?

I have already seen some answers here, concerning to this issue, but, since
i am really beginner when dealing with API, messages, handles, I'd like to
have a more easy to follow help.

Thanks,

Andre Viol.

Andre Luis

olvasatlan,
1999. jan. 4. 3:00:001999. 01. 04.
It's me again yet trying to make a SendKeys in Delphi, despite all of the
tips i have read or received. Maybe i should go to school...

Below is a sample code I wrote, based on some freeware programs out there
and on my readings, but it is not working. Can someone help me with it
telling me what is wrong.

procedure TForm1.DLoaderButtonClick(Sender: TObject);
var
myHandle,
thisHandle : THandle;
i : integer;
TestStr : string;
begin
{Ora Pro Nobis is the program with the DLoaderButton, used to test this
procedure}
thisHandle:= FindWindow( 'TApplication', 'Ora Pro Nobis');
myHandle:= FindWindow( 'Notepad', 'Test.txt - Notepad');
if (myHandle <> 0) and (thisHandle <> 0) then
showmessage('handles are ok!');
{i am receiving the message above, so the handles are ok}
SendMessage( thisHandle, WM_KILLFOCUS, 0, 0);
SendMessage( myHandle, WM_SETFOCUS, 0, 0);
TestStr := 'TEST';
for i := 1 to Length(TestStr) do
begin
SendMessage(myHandle, WM_KEYDOWN, Ord(TestStr[i]), 0);
// SendMessage(myHandle, WM_CHAR, Ord(TestStr[i]), 0); I tried this
also and did not work also
end;
end;

This procedure above was supposed to write the text "TEST" in a notepad text
open file but it is not working. Can someone tell me why. What do I have
to do to make it work?

Thankx for any help.

Thanks also for the people from this Newsgroup that has already sent me
tips.

Andre Viol
i...@fazenda.gov.br


Peter Below

olvasatlan,
1999. jan. 4. 3:00:001999. 01. 04.
> Below is a sample code I wrote, based on some freeware programs out there
> and on my readings, but it is not working. Can someone help me with it
> telling me what is wrong.
>
> myHandle:= FindWindow( 'Notepad', 'Test.txt - Notepad');
> TestStr := 'TEST';
> for i := 1 to Length(TestStr) do
> begin
> SendMessage(myHandle, WM_CHAR, Ord(TestStr[i]), 0);

> This procedure above was supposed to write the text "TEST" in a notepad text


> open file but it is not working. Can someone tell me why.

You are not sending the messages to the correct window. The notepad window is
filled by a multiline edit control, and *that* is the window that processes
keyboard messages, not the main window.

myHandle:= FindWindow( 'Notepad', 'Test.txt - Notepad');

if myHandle <> 0 then
myHandle:= GetWindow( myHandle, GW_CHILD );

will give you the correct handle. But this is something that will have to be
customized for every target application and is thus not something you would
want to use if a "generic" solution is required. Using Keybd_event avoids this
issue, you just make the target app active (SetForegroundWindow( myHAndle ))
and then fire away, the keys automatically go to the control with focus.

{************************************************************
* Procedure PostKeyEx32
*
* Parameters:
* key : virtual keycode of the key to send. For printable
* keys this is simply the ANSI code (Ord(character)).
* shift : state of the modifier keys. This is a set, so you
* can set several of these keys (shift, control, alt,
* mouse buttons) in tandem. The TShiftState type is
* declared in the Classes Unit.
* specialkey: normally this should be False. Set it to True to
* specify a key on the numeric keypad, for example.
* Description:
* Uses keybd_event to manufacture a series of key events matching
* the passed parameters. The events go to the control with focus.
* Note that for characters key is always the upper-case version of
* the character. Sending without any modifier keys will result in
* a lower-case character, sending it with [ssShift] will result
* in an upper-case character!
*Created: 17.7.98 by P. Below
************************************************************}
Procedure PostKeyEx32( key: Word; Const shift: TShiftState;
specialkey: Boolean );
Type
TShiftKeyInfo = Record
shift: Byte;
vkey : Byte;
End;
byteset = Set of 0..7;
Const
shiftkeys: Array [1..3] of TShiftKeyInfo =
((shift: Ord(ssCtrl); vkey: VK_CONTROL ),
(shift: Ord(ssShift); vkey: VK_SHIFT ),
(shift: Ord(ssAlt); vkey: VK_MENU ));
Var
flag: DWORD;
bShift: ByteSet absolute shift;
i: Integer;
Begin
For i := 1 To 3 Do Begin
If shiftkeys[i].shift In bShift Then
keybd_event( shiftkeys[i].vkey,
MapVirtualKey(shiftkeys[i].vkey, 0),
0, 0);
End; { For }
If specialkey Then
flag := KEYEVENTF_EXTENDEDKEY
Else
flag := 0;

keybd_event( key, MapvirtualKey( key, 0 ), flag, 0 );
flag := flag or KEYEVENTF_KEYUP;
keybd_event( key, MapvirtualKey( key, 0 ), flag, 0 );

For i := 3 DownTo 1 Do Begin
If shiftkeys[i].shift In bShift Then
keybd_event( shiftkeys[i].vkey,
MapVirtualKey(shiftkeys[i].vkey, 0),
KEYEVENTF_KEYUP, 0);
End; { For }
End; { PostKeyEx32 }

procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
Memo1.Setfocus;
PostKeyEx32( VK_END, [ssCtrl, ssShift], False ); {select all}
PostKeyEx32( Ord('C'), [ssCtrl], False ); {copy to clipboard}
PostKeyEx32( Ord('C'), [ssShift], False ); {replace with C}
PostKeyEx32( VK_RETURN, [], False ); {new line}
PostKeyEx32( VK_END, [], False ); {goto end}
PostKeyEx32( Ord('V'), [ssCtrl], False ); {paste from keyboard}
end;

Microsoft changed the behaviour of SetForegroundWindow on Win98 and NT 5, i
don't know if it would still work as intended for the purpose of activating
the target for a POstKeyex32 on these platforms. There is also a problem if
you want to send characters not in the range A..Z,0..9 (a..z is send as
A..Z!). The Ord-values of other characters are usually already assigned to
other virtual key codes (e.g. Ord('!') = VK_PRIOR). YOu have to use the
VkKeyScan API function to figure out the virtual key code and modifier key
combination to use for a specific character.

Procedure SendText( S: String );
Var
flags: TShiftState;
vcode: word;
ret : word;
i, n : Integer;
mask : word;
Begin
For i := 1 To Length(S) Do Begin
ret := VkKeyScan( S[i] );
vcode := Lobyte( ret );
flags := [];
mask := $100;
For n := 1 To 3 Do Begin
If (ret and mask) <> 0 Then Begin
Case mask Of
$100: Include( flags, ssShift );
$200: Include( flags, ssCtrl );
$400: Include( flags, ssAlt );
End; { Case }
End; { If }
mask := mask shl 1;
End; { For }
PostKeyEx32( vcode, flags, false );
End; { For }
End; { SendText }


Peter Below (TeamB) 10011...@compuserve.com)
No e-mail responses, please, unless explicitely requested!


0 új üzenet