• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1579
  • Last Modified:

MSFlexGrid - keydown event - can't intercept up/down keys

I have an application with a MSFlexGrid control, and I would like to give another control focus when I press key up at the top row, or key down at the bottom row. I've created a little test app with two small routines (keypreview=true for the form):

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
    If KeyCode = vbKeyUp Then MsgBox "Up pressed!"
End Sub

Private Sub MSFlexGrid1_KeyDown(KeyCode As Integer, Shift As Integer)
    If KeyCode = vbKeyUp Then MsgBox "Up pressed!"
End Sub

However, the message box never appears, and key up behaves normally, as if it wasn't trapped in the program.
How can I program my own behaviour for key up/down/home/end etc?
0
stubbscroll
Asked:
stubbscroll
  • 6
  • 6
  • 4
  • +6
1 Solution
 
appariCommented:
the same code is working fine on my m/c.

0
 
appariCommented:
but it was executing flexgrids keydown event only but not forms keydown event
0
 
stubbscrollAuthor Commented:
Really? Did the message boxes show up when pressing key up? I have VB 6.0, with Service Pack 4. What version do you have?
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
rkot2000Commented:
do you breakpoints in your code?
0
 
RemCommented:
Listening,

With MSFlexGrid all keys but 37, 38, 39, 40, pageup down are trapped.

appari : are you working with the msflexgrid or with another grid?

Bye

Rem
0
 
planoczCommented:
Hi stubbscroll,

Here is some code that might help...

Private Sub MSFlexGrid1_KeyUp(KeyCode As Integer, Shift As Integer)
CheckRows
End Sub
Private Sub MSFlexGrid1_RowColChange()
  CheckRows
End Sub
 Private Sub CheckRows()
     Select Case MSFlexGrid1.Col = 0
       Case (MSFlexGrid1.Rows - 1) = MSFlexGrid1.Row
            If (MSFlexGrid1.Rows - 1) = MSFlexGrid1.Row Then
               Text1.SetFocus
            End If
       Case MSFlexGrid1.Row = 1
            If MSFlexGrid1.Row = 1 Then
               Text1.SetFocus
            End If
       End Select
End Sub
0
 
PeterMCCommented:
Perhaps the following will solve your problem

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
   If KeyCode = Asc(vbKeyUp) Then MsgBox "Up pressed!"
End Sub

Private Sub MSFlexGrid1_KeyDown(KeyCode As Integer, Shift As Integer)
   If KeyCode = Asc(vbKeyUp) Then MsgBox "Up pressed!"
End Sub
0
 
RemCommented:
Doesn't work mate,

Try to comply with EE guidelines, and propose answers only when about 200% sure.

Bye

Rem
0
 
rovermCommented:
Maybe it has something to do with the KeyPreview prop of the form ?

D'Mzzl!
RoverM
0
 
Chandramouli kArchitectCommented:
hi friends, i too had the similar problem,
the bad thing in MSFlexgrid's KeyDown event doesnt trap Arrow Keys.
0
 
rkot2000Commented:
you can try to sub-class flexgrid
0
 
RemCommented:
Only workaround I see is using your code and pressing the shift button before using the arrowbuttons.

Private Sub MSFlexGrid1_KeyUp(KeyCode As Integer, Shift As Integer)

   If KeyCode = 38 Then MsgBox "Up pressed!"
End Sub
0
 
rkot2000Commented:
0
 
RemCommented:
rkot2000  : thanx for the link.
My workaround was just to make sure the event is trapped by the shift button. The arrowbutton pressed later passes its keycode to the event.

Rem
0
 
rkot2000Commented:
code to sub-class control

in the module :


Option Explicit

Declare Function CallWindowProc Lib "user32" Alias _
"CallWindowProcA" (ByVal lpPrevWndFunc As Long, _
   ByVal hwnd As Long, ByVal Msg As Long, _
   ByVal wParam As Long, ByVal lParam As Long) As Long

Declare Function SetWindowLong Lib "user32" Alias _
"SetWindowLongA" (ByVal hwnd As Long, _
ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Public Const GWL_WNDPROC = -4
Global lpPrevWndProc As Long
Global gHW As Long


Public Sub Hook()
   lpPrevWndProc = SetWindowLong(Form1.MSFlexGrid1.hwnd, GWL_WNDPROC, AddressOf WindowProc)
End Sub

Public Sub Unhook()
   Dim temp As Long
   temp = SetWindowLong(Form1.MSFlexGrid1.hwnd, GWL_WNDPROC, lpPrevWndProc)
End Sub

Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
   Debug.Print "Message: "; hw, uMsg, wParam, lParam
   WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam)
End Function



on form you need to add flexgrid and two buttons:

and paste this code

Option Explicit

Private Sub cmdHook_Click()
Call Hook
End Sub

Private Sub cmdUnHook_Click()
  Call Unhook
End Sub

start app click on Hook button and to begin sub-classing and on Unhook to stop.

0
 
LunchyCommented:
PeterMC, I am rejecting your answer to return to the questions awaiting answer queue.  Your answer doesn't work as evidenced by rkot2000's link.

See the other question I unlocked for general tips on the VB area etiquette. 8*)

Lunchy
Friendly Neighbourhood Community Support Moderator
0
 
appariCommented:
sorry, i misread the question. i used MS Hierarical FlexGrid control 6.0 SP3 OLEDB.



0
 
stubbscrollAuthor Commented:
Thanks for all the feedback! I will dive into these, and try out the different suggestions. I'm very busy at work today, so I may not be able to test it all until Monday.
0
 
stubbscrollAuthor Commented:
Thanks for all the feedback! I will dive into these, and try out the different suggestions. I'm very busy at work today, so I may not be able to test it all until Monday.
0
 
stubbscrollAuthor Commented:
Subclassing doesn't seem to help. Wparam doesn't seem to change according to the arrow keys I press. They all look like this:

Message:  262344        15            0             0
Message:  262344        20            16845163      0

Perhaps I should opt for a MSHflexgrid instead, since arrow keys are trappable.
0
 
rkot2000Commented:
You need to use sub-classing to add additional functionality.
So every time when you have code 20 you can run code to check current row and set focus to another control
:)
0
 
stubbscrollAuthor Commented:
Is it possible to use sub-classing to determine which key was pressed?
0
 
rkot2000Commented:
just found better example :

http://support.microsoft.com/support/kb/articles/Q216/6/64.ASP?LN=EN-US&SD=gn&FR=0&qry=vbKeyRight&rnk=1&src=DHCS_MSPSS_gn_SRCH&SPR=VBB


make sure that you have correct cotrol name in the following line :

Form2.ActiveControl.Name = "MSFlexGrid1" Then

module :
Option Explicit

Public Declare Function CallNextHookEx Lib "user32" _
   (ByVal hHook As Long, _
   ByVal nCode As Long, _
   ByVal wParam As Long, _
   ByVal lParam As Long) As Long

Public Declare Function UnhookWindowsHookEx Lib "user32" _
   (ByVal hHook As Long) As Long

Public Declare Function SetWindowsHookEx Lib "user32" _
   Alias "SetWindowsHookExA" _
   (ByVal idHook As Long, _
   ByVal lpfn As Long, _
   ByVal hmod As Long, _
   ByVal dwThreadId As Long) As Long

Public Const WH_KEYBOARD = 2
Public hHook As Long

Public Function KeyboardProc(ByVal nCode As Long, _
                             ByVal wParam As Long, _
                             ByVal lParam As Long) As Long
   If nCode >= 0 Then
   ' Process keys you want to filter in TreeView1 control.
      If Form2.ActiveControl.Name = "MSFlexGrid1" Then
         Select Case wParam
            Case vbKeyReturn
               Debug.Print "    Enter Key"
               KeyboardProc = 1
               Exit Function
            Case vbKeyRight
               Debug.Print "    Right Arrow"
               KeyboardProc = 1
               Exit Function
            Case vbKeyLeft
               Debug.Print "    Left Arrow"
               KeyboardProc = 1
               Exit Function
            Case vbKeyDown
               Debug.Print "    Down Arrow"
               KeyboardProc = 1
               Exit Function
         
            Case vbKeyUp
               Debug.Print "    Up Arrow"
               KeyboardProc = 1
               Exit Function
         
         End Select
      End If
   End If
   KeyboardProc = CallNextHookEx(hHook, nCode, wParam, lParam)
End Function

Form :

Private Sub Form_Load()
' Set keyboard hook
   hHook = SetWindowsHookEx(WH_KEYBOARD, _
                            AddressOf KeyboardProc, _
                            0&, _
                            App.ThreadID)
End Sub

Private Sub Form_Unload(Cancel As Integer)
   Call UnhookWindowsHookEx(hHook)
End Sub

0
 
stubbscrollAuthor Commented:
Thanks for this snippet! After fiddling with this a while, and interpreting the 4 events that occured for each key press, I finally got my app to work as I planned.
0

Featured Post

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

  • 6
  • 6
  • 4
  • +6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now