Author Topic: shift key down  (Read 11852 times)

0 Members and 1 Guest are viewing this topic.

Joe Burke

  • Guest
shift key down
« on: October 26, 2007, 10:01:29 AM »
I'm looking for a function which tests for shift key down within
a routine like the ExpressTools function (acet-sys-shift-down).
It works well, returning either T or nil depending on the state of
the key. But I'd rather not depend on an ET function if there's a
generic alternative available.

Assuming it can be done, a similar test for either ctrl or alt key
down would also be welcome.

TIA for any thoughts on this.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: shift key down
« Reply #1 on: October 26, 2007, 01:18:06 PM »
Looks like you should be able to get to it with Activex but I don't know how.
http://msdn2.microsoft.com/en-us/library/3476fwez(VS.71).aspx
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

VovKa

  • Water Moccasin
  • Posts: 1632
  • Ukraine
Re: shift key down
« Reply #2 on: October 26, 2007, 04:17:16 PM »
The Note at the bottom of the screenshot sounds rather disappointing to a lisp programmer :(

sinc

  • Guest
Re: shift key down
« Reply #3 on: October 26, 2007, 05:31:54 PM »
Alright, who's going to volunteer to implement Lisp.NET?   :-D

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: shift key down
« Reply #4 on: October 26, 2007, 06:23:24 PM »
So you really can't get Activex to do it?

I was digging and found 3 code snips but don't  have any idea how to translate.
Code: [Select]
Private Function objDoc_onclick() As Boolean
    Dim objEvent As IHTMLEventObj

    Set objEvent = objWindow.event
   
    Select Case objEvent.shiftKey
        Case False
            MsgBox "You are not pressing your SHIFT key."
        Case True
            MsgBox "You are pressing your SHIFT key."
    End Select
End Function

-------------------------------------------------

Private WithEvents objDoc As FPHTMLDocument
Public objWindow As FPHTMLWindow2

Private Sub Class_Initialize()

    Set objWindow = ActiveDocument.parentWindow
    Set objDoc = ActiveDocument

End Sub

Private Function objDoc_onclick() As Boolean

    Dim objEvent As IHTMLEventObj
   
    Set objEvent = objWindow.event
   
    MsgBox objEvent.Button
   
End Function

---------------------------------------------------

Sub Document()
    Dim objDoc As FPHTMLDocument
    Dim objWindow As PageWindowEx
   
    'Create a reference to the active page window.
    Set objWindow = ActivePageWindow
   
    'Create a reference to the currently open document.
    Set objDoc = objWindow.Document

    objDoc.bgColor = "yellow"
End Sub
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

LE

  • Guest
Re: shift key down
« Reply #5 on: October 26, 2007, 08:59:34 PM »
Here is one arx command GETKEY with a very basic (Mickey Mouse) code - that grabs some of the windows messages - did not found the value for the shift key, so it is not there.

See, if works with the other messages - The problem it is going to be the same as the express tools, what happen if no one end up updating the project to work with any future AutoCAD release?...

Usage:
Call the command GETKEY and for example leave the mouse in one place - if it is moved it will exit and print the message "Mouse move..." if a key is press down... it will exit and print the message... etc.

Code: [Select]
#include<windows.h>
using namespace std;

void getKeyMessages()
{
MSG msg;
int status;
while ((status = ::GetMessage (&msg, 0, 0, 0)) != 0)
{
if (status == -1)
return;
switch(msg.message)
{
case WM_KEYDOWN:
acutPrintf(_T("\nKeydown... now stop..."));
return;
break;
case WM_MOUSEMOVE:
acutPrintf(_T("\nMouse move.."));
return;
break;
case WM_LBUTTONDOWN:
acutPrintf(_T("\nLeft Button Down..."));
return;
break;
case WM_RBUTTONDOWN:
acutPrintf(_T("\nRight Button Down..."));
return;
break;
case WM_MBUTTONDBLCLK:
acutPrintf(_T("\nDouble click..."));
return;
break;
case WM_GETHOTKEY:
acutPrintf(_T("\nGet hot key..."));
return;
break;
}
}
}

static void LESQKeyLog17_GETKEY(void)
{
getKeyMessages();
}

ARX file debug file included

VovKa

  • Water Moccasin
  • Posts: 1632
  • Ukraine
Re: shift key down
« Reply #6 on: October 27, 2007, 04:13:22 AM »
the same can be done with lisp
Code: [Select]
(defun test (/)
  (while t
    ((lambda (Key)
       (cond ((equal Key '(11 1000)) (prompt "Shift+RightClick\n"))
     ((equal Key '(11 2000)) (prompt "Ctrl+RightClick\n"))
       )
     )
      (grread nil 2)
    )
  )
)
but i think objectarx is the only way out

Joe Burke

  • Guest
Re: shift key down
« Reply #7 on: October 27, 2007, 07:11:22 AM »
Thanks to all who replied.

It's a shame it has to be so complicated.

BTW, I found this also works (acet-sys-control-down).

LE

  • Guest
Re: shift key down
« Reply #8 on: October 27, 2007, 01:30:22 PM »
Joe;

Here is the function it does exactly the same as the one (acet-sys-shift-down)

Function name: (shiftkeydown)

Usage [Call the function in the command line and press the SHIFT key]:
Command: (shiftkeydown)
nil

Command: (shiftkeydown)
T

The source code:
Code: [Select]
#include<windows.h>

int DescribeKeyState()
{
int state = 0;
short ks;
ks = GetKeyState(VK_SHIFT);
if(ks & 0xF000) state += 0x02;
return state;
}

static int ads_shiftkeydown(void)
{
int state = DescribeKeyState();
if (state == 2)
acedRetT();
else
acedRetNil();
return (RSRSLT);
}


HTH

edit: arx file is in this message: http://www.theswamp.org/index.php?topic=19644.msg239517#msg239517
« Last Edit: October 29, 2007, 10:11:53 AM by LE »

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8728
  • AKA Daniel
Re: shift key down
« Reply #9 on: October 27, 2007, 01:52:53 PM »
Pretty cool Luis!

LE

  • Guest
Re: shift key down
« Reply #10 on: October 27, 2007, 01:56:29 PM »
OK... you want also a way to read the CTRL key and ALT

For now, here is again the ARX (release) file, including the CTRL status - The ALT appears to be a little more complex, but will see if can be capture.


Code: [Select]
#include<windows.h>

int DescribeKeyState()
{
int state = 0; short ks;

ks = GetKeyState(VK_SHIFT);
if(ks & 0xF000) state += 0x02;

ks = GetKeyState(VK_CONTROL);
if(ks & 0xF000) state += 0x04;

return state;
}

static int ads_shiftkeydown(void)
{
if (DescribeKeyState() == 2)
acedRetT();
else
acedRetNil();
return (RSRSLT);
}

static int ads_ctrlkeydown(void)
{
if (DescribeKeyState() == 4)
acedRetT();
else
acedRetNil();
return (RSRSLT) ;
}

Usage:
Command: (ctrlkeydown)
nil

Command: (ctrlkeydown)
T

Command: (shiftkeydown)
nil

Command: (shiftkeydown)
T

LE

  • Guest
Re: shift key down
« Reply #11 on: October 27, 2007, 01:57:09 PM »

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: shift key down
« Reply #12 on: October 27, 2007, 08:58:19 PM »
For fun a proof of concept approach using VBA and LISP ... :lol:

Create a VBA project file in one's search path named ApiUtils.dvb, add a module named Keyboard, and add this code to said module --

Code: [Select]
Private Declare Function ApiKeyStates _
    Lib "user32" _
    Alias "GetKeyState" _
    (ByVal virtualKeyCode As Long) _
    As Long
   
Private Const _
    IS_DOWN     As Integer = &H8000, _
    SHIFT_KEY   As Integer = 1, _
    CONTROL_KEY As Integer = 2, _
    ALT_KEY     As Integer = 4

Public Sub GetKeyStates()

    Dim vlClass     As String, _
        vlFunctions As Object, _
        vlSymbol    As Object, _
        vlSet       As Object, _
        vlResult    As Integer
       
    vlResult = IIf(ApiKeyStates(vbKeyShift)   And IS_DOWN, SHIFT_KEY, 0)   Or _
               IIf(ApiKeyStates(vbKeyControl) And IS_DOWN, CONTROL_KEY, 0) Or _
               IIf(ApiKeyStates(vbKeyMenu)    And IS_DOWN, ALT_KEY, 0)
   
    ''  I'm not sure about these version numbers, can anyone help out?
    ''  This runs successfully under AutoCAD 2008, which is version
    ''  "17.1s (LMS Tech)" which when converted to a value and rounded
    ''  down becomes 17. The proper vl.application.xx number for same
    ''  is actually 16.

    Select Case Fix(Val(ThisDrawing.Application.Version))
        Case 16 To 17: vlClass = "Vl.Application.16"
        Case 15:       vlClass = "Vl.Application.15"
        Case Else:     vlClass = "Vl.Application.1"
    End Select

    ''  Note: the technique below of using vl.application to talk back
    ''  to LISP was first made public by Tony Tanzillo or Cyrille Fauvel,
    ''  I cannot definitively say which, but to whom I both give a nod.
   
    Set vlFunctions = CreateObject(vlClass).ActiveDocument.functions
    Set vlSymbol    = vlFunctions.Item("read").funcall("keystates")
    Set vlSet       = vlFunctions.Item("set")
   
    Call vlSet.funcall(vlSymbol, vlResult)

End Sub

Create a LISP file that sports this code --

Code: [Select]
(defun _GetKeyStates ( / dvbpath dvbfile macro keystates result )

    (vl-load-com)

    ;;  Make some modest attempts to troubleshoot
    ;;  if things go south so you can remedy ...
   
    (cond
   
        (   (null
                (setq dvbpath
                    (findfile
                        (setq dvbfile "ApiUtils.dvb")
                    )
                )
            )
            (princ
                (strcat
                    "Error: Could not locate "
                    dvbfile
                    ". "
                )
            )
        )
       
        (   (vl-catch-all-error-p               
                (vl-catch-all-apply
                   '(lambda ( )
                        (vla-runmacro
                            (vlax-get-acad-object)
                            (setq macro
                                (strcat
                                    dvbpath
                                    "!Keyboard.GetKeyStates"
                                )
                            )           
                        )
                    )
                )
            )
            (princ
                (strcat
                    "Error attempting to execute "
                    macro
                    "."
                )
            )
        )
       
        (   (null keystates) ;; keystates is set by the vba macro
            (princ
                (strcat
                    macro
                    " failed to set the keystate variable;"
                    " may be an incorrect vl.application.##"
                    " value."
                )
            )
        )
       
        (   (setq result
                ;;  return each key (shift, control, alt) with T or nil
                ;;  to indicate down (pressed) or up status respectively
                (list
                    (cons 'shift (eq 1 (logand 1 keystates)))
                    (cons 'control (eq 2 (logand 2 keystates)))
                    (cons 'alt (eq 4 (logand 4 keystates)))
                )
            )       
        )
    )
   
    result
   
)

;;  wrapper functions

(defun _ShiftKeyDown ( )
    (cdr
        (assoc
           'shift
            (_GetKeyStates)
        )
    )
)

(defun _ControlKeyDown ( )
    (cdr
        (assoc
           'control
            (_GetKeyStates)
        )
    )
)

(defun _AltKeyDown ( )
    (cdr
        (assoc
           'alt
            (_GetKeyStates)
        )
    )
)

Examples:

Code: [Select]
;;  With shift key held down:

(_GetKeyStates) => ((SHIFT . T) (CONTROL) (ALT))

;;  If you prefer the wrappered approach

(_ShifyKeyDown) => T
(_ControlKeyDown) => nil
(_AltKeyDown) => nil

For what it's worth ... Michael.
« Last Edit: October 27, 2007, 11:24:01 PM by MP »
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

Joe Burke

  • Guest
Re: shift key down
« Reply #13 on: October 27, 2007, 11:15:40 PM »
OK... you want also a way to read the CTRL key and ALT

For now, here is again the ARX (release) file, including the CTRL status - The ALT appears to be a little more complex, but will see if can be capture.

Thanks Luis,

Works great. It's comforting to have an alternative to the ExpressTools functions.

I will use your ARX. And BTW, I don't really need the Alt key option.

Joe Burke

  • Guest
Re: shift key down
« Reply #14 on: October 27, 2007, 11:23:25 PM »
For fun a proof of concept approach using VBA and LISP ... :lol:

Create a VBA project file in one's search path named ApiUtils.dvb, add a module named Keyboard, and add this code to said module --

For what it's worth ... Michael.

Thanks Michael,

I'm stumped at "add a module..." so I'm starting to study VBA. Is it going to be fun? Is there a book you would recommend?