Problem getting hWnd of a Combo with GetFocus api

  • Thread starter Ricardo Hernández Sáez
  • Start date
R

Ricardo Hernández Sáez

The API function "GetFocus" return the hWnd of the form when you get
into the combobox using the mouse.

Try this:
....
Private Declare Function GetFocus Lib "user32" () As Long
....
Private Sub MyCombo_GotFocus()
Dim hWndFrm As Long
Dim hWndCb As Long

hWndFrm = Me.hWnd
hWndCb = GetFocus()
If hWndFrm <> hWndCb Then
MsgBox "Ok. I Have the hWnd of the Combo.", vbInformation
Else
MsgBox "The API function GetFocus return the hWnd of the form",
vbExclamation
End If
End Sub

Any solution or workaround??
 
G

Graham R Seach

Ricardo,

This behaviour is by design.

The GetFocus() function retrieves the handle of the window that has the
*keyboard* focus. That is, the window that's able to accept events from the
keyboard. When you use the mouse to enter a control, there are several mouse
events that must be processed before keyboard events are allowed to be
processed. So the short answer is that, while the mouse events are being
processed, the control has *mouse* focus, but does not have *keyboard*
focus.

You can test this yourself by placing the following code in the control's
Enter, MouseDown, MouseUp, Click, Exit, GotFocus and LostFocus event
procedures:
Debug.Print "<event name>"
Debug.Print vbTab & "Form hWnd: " & Me.hWnd & vbTab & "Ctrl hWnd: " &
GetFocus

You can clearly see that...

a). using the mouse click to enter the control, the control's hWnd is
unavailable (using GetFocus) until the MouseUp event fires. Even calling
Me!MyCombo.SetFocus prior to GetFocus fails to make the hWnd available any
earlier.

b). using the Tab key to enter the control, the control's hWnd is available
(using GetFocus) from the Enter event.

Regards,
Graham R Seach
Microsoft Access MVP
Sydney, Australia

Microsoft Access 2003 VBA Programmer's Reference
http://www.wiley.com/WileyCDA/WileyTitle/productCd-0764559036.html
 
S

Stephen Lebans

Further to Graham's post, remember that there are actaully two seperate
windows that comprise the Combo control. The editing TextBox and the
drop down ListBox. To get the hWnd of these controls see Dev's solution
here:
http://www.mvps.org/access/api/api0052.htm


By the way, just what are you trying to do? THe Access Combo control is
a heavily subclassed control that will not respond to the majority of
standard control messages.

--

HTH
Stephen Lebans
http://www.lebans.com
Access Code, Tips and Tricks
Please respond only to the newsgroups so everyone can benefit.
 
R

Ricardo Hernández Sáez

I want to control modifications on given bound controls. Suppose i have
a control "OperationType" and changes on this control requires insertions
, updates or deletions on others tables.

At this time, when i encounter situations like this, i use a locked
bound control. Using a button or key combination, i open a dialog to get a
new value.

I've write a class that receives a control as input parameter and
intercept keystrokes. If keystrokes modify the content of the control,
then this class put an independent form (with only a textbox) over the
original control. It copies size, position and aspect. Then cancel the
original keystroke and send it to the new textbox.

When user finish data introduction, the class fire an event. This event
includes the value entered and a boolean parameter. Inside the event proc.
i can use transactions or do anything because the original control has not
been modified and the record is not edited (if is necessary save it before
this process start).

The user uses the form and modify the control content without apparent
changes over the normal behaviour.

This class is working fine, but only works with textboxes. On combo,
listbox, ... i need to intercept mouse events also.

I dont want to use subclassing.

With combox, i put the new form over the original combo when it
receives the focus. This way i dont have to worry about mouse
events, keys that modify the control content, ... I fire the event inside
the exit event of the combo over the original.

This works fine when i use keyboard, but fails when i use the mouse.

This is what i want to do.

PD: Sorry. I don't write in english well.
 
G

Graham R Seach

Ricardo,

<< I dont want to use subclassing.>>
If you've written a class to handle a control's events, you're already
subclassing.

Unless I've completely misunderstood your requirements, it seems to me that
all you probably need is to use the control's BeforeUpdate or NotInList
(combo) events. Used in conjunction with the controls' Undo method, I'm sure
you can achieve the same result with a lot less fuss.

Regards,
Graham R Seach
Microsoft Access MVP
Sydney, Australia
---------------------------
 
R

Ricardo Hernández Sáez

Of course. I'm using two thecniques

1.- In the AfterUpdate event, i save the record and make other changes
(usually transactions are involved). If something goes wrong, i restore the
old value (saved before actions). The record were in edition before and is
in edition after. But i don't want to edit-save-reedit. I want a technic
more
clean .

2.- When i enter into the control, i unlock the control, erase the
controlSource, and copy the form's recordset value. On the exit event, i
have the new value in the control and old value in the form's recordset.
This works, but i can't use in continuous forms o data sheets. All the
data in column show the same value. User's don't want this and it
doesn't like me.

Write this class was hard, but it's working and it makes thing's easier
(much easier).
' METHOD OF USE:
'1.- the "client" form must declare _
a module level variable using withevents: _
private mObjKD as ClsKeyDown

'2.- In the "Form_Load" event proc, create and initialize it _
Set mObjKD = New ClsKeyDown _
mObjKD.Initialize me.NumDoc

'3.- Write the corresponding event proc.
'Private Sub oKdDni_VerifyValue(Cancel As Integer, varValue As Variant)
' Dim varResp As Variant
' Dim resp As VbMsgBoxResult
' Dim strMsg As String
'On Error GoTo HandleErr
' If Nz(Me.NumDoc, "") = Nz(varValue, "") Then
' Cancel = False
' GoTo ExitHere
' End If
' Do anything you want ...
'ExitHere:
' Exit Sub
'HandleErr:
' MsgBox Err.Description, vbExclamation
' Cancel = True
' Resume ExitHere
' Resume
'End Sub

The class makes all the work. I only initialize it and wait the event.

I'm trying to expand the class to combos, listboxes, checkboxes, ...
Subclassing seems to be the obvious solution, but it's a dangerous technic.
I wil use subclassing if don't encounter safer alternatives.
 
G

Graham R Seach

Ricardo,

I still don't understand why you're doing all that. Is it just to provide an
Undo facility at subform level? If so, the Access 2000 Developers Handbook
(Litwin, Getz, Gilbert) provides a much easier way to wrap a subform in a
transaction.

http://www.amazon.com/exec/obidos/tg/detail/-/0782123716/103-5830147-4952642?v=glance

Otherwise, I can't see a way around the hWnd problem during mouse events.
Certainly not without some hairy subclassing trickery.

Stephen Lebans is the subclassing guru around these parts, so he can
definitely advise you better than I can in this regard.

Regards,
Graham R Seach
Microsoft Access MVP
Sydney, Australia
---------------------------
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top