Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Postmessage, Shift Key & control Key usage

Posted on 1999-07-22
16
Medium Priority
?
2,084 Views
Last Modified: 2012-05-04
I'm using VB6, but y'all should be able to answer this.

I tried to use the postmessage command to send keystrokes to MS Word 97 (I'm using Word 97 as a test of my program) from a VB program.  I used the WM_KEYDOWN, WM_CHAR, and WM_KEYUP            commands.

                (I'm not creating a process instance, I'm just grabbing the hwnd of an already open app.)

                The order of messages are:
                1.  WM_KEYDOWN shift
                2.  WM_KEYDOWN "A"
                3.  WM_CHAR "A"
                4.  WM_KEYUP "A"

What happens is that a capital A and a lowercase a is sent.  When I remove the WM_CHAR,  only one a is sent (lower case).  When I put the caps lock on, then a capital A is sent.  All of the values are &H41 (65 , letter A).

                My suspiscion is that when I send the shift message, it doesn't "hold" while the next message is               being sent, ie, when I send the a, it checks that status of the shift key.

                I'm not sure if this is the way MS Word handles keystrokes, but I need to be able to send               keystrokes this way (not via Sendkeys or COM or any way.  I WANT to use the post message way).

                My question is, how do I force Shift and letter combinations, and especially, how do I force                 Control and letter combinations via postmessage/sendmessage  (send message won't work)?  Do I have to force  a caps locks?  What about CTRL, since there is no CTRL lock?  

                There are some apps besides Word that I need to send control combinations (ie CTRL + Z)

                Thanks,
                Ruben
0
Comment
Question by:obregoru
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 4
  • 3
  • +3
16 Comments
 
LVL 14

Expert Comment

by:AlexVirochovsky
ID: 1200820
Easiest way to make it: using kebd_event function!
Example:
keybd_event('A', 'A',KEYEVENTF_KEYUP, 0);
See Windows doc about more deatiles:
Other possibility: use SetKeyboardState(for set many
codes).
Good Luck, Alex
0
 
LVL 2

Author Comment

by:obregoru
ID: 1200821
I need some sample code of this actually happening.  I don't know if I can use keybd_event or setkeyboard state for other tasks.

0
 
LVL 2

Author Comment

by:obregoru
ID: 1200822
I tried the following (&H105D4 is the hwnd to Document 1 in word.) and it still gave me lower case keystrokes in the document.  (Seems to work in the VB environment, status of shift is true when the code runs.)


keybd_event(&H10, &H45, KEYEVENTF_EXTENDEDKEY Or 0, 0) 'shift down
PostMessage(&H105D4, WM_KEYDOWN, &H41, &H1E0001)  'A down
PostMessage(&H105D4, &H101, &H41, &HC01E0001) 'A up
Call keybd_event(&H10, &H45, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0) 'shift up

Tried all keybd_events instead of postmessages, no luck!
(I'm in NT4).  Maybe I'm passing the wrong paramters (the hwind is correct).

I need to use VB as a "front" end and send keystroke combinations to another application, such as Word 97.  (I can't use VB sendkeys.)

This seems to be difficult, so I'm increasing to points to 500.

Thanks.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 15

Expert Comment

by:Tommy Hui
ID: 1200823
Try setting the focus to the window prior to calling keybd_event().

0
 
LVL 22

Expert Comment

by:nietod
ID: 1200824
The problem with posting/sending keyboard messages to an app is that its internal keyboard state doesn't get updated right.  Thus you can usually send simple keystrokes with decent results, but complex keystrokes, like ones involving contro andlor /shift can get messed up.  This depends on both the keystroke being send and the application that reads it (It depends on the code the app uses to handle the key.)  For this reason, your best bet is to use keybd_event(0 as it does update the internal keystate information.  It is completely reliable, whereas sending key messages is a little unpredictable.  The only hitch is that the application you want to have receive the key must have the focus.
0
 
LVL 4

Expert Comment

by:wylliker
ID: 1200825
You are always sending A (65) this is a capital letter.  If you use Shift you are asking for a lowercase a.  

A = 65
a = 97

You seem to be getting exactly the behavior you asked for.
That is why when you have caps lock on it came out as a capital letter.  Try it on your PC in a text editor.  As expected pressing the 'a' key will give you a lower case a. Pressing Shift+a gives you a capital A.  With Caps Lock on pressing 'a' gives you a capital A while pressing Shift+'a' gives you a lower case a.

Seems like you need to be sure whether you want to send upper or lower case of your keys. (I believe you will want lowercase as your default?)


0
 
LVL 14

Expert Comment

by:AlexVirochovsky
ID: 1200826
>>Try setting the focus to the window prior to calling >>keybd_event().
Of couse, thui is right. Using keybd_event exectly equal
pressing key of Keyboard and only Active Windows get it!
Using SendMessage not so good, becouse , for example,
for sending 1 symbol  must use 4 SendMessage!
0
 
LVL 2

Author Comment

by:obregoru
ID: 1200827

Here is the code to do it:

(The question was answered in the VB forum)

Thanks for the help anyway.


Private Declare Sub keybd_event Lib "user32" _
                                (ByVal bVk As Byte, _
                                ByVal bScan As Byte, _
                                ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
                                 
Private Declare Function FindWindow Lib "user32" Alias _
                                "FindWindowA" (ByVal lpClassName As String, _
                                ByVal lpWindowName As String) As Long
Private Declare Function SetFocusX Lib "user32" Alias "SetFocus" (ByVal hwnd As Long) As Long
                  'setfocus is a VB reserved word, so we give it a new name
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long

    Const VK_SHIFT = &H10
    Const KEYEVENTF_EXTENDEDKEY = &H1
    Const KEYEVENTF_KEYUP = &H2


Dim h As Long

         h = FindWindow(vbNullString, "Microsoft Word - Document2")
         If h = 0 Then
           MsgBox "Error: Invalid Handle"
           Exit Sub
         End If


         Call SetFocusX(h)
         Call SetForegroundWindow(h)
         Call keybd_event(&H10, 0, KEYEVENTF_EXTENDEDKEY, 0)
         Call keybd_event(65, 0, 0, 0)
         Call keybd_event(65, 0, KEYEVENTF_KEYUP, 0)
         Call keybd_event(&H10, 0, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0)

0
 
LVL 14

Expert Comment

by:AlexVirochovsky
ID: 1200828
As I understand, you use keybd_event(my reply, that
you rejected, + nietod comment ) + SetFocus (from thui comment) and win!
Nu, and what you want make with Q? Dou you think,
that someone helps you(in such case you must point
out, who can submit Q), or you must cancel Q, if you
think, that anyone don't helps you!
Alex
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1200829
yeah, but you gave me a B not an A... what's up with that?
0
 
LVL 14

Accepted Solution

by:
AlexVirochovsky earned 1000 total points
ID: 1200830
I risk to answer, based on you silence(and discussion is
over)!
If you shall reject my reply, you must cancel you Q.
If you will acceept,  post to whom else I must send PTS.
Alex
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1200831
Alex, this is the second time you do this nasty trick.. Didn't you understand that the question has been answered by me already? Your answer should be rejected now!! That's just not right...

..-=ViKtOr=-..
0
 
LVL 14

Expert Comment

by:AlexVirochovsky
ID: 1200832
Vikror, can be you reply in VB , but not here! Here
i post absolutly right reply for C++. Obregoru
can't use it in VB, may be, but it is C++ forum, not VB!!!!
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1200833
Alex, I SAID IT ALREADY... I had answered the question while you were still wondering here... The thing is that I saw it in the VB area first... I could've LOCKED UP both questions my self but I didn't do it so this guy can get his points back... he already paid once, and there is no need to do it twice... OBREGORU, PLEASE REJECT ALEX'S ANSWER>>> HE SHOULD LEARN HOW E-E WORKS FIRST, AND THEN ANSWER....

btw, This is your second time (that ive seen you do it).... please be more careful... and this questions should be rejected... or I'll talk to Linda myself....

..-=ViKtOr=-..
0
 
LVL 14

Expert Comment

by:AlexVirochovsky
ID: 1200834
Viktor, dou you understand, what you prepose?
Every expert, before reply to Q, must test: can be in
VB, Windows, Delfi, OWL, ... someone submit
same Q , and only after this reply!
This is a little hard, a?
Right way: if you see, that such Q have double,
you simply right  : Attentions, experts, it is double!
This way use Nietod, Chensu, AlexO, my modest person
and many others(but not you)!
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1200835
Alex, what the hell are you talking about? This was not a double question because it's been posted in two different areas... but the person told you specifically that a solution has been found, so you shouldn't have answered the question after that... It's a different story if you had answered the question BEFORE an answer had been found.. the thing is that that individual knows both C and VB so s/he doesn't care where he's gonna find an answer.. he could easily translate it from one prog. language to another...

NOW: OBREGORU, I KNOW YOU'RE THERE!! JUST REJECT AND LETS GET OVER WITH THIS...

Alex, I'm sorry, but is not fare to get points for nothing.. the person had solved the problem by the time you answered... If I have to write another comment, I will talk to Linda myself, and this time I'm serious!!!

..-=ViKtOr=-..
0

Featured Post

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
Suggested Courses

715 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