Solved

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

Posted on 2001-09-06
24
1,276 Views
Last Modified: 2007-11-27
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
Comment
Question by:stubbscroll
  • 6
  • 6
  • 4
  • +6
24 Comments
 
LVL 39

Expert Comment

by:appari
ID: 6460820
the same code is working fine on my m/c.

0
 
LVL 39

Expert Comment

by:appari
ID: 6460829
but it was executing flexgrids keydown event only but not forms keydown event
0
 

Author Comment

by:stubbscroll
ID: 6460929
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
 
LVL 5

Expert Comment

by:rkot2000
ID: 6461015
do you breakpoints in your code?
0
 
LVL 3

Expert Comment

by:Rem
ID: 6461131
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
 
LVL 27

Expert Comment

by:planocz
ID: 6461247
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
 

Expert Comment

by:PeterMC
ID: 6461408
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
 
LVL 3

Expert Comment

by:Rem
ID: 6461422
Doesn't work mate,

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

Bye

Rem
0
 
LVL 12

Expert Comment

by:roverm
ID: 6461425
Maybe it has something to do with the KeyPreview prop of the form ?

D'Mzzl!
RoverM
0
 
LVL 5

Expert Comment

by:kcm76
ID: 6461924
hi friends, i too had the similar problem,
the bad thing in MSFlexgrid's KeyDown event doesnt trap Arrow Keys.
0
 
LVL 5

Expert Comment

by:rkot2000
ID: 6461975
you can try to sub-class flexgrid
0
 
LVL 3

Expert Comment

by:Rem
ID: 6461987
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
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 5

Expert Comment

by:rkot2000
ID: 6462001
0
 
LVL 3

Expert Comment

by:Rem
ID: 6462030
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
 
LVL 5

Expert Comment

by:rkot2000
ID: 6462061
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
 
LVL 2

Expert Comment

by:Lunchy
ID: 6462257
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
 
LVL 39

Expert Comment

by:appari
ID: 6462679
sorry, i misread the question. i used MS Hierarical FlexGrid control 6.0 SP3 OLEDB.



0
 

Author Comment

by:stubbscroll
ID: 6463607
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
 

Author Comment

by:stubbscroll
ID: 6463897
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
 

Author Comment

by:stubbscroll
ID: 6474460
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
 
LVL 5

Expert Comment

by:rkot2000
ID: 6476679
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
 

Author Comment

by:stubbscroll
ID: 6476731
Is it possible to use sub-classing to determine which key was pressed?
0
 
LVL 5

Accepted Solution

by:
rkot2000 earned 200 total points
ID: 6476782
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
 

Author Comment

by:stubbscroll
ID: 6478922
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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
When designing a form there are several BorderStyles to choose from, all of which can be classified as either 'Fixed' or 'Sizable' and I'd guess that 'Fixed Single' or one of the other fixed types is the most popular choice. I assume it's the most p…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now