[RESOLVED] No focus to command buttons!!!
Hi, does any one know how to create a form where the command buttons are not given focus. I am trying to create a calculator that accepts keyboard accelerators.
I have changed the forms KeyPreview setting to True and all of the other keyboard shortcuts work except the Return/Enter key. Every time I press these keys, instead of the configured event from running, it just presses the selected command button. This does not happen on Windows Calculator so it must be possible to change. I have already changed the buttons' TabStop property to False but this has no effect.
Please help! Thanx in advance!
Re: No focus to command buttons!!!
Is the Default property set to true for one of the buttons? If so it will get the keypress for Enter.
If not, which event are you using to get the key pressed?
Re: No focus to command buttons!!!
No, the Default property is not set for any of the command buttons. If have got a KeyPress event in my code is uses Select Case for the KeyAscii code returned by the keys pressed. It works fine for all the other key combinations except for Return/Enter and Delete.
Re: No focus to command buttons!!!
I've had this problem many times before. To the point where I had to delete the command button.
Did you try, when firing the sub for keypress or keydown event setting focus to the form?
Re: No focus to command buttons!!!
Can you attach your form?
Re: No focus to command buttons!!!
You can always have a button that is outside the area of the form and everytime a button is given focus, it can shift the focus to the outside button.
Re: No focus to command buttons!!!
If interested, I have a UniCommand, which has a property ShowFocus. You can also customize the borderstyle to flat if you like. It is just one user control (= one file) to your project, and it compiles into the EXE.
It can't display graphics, but as it supports Unicode, you can find the Unicode character for whatever you need and it can display it.
Re: No focus to command buttons!!!
Perhaps you could use the command button in the Microsoft Forms 2.0, it have a TakeFocusOnClick property which you could set... Or perhaps using the command button's click event you could setfocus to another control?
Re: No focus to command buttons!!!
Quote:
Originally Posted by Andrew G
You can always have a button that is outside the area of the form and everytime a button is given focus, it can shift the focus to the outside button.
... or textbox or picturebox that are placed somewhere in the negative range ... (Left = -1000; Top = -1000)
Re: No focus to command buttons!!!
A bit more advanced solution:
Code:
Option Explicit
' all these just for DrawEdge API...
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Const BF_LEFT = &H1
Private Const BF_TOP = &H2
Private Const BF_RIGHT = &H4
Private Const BF_BOTTOM = &H8
Private Const BF_RECT = (BF_LEFT Or BF_TOP Or BF_RIGHT Or BF_BOTTOM)
Private Const BDR_INNER = &HC
Private Const BDR_OUTER = &H3
Private Const BDR_RAISED = &H5
Private Const BDR_RAISEDINNER = &H4
Private Const BDR_RAISEDOUTER = &H1
Private Const BDR_SUNKEN = &HA
Private Const BDR_SUNKENINNER = &H8
Private Const BDR_SUNKENOUTER = &H2
Private Declare Function DrawEdge Lib "user32" (ByVal hdc As Long, qrc As RECT, ByVal edge As Long, ByVal grfFlags As Long) As Long
' and then a custom user defined type
Private Type MY_BUTTON
Caption As String
Hold As Boolean
InUse As Boolean
Position As RECT
Width As Integer
Height As Integer
End Type
' and then an array for it, too
Dim MyButton() As MY_BUTTON
Dim MyIndex As Integer
Private Function AddButton(ByVal Caption As String, ByVal Left As Integer, ByVal Top As Integer, ByVal Width As Integer, ByVal Height As Integer) As Integer
Dim intA As Integer
' check if there are any items in the array
If Not ((Not MyButton) = True) Then
' see if any of the existing buttons is free (= removed)
For intA = 0 To UBound(MyButton)
If Not MyButton(intA).InUse Then Exit For
Next intA
' if there were no removed buttons, create a new button
If intA > UBound(MyButton) Then ReDim Preserve MyButton(intA)
Else ' add first button
ReDim MyButton(0)
End If
' just a shortcut
With MyButton(intA)
' and set button details
.Caption = Caption
.Hold = False
.InUse = True
' drawing rectangle
.Position.Left = Left
.Position.Top = Top
.Position.Right = Left + Width
.Position.Bottom = Top + Height
' yeah, here just to keep things easier elsewhere...
.Width = Width
.Height = Height
End With
' the function returns the new button index in the array
AddButton = intA
End Function
Private Function RemoveButton(ByVal Index As Integer) As Boolean
' check if there are buttons at all
If (Not MyButton) = True Then Exit Function
' check for valid range
If Index < 0 Or Index > UBound(MyButton) Then Exit Function
' mark removed
MyButton(Index).InUse = False
' return true in success
RemoveButton = True
End Function
Private Sub Form_Click()
If MyIndex = -1 Then Exit Sub
MsgBox "You pushed button '" & MyButton(MyIndex).Caption & "' !", vbInformation, "Wow!"
End Sub
Private Sub Form_Load()
' set proper scalemode for us
Me.ScaleMode = vbPixels
' set to no button being pushed
MyIndex = -1
' add some buttons
AddButton "Button 1", 0, 0, 100, 50
AddButton "Button 2", 10, 50, 50, 25
AddButton "Button 3", 200, 20, 100, 40
End Sub
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim intA As Integer, intX As Integer, intY As Integer
If (Not MyButton) = True Then Exit Sub
If Button <> vbLeftButton Then Exit Sub
' you can pretty much ignore the error checking lines...
' atleast my VB seems to dislike floating point numbers (Singles and Doubles)
On Error Resume Next
I_Hate_IDE_Problems:
intX = CInt(X)
intY = CInt(Y)
If Err.Number <> 0 Then Err.Clear: GoTo I_Hate_IDE_Problems
On Error GoTo 0
' loop through all buttons to see if one is being clicked
For intA = 0 To UBound(MyButton)
With MyButton(intA)
' see if this button is clicked down
.Hold = (.Position.Left <= intX And .Position.Right > intX And .Position.Top <= intY And .Position.Bottom > intY)
' if hold it down, mark it being the holded one and repaint
If .Hold Then MyIndex = intA: Me.Refresh: Exit Sub
End With
Next intA
End Sub
Private Sub Form_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim intX As Integer, intY As Integer
If (Not MyButton) = True Then Exit Sub
If Button <> vbLeftButton Then Exit Sub
If MyIndex = -1 Then Exit Sub
' you can pretty much ignore the error checking lines...
' atleast my VB seems to dislike floating point numbers (Singles and Doubles)
On Error Resume Next
I_Hate_IDE_Problems:
intX = CInt(X)
intY = CInt(Y)
If Err.Number <> 0 Then Err.Clear: GoTo I_Hate_IDE_Problems
On Error GoTo 0
With MyButton(MyIndex)
.Hold = False
' repaint the form
Me.Refresh
' check if the mouse is still within the button area; raise Form_Click if so
If (.Position.Left <= intX And .Position.Right >= intX And .Position.Top <= intY And .Position.Bottom >= intY) Then Form_Click
End With
' no button is being pushed
MyIndex = -1
End Sub
Private Sub Form_Paint()
Static HereAlready As Boolean
Dim intA As Integer, intW As Integer, intH As Integer
' make sure there are buttons
If (Not MyButton) = True Then Exit Sub
' prevent this sub being run multiple times
If HereAlready Then Exit Sub
' mark we are in
HereAlready = True
' draw all buttons
For intA = 0 To UBound(MyButton)
With MyButton(intA)
' get text width and height
intW = Me.TextWidth(.Caption)
intH = Me.TextHeight(.Caption)
' set where we draw the text
Me.CurrentX = .Position.Left + (.Width - intW) \ 2
Me.CurrentY = .Position.Top + (.Height - intH) \ 2
' check if to draw button up or down
If Not .Hold Then
' up
'DrawEdge Me.hdc, .Position, BDR_RAISED, BF_RECT
DrawEdge Me.hdc, .Position, BDR_RAISEDINNER, BF_RECT
Else ' down
'DrawEdge Me.hdc, .Position, BDR_SUNKEN, BF_RECT
DrawEdge Me.hdc, .Position, BDR_SUNKENOUTER, BF_RECT
' move it down a bit
Me.CurrentX = Me.CurrentX + 1
Me.CurrentY = Me.CurrentY + 1
End If
' draw the text
Print .Caption
End With
Next intA
' now we are going out
HereAlready = False
End Sub
Just paste it into empty new form to see how it works :)
Re: No focus to command buttons!!!
Quote:
Originally Posted by dee-u
Perhaps you could use the command button in the Microsoft Forms 2.0, it have a TakeFocusOnClick property which you could set... Or perhaps using the command button's click event you could setfocus to another control?
You probably don't want to do that.
Quote:
Originally Posted by MicroSoft
The Fm20.dll is NOT redistributable. You must have an application such as Microsoft Office 97 on the target system that installs Fm20.dll as part of its setup. (Fm20.dll is included with the OSR2 and OSR2.5 releases of Windows 95.) You can also find this file on the Visual Basic 5.0 CD under the \TOOLS\DataTool\Datatool\Msdesign folder. This will be installed only if you run the setup for the Visual Database Tools. In any case, you may not distribute the Fm20.dll as part of your setup, even if you purchase the Microsoft Office Developer Edition product.
As an alternative to having your end users install Microsoft Office, you can have them freely download and install the Microsoft ActiveX Control Pad, which also installs the Fm20.dll. For more information, see the following Microsoft Developer Network (MSDN) Web site:
Microsoft ActiveX Control Pad
http://msdn.microsoft.com/workshop/misc/cpad/
NOTE: The use of these Microsoft Forms components in your own compiled applications, such as those written with Microsoft Visual C++ and Microsoft Visual Basic, is not recommended or supported. These controls were designed and tested to work exclusively within Microsoft Office and its Visual Basic for Applications environment.
Re: No focus to command buttons!!!
Quote:
Originally Posted by MartinLiss
You probably don't want to do that.
I'm glad to have said "Perhaps"... :D
Just wondering, why did they include it if they don't want it to be used? :confused:
Re: No focus to command buttons!!!
It is designed as a non-redistributable component of VBA and as such it is included for use within Office.
Re: No focus to command buttons!!!
Quote:
you can have them freely download and install the Microsoft ActiveX Control Pad, which also installs the Fm20.dll.
If It can be downloaded freely.. why can't it be redistributed? :D