Author Topic: Keystroke Queue vba HELP  (Read 4650 times)

0 Members and 1 Guest are viewing this topic.

MeyerForHire

  • Guest
Keystroke Queue vba HELP
« on: January 05, 2012, 08:53:46 AM »
I am working on a routine that, at one point, goes into a Do loop and reacts to keystroke input via the GetAsyncKeystroke API. The routine looks at the arrow keys and a couple others and translates those keystrokes into activating flip and angle states of the dynamic block selected--giving the user and interactive tool for block manipulation.

Anyway, the issue I'm having is that when the loop is complete, all of the keystrokes pressed while in the loop come rushing into the command line. I've been very careful to choose keys for the routine which do not have a command or shortcut associated with them. However, the UP arrow key is the kicker. I would like to keep it in the routine because it's obvious when using the others. Plus, even if I don't use it, I'm sure users will still hit it while using the other arrow keys.

What I would like to be able to do, is prevent all of those keystrokes from going back into the command line when the sub is complete.

I've tried using the SetKeyboardState API after each keystroke to try to cover my tracks. But, it doesn't do anything. My guess is that there is some keystroke queue that needs to be cleared prior to exiting the sub. Does anyone know if it exists and, if so, how to clear it? If it doesn't exist, is there some Acad variable I can turn off? Is there a system variable, etc.....?

I've briefly looked at keystroke hooks, but they seem awfully involved and complicated and I'm not even sure if it will do what I want.

Any help??????

Oh, and yes I know, I should quit using vba for .NET.....I know. Also, I have no interest in converting my code into lisp. I can use lisp to do some very basic tasks. I could use lisp to set a variable if need be, but I don't want to go "all out" with it.

Thanks in advance.

Here's a snippet of the code:
Code: [Select]
Do
               
            U = GetAsyncKeyState(VK_UP)
            D = GetAsyncKeyState(VK_DOWN)
            L = GetAsyncKeyState(VK_LEFT)
            R = GetAsyncKeyState(VK_RIGHT)
            A = GetAsyncKeyState(VK_RCONTROL)
            'Ret = GetAsyncKeyState(VK_RETURN)
            'Space = GetAsyncKeyState(VK_SPACE)
            S = GetAsyncKeyState(VK_RSHIFT)
               
            If (Rot >= 0 And Rot <= 45) Or (Rot >= 135 And Rot <= 225) Or Rot >= 315 Then
               
                If HasH And (U < 0 Or D < 0) Then
                   
                    Set objDyn = DynProps(h)
                   
                    If Hflip = 0 Then
                        objDyn.Value = 1
                        objRef.Update
                        objRef.Highlight True
                        Exit Do
                    Else
                        objDyn.Value = 0
                        objRef.Update
                        objRef.Highlight True
                        Exit Do
                    End If
                           
                ElseIf HasV And (R < 0 Or L < 0) Then
                   
                    Set objDyn = DynProps(v)
                       
                    If Vflip = 0 Then
                        objDyn.Value = 1
                        objRef.Update
                        objRef.Highlight True
                        Exit Do
                    Else
                        objDyn.Value = 0
                        objRef.Update
                        objRef.Highlight True
                        Exit Do
                    End If
                       
                ElseIf A < 0 And HasRot Then
                   
                    Set objDyn = DynProps(t)
                    objDyn.Value = Rad - (¶ / 2)
                    objRef.Update
                    objRef.Highlight True
                    Exit Do
                       
                ElseIf S < 0 Then 'Ret < 0 Or Space < 0 Then
                   
                Done = True
                Exit Do
                       
                End If
                   
            Else
               
                If HasV And (U < 0 Or D < 0) Then
                   
                    Set objDyn = DynProps(v)
                   
                    If Vflip = 0 Then
                        objDyn.Value = 1
                        objRef.Update
                        objRef.Highlight True
                        Exit Do
                    Else
                        objDyn.Value = 0
                        objRef.Update
                        objRef.Highlight True
                        Exit Do
                    End If
                           
                ElseIf HasH And (R < 0 Or L < 0) Then
                   
                    Set objDyn = DynProps(h)
                       
                    If Hflip = 0 Then
                        objDyn.Value = 1
                        objRef.Update
                        objRef.Highlight True
                        Exit Do
                    Else
                        objDyn.Value = 0
                        objRef.Update
                        objRef.Highlight True
                        Exit Do
                    End If
                       
                ElseIf A < 0 And HasRot Then
                   
                    Set objDyn = DynProps(t)
                    objDyn.Value = Rad - (¶ / 2)
                    objRef.Update
                    objRef.Highlight True
                    Exit Do
                       
                ElseIf S < 0 Then 'Ret < 0 Or Space < 0 Then
                   
                    Done = True
                    Exit Do
                       
                End If
                   
            End If
               
        Loop

I can post more of the code, but I don't think what I'm looking for has much to do with what I already have.


Daniel Eiszele

  • Newt
  • Posts: 85
Re: Keystroke Queue vba HELP
« Reply #1 on: January 06, 2012, 06:57:52 PM »
Try using the WinAPI function "Peakmessage" to loop through the messages(key presses etc) currently in the application message queue and make sure the wRemovemsg parameter is set to 1 to clear the message queue. You can use the handle of the current application object as this traps all child calls as well.

Regards

http://msdn.microsoft.com/en-us/library/windows/desktop/ms644943(v=vs.85).aspx

ChuckHardin

  • Guest
Re: Keystroke Queue vba HELP
« Reply #2 on: January 09, 2012, 05:54:44 PM »
Just a small question.
Could you do something like this?:
Code: [Select]
                        objDyn.Value = cint(Not cbool(Hflip))
                        objRef.Update
                        objRef.Highlight True
                        Exit Do

Instead of:
Code: [Select]
                    If Hflip = 0 Then
                        objDyn.Value = 1
                        objRef.Update
                        objRef.Highlight True
                        Exit Do
                    Else
                        objDyn.Value = 0
                        objRef.Update
                        objRef.Highlight True
                        Exit Do
                    End If
« Last Edit: January 09, 2012, 05:58:55 PM by ChuckHardin »

MeyerForHire

  • Guest
Re: Keystroke Queue vba HELP
« Reply #3 on: January 10, 2012, 02:54:47 PM »
Thanks to both of you for the replies!

Chuck,
My lack of knowledge of the language and understanding of its logic shows, doesn't it?  Thanks for the tips!  I'm sure I can remove several hundred lines of code from the various modules I use.

Daniel,
I'll give the Peakmessage a try.  In the interim, a quick quesitons would be how to determine the handle for AutoCAD?

Again, thanks to both!!

ChuckHardin

  • Guest
Re: Keystroke Queue vba HELP
« Reply #4 on: January 10, 2012, 03:11:11 PM »
I have and still code the same way.
Then a month or 2 later I reread some code and think there has to be a better way.
Not saying mine is better it was just a question and also depends on if HFlip/VFlip can only be 0 or 1.
The handle for the AutoCAD app I think is stored as Application.HWnd or some such.

MeyerForHire

  • Guest
Re: Keystroke Queue vba HELP
« Reply #5 on: January 11, 2012, 09:46:54 AM »
When I started to get deeper into working with vba, I've been noticing how much you deal with one or two variables that you need to flip upon each other given the opposite.  Given these dynamic properties, it's easy using the method you described.  My first instinct is to generate a mathematical formula to do just that then work it into a function.  There has to be a way given any two integers and I've been looking into figuring it out.  But, I guess by that point, I could do it with if statements in a function.

ChuckHardin

  • Guest
Re: Keystroke Queue vba HELP
« Reply #6 on: January 11, 2012, 12:40:29 PM »
Here is what the code I wrote is doing:
Code: [Select]
objDyn.Value = cint(Not cbool(Hflip))Set objDyn.Value = Convert True/False to Integer(the opposite of (convert integer 0/1 to False/True))
objDyn.Value = Integer
HFlip = Integer
True= 1 = Not False
False = 0 = Not True

Other numbers might be more difficult.
1s and 0s are easy.

MeyerForHire

  • Guest
Re: Keystroke Queue vba HELP
« Reply #7 on: January 11, 2012, 04:27:59 PM »
That's what I figured.  I'd seen cbool in various places but never understood its practical uses until this post.  I also didn't realize I could use Not to flip a boolean variable--I never thought to try it outside of ifs, loops, etc.  Makes sense, though.

Thanks