Like before , i have another question to ask , this time about command button.
My question is , how to make the focus rect invisible when a command button got focus? thanks.
it doesn't work . but i think that code used for draw a rectangle not to make it dissappeared , all i want is to make it(focus rectangle) dissappeared.
But thanks anyway. Please help me to resolved this.
I think subclassing might create a bit of overhead. Personally I love using DrawEdge() function - works nice. It gives you great deal of flexibility: you may have completely empty form in design filled up with many "controls" at runtime that could be functional but it may become quite tricky, tough.
Sorry, I just didnt have the time to create an example for you but are you saying that the code you posted works?
It would be strange if it did because I dont think the third parameter will be the command button handle again.
I'm not exactly sure what the correct parameters would be for the third and fourth parameters but I thought if
this is what you wanted we could try to figure it out.
Btw, Hope This Helps.
VB/Office Guru™ (AKA: Gangsta Yoda™ ®)
I dont answer coding questions via PM. Please post a thread in the appropriate forum.
yes , its work.
But i found a little problem, when i click the 'button without focus' for the first time, the event click did not triggered. And if i show up a msgbox when i click the button then i close the msgbox, the focus rect visible again at the button.
can anyone figure it out for me, please ... .
I have an idea but do not know how to do that, something like this:
This is why I believe it needs to be handled with subclassing and intercepting the WM_SETFOCUS message.
If I get some time I will try to whip up an example for you. I currently have 3
examples to finish writting. So I will see if I can squeeze it in before bedtime.
If not I will do it over the weekend.
VB/Office Guru™ (AKA: Gangsta Yoda™ ®)
I dont answer coding questions via PM. Please post a thread in the appropriate forum.
No it doesnt work because the focus rectangle is still visible. If you use a picture of a button
that will not allow for resizing or color changes or font/language changes.
VB/Office Guru™ (AKA: Gangsta Yoda™ ®)
I dont answer coding questions via PM. Please post a thread in the appropriate forum.
Ok, here's the deal. In order to kill the focus rectangle you only need to prevent
the message handling by windows and basically cancel it out. This was not
as bad as I thought, but it does require subclassing.
Note: when debugging a subclassed project do not click the stop or pause
buttions in the VB IDE as it will crash your project. ALWAYS stop a project by
clicking on the forms x cancel button.
In case you dont want to download the code this example will kill the focus
rectangle of command2 command button when you click command1 button.
VB Code:
'BEHIND A FORM (FORM1)
Option Explicit
Private Sub Command1_Click()
'PREVENT THE FOCUS RECTANGLE ON COMMAND2 COMMAND BUTTON
SubClassHwnd Command2.hWnd
End Sub
'INSIDE A MODULE (MODULE1)
Option Explicit
'<RR VB/OUTLOOK GURU 02/04/2005 - PREVENT FOCUS RECTANGLE>
'GETWINDOWLONG CONSTANTS
Private Const GWL_WNDPROC As Long = (-4)
'WINDOWS MESSAGE CONSTANTS
Private Const WM_NOTIFY As Long = &H4E
Private Const WM_DESTROY As Long = &H2
Private Const WM_SETFOCUS As Long = &H7
Private Const WM_KILLFOCUS As Long = &H8
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, _
ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Private 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
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private mlPrevWndProc As Long
Private Function WindowProc(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Select Case Msg
Case WM_SETFOCUS
'KILL THE FOCUS RECTANGLE
Exit Function
Case WM_DESTROY
'REMOVE SUBCLASSING WHEN COMMAND BUTTON IS DESTROYED (FORM UNLOADED)
Thank you, RobDog888
you help me so much ...
But, one problem solve , another problem show up.
I have an array of command button , do i need to subclass it one by one , that's mean i have to write:
Private mlPrevWndProc1 As Long
Public Sub SubClassHwnd1
Private Function WindowProc1
Private mlPrevWndProc2 As Long
Public Sub SubClassHwnd2
Private Function WindowProc2
Private mlPrevWndProc3 As Long
Public Sub SubClassHwnd3
Private Function WindowProc3
You could also just subclass the entire form, but you would then have to
parse out the message parameters to determine which control was receiving
the focus.
VB/Office Guru™ (AKA: Gangsta Yoda™ ®)
I dont answer coding questions via PM. Please post a thread in the appropriate forum.
im not sure but i think you can do something like this
Private mlPrevWndProc1, mlPrevWndProc2, mlPrevWndProc3 As Long
you have to test it for the other cos im not sure.
You cant dimension the variables that way because your only dimming the
last one as long. The first and second ones are undefined so they would be
dimmed as Variant.
VB/Office Guru™ (AKA: Gangsta Yoda™ ®)
I dont answer coding questions via PM. Please post a thread in the appropriate forum.
I know this is an old thread.. but I have to throw this in
Normally if someone wants to do this it is for asthetic reasons ... and the simple way to do it would be to just set the focus to something else through the click event ... the button does not have focus anymore - but that obviously is not an issue because the user would not really know what has focus anyway.
Yes, but if they dont realize that another control actually hs the focus it may cause unexpected results for the user when they try to activate the button by normal means. Killing the focus via subclassing is the best and most solid method for this.
VB/Office Guru™ (AKA: Gangsta Yoda™ ®)
I dont answer coding questions via PM. Please post a thread in the appropriate forum.
I have a control array of command buttons - and changed your code to this
Code:
Option Explicit
Private Sub Command1_Click()
'PREVENT THE FOCUS RECTANGLE ON COMMAND2 COMMAND BUTTON
SubClassHwnd Command2(0).hWnd
SubClassHwnd Command2(1).hWnd
End Sub
Subclassing each index of the control array.
And that seems to work - without having to add additional WindowProc routines.
Thanks for the code!
*** Read the sticky in the DB forum about how to get your question answered quickly!! ***
Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".
LeonX's & szlamany's Problems are already solved i guess. Thanks to Rob's Subclassing Technique.
But there seem to be another method. That is to draw a line over the focus rect using the backcolor of the object.
In my code, i can erase my own focusrect drawn on the form. I can apply this technique to the command button as well. Problem is, i don't no how to get the rect of the focus rect drawn by the system on the command button.
Code:
Option Explicit
Private Declare Function DrawFocusRect Lib "user32" (ByVal hdc As Long, lpRect As RECT) As Long
Private Declare Function CreatePen Lib "gdi32" _
(ByVal nPenStyle As Long, ByVal nWidth As Long, ByVal crColor As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function GetBkcolor Lib "gdi32.dll" Alias "GetBkColor" (ByVal hdc As Long) As Long
Private Declare Function LineTo Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
Private Declare Function MoveToEx Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, lpPoint As POINTAPI) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Type POINTAPI
x As Long
y As Long
End Type
Private rt As RECT
Private pt As POINTAPI
Private Const PS_SOLID = 0 'Brush Type
Private lpn As Long
Private lOldObj As Long
Code:
Private Sub Command1_Click()
rt.Top = 10
rt.Left = 10
rt.Right = 100
rt.Bottom = 100
DrawFocusRect Me.hdc, rt
End Sub
Code:
Private Sub EraseRect()
lpn = CreatePen(PS_SOLID, 4, GetBkcolor(Form1.hdc))
'create a pen
lOldObj = SelectObject(Form1.hdc, lpn)
'Select a Brush in to the DC
MoveToEx Form1.hdc, rt.Left, rt.Top, pt
LineTo Form1.hdc, rt.Right, rt.Top
MoveToEx Form1.hdc, rt.Right, rt.Top, pt
LineTo Form1.hdc, rt.Right, rt.Bottom
MoveToEx Form1.hdc, rt.Right, rt.Bottom, pt
LineTo Form1.hdc, rt.Left, rt.Bottom
MoveToEx Form1.hdc, rt.Left, rt.Bottom, pt
LineTo Form1.hdc, rt.Left, rt.Top
DeleteObject lpn
ReleaseDC Me.hwnd, Me.hdc
End Sub
Code:
Private Sub Command2_Click()
EraseRect
End Sub
Edited : OOoOooos, Now only noticed. A thread created way back in 2005
@fazi - doesn't matter if the thread is 2 years old - anything you can add to the discusion is always appreciated
We already subclass several aspects of our user interface - capture mouse wheel scrolling so that the flexgrid the mouse is over gets scrolled nicely...
Capture WM_APPACTIVATE so that when our app re-gains focus from some other task running on the PC we know about it - something no form event tells you about.
So adding this additional subclass for WM_SETFOCUS was a simple consideration.
Our command buttons are small - so having that FOCUS RECTANGLE interferes with the "caption" on the button - simply doesn't look good. So we decided that changing the color of the button "selected" would work nicely.
Most visually appealling would be the color without the FOCUS RECTANGLE.
This image shows where we were going with all this (note that we are currently working on getting rid of the "bleed" of color that appears above the frame)
*** Read the sticky in the DB forum about how to get your question answered quickly!! ***
Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".
So much about basically nothing - place controls inside picturebox and set focus to container. That's all.
That wont work as the focus is still desired and its function, just its appearance is not desired. If by using your method you press the space bar or enter key then there would be no action of the button since the picturebox has the focus.
VB/Office Guru™ (AKA: Gangsta Yoda™ ®)
I dont answer coding questions via PM. Please post a thread in the appropriate forum.
LeonX's & szlamany's Problems are already solved i guess. Thanks to Rob's Subclassing Technique.
But there seem to be another method. That is to draw a line over the focus rect using the backcolor of the object.
In my code, i can erase my own focusrect drawn on the form. I can apply this technique to the command button as well. Problem is, i don't no how to get the rect of the focus rect drawn by the system on the command button.
Code:
Option Explicit
Private Declare Function DrawFocusRect Lib "user32" (ByVal hdc As Long, lpRect As RECT) As Long
Private Declare Function CreatePen Lib "gdi32" _
(ByVal nPenStyle As Long, ByVal nWidth As Long, ByVal crColor As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function GetBkcolor Lib "gdi32.dll" Alias "GetBkColor" (ByVal hdc As Long) As Long
Private Declare Function LineTo Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
Private Declare Function MoveToEx Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, lpPoint As POINTAPI) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Type POINTAPI
x As Long
y As Long
End Type
Private rt As RECT
Private pt As POINTAPI
Private Const PS_SOLID = 0 'Brush Type
Private lpn As Long
Private lOldObj As Long
Code:
Private Sub Command1_Click()
rt.Top = 10
rt.Left = 10
rt.Right = 100
rt.Bottom = 100
DrawFocusRect Me.hdc, rt
End Sub
Code:
Private Sub EraseRect()
lpn = CreatePen(PS_SOLID, 4, GetBkcolor(Form1.hdc))
'create a pen
lOldObj = SelectObject(Form1.hdc, lpn)
'Select a Brush in to the DC
MoveToEx Form1.hdc, rt.Left, rt.Top, pt
LineTo Form1.hdc, rt.Right, rt.Top
MoveToEx Form1.hdc, rt.Right, rt.Top, pt
LineTo Form1.hdc, rt.Right, rt.Bottom
MoveToEx Form1.hdc, rt.Right, rt.Bottom, pt
LineTo Form1.hdc, rt.Left, rt.Bottom
MoveToEx Form1.hdc, rt.Left, rt.Bottom, pt
LineTo Form1.hdc, rt.Left, rt.Top
DeleteObject lpn
ReleaseDC Me.hwnd, Me.hdc
End Sub
Code:
Private Sub Command2_Click()
EraseRect
End Sub
Edited : OOoOooos, Now only noticed. A thread created way back in 2005
Good idea but takes more code and when the form is moved or invalidated the focus rectangle will be redrawn again by the system.
VB/Office Guru™ (AKA: Gangsta Yoda™ ®)
I dont answer coding questions via PM. Please post a thread in the appropriate forum.
That wont work as the focus is still desired and its function, just its appearance is not desired. If by using your method you press the space bar or enter key then there would be no action of the button since the picturebox has the focus.
So? Use the mouse. Most of skinned apps don't allow setting focus at all...
What's the big deal? Use picturebox with images to create your own button so it can get the focus but going through that much subcalssing troubles for just a "silly" focus rectangle is way too much if you ask me.
Well thats your opinion and if subclassing is already established in the project then its no extra trouble at all. Adding an extra picturebox for each button is making your form heavier and changes the functionality.
VB/Office Guru™ (AKA: Gangsta Yoda™ ®)
I dont answer coding questions via PM. Please post a thread in the appropriate forum.
This thread is getting off topic but a picturebox is considered a heavy control. Then if you have severl buttons to do that suggestion with it adds even more. As you have stated the focus not being on the button anymore will force the user to use the mouse to click it, that a change in functionality.
Later
VB/Office Guru™ (AKA: Gangsta Yoda™ ®)
I dont answer coding questions via PM. Please post a thread in the appropriate forum.
This thread is getting off topic but a picturebox is considered a heavy control...
I think we stay right on topic. However, who considers picturebox to be heavy? It's "heavier" than image control but only for one reason - picturebox is a window and image control is not. Command button just like picturebox is a window.
By substituting command button with picturebox you don't add much weight to your form in this case - you won't be processing large images.
But opinions vary so I figured I mention mine so everyone see the difference and have an alternative way (and btw far not a bad one).
Well this was an old thread and debating which is the better method is not on topic. If you want to converse about that topic more then a new thread is needed.