Faceți căutări pe acest blog

vineri, 18 august 2017

Easter eggs (1)



The starting point of this article is here [1]
Many respectable applications have “Easter eggs”, in other words, peculiar key combinations that start some surprises (hidden pieces of code).
You’ll find that is not that easy to capture key combinations like CTRL+P+M, because most pieces of software are “protected” against them.
I will show how to create such combinations and how to create restrictions.

The following Windows messages: wm_keydown and wm_keyup are what is needed to create such key combinations.
In VFP, Windows messages can be “captured ” with the help of BindEvent() function.

The Bindevent() parameters are:
The first parameter must be the form’s “hwnd”property (or VFP’s one).
The second must be the message code (0x100 is wm_keydown and 0x101 is wm_keyup)
The third parameter is a pointer to the object that contains the method, while the fourth parameter is the method name. The method in question handles keydown and keyup, and must have the following signature:

PROCEDURE method_name
LPARAMETERS p1,p2,p3,p4
* p1 = ThisForm.hwnd
           
* p2 - The message; 256 = 0x100 / 257 = 0x101 in this case

* p3 = Virtual-key code

* p4 % 65536 - the number of times the keystroke is autorepeated as a result of the user holding down the key. The repeat count is always 1 for a WM_KEYUP message
* FLOOR(p4 / 65536) % 256 - The scan code. The value depends on the OEM.
* BITTEST(p4, 24) - indicates whether the key is an extended key, such as the right-hand ALT and CTRL keys that appear on an enhanced 101- or 102-key keyboard. The value is .t. if it is an extended key; otherwise, it is .f.

To capture a particular key combination, you must have some public variables, or form properties, that stores the “keydown” state of a key.
In the next example, the form has three properties: lCtrl, lP and lM. When the CTRL key is pressed, lCtrl becomes .T., and when CTRL is released, lCTRL becomes .F. Similarly behaves lP and lM for the P and M key.
Run it and look behind the form, on the VFP main screen. When CTRL, P and M are all three simultaneously pressed, a message is typed.
CLEAR
PUBLIC ofrm
ofrm = CREATEOBJECT("myform")
ofrm.show()

DEFINE CLASS myform as form
      Autocenter = .T.
      lCtrl = .F. && .T. while CTRL is down (pressed)
      lM = .F. && .T. while M is down (pressed)
      lP = .F. && .T. while P is down (pressed)
      ADD OBJECT txt1 as textbox
      ADD OBJECT cmd as commandbutton WITH top = 50
      PROCEDURE init
            UNBINDEVENTS(This.hwnd)
            BINDEVENT(This.hwnd,0x0100,This,"detectkeydown")
            BINDEVENT(This.hwnd,0x0101,This,"detectkeyup")
      ENDPROC
      PROCEDURE detectkeydown
            LPARAMETERS p1,p2,p3,p4
            * p3 = Virtual-key code
            IF p3 = 0x11 && Ctrl is pressed
                  This.lCtrl = .T.
            ENDIF
            IF p3 = 0x4D && M is pressed
                  This.lM = .T.
            ENDIF
            IF p3 = 0x50 && P is pressed
                  This.lP = .T.
            ENDIF
            IF This.lCtrl AND This.lM AND This.lP
                  ACTIVATE SCREEN
                  ? 'Bingo!'
                  ? 'An CTRL+P+M occures'
            ENDIF
      ENDPROC
      PROCEDURE detectkeyup
            LPARAMETERS p1,p2,p3,p4
            * p3 = Virtual-key code
            IF p3 = 0x11 && Ctrl is released
                  This.lCtrl = .F.
            ENDIF
            IF p3 = 0x4D && M is released
                  This.lM = .F.
            ENDIF
            IF p3 = 0x50 && P is released
                  This.lP = .F.
            ENDIF
      ENDPROC
ENDDEFINE
Virtual-key codes are listed here  [4]
Can combination of more than three keys be captured? Obviously, yes. All that is needed is to add the corresponding properties to the form, and the corresponding IF – ENDIF branches in the two methods. Let’s try this unusual combination: 1 + 2 +3 + 4 + 6 (don’t use the numeric keypad in the next test)

CLEAR
PUBLIC ofrm
ofrm = CREATEOBJECT("myform")
ofrm.show()

DEFINE CLASS myform as form
      Autocenter = .T.
      l1 = .F. && .T. while 1 is down (pressed)
      l2 = .F. && .T. while 2 is down (pressed)
      l3 = .F. && .T. while 3 is down (pressed)
      l4 = .F. && .T. while 4 is down (pressed)
      l6 = .F. && .T. while 6 is down (pressed)
      ADD OBJECT txt1 as textbox
      ADD OBJECT cmd as commandbutton WITH top = 50
      PROCEDURE init
            UNBINDEVENTS(This.hwnd)
            BINDEVENT(This.hwnd,0x0100,This,"detectkeydown")
            BINDEVENT(This.hwnd,0x0101,This,"detectkeyup")
      ENDPROC
      PROCEDURE detectkeydown
            LPARAMETERS p1,p2,p3,p4
            * p3 = Virtual-key code
            IF p3 = 0x31 && 1 is pressed
                  This.l1 = .T.
            ENDIF
            IF p3 = 0x32 && 2 is pressed
                  This.l2 = .T.
            ENDIF
            IF p3 = 0x33 && 3 is pressed
                  This.l3 = .T.
            ENDIF
            IF p3 = 0x34 && 4 is pressed
                  This.l4 = .T.
            ENDIF
            IF p3 = 0x36 && 6 is pressed
                  This.l6 = .T.
            ENDIF
            IF This.l1 AND This.l2 AND This.l3 AND This.l4 AND This.l6
                  ACTIVATE SCREEN
                  ? 'Bingo!'
                  ? 'An 1+2+3+4+6 occures'
            ENDIF
                  ACTIVATE SCREEN
      ENDPROC
      PROCEDURE detectkeyup
            LPARAMETERS p1,p2,p3,p4
            * p3 = Virtual-key code
            IF p3 = 0x31 && 1 is released
                  This.l1 = .F.
            ENDIF
            IF p3 = 0x32 && 2 is released
                  This.l2 = .F.
            ENDIF
            IF p3 = 0x33 && 3 is released
                  This.l3 = .F.
            ENDIF
            IF p3 = 0x34 && 4 is released
                  This.l4 = .F.
            ENDIF
            IF p3 = 0x36 && 6 is released
                  This.l6 = .F.
            ENDIF
      ENDPROC
ENDDEFINE

The next step is to impose a specific order. You’ve noticed that pressing CTRL + P, in many applications displays the print dialog box. But you’ve noticed that you always have to first press CTRL and then P, otherwise nothing happens (I mean P + CTRL)
Let’s change our first example to impose the order CTRL + P + M, i.e. first CTRL, than P, and at last M. To do this, we must change the IF’s form detectkeydown() method:

            * p3 = Virtual-key code
            IF p3 = 0x11 && Ctrl is pressed
                  This.lCtrl = .T.
            ENDIF
            IF This.lCtrl AND p3 = 0x50 && CTRL + P is pressed
                  This.lP = .T.
            ENDIF
            IF This.lCtrl AND This.lP AND p3 = 0x4D && CTRL + P + M is pressed
                  This.lM = .T.
            ENDIF
            IF This.lCtrl AND This.lM AND This.lP
                  ACTIVATE SCREEN
                  ? 'Bingo!'
                  ? 'An CTRL+P+M occures'
            ENDIF

Please notice that this time, only when CTRL, P and M are simultaneously pressed, but in that order, the messages appear. If you try CTRL + M + P, or if you release P and the press again, the message does not appear.


[2] https://www.foxite.com/archives/detect-keypress-release-0000424382.htm
[3] WM_KEYDOWN message
[4] Virtual-Key Codes
[5] WM_KEYUP message


Related posts
http://praisachion.blogspot.com/2017/08/easter-eggs-4.html
http://praisachion.blogspot.com/2017/08/easter-eggs-3.html
http://praisachion.blogspot.com/2017/08/easter-eggs-2.html
http://praisachion.blogspot.com/2017/08/easter-eggs-1.html

http://praisachion.blogspot.com/2016/02/interceptin-ctrlshiftenter.html
http://praisachion.blogspot.com/2015/06/detect-keyup-like-mouseup.html
http://praisachion.blogspot.com/2015/01/how-can-i-prevent-undocking-docked-form.html 

Niciun comentariu:

Trimiteți un comentariu