Announcement

Collapse
No announcement yet.

Trapping Keyboard Input; a basic question from a GUI programming novice

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Peter Simmonds
    replied
    Michael

    Well the program (which I am converting from PBCC) edits large blocks of nucleotide sequence data, often several thousand bases ling, windowed using the scrollbar. This can only be feasibly represented in a graphics screen onto which is placed a cursor that is required for editing, moving sequences etc. There are menus etc. but most of the activity associated with the program is editing the sequences themselves.

    As for the possibility of using a text editor box (with built in keyboard support), the actual editing and display of sequences goes far beyond its capabilities. I therefore have to create the editing environment from the ground up, and that includes getting keyboard input. Left, right, up and down arrows for moving the cursor, ALT and CONTROL arrows for larger jumps, HOME, END, SHIFT arrows to drag sequences around, keyboard entry of bases (A, C, G, T) and amino acids, etc. etc.

    Certainly the accelerator method you suggested works fine. Very easy to put something like this in the callback loop:

    Code:
    CASE %WM_COMMAND
        ' Process control notifications
    
        SELECT CASE AS LONG CBCTL
    
            CASE Key_offset + 1 to Key_offset + 150
    
                keycode = CBCTL - Key_offset
                CALL old_program(keycode): REM The keyboard processing loop for ASCII codes in the old program
    There seems to be no slow down in the reaction time of the callback loop despite the huge table, so will probably stick with this method for the time being (until I come across the next problem!).
    Last edited by Peter Simmonds; 15 Oct 2010, 09:57 AM.

    Leave a comment:


  • Jim Dunn
    replied
    Mike, thx for the "ENTER key to TAB"... much needed!!

    Leave a comment:


  • Michael Mattias
    replied
    Code:
    WHILE GetMessage(Msg, %NULL, 0, 0)
        LOCAL k AS LONG
        SELECT CASE Msg.message
          k = Msg.wParam
          CASE %WM_SYSKEYDOWN
            SELECT CASE k 'Msg.wParam
              CASE %VK_LEFT
              CASE %VK_RIGHT
              CASE %VK_DOWN
              CASE %VK_UP
              CASE ELSE
    ....
    That will work, but as a matter of style I don't like playing with the message loop like this.

    I prefer to use keyboard accelerators (post #27 from Mr. Simmonds), but only define "keys of interest" and then process the resulting WM_COMMAND notification messages in my window/dialog procedure.

    Frankly I can't see what keys of interest you might have beyond F2 thru F12 (F1 already generates a WM_HELP notification message, but you can preempt that).

    There is no reason in a gui program for the programmer to care about left/right/up/down arrows or delete or home keys, et al... the use of the proper controls will allow the system to process these keys "the Windows way".. meaning of course, the way your users expect those keys to behave in the Windows' environment.

    MCM

    Leave a comment:


  • Peter Simmonds
    replied
    Stupid and clumsy way....

    After the messages yesterday evening, I wrote out the following key accelerator table to reproduce ASCII and extended codes (1000 + code) from each key on the keyboard. This works fine with the line:

    Code:
    REM Add keyboard accelerator codes
    ACCEL ATTACH main_handle, ac() TO hAccelHandle
    in the CASE %WM_INITDIALOG section of the callback of the main dialog. It's all rather inelegant, although nice to have control of what the keys return (and obviously could be made to deviate from the old ASCII codes if necessary). I was wondering whether inserting such a large table into the callback would slow down its responsiveness to the keyboard (and to the callback generally).

    From the messages received since there is clearly a better way to achieve this using modeless dialogs, and I'll certainly have a try.

    Anyway, here is the table if it's of any use to anyone else:

    Code:
        ' The key_offset variable adds a fixed number (eg. 5000) to the CBCTL code
        ' to keep it away from other returned codes in the callback
        
        ' Keypresses that would return extended (2 byte) codes have 1000 added to the
        ' return code so they can be identified separately in the callback
    
        DIM ac(1 TO 304) AS ACCELAPI
    
        ac(1).fvirt = %FVIRTKEY: ac(1).key = %VK_ADD:        ac(1).cmd = key_offset + 61
        ac(2).fvirt = %FVIRTKEY: ac(2).key = %VK_BACK:       ac(2).cmd = key_offset + 8
        ac(3).fvirt = %FVIRTKEY: ac(3).key = %VK_TAB:        ac(3).cmd = key_offset + 9
        ac(4).fvirt = %FVIRTKEY: ac(4).key = %VK_SUBTRACT:   ac(4).cmd = key_offset + 45
        ac(5).fvirt = %FVIRTKEY: ac(5).key = %VK_RETURN:     ac(5).cmd = key_offset + 13
        ac(6).fvirt = %FVIRTKEY: ac(6).key = %VK_ESCAPE:     ac(6).cmd = key_offset + 27
        ac(7).fvirt = %FVIRTKEY: ac(7).key = %VK_SPACE:      ac(7).cmd = key_offset + 32
        ac(8).fvirt = %FVIRTKEY: ac(8).key = %VK_PGUP:       ac(8).cmd = key_offset + 1073
        ac(9).fvirt = %FVIRTKEY: ac(9).key = %VK_PGDN:       ac(9).cmd = key_offset + 1081
        ac(10).fvirt = %FVIRTKEY: ac(10).key = %VK_END:     ac(10).cmd = key_offset + 1079
        ac(11).fvirt = %FVIRTKEY: ac(11).key = %VK_HOME:    ac(11).cmd = key_offset + 1071
        ac(12).fvirt = %FVIRTKEY: ac(12).key = %VK_LEFT:    ac(12).cmd = key_offset + 1075
        ac(13).fvirt = %FVIRTKEY: ac(13).key = %VK_UP:      ac(13).cmd = key_offset + 1072
        ac(14).fvirt = %FVIRTKEY: ac(14).key = %VK_RIGHT:   ac(14).cmd = key_offset + 1077
        ac(15).fvirt = %FVIRTKEY: ac(15).key = %VK_DOWN:    ac(15).cmd = key_offset + 1080
        ac(16).fvirt = %FVIRTKEY: ac(16).key = %VK_INSERT:  ac(15).cmd = key_offset + 1082
        ac(17).fvirt = %FVIRTKEY: ac(17).key = %VK_DELETE:  ac(16).cmd = key_offset + 1083
        ac(18).fvirt = %FVIRTKEY: ac(18).key = %VK_HELP:    ac(17).cmd = key_offset + 1059
    
        ac(19).fvirt = %FVIRTKEY: ac(19).key = %VK_A: ac(19).cmd = key_offset + 97
        ac(20).fvirt = %FVIRTKEY: ac(20).key = %VK_B: ac(20).cmd = key_offset + 98
        ac(21).fvirt = %FVIRTKEY: ac(21).key = %VK_C: ac(21).cmd = key_offset + 99
        ac(22).fvirt = %FVIRTKEY: ac(22).key = %VK_D: ac(22).cmd = key_offset + 100
        ac(23).fvirt = %FVIRTKEY: ac(23).key = %VK_E: ac(23).cmd = key_offset + 101
        ac(24).fvirt = %FVIRTKEY: ac(24).key = %VK_F: ac(24).cmd = key_offset + 102
        ac(25).fvirt = %FVIRTKEY: ac(25).key = %VK_G: ac(25).cmd = key_offset + 103
        ac(26).fvirt = %FVIRTKEY: ac(26).key = %VK_H: ac(26).cmd = key_offset + 104
        ac(27).fvirt = %FVIRTKEY: ac(27).key = %VK_I: ac(27).cmd = key_offset + 105
        ac(28).fvirt = %FVIRTKEY: ac(28).key = %VK_J: ac(28).cmd = key_offset + 106
        ac(29).fvirt = %FVIRTKEY: ac(29).key = %VK_K: ac(29).cmd = key_offset + 107
        ac(30).fvirt = %FVIRTKEY: ac(30).key = %VK_L: ac(30).cmd = key_offset + 108
        ac(31).fvirt = %FVIRTKEY: ac(31).key = %VK_M: ac(31).cmd = key_offset + 109
        ac(32).fvirt = %FVIRTKEY: ac(32).key = %VK_N: ac(32).cmd = key_offset + 110
        ac(33).fvirt = %FVIRTKEY: ac(33).key = %VK_O: ac(33).cmd = key_offset + 111
        ac(34).fvirt = %FVIRTKEY: ac(34).key = %VK_P: ac(34).cmd = key_offset + 112
        ac(35).fvirt = %FVIRTKEY: ac(35).key = %VK_Q: ac(35).cmd = key_offset + 113
        ac(36).fvirt = %FVIRTKEY: ac(36).key = %VK_R: ac(36).cmd = key_offset + 114
        ac(37).fvirt = %FVIRTKEY: ac(37).key = %VK_S: ac(37).cmd = key_offset + 115
        ac(38).fvirt = %FVIRTKEY: ac(38).key = %VK_T: ac(38).cmd = key_offset + 116
        ac(39).fvirt = %FVIRTKEY: ac(39).key = %VK_U: ac(39).cmd = key_offset + 117
        ac(40).fvirt = %FVIRTKEY: ac(40).key = %VK_V: ac(40).cmd = key_offset + 118
        ac(41).fvirt = %FVIRTKEY: ac(41).key = %VK_W: ac(41).cmd = key_offset + 119
        ac(42).fvirt = %FVIRTKEY: ac(42).key = %VK_X: ac(42).cmd = key_offset + 120
        ac(43).fvirt = %FVIRTKEY: ac(43).key = %VK_Y: ac(43).cmd = key_offset + 121
        ac(44).fvirt = %FVIRTKEY: ac(44).key = %VK_Z: ac(44).cmd = key_offset + 122
    
        ac(45).fvirt = %FVIRTKEY: ac(45).key = %VK_0: ac(45).cmd = key_offset + 48
        ac(46).fvirt = %FVIRTKEY: ac(46).key = %VK_1: ac(46).cmd = key_offset + 49
        ac(47).fvirt = %FVIRTKEY: ac(47).key = %VK_2: ac(47).cmd = key_offset + 50
        ac(48).fvirt = %FVIRTKEY: ac(48).key = %VK_3: ac(48).cmd = key_offset + 51
        ac(49).fvirt = %FVIRTKEY: ac(49).key = %VK_4: ac(49).cmd = key_offset + 52
        ac(50).fvirt = %FVIRTKEY: ac(50).key = %VK_5: ac(50).cmd = key_offset + 53
        ac(51).fvirt = %FVIRTKEY: ac(51).key = %VK_6: ac(51).cmd = key_offset + 54
        ac(52).fvirt = %FVIRTKEY: ac(52).key = %VK_7: ac(52).cmd = key_offset + 55
        ac(53).fvirt = %FVIRTKEY: ac(53).key = %VK_8: ac(53).cmd = key_offset + 56
        ac(54).fvirt = %FVIRTKEY: ac(54).key = %VK_9: ac(54).cmd = key_offset + 57
    
        ac(55).fvirt = %FVIRTKEY: ac(55).key = %VK_NUMPAD0: ac(55).cmd = key_offset + 48
        ac(56).fvirt = %FVIRTKEY: ac(56).key = %VK_NUMPAD1: ac(56).cmd = key_offset + 49
        ac(57).fvirt = %FVIRTKEY: ac(57).key = %VK_NUMPAD2: ac(57).cmd = key_offset + 50
        ac(58).fvirt = %FVIRTKEY: ac(58).key = %VK_NUMPAD3: ac(58).cmd = key_offset + 51
        ac(59).fvirt = %FVIRTKEY: ac(59).key = %VK_NUMPAD4: ac(59).cmd = key_offset + 52
        ac(60).fvirt = %FVIRTKEY: ac(60).key = %VK_NUMPAD5: ac(60).cmd = key_offset + 53
        ac(61).fvirt = %FVIRTKEY: ac(61).key = %VK_NUMPAD6: ac(61).cmd = key_offset + 54
        ac(62).fvirt = %FVIRTKEY: ac(62).key = %VK_NUMPAD7: ac(62).cmd = key_offset + 55
        ac(63).fvirt = %FVIRTKEY: ac(63).key = %VK_NUMPAD8: ac(63).cmd = key_offset + 56
        ac(64).fvirt = %FVIRTKEY: ac(64).key = %VK_NUMPAD9: ac(64).cmd = key_offset + 57
    
        ac(65).fvirt = %FVIRTKEY: ac(65).key = %VK_F1: ac(65).cmd = key_offset + 1059
        ac(66).fvirt = %FVIRTKEY: ac(66).key = %VK_F2: ac(66).cmd = key_offset + 1060
        ac(67).fvirt = %FVIRTKEY: ac(67).key = %VK_F3: ac(67).cmd = key_offset + 1061
        ac(68).fvirt = %FVIRTKEY: ac(68).key = %VK_F4: ac(68).cmd = key_offset + 1062
        ac(69).fvirt = %FVIRTKEY: ac(69).key = %VK_F5: ac(69).cmd = key_offset + 1063
        ac(70).fvirt = %FVIRTKEY: ac(70).key = %VK_F6: ac(70).cmd = key_offset + 1064
        ac(71).fvirt = %FVIRTKEY: ac(71).key = %VK_F7: ac(71).cmd = key_offset + 1065
        ac(72).fvirt = %FVIRTKEY: ac(72).key = %VK_F8: ac(72).cmd = key_offset + 1066
        ac(73).fvirt = %FVIRTKEY: ac(73).key = %VK_F9: ac(73).cmd = key_offset + 1067
        ac(74).fvirt = %FVIRTKEY: ac(74).key = %VK_F10: ac(74).cmd = key_offset + 1068
        ac(75).fvirt = %FVIRTKEY: ac(75).key = %VK_F11: ac(75).cmd = key_offset + 1133
        ac(76).fvirt = %FVIRTKEY: ac(76).key = %VK_F12: ac(76).cmd = key_offset + 1134
    
        REM SHIFT Keys
        ac(76 + 1).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 1).key = %VK_ADD:       ac(76 + 1).cmd = key_offset + 43
        ac(76 + 2).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 2).key = %VK_BACK:      ac(76 + 2).cmd = key_offset + 8
        ac(76 + 3).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 3).key = %VK_TAB:       ac(76 + 3).cmd = key_offset + 1015
        ac(76 + 4).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 4).key = %VK_SUBTRACT:  ac(76 + 4).cmd = key_offset + 95
        ac(76 + 5).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 5).key = %VK_RETURN:    ac(76 + 5).cmd = key_offset + 13
        ac(76 + 6).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 6).key = %VK_ESCAPE:    ac(76 + 6).cmd = key_offset + 27
        ac(76 + 7).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 7).key = %VK_SPACE:     ac(76 + 7).cmd = key_offset + 32
        ac(76 + 8).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 8).key = %VK_PGUP:      ac(76 + 8).cmd = key_offset + 57
        ac(76 + 9).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 9).key = %VK_PGDN:      ac(76 + 9).cmd = key_offset + 51
        ac(76 + 10).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 10).key = %VK_END:    ac(76 + 10).cmd = key_offset + 49
        ac(76 + 11).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 11).key = %VK_HOME:   ac(76 + 11).cmd = key_offset + 55
        ac(76 + 12).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 12).key = %VK_LEFT:   ac(76 + 12).cmd = key_offset + 52
        ac(76 + 13).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 13).key = %VK_UP:     ac(76 + 13).cmd = key_offset + 56
        ac(76 + 14).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 14).key = %VK_RIGHT:  ac(76 + 14).cmd = key_offset + 54
        ac(76 + 15).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 15).key = %VK_DOWN:   ac(76 + 15).cmd = key_offset + 50
        ac(76 + 16).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 16).key = %VK_INSERT: ac(76 + 15).cmd = key_offset + 82
        ac(76 + 17).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 17).key = %VK_DELETE: ac(76 + 16).cmd = key_offset + 83
        ac(76 + 18).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 18).key = %VK_HELP:   ac(76 + 17).cmd = key_offset + 59
    
        ac(76 + 19).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 19).key = %VK_A: ac(76 + 19).cmd = key_offset + 65
        ac(76 + 20).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 20).key = %VK_B: ac(76 + 20).cmd = key_offset + 66
        ac(76 + 21).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 21).key = %VK_C: ac(76 + 21).cmd = key_offset + 67
        ac(76 + 22).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 22).key = %VK_D: ac(76 + 22).cmd = key_offset + 68
        ac(76 + 23).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 23).key = %VK_E: ac(76 + 23).cmd = key_offset + 69
        ac(76 + 24).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 24).key = %VK_F: ac(76 + 24).cmd = key_offset + 70
        ac(76 + 25).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 25).key = %VK_G: ac(76 + 25).cmd = key_offset + 71
        ac(76 + 26).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 26).key = %VK_H: ac(76 + 26).cmd = key_offset + 72
        ac(76 + 27).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 27).key = %VK_I: ac(76 + 27).cmd = key_offset + 73
        ac(76 + 28).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 28).key = %VK_J: ac(76 + 28).cmd = key_offset + 74
        ac(76 + 29).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 29).key = %VK_K: ac(76 + 29).cmd = key_offset + 75
        ac(76 + 30).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 30).key = %VK_L: ac(76 + 30).cmd = key_offset + 76
        ac(76 + 31).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 31).key = %VK_M: ac(76 + 31).cmd = key_offset + 77
        ac(76 + 32).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 32).key = %VK_N: ac(76 + 32).cmd = key_offset + 78
        ac(76 + 33).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 33).key = %VK_O: ac(76 + 33).cmd = key_offset + 79
        ac(76 + 34).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 34).key = %VK_P: ac(76 + 34).cmd = key_offset + 80
        ac(76 + 35).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 35).key = %VK_Q: ac(76 + 35).cmd = key_offset + 81
        ac(76 + 36).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 36).key = %VK_R: ac(76 + 36).cmd = key_offset + 82
        ac(76 + 37).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 37).key = %VK_S: ac(76 + 37).cmd = key_offset + 83
        ac(76 + 38).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 38).key = %VK_T: ac(76 + 38).cmd = key_offset + 84
        ac(76 + 39).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 39).key = %VK_U: ac(76 + 39).cmd = key_offset + 85
        ac(76 + 40).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 40).key = %VK_V: ac(76 + 40).cmd = key_offset + 86
        ac(76 + 41).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 41).key = %VK_W: ac(76 + 41).cmd = key_offset + 87
        ac(76 + 42).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 42).key = %VK_X: ac(76 + 42).cmd = key_offset + 88
        ac(76 + 43).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 43).key = %VK_Y: ac(76 + 43).cmd = key_offset + 89
        ac(76 + 44).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 44).key = %VK_Z: ac(76 + 44).cmd = key_offset + 90
    
        ac(76 + 45).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 45).key = %VK_0: ac(76 + 45).cmd = key_offset + 41
        ac(76 + 46).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 46).key = %VK_1: ac(76 + 46).cmd = key_offset + 33
        ac(76 + 47).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 47).key = %VK_2: ac(76 + 47).cmd = key_offset + 64
        ac(76 + 48).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 48).key = %VK_3: ac(76 + 48).cmd = key_offset + 35
        ac(76 + 49).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 49).key = %VK_4: ac(76 + 49).cmd = key_offset + 36
        ac(76 + 50).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 50).key = %VK_5: ac(76 + 50).cmd = key_offset + 37
        ac(76 + 51).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 51).key = %VK_6: ac(76 + 51).cmd = key_offset + 94
        ac(76 + 52).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 52).key = %VK_7: ac(76 + 52).cmd = key_offset + 38
        ac(76 + 53).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 53).key = %VK_8: ac(76 + 53).cmd = key_offset + 42
        ac(76 + 54).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 54).key = %VK_9: ac(76 + 54).cmd = key_offset + 40
    
        ac(76 + 55).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 55).key = %VK_NUMPAD0: ac(76 + 55).cmd = key_offset + 48
        ac(76 + 56).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 56).key = %VK_NUMPAD1: ac(76 + 56).cmd = key_offset + 49
        ac(76 + 57).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 57).key = %VK_NUMPAD2: ac(76 + 57).cmd = key_offset + 50
        ac(76 + 58).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 58).key = %VK_NUMPAD3: ac(76 + 58).cmd = key_offset + 51
        ac(76 + 59).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 59).key = %VK_NUMPAD4: ac(76 + 59).cmd = key_offset + 52
        ac(76 + 60).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 60).key = %VK_NUMPAD5: ac(76 + 60).cmd = key_offset + 53
        ac(76 + 61).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 61).key = %VK_NUMPAD6: ac(76 + 61).cmd = key_offset + 54
        ac(76 + 62).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 62).key = %VK_NUMPAD7: ac(76 + 62).cmd = key_offset + 55
        ac(76 + 63).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 63).key = %VK_NUMPAD8: ac(76 + 63).cmd = key_offset + 56
        ac(76 + 64).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 64).key = %VK_NUMPAD9: ac(76 + 64).cmd = key_offset + 57
    
        ac(76 + 65).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 65).key = %VK_F1: ac(76 + 65).cmd = key_offset + 1084
        ac(76 + 66).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 66).key = %VK_F2: ac(76 + 66).cmd = key_offset + 1085
        ac(76 + 67).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 67).key = %VK_F3: ac(76 + 67).cmd = key_offset + 1086
        ac(76 + 68).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 68).key = %VK_F4: ac(76 + 68).cmd = key_offset + 1087
        ac(76 + 69).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 69).key = %VK_F5: ac(76 + 69).cmd = key_offset + 1088
        ac(76 + 70).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 70).key = %VK_F6: ac(76 + 70).cmd = key_offset + 1089
        ac(76 + 71).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 71).key = %VK_F7: ac(76 + 71).cmd = key_offset + 1090
        ac(76 + 72).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 72).key = %VK_F8: ac(76 + 72).cmd = key_offset + 1091
        ac(76 + 73).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 73).key = %VK_F9: ac(76 + 73).cmd = key_offset + 1092
        ac(76 + 74).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 74).key = %VK_F10: ac(76 + 74).cmd = key_offset + 1093
        ac(76 + 75).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 75).key = %VK_F11: ac(76 + 75).cmd = key_offset + 1135
        ac(76 + 76).fvirt = %FVIRTKEY OR %FSHIFT: ac(76 + 76).key = %VK_F12: ac(76 + 76).cmd = key_offset + 1136
    
        REM CONTROL Keys
        ac(152 + 1).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 1).key = %VK_ADD:       ac(152 + 1).cmd = key_offset + 0
        ac(152 + 2).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 2).key = %VK_BACK:      ac(152 + 2).cmd = key_offset + 127
        ac(152 + 3).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 3).key = %VK_TAB:       ac(152 + 3).cmd = key_offset + 0
        ac(152 + 4).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 4).key = %VK_SUBTRACT:  ac(152 + 4).cmd = key_offset + 31
        ac(152 + 5).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 5).key = %VK_RETURN:    ac(152 + 5).cmd = key_offset + 10
        ac(152 + 6).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 6).key = %VK_ESCAPE:    ac(152 + 6).cmd = key_offset + 27
        ac(152 + 7).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 7).key = %VK_SPACE:     ac(152 + 7).cmd = key_offset + 32
        ac(152 + 8).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 8).key = %VK_PGUP:      ac(152 + 8).cmd = key_offset + 1132
        ac(152 + 9).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 9).key = %VK_PGDN:      ac(152 + 9).cmd = key_offset + 1118
        ac(152 + 10).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 10).key = %VK_END:    ac(152 + 10).cmd = key_offset + 1117
        ac(152 + 11).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 11).key = %VK_HOME:   ac(152 + 11).cmd = key_offset + 1119
        ac(152 + 12).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 12).key = %VK_LEFT:   ac(152 + 12).cmd = key_offset + 1115
        ac(152 + 13).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 13).key = %VK_UP:     ac(152 + 13).cmd = key_offset + 1141
        ac(152 + 14).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 14).key = %VK_RIGHT:  ac(152 + 14).cmd = key_offset + 1116
        ac(152 + 15).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 15).key = %VK_DOWN:   ac(152 + 15).cmd = key_offset + 1145
        ac(152 + 16).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 16).key = %VK_INSERT: ac(152 + 15).cmd = key_offset + 1146
        ac(152 + 17).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 17).key = %VK_DELETE: ac(152 + 16).cmd = key_offset + 1147
        ac(152 + 18).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 18).key = %VK_HELP:   ac(152 + 17).cmd = key_offset + 1094
        
        ac(152 + 19).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 19).key = %VK_A: ac(152 + 19).cmd = key_offset + 1
        ac(152 + 20).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 20).key = %VK_B: ac(152 + 20).cmd = key_offset + 2
        ac(152 + 21).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 21).key = %VK_C: ac(152 + 21).cmd = key_offset + 3
        ac(152 + 22).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 22).key = %VK_D: ac(152 + 22).cmd = key_offset + 4
        ac(152 + 23).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 23).key = %VK_E: ac(152 + 23).cmd = key_offset + 5
        ac(152 + 24).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 24).key = %VK_F: ac(152 + 24).cmd = key_offset + 6
        ac(152 + 25).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 25).key = %VK_G: ac(152 + 25).cmd = key_offset + 7
        ac(152 + 26).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 26).key = %VK_H: ac(152 + 26).cmd = key_offset + 8
        ac(152 + 27).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 27).key = %VK_I: ac(152 + 27).cmd = key_offset + 9
        ac(152 + 28).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 28).key = %VK_J: ac(152 + 28).cmd = key_offset + 10
        ac(152 + 29).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 29).key = %VK_K: ac(152 + 29).cmd = key_offset + 11
        ac(152 + 30).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 30).key = %VK_L: ac(152 + 30).cmd = key_offset + 12
        ac(152 + 31).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 31).key = %VK_M: ac(152 + 31).cmd = key_offset + 13
        ac(152 + 32).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 32).key = %VK_N: ac(152 + 32).cmd = key_offset + 14
        ac(152 + 33).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 33).key = %VK_O: ac(152 + 33).cmd = key_offset + 15
        ac(152 + 34).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 34).key = %VK_P: ac(152 + 34).cmd = key_offset + 16
        ac(152 + 35).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 35).key = %VK_Q: ac(152 + 35).cmd = key_offset + 17
        ac(152 + 36).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 36).key = %VK_R: ac(152 + 36).cmd = key_offset + 18
        ac(152 + 37).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 37).key = %VK_S: ac(152 + 37).cmd = key_offset + 19
        ac(152 + 38).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 38).key = %VK_T: ac(152 + 38).cmd = key_offset + 20
        ac(152 + 39).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 39).key = %VK_U: ac(152 + 39).cmd = key_offset + 21
        ac(152 + 40).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 40).key = %VK_V: ac(152 + 40).cmd = key_offset + 22
        ac(152 + 41).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 41).key = %VK_W: ac(152 + 41).cmd = key_offset + 23
        ac(152 + 42).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 42).key = %VK_X: ac(152 + 42).cmd = key_offset + 24
        ac(152 + 43).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 43).key = %VK_Y: ac(152 + 43).cmd = key_offset + 25
        ac(152 + 44).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 44).key = %VK_Z: ac(152 + 44).cmd = key_offset + 26
    
        ac(152 + 45).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 45).key = %VK_0: ac(152 + 45).cmd = key_offset + 0
        ac(152 + 46).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 46).key = %VK_1: ac(152 + 46).cmd = key_offset + 0
        ac(152 + 47).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 47).key = %VK_2: ac(152 + 47).cmd = key_offset + 1003
        ac(152 + 48).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 48).key = %VK_3: ac(152 + 48).cmd = key_offset + 0
        ac(152 + 49).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 49).key = %VK_4: ac(152 + 49).cmd = key_offset + 0
        ac(152 + 50).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 50).key = %VK_5: ac(152 + 50).cmd = key_offset + 0
        ac(152 + 51).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 51).key = %VK_6: ac(152 + 51).cmd = key_offset + 30
        ac(152 + 52).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 52).key = %VK_7: ac(152 + 52).cmd = key_offset + 0
        ac(152 + 53).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 53).key = %VK_8: ac(152 + 53).cmd = key_offset + 0
        ac(152 + 54).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 54).key = %VK_9: ac(152 + 54).cmd = key_offset + 0
    
        ac(152 + 55).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 55).key = %VK_NUMPAD0: ac(152 + 55).cmd = key_offset + 48
        ac(152 + 56).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 56).key = %VK_NUMPAD1: ac(152 + 56).cmd = key_offset + 49
        ac(152 + 57).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 57).key = %VK_NUMPAD2: ac(152 + 57).cmd = key_offset + 50
        ac(152 + 58).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 58).key = %VK_NUMPAD3: ac(152 + 58).cmd = key_offset + 51
        ac(152 + 59).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 59).key = %VK_NUMPAD4: ac(152 + 59).cmd = key_offset + 52
        ac(152 + 60).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 60).key = %VK_NUMPAD5: ac(152 + 60).cmd = key_offset + 53
        ac(152 + 61).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 61).key = %VK_NUMPAD6: ac(152 + 61).cmd = key_offset + 54
        ac(152 + 62).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 62).key = %VK_NUMPAD7: ac(152 + 62).cmd = key_offset + 55
        ac(152 + 63).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 63).key = %VK_NUMPAD8: ac(152 + 63).cmd = key_offset + 56
        ac(152 + 64).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 64).key = %VK_NUMPAD9: ac(152 + 64).cmd = key_offset + 57
    
        ac(152 + 65).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 65).key = %VK_F1: ac(152 + 65).cmd = key_offset + 1094
        ac(152 + 66).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 66).key = %VK_F2: ac(152 + 66).cmd = key_offset + 1095
        ac(152 + 67).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 67).key = %VK_F3: ac(152 + 67).cmd = key_offset + 1096
        ac(152 + 68).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 68).key = %VK_F4: ac(152 + 68).cmd = key_offset + 1097
        ac(152 + 69).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 69).key = %VK_F5: ac(152 + 69).cmd = key_offset + 1098
        ac(152 + 70).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 70).key = %VK_F6: ac(152 + 70).cmd = key_offset + 1099
        ac(152 + 71).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 71).key = %VK_F7: ac(152 + 71).cmd = key_offset + 1100
        ac(152 + 72).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 72).key = %VK_F8: ac(152 + 72).cmd = key_offset + 1101
        ac(152 + 73).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 73).key = %VK_F9: ac(152 + 73).cmd = key_offset + 1102
        ac(152 + 74).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 74).key = %VK_F10: ac(152 + 74).cmd = key_offset + 1103
        ac(152 + 75).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 75).key = %VK_F11: ac(152 + 75).cmd = key_offset + 1137
        ac(152 + 76).fvirt = %FVIRTKEY OR %FCONTROL: ac(152 + 76).key = %VK_F12: ac(152 + 76).cmd = key_offset + 1138
    
        REM ALT Keys
        ac(228 + 1).fvirt = %FVIRTKEY OR %FALT: ac(228 + 1).key = %VK_ADD:      ac(228 + 1).cmd = key_offset + 1131
        ac(228 + 2).fvirt = %FVIRTKEY OR %FALT: ac(228 + 2).key = %VK_BACK:     ac(228 + 2).cmd = key_offset + 0
        ac(228 + 3).fvirt = %FVIRTKEY OR %FALT: ac(228 + 3).key = %VK_TAB:      ac(228 + 3).cmd = key_offset + 0
        ac(228 + 4).fvirt = %FVIRTKEY OR %FALT: ac(228 + 4).key = %VK_SUBTRACT: ac(228 + 4).cmd = key_offset + 1130
        ac(228 + 5).fvirt = %FVIRTKEY OR %FALT: ac(228 + 5).key = %VK_RETURN:   ac(228 + 5).cmd = key_offset + 0
        ac(228 + 6).fvirt = %FVIRTKEY OR %FALT: ac(228 + 6).key = %VK_ESCAPE:   ac(228 + 6).cmd = key_offset + 0
        ac(228 + 7).fvirt = %FVIRTKEY OR %FALT: ac(228 + 7).key = %VK_SPACE:    ac(228 + 7).cmd = key_offset + 1032
        ac(228 + 8).fvirt = %FVIRTKEY OR %FALT: ac(228 + 8).key = %VK_PGUP:     ac(228 + 8).cmd = key_offset + 1153
        ac(228 + 9).fvirt = %FVIRTKEY OR %FALT: ac(228 + 9).key = %VK_PGDN:     ac(228 + 9).cmd = key_offset + 1161
        ac(228 + 10).fvirt = %FVIRTKEY OR %FALT: ac(228 + 10).key = %VK_END:    ac(228 + 10).cmd = key_offset + 1159
        ac(228 + 11).fvirt = %FVIRTKEY OR %FALT: ac(228 + 11).key = %VK_HOME:   ac(228 + 11).cmd = key_offset + 1151
        ac(228 + 12).fvirt = %FVIRTKEY OR %FALT: ac(228 + 12).key = %VK_LEFT:   ac(228 + 12).cmd = key_offset + 1155
        ac(228 + 13).fvirt = %FVIRTKEY OR %FALT: ac(228 + 13).key = %VK_UP:     ac(228 + 13).cmd = key_offset + 1152
        ac(228 + 14).fvirt = %FVIRTKEY OR %FALT: ac(228 + 14).key = %VK_RIGHT:  ac(228 + 14).cmd = key_offset + 1157
        ac(228 + 15).fvirt = %FVIRTKEY OR %FALT: ac(228 + 15).key = %VK_DOWN:   ac(228 + 15).cmd = key_offset + 1160
        ac(228 + 16).fvirt = %FVIRTKEY OR %FALT: ac(228 + 16).key = %VK_INSERT: ac(228 + 15).cmd = key_offset + 1162
        ac(228 + 17).fvirt = %FVIRTKEY OR %FALT: ac(228 + 17).key = %VK_DELETE: ac(228 + 16).cmd = key_offset + 1163
        ac(228 + 18).fvirt = %FVIRTKEY OR %FALT: ac(228 + 18).key = %VK_HELP:   ac(228 + 17).cmd = key_offset + 59
    
        ac(228 + 19).fvirt = %FVIRTKEY OR %FALT: ac(228 + 19).key = %VK_A: ac(228 + 19).cmd = key_offset + 1030
        ac(228 + 20).fvirt = %FVIRTKEY OR %FALT: ac(228 + 20).key = %VK_B: ac(228 + 20).cmd = key_offset + 1048
        ac(228 + 21).fvirt = %FVIRTKEY OR %FALT: ac(228 + 21).key = %VK_C: ac(228 + 21).cmd = key_offset + 1046
        ac(228 + 22).fvirt = %FVIRTKEY OR %FALT: ac(228 + 22).key = %VK_D: ac(228 + 22).cmd = key_offset + 1032
        ac(228 + 23).fvirt = %FVIRTKEY OR %FALT: ac(228 + 23).key = %VK_E: ac(228 + 23).cmd = key_offset + 1018
        ac(228 + 24).fvirt = %FVIRTKEY OR %FALT: ac(228 + 24).key = %VK_F: ac(228 + 24).cmd = key_offset + 1033
        ac(228 + 25).fvirt = %FVIRTKEY OR %FALT: ac(228 + 25).key = %VK_G: ac(228 + 25).cmd = key_offset + 1034
        ac(228 + 26).fvirt = %FVIRTKEY OR %FALT: ac(228 + 26).key = %VK_H: ac(228 + 26).cmd = key_offset + 1035
        ac(228 + 27).fvirt = %FVIRTKEY OR %FALT: ac(228 + 27).key = %VK_I: ac(228 + 27).cmd = key_offset + 1023
        ac(228 + 28).fvirt = %FVIRTKEY OR %FALT: ac(228 + 28).key = %VK_J: ac(228 + 28).cmd = key_offset + 1036
        ac(228 + 29).fvirt = %FVIRTKEY OR %FALT: ac(228 + 29).key = %VK_K: ac(228 + 29).cmd = key_offset + 1037
        ac(228 + 30).fvirt = %FVIRTKEY OR %FALT: ac(228 + 30).key = %VK_L: ac(228 + 30).cmd = key_offset + 1038
        ac(228 + 31).fvirt = %FVIRTKEY OR %FALT: ac(228 + 31).key = %VK_M: ac(228 + 31).cmd = key_offset + 1050
        ac(228 + 32).fvirt = %FVIRTKEY OR %FALT: ac(228 + 32).key = %VK_N: ac(228 + 32).cmd = key_offset + 1049
        ac(228 + 33).fvirt = %FVIRTKEY OR %FALT: ac(228 + 33).key = %VK_O: ac(228 + 33).cmd = key_offset + 1024
        ac(228 + 34).fvirt = %FVIRTKEY OR %FALT: ac(228 + 34).key = %VK_P: ac(228 + 34).cmd = key_offset + 1025
        ac(228 + 35).fvirt = %FVIRTKEY OR %FALT: ac(228 + 35).key = %VK_Q: ac(228 + 35).cmd = key_offset + 1016
        ac(228 + 36).fvirt = %FVIRTKEY OR %FALT: ac(228 + 36).key = %VK_R: ac(228 + 36).cmd = key_offset + 1019
        ac(228 + 37).fvirt = %FVIRTKEY OR %FALT: ac(228 + 37).key = %VK_S: ac(228 + 37).cmd = key_offset + 1031
        ac(228 + 38).fvirt = %FVIRTKEY OR %FALT: ac(228 + 38).key = %VK_T: ac(228 + 38).cmd = key_offset + 1020
        ac(228 + 39).fvirt = %FVIRTKEY OR %FALT: ac(228 + 39).key = %VK_U: ac(228 + 39).cmd = key_offset + 1022
        ac(228 + 40).fvirt = %FVIRTKEY OR %FALT: ac(228 + 40).key = %VK_V: ac(228 + 40).cmd = key_offset + 1047
        ac(228 + 41).fvirt = %FVIRTKEY OR %FALT: ac(228 + 41).key = %VK_W: ac(228 + 41).cmd = key_offset + 1017
        ac(228 + 42).fvirt = %FVIRTKEY OR %FALT: ac(228 + 42).key = %VK_X: ac(228 + 42).cmd = key_offset + 1045
        ac(228 + 43).fvirt = %FVIRTKEY OR %FALT: ac(228 + 43).key = %VK_Y: ac(228 + 43).cmd = key_offset + 1021
        ac(228 + 44).fvirt = %FVIRTKEY OR %FALT: ac(228 + 44).key = %VK_Z: ac(228 + 44).cmd = key_offset + 1044
    
        ac(228 + 45).fvirt = %FVIRTKEY OR %FALT: ac(228 + 45).key = %VK_0: ac(228 + 45).cmd = key_offset + 1129
        ac(228 + 46).fvirt = %FVIRTKEY OR %FALT: ac(228 + 46).key = %VK_1: ac(228 + 46).cmd = key_offset + 1120
        ac(228 + 47).fvirt = %FVIRTKEY OR %FALT: ac(228 + 47).key = %VK_2: ac(228 + 47).cmd = key_offset + 1121
        ac(228 + 48).fvirt = %FVIRTKEY OR %FALT: ac(228 + 48).key = %VK_3: ac(228 + 48).cmd = key_offset + 1122
        ac(228 + 49).fvirt = %FVIRTKEY OR %FALT: ac(228 + 49).key = %VK_4: ac(228 + 49).cmd = key_offset + 1123
        ac(228 + 50).fvirt = %FVIRTKEY OR %FALT: ac(228 + 50).key = %VK_5: ac(228 + 50).cmd = key_offset + 1124
        ac(228 + 51).fvirt = %FVIRTKEY OR %FALT: ac(228 + 51).key = %VK_6: ac(228 + 51).cmd = key_offset + 1125
        ac(228 + 52).fvirt = %FVIRTKEY OR %FALT: ac(228 + 52).key = %VK_7: ac(228 + 52).cmd = key_offset + 1126
        ac(228 + 53).fvirt = %FVIRTKEY OR %FALT: ac(228 + 53).key = %VK_8: ac(228 + 53).cmd = key_offset + 1127
        ac(228 + 54).fvirt = %FVIRTKEY OR %FALT: ac(228 + 54).key = %VK_9: ac(228 + 54).cmd = key_offset + 1128
    
        ac(228 + 55).fvirt = %FVIRTKEY OR %FALT: ac(228 + 55).key = %VK_NUMPAD0: ac(228 + 55).cmd = key_offset + 48
        ac(228 + 56).fvirt = %FVIRTKEY OR %FALT: ac(228 + 56).key = %VK_NUMPAD1: ac(228 + 56).cmd = key_offset + 49
        ac(228 + 57).fvirt = %FVIRTKEY OR %FALT: ac(228 + 57).key = %VK_NUMPAD2: ac(228 + 57).cmd = key_offset + 50
        ac(228 + 58).fvirt = %FVIRTKEY OR %FALT: ac(228 + 58).key = %VK_NUMPAD3: ac(228 + 58).cmd = key_offset + 51
        ac(228 + 59).fvirt = %FVIRTKEY OR %FALT: ac(228 + 59).key = %VK_NUMPAD4: ac(228 + 59).cmd = key_offset + 52
        ac(228 + 60).fvirt = %FVIRTKEY OR %FALT: ac(228 + 60).key = %VK_NUMPAD5: ac(228 + 60).cmd = key_offset + 53
        ac(228 + 61).fvirt = %FVIRTKEY OR %FALT: ac(228 + 61).key = %VK_NUMPAD6: ac(228 + 61).cmd = key_offset + 54
        ac(228 + 62).fvirt = %FVIRTKEY OR %FALT: ac(228 + 62).key = %VK_NUMPAD7: ac(228 + 62).cmd = key_offset + 55
        ac(228 + 63).fvirt = %FVIRTKEY OR %FALT: ac(228 + 63).key = %VK_NUMPAD8: ac(228 + 63).cmd = key_offset + 56
        ac(228 + 64).fvirt = %FVIRTKEY OR %FALT: ac(228 + 64).key = %VK_NUMPAD9: ac(228 + 64).cmd = key_offset + 57
    
        ac(228 + 65).fvirt = %FVIRTKEY OR %FALT: ac(228 + 65).key = %VK_F1: ac(228 + 65).cmd = key_offset + 1104
        ac(228 + 66).fvirt = %FVIRTKEY OR %FALT: ac(228 + 66).key = %VK_F2: ac(228 + 66).cmd = key_offset + 1105
        ac(228 + 67).fvirt = %FVIRTKEY OR %FALT: ac(228 + 67).key = %VK_F3: ac(228 + 67).cmd = key_offset + 1106
        ac(228 + 68).fvirt = %FVIRTKEY OR %FALT: ac(228 + 68).key = %VK_F4: ac(228 + 68).cmd = key_offset + 1107
        ac(228 + 69).fvirt = %FVIRTKEY OR %FALT: ac(228 + 69).key = %VK_F5: ac(228 + 69).cmd = key_offset + 1108
        ac(228 + 70).fvirt = %FVIRTKEY OR %FALT: ac(228 + 70).key = %VK_F6: ac(228 + 70).cmd = key_offset + 1109
        ac(228 + 71).fvirt = %FVIRTKEY OR %FALT: ac(228 + 71).key = %VK_F7: ac(228 + 71).cmd = key_offset + 1110
        ac(228 + 72).fvirt = %FVIRTKEY OR %FALT: ac(228 + 72).key = %VK_F8: ac(228 + 72).cmd = key_offset + 1111
        ac(228 + 73).fvirt = %FVIRTKEY OR %FALT: ac(228 + 73).key = %VK_F9: ac(228 + 73).cmd = key_offset + 1112
        ac(228 + 74).fvirt = %FVIRTKEY OR %FALT: ac(228 + 74).key = %VK_F10: ac(228 + 74).cmd = key_offset + 1113
        ac(228 + 75).fvirt = %FVIRTKEY OR %FALT: ac(228 + 75).key = %VK_F11: ac(228 + 75).cmd = key_offset + 1139
        ac(228 + 76).fvirt = %FVIRTKEY OR %FALT: ac(228 + 76).key = %VK_F12: ac(228 + 76).cmd = key_offset + 1140

    Leave a comment:


  • Mike Doty
    replied
    Next step might be to write a function that keeps track of
    last control, current control, last key pressed, last click
    last mouse position, current mouse position.
    A modeless skeleton for PBFORMS.

    This is a stripped down version of the above program.
    Code:
    #PBFORMS CREATED V2.01
    #PBFORMS BEGIN INCLUDES
    #INCLUDE ONCE "WIN32API.INC"
    #PBFORMS END INCLUDES
    #PBFORMS BEGIN CONSTANTS
    %IDD_DIALOG1 = 1000
    %Textbox1    = 1001
    %Textbox2    = 1002
    %Label       = 2001
    #PBFORMS END CONSTANTS
    #PBFORMS DECLARATIONS
    FUNCTION PBMAIN()
      Form1 %HWND_DESKTOP
    END FUNCTION
    CALLBACK FUNCTION MyCallBack
      SELECT CASE AS LONG CB.MSG
        CASE %WM_INITDIALOG
        CASE %WM_NCACTIVATE
          STATIC hWndSaveFocus AS DWORD
          IF ISFALSE CB.WPARAM THEN
            ' Save control focus
            hWndSaveFocus = GetFocus()
          ELSEIF hWndSaveFocus THEN
            ' Restore control focus
            SetFocus(hWndSaveFocus)
            hWndSaveFocus = 0
          END IF
        CASE %WM_COMMAND
          SELECT CASE AS LONG CB.CTL
          END SELECT
        CASE %WM_CLOSE
        CASE %WM_DESTROY
      END SELECT
    END FUNCTION
    FUNCTION FORM1(BYVAL hParent AS DWORD) AS LONG
      LOCAL Result AS LONG
      LOCAL Msg  AS tagMsg
    #PBFORMS BEGIN DIALOG %IDD_DIALOG1->->
      LOCAL hDlg  AS DWORD
      DIALOG NEW hParent, "Message pump", 305, 116, 116, 114, %WS_POPUP OR _
        %WS_BORDER OR %WS_DLGFRAME OR %WS_CAPTION OR %WS_SYSMENU OR _
        %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR %WS_CLIPSIBLINGS OR %WS_VISIBLE OR _
        %DS_MODALFRAME OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, _
        %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
        %WS_EX_RIGHTSCROLLBAR, TO hDlg
      CONTROL ADD TEXTBOX, hDlg, %Textbox1, "", 5, 10, 100, 13
      CONTROL ADD TEXTBOX, hDlg, %Textbox2, "", 5, 30, 100, 55, %WS_CHILD OR _
        %WS_VISIBLE OR %WS_TABSTOP OR %ES_LEFT OR %ES_MULTILINE OR _
        %ES_WANTRETURN, %WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
        %WS_EX_RIGHTSCROLLBAR
      CONTROL ADD LABEL,   hDlg, %Label, "Keystroke", 5, 95, 100, 10
    #PBFORMS END DIALOG
      DIALOG SHOW MODELESS hDlg CALL MyCallBack TO result
      WHILE GetMessage(Msg, %NULL, 0, 0)
        LOCAL k AS LONG
        SELECT CASE Msg.message
          k = Msg.wParam
          CASE %WM_SYSKEYDOWN
            SELECT CASE k 'Msg.wParam
              CASE %VK_LEFT
              CASE %VK_RIGHT
              CASE %VK_DOWN
              CASE %VK_UP
              CASE ELSE
            END SELECT
          CASE %WM_KEYDOWN
            IF ISTRUE(LOWRD(GetKeyState(%VK_CONTROL)) AND &H8000) THEN
              SELECT CASE k 'Msg.wParam
                CASE %VK_LEFT
                  CASE %VK_RIGHT
                  CASE %VK_DOWN
                  CASE %VK_UP
                  CASE %VK_A
                  CASE 65 TO 90
              END SELECT
            ELSEIF ISTRUE(LOWRD(GetKeyState(%VK_SHIFT)) AND &H8000) THEN
              SELECT CASE k 'Msg.wParam
                CASE %VK_LEFT
                CASE %VK_RIGHT
                CASE %VK_DOWN
                CASE %VK_UP
                CASE ELSE
              END SELECT
     '   ***   Handle single keystrokes ****
            ELSE
              'Here you can handle a keystroke or turn it into another value
              SELECT CASE k
                  CASE  9 'TAB key
                CASE 13 'ENTER converted to TAB unless in multi-line control
                  IF Msg.hWnd <> GetDlgItem(hDlg, %TEXTBOX2) THEN
                    msg.wParam = 9
                  END IF
                CASE ELSE
                  CONTROL SET TEXT hDlg, %LABEL, FORMAT$(k)+ "/"+ CHR$(k)
              END SELECT
            END IF
        END SELECT
        'IF Msg.hWnd = GetDlgItem(hDlg, %TEXTBOX1)
        IF IsDialogMessage(hDlg, Msg) = %FALSE THEN  ' Don't touch Tab
          TranslateMessage Msg
          DispatchMessage Msg
        END IF
      LOOP WHILE isWindow(hDlg)
    #PBFORMS BEGIN CLEANUP %IDD_DIALOG1
    #PBFORMS END CLEANUP
      FUNCTION = result
    END FUNCTION
    Last edited by Mike Doty; 15 Oct 2010, 02:47 AM.

    Leave a comment:


  • Mike Doty
    replied
    Modeless in PBFORMS - original code by Semen Matusovski

    Code:
    #PBFORMS CREATED V2.01
    #COMPILE EXE  'MessagePumper.bas
    #DIM ALL
    '------------------------------------------------------------------------------
    '   ** Includes **
    '------------------------------------------------------------------------------
    #PBFORMS BEGIN INCLUDES
    %USEMACROS = 1
    #INCLUDE ONCE "WIN32API.INC"
    #PBFORMS END INCLUDES
    '------------------------------------------------------------------------------
    '   ** Constants **
    '------------------------------------------------------------------------------
    #PBFORMS BEGIN CONSTANTS
    %IDD_DIALOG1 = 1000
    %Label       =  101
    %Button1     =  201
    %Button2     =  202
    %Textbox1    =  301
    %Textbox2    =  302
    %ComboBox    =  401
    %IDR_MENU1   = 2000
    %MENU1       = 2001
    %Listbox     = 3001
    #PBFORMS END CONSTANTS
    '------------------------------------------------------------------------------
    '   ** Declarations **
    '------------------------------------------------------------------------------
    DECLARE FUNCTION AttachMENU1(BYVAL hDlg AS DWORD) AS DWORD
    DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()
    DECLARE FUNCTION SampleComboBox(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL _
      lCount AS LONG) AS LONG
    DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
    #PBFORMS DECLARATIONS
    '------------------------------------------------------------------------------
    '   ** Main Application Entry Point **
    '------------------------------------------------------------------------------
    FUNCTION PBMAIN()
      ShowDIALOG1 %HWND_DESKTOP
    END FUNCTION
     
    THREAD FUNCTION ListBoxCounter(BYVAL hDlg AS DWORD) AS DWORD
      'Clear the list box after so many items
      LOCAL ItemCount, x AS LONG
      DO
       LISTBOX GET COUNT hDlg, %LISTBOX TO ItemCount
       'LISTBOX ADD hDlg, %LISTBOX, STR$(ItemCount) + " items"
       IF ItemCount > 20 THEN
          LISTBOX RESET hDlg, %LISTBOX
          LISTBOX ADD hDlg, %LISTBOX,"LISTBOX RESET " + TIME$
       END IF
       SLEEP 250
      LOOP
    END FUNCTION
    '------------------------------------------------------------------------------
    '   ** Menus **
    '------------------------------------------------------------------------------
    FUNCTION AttachMENU1(BYVAL hDlg AS DWORD) AS DWORD
    #PBFORMS BEGIN MENU %IDR_MENU1->%IDD_DIALOG1
      LOCAL hMenu   AS DWORD
      LOCAL hPopUp1 AS DWORD
      MENU NEW BAR TO hMenu
      MENU NEW POPUP TO hPopUp1
      MENU ADD POPUP, hMenu, "Pop-up menu", hPopUp1, %MF_ENABLED
        MENU ADD STRING, hPopUp1, "Item 1", %MENU1, %MF_ENABLED
      MENU ATTACH hMenu, hDlg
    #PBFORMS END MENU
      FUNCTION = hMenu
    END FUNCTION
    '------------------------------------------------------------------------------
    '   ** CallBacks **
    '------------------------------------------------------------------------------
    CALLBACK FUNCTION ShowDIALOG1Proc()
      SELECT CASE AS LONG CB.MSG
        CASE %WM_INITDIALOG
          LOCAL h AS DWORD
          'clear listbox automatically
          THREAD CREATE ListBoxCounter(CB.HNDL) TO h
          THREAD CLOSE h TO h
          ShowHelp CB.HNDL
        CASE %WM_NCACTIVATE
          STATIC hWndSaveFocus AS DWORD
          IF ISFALSE CB.WPARAM THEN
            ' Save control focus
            hWndSaveFocus = GetFocus()
          ELSEIF hWndSaveFocus THEN
            ' Restore control focus
            SetFocus(hWndSaveFocus)
            hWndSaveFocus = 0
          END IF
        CASE %WM_COMMAND
          SELECT CASE AS LONG CB.CTL
            CASE %BUTTON1
              IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN
              END IF
            CASE %BUTTON2
              IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN
                LISTBOX RESET CB.HNDL, %LISTBOX
              END IF
            CASE %MENU1
              ? "Hi, Peter!"
          END SELECT
        CASE %WM_CLOSE
        CASE %WM_DESTROY
      END SELECT
    END FUNCTION
    '------------------------------------------------------------------------------
    '   ** Sample Code **
    '------------------------------------------------------------------------------
    FUNCTION SampleComboBox(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL lCount _
      AS LONG) AS LONG
      LOCAL i AS LONG
      CONTROL SEND hDlg, lID, %CB_SETEXTENDEDUI, %TRUE, 0
      FOR i = 1 TO lCount
        COMBOBOX ADD hDlg, lID, USING$("Combo item #", i)
      NEXT i
    END FUNCTION
    '------------------------------------------------------------------------------
    '   ** Dialogs **
    '------------------------------------------------------------------------------
    FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
      LOCAL lRslt AS LONG
      LOCAL Msg  AS tagMsg
    #PBFORMS BEGIN DIALOG %IDD_DIALOG1->%IDR_MENU1->
      LOCAL hDlg   AS DWORD
      LOCAL hFont1 AS DWORD
      DIALOG NEW hParent, "Subclass?", 100, 50, 400, 300, %WS_POPUP OR %WS_BORDER OR %WS_DLGFRAME OR _
        %WS_CAPTION OR %WS_SYSMENU OR %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR _
        %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR _
        %DS_NOFAILCREATE OR %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR _
        %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
      CONTROL ADD TEXTBOX,  hDlg, %Textbox1, "Textbox1", 10, 25, 111, 12
      CONTROL ADD TEXTBOX,  hDlg, %Textbox2, "Textbox2", 10, 45, 111, 40, _
        %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %ES_LEFT OR %ES_MULTILINE OR _
        %ES_WANTRETURN, %WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
        %WS_EX_RIGHTSCROLLBAR
      CONTROL ADD COMBOBOX, hDlg, %ComboBox, , 10, 105, 111, 100, _
        %CBS_DROPDOWNLIST OR %WS_TABSTOP OR %WS_CHILD OR %WS_VISIBLE, _
        %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR
      CONTROL ADD BUTTON,   hDlg, %Button1, "&Button1", 55, 5, 48, 12, %WS_CHILD _
        OR %WS_VISIBLE OR %BS_TEXT OR %BS_PUSHBUTTON OR %BS_CENTER OR _
        %BS_VCENTER, %WS_EX_LEFT OR %WS_EX_LTRREADING
      CONTROL ADD LABEL,    hDlg, %Label, "CTRL+A  select all in TextBox2", 5, _
        145, 270, 145
      CONTROL ADD LISTBOX,  hDlg, %Listbox, , 190, 5, 195, 195, %WS_CHILD OR _
        %WS_VISIBLE OR %WS_VSCROLL OR %LBS_NOTIFY, %WS_EX_CLIENTEDGE OR _
        %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR
      CONTROL ADD BUTTON,   hDlg, %Button2, "Button2", 335, 211, 50, 15, _
        %WS_CHILD OR %WS_VISIBLE OR %BS_TEXT OR %BS_PUSHBUTTON OR %BS_CENTER OR _
        %BS_VCENTER, %WS_EX_LEFT OR %WS_EX_LTRREADING
      FONT NEW "Courier New", 8, 0, %ANSI_CHARSET TO hFont1
      CONTROL SET FONT hDlg, %Listbox, hFont1
      AttachMENU1 hDlg
    #PBFORMS END DIALOG
      SampleComboBox hDlg, %COMBOBOX, 10
      DIALOG SHOW MODELESS hDlg CALL ShowDIALOG1Proc TO lRslt
      WHILE GetMessage(Msg, %NULL, 0, 0)
        LOCAL Title$
        LOCAL k AS LONG
        Title$ = ""  'required!!
        SELECT CASE Msg.message
          k = Msg.wParam
          CASE %WM_SYSKEYDOWN
            SELECT CASE k 'Msg.wParam
              CASE %VK_LEFT : LISTBOX ADD hDlg, %LISTBOX, "ALT + LEFT ARROW"
              CASE %VK_RIGHT: LISTBOX ADD hDlg, %LISTBOX , "ALT + RIGHT ARROW"
              CASE %VK_DOWN : LISTBOX ADD hDlg, %LISTBOX , "ALT + ARROW DOWN"
              CASE %VK_UP   : LISTBOX ADD hDlg, %LISTBOX , "ALT + ARROW UP"
              CASE ELSE     : LISTBOX ADD hDlg, %LISTBOX , "ALT" + STR$(k)
            END SELECT
          CASE %WM_KEYDOWN
            IF ISTRUE(LOWRD(GetKeyState(%VK_CONTROL)) AND &H8000) THEN
              SELECT CASE k 'Msg.wParam
                CASE %VK_LEFT   : LISTBOX ADD hDlg, %LISTBOX , "CONTROL + LEFT ARROW"
                  CASE %VK_RIGHT: LISTBOX ADD hDlg, %LISTBOX , "CONTROL + RIGHT ARROW"
                  CASE %VK_DOWN : LISTBOX ADD hDlg, %LISTBOX , "CONTROL + ARROW DOWN"
                  CASE %VK_UP   : LISTBOX ADD hDlg, %LISTBOX , "CONTROL + ARROW UP"
                  CASE %VK_A    : LISTBOX ADD hDlg, %LISTBOX , "CONTROL + A"
                                  CONTROL SET FOCUS hDlg, %TEXTBOX2
                                  CONTROL SEND hDlg,%TEXTBOX2, %EM_SETSEL,0,-1
                  CASE 65 TO 90 : LISTBOX ADD hDlg, %LISTBOX , "CONTROL + " + STR$(k)
                  CASE ELSE     : LISTBOX ADD hDlg, %LISTBOX , "CONTROL + " + STR$(k)
              END SELECT
            ELSEIF ISTRUE(LOWRD(GetKeyState(%VK_SHIFT)) AND &H8000) THEN
              SELECT CASE k 'Msg.wParam
                CASE %VK_LEFT : LISTBOX ADD hDlg, %LISTBOX , "SHIFT + LEFT ARROW"
                CASE %VK_RIGHT: LISTBOX ADD hDlg, %LISTBOX , "SHIFT + RIGHT ARROW"
                CASE %VK_DOWN : LISTBOX ADD hDlg, %LISTBOX , "SHIFT + ARROW DOWN"
                CASE %VK_UP   : LISTBOX ADD hDlg, %LISTBOX , "SHIFT + ARROW UP"
                CASE ELSE     : LISTBOX ADD hDlg, %LISTBOX , "SHIFT +" + STR$(k)
                              'TranslateMessage Msg
                              'DispatchMessage Msg
              END SELECT
     '   ***   Handle single keystrokes ****
            ELSE
              'Here you can handle a keystroke or turn it into another value
              SELECT CASE k
                  CASE  9 'TAB key
                  LISTBOX ADD hDlg, %LISTBOX, "TAB"
                CASE 13 'ENTER converted to TAB unless in multi-line control
                  IF Msg.hWnd <> GetDlgItem(hDlg, %TEXTBOX2) THEN
                    msg.wParam = 9
                    LISTBOX ADD hDlg, %LISTBOX, "ENTER converted to TAB"
                  ELSE
                    LISTBOX ADD hDlg, %LISTBOX, "ENTER not to TAB in this control"
                  END IF
                CASE ELSE
                  Title = FORMAT$(k)+ "/"+ CHR$(k)
                  TranslateMessage Msg
                  DispatchMessage Msg
              END SELECT
            END IF
        END SELECT
        IF LEN(Title$) THEN
          IF Msg.hWnd = GetDlgItem(hDlg, %TEXTBOX1) THEN Title$ = Title + " TextBox1" ELSE _
          IF Msg.hWnd = GetDlgItem(hDlg, %TEXTBOX2) THEN Title$ = Title + "   TextBox2" ELSE _
          IF Msg.hWnd = GetDlgItem(hDlg, %COMBOBOX)THEN Title$ = Title +  "     ComboBox"
          'SetWindowText hDlg, BYVAL STRPTR(Title$)
          LISTBOX ADD hDlg, %LISTBOX, Title
        ELSEIF IsDialogMessage(hDlg, Msg) = %FALSE THEN  ' Don't touch Tab
          TranslateMessage Msg
          DispatchMessage Msg
        END IF
      LOOP WHILE IsWindow(hdlg)
    #PBFORMS BEGIN CLEANUP %IDD_DIALOG1
      FONT END hFont1
    #PBFORMS END CLEANUP
      FUNCTION = lRslt
    END FUNCTION
    SUB ShowHelp(hDlg AS DWORD)
      LOCAL s AS STRING
      LOCAL ds AS STRING
      ds = $CR + $CR
      s =     "CTRL+A select all text in TextBox2." + ds
      s = s + "Enter treated as TAB except in multi-line Textbox2." + ds
      s = s + "Listbox auto reset using a thread." + ds
      s = s + "Credit:" + $CR
      s = s + "Semen Matusovski code into PBFORMS post #12 2/29/2000" + $CR
      s = s + "[URL]http://www.powerbasic.com/support/pbforums/showthread.php?t=2037[/URL]" + ds
      s = s + "Placed into PBFORMS by Mike Doty 10/15/2010" + $CR
      s = s + "Please post problems or suggestions!" + ds
      s = s + "How to get rid of BEEPS?
      CONTROL SET TEXT hDlg, %LABEL, s
    END SUB
    Last edited by Mike Doty; 15 Oct 2010, 01:50 AM.

    Leave a comment:


  • Dominic Mitchell
    replied
    You are doing this the hard way. This is something that is very easy to do
    with SDK programming where one has direct access to the message loop of the app.

    You dug yourself into a deep hole right of the bat with this
    Code:
    DIALOG SHOW MODAL ghDlg CALL MainDlgProc
    This requires a hook to access the message loop hidden in the OS which, as you have
    discovered, is going to get you into trouble with the hidden, internal modal message loop for
    menus and modal dialogs.

    Start anew using DIALOG SHOW MODELESS, install a message loop(aka pump), and
    do your key trapping within the message loop. Do not do it from the dialog callback.
    Do not bother with hooks, accelerator tables or subclassing which are not elegant solutions to a simple problem.

    Leave a comment:


  • Michael Mattias
    replied
    Looks as though I could make a massive table of keyboard shortcuts as suggested by Michael [Mattias], although this is hardly an elegant solution for mapping the whole keyboard along with SHIFT, ALT and CONTROL key combinations.
    News Flash: This is not MS-DOS. This is not a console program. In a Windows' GUI environment, keyboard accelerators is the elegant solution.

    Listen to what Mr. Purvis said. I remember when he was first doing GUI programs an looking for the "new way" to handle things and asking the same kinds of questions you are asking today.

    The difference I see is, Mr. Purvis was not prejudiced into thinking "trap keystrokes;" he was open to "the Windows GUI Way." Now he's a certified GUI veteran.

    MCM

    Leave a comment:


  • Peter Simmonds
    replied
    Yes, seems pretty difficult to sort this out....so easy in the PBCC version of the program! And yes, checking keystrokes during data entry was such a great way to make sure correct user data was entered on forms. eg. if you want an answer between 1 and 3, then only allow keys 1, 2 and 3 to be pressed (and bleep for a wrong key!).

    Looks as though I could make a massive table of keyboard shortcuts as suggested by Michael Matthias, although this is hardly an elegant solution for mapping the whole keyboard along with SHIFT, ALT and CONTROL key combinations.

    Peter

    Leave a comment:


  • Paul Purvis
    replied
    Yes, creating a gui program makes you have to deal
    with writting code that understands and uses message notification
    from the windows os. Coming from a dos or console programing background where if you did not use interrups in a high level language can test ones sanity in creating a gui program that validates keyboard presses.
    I have been writting a few gui programs and i hate having to deal with keyboard validation so i just do not. I check a controls input only after a compeletion of whole input until i grasp those skills which i believe every coder does at some point in time different from others and some people have more pain in learning those skills than others. Not a fault of powerbasic, just the way windows works to be a multitasking operating system.
    Last edited by Paul Purvis; 14 Oct 2010, 12:18 PM.

    Leave a comment:


  • Mike Doty
    replied
    Egbert is the author.
    http://www.powerbasic.com/support/pb...ad.php?t=24721

    Leave a comment:


  • Michael Mattias
    replied
    If you click on a pull down menu and use up and down arrow keys to scroll through the choices, this still activates the keyboard callback whereas ideally it shouldn't.
    It shouldn't? The keyboard was used, wasn't it?

    To make the problem worse, none of the callback function values (eg. CBHNDL, CBCTL) differentiate between keypresses in a menu from those done elsewhere (CBCTL actually reports the key value, ie. the same value as CBWPARAM).
    The DDT system variables "CB*" are not valid for use with menus.. they are only valid in response to a notification message sent to a dialog procedure or DDT-specific control-level callback function named in a 'CONTROL ADD statement.'

    Another problem is that if the main dialog (with the trap in its callback function) calls a child (modal) dialog, the keyboard trap still catches keypresses whereas I had hoped that by running the child menu modally it shouldn't interfere.
    ???

    Above you complain that the keyboard trap does not work when you think it should; now you are complaining that it does work when it shouldn't. ("should" and "shouldn't" here highly subjective and used only to provide context). Do you want to fish or cut bait?

    Why don't you just quit screwing around with keyboard traps and use the tools provided?

    Any user action - any user action - will generate a notification message to your dialog procedure; all you have to do is process those notification messages. Yes, some 'actions of interest' may - may - require you to subclass a control or two, but there are plenty of examples of doing that on this board.

    Yes, you may have to 'rethink' how your program reacts to user actions... but this is not MS-DOS, and for sure it's not your father's Oldsmobasic.

    MCM

    Leave a comment:


  • Peter Simmonds
    replied
    Problem with menu bar in Mike Doty's program

    I've just gone back to the "project" and have incorporated the keyboard trap written by Mike Doty (in post #2). As mentioned it works well, but there is a problem that it continues to work when really not appropriate.

    one example is pull down menus. If you click on a pull down menu and use up and down arrow keys to scroll through the choices, this still activates the keyboard callback whereas ideally it shouldn't. To make the problem worse, none of the callback function values (eg. CBHNDL, CBCTL) differentiate between keypresses in a menu from those done elsewhere (CBCTL actually reports the key value, ie. the same value as CBWPARAM).

    Another problem is that if the main dialog (with the trap in its callback function) calls a child (modal) dialog, the keyboard trap still catches keypresses whereas I had hoped that by running the child menu modally it shouldn't interfere.

    Is there any way to turn off the keyboard trap when required and to identify in what context the keypress occurs?

    Thanks

    Peter

    Leave a comment:


  • Cliff Nichols
    replied
    Virtual Keyboard

    Sorry, I thought I had posted this earlier but would my Virtual Keyboard in the source code forum be of any help?

    (I will try to revisit the code and modify if it is of use)

    Leave a comment:


  • Michael Mattias
    replied
    The old program written in PBCC did have a huge series of keyboard shortcuts, including <CNTRL>F1 to F12, <ALT>F1-F12, CNTRL<PageUp>, basically any combination of <ALT>, <SHIFT> and <CONTROL>
    Keyboard accelerators are calling to you.......

    Leave a comment:


  • Michael Mattias
    replied
    > The old program written in PBCC...

    Console programs are not GUI programs.

    Leave a comment:


  • Peter Simmonds
    replied
    Just to interrupt... The old program written in PBCC did have a huge series of keyboard shortcuts, including <CNTRL>F1 to F12, <ALT>F1-F12, CNTRL<PageUp>, basically any combination of <ALT>, <SHIFT> and <CONTROL> with all the keys (except CAPS LOCK!!). The program now means I can implement them, and still pass on the <ALT>F etc. codes needed for the menu. The only non-standard thing is that many of the items within the menus have <ALT> shortcuts, which I want to keep even though it might annoy some users.

    Playing around with the callback this afternoon seems to have produced a workable system, although unfortunately many the codes returned by non-character keys in Windows are different from the old values returned by INKEY$ in PBCC. Anyway, so far, I can read the keyboard through callback within the new program,although I'm sure there will be further hurdles to overcome...

    Ar least I don't have to use GRAPHIC INKEY$ !!!

    Peter

    Leave a comment:


  • Michael Mattias
    replied
    Besides, we should not encourage the use of keyboard hooks by a self-described "GUI programming novice."

    Better he should walk before he runs.

    Better still he should understand the GUI programming model before writing GUI applications.

    Yes, that is subjective. But I'm stickin' with it.


    MCM

    Leave a comment:


  • Michael Mattias
    replied
    >Why not post some code to show another way?

    Because Egbert's code (keyboard hook) is the best way I can think of - if you REALLY "Want all keys." If it ain't broke, why should I fix it?

    I simply don't believe OP REALLY "wants all keys." eg, I cannot imagine what possible interest there is in LEFT-SHIFT+ALT+lowercase "q"

    MCM

    Leave a comment:


  • Mike Doty
    replied
    Why not post some code to show another way?
    %VK_RETURN was added to show that it is returned before the dialog ends.
    I also added a message box so the dialog wasn't destroyed before seeing the return code.
    All the virtual keys can be displayed without the CASE statements.
    Last edited by Mike Doty; 31 Jul 2009, 08:51 AM.

    Leave a comment:

Working...
X