Solved

Mouse events for Combo Control

Posted on 2000-03-03
9
189 Views
Last Modified: 2011-09-20
Is there a way to add mouse events to the combo control? I want to attach a popupmenu to the combo control, but can't figure out how to get mouse events.
I tried creating an activex control with the mouse events enabled, but they don't fire if you click on the combo box.
I've considered using the forms 2.0 combo box, but from what I've read from the microsoft site, the forms 2.0 controls are not allowed to be distributed.
0
Comment
Question by:chaos_59
9 Comments
 
LVL 14

Expert Comment

by:mcrider
ID: 2582549
There is no problem using the Microsoft Forms 2.0 Object Library (FM20.DLL) in your product... If Microsoft Office is installed on the target system, FM20.DLL is already installed.  If not, you can provide the "Microsoft ActiveX Control Pad" which is *FREE* and installs FM20.DLL.

Read this article:
INFO: Usage and Redistribution of FM20.DLL
http://support.microsoft.com/support/kb/articles/Q224/3/05.ASP
 

Cheers!®©

0
 
LVL 27

Expert Comment

by:Ark
ID: 2582608
Hi
You can use subclassing
'---module code
Public Type RECT
   Left As Long
   Top As Long
   Right As Long
   Bottom As Long
End Type

Public Type COMBOBOXINFO
   cbSize As Long
   rcItem As RECT
   rcButton As RECT
   stateButton  As Long
   hwndCombo  As Long
   hwndEdit  As Long
   hwndList As Long
End Type

Declare Function GetComboBoxInfo Lib "user32.dll" (ByVal hwndCombo As Long, CBInfo As COMBOBOXINFO) As Long
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
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
Public Const GWL_WNDPROC = (-4)
Public Const WM_RBUTTONDOWN = &H204
Public Const WM_RBUTTONUP = &H205

Public OldProc As Long
Public hcboList As Long

Public Function GetComboListHandle(ctl As ComboBox) As Long
   Dim CBI As COMBOBOXINFO
   CBI.cbSize = Len(CBI)
   Call GetComboBoxInfo(ctl.hWnd, CBI)
   GetComboListHandle = CBI.hwndList
End Function

Public Function WndProc(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
 If wMsg = WM_RBUTTONDOWN Then
    MsgBox "You Right_Click on " & Form1.Combo1.List(Form1.Combo1.ListIndex) & " Item"
 End If
 WndProc = CallWindowProc(OldProc, hWnd, wMsg, wParam, lParam)
End Function
'---Form1 code (form1 has Combo1 control)
Private Sub Form_Load()
  For i = 1 To 10
      Combo1.AddItem CStr(i)
  Next i
  hcboList = GetComboListHandle(Combo1)
  OldProc = GetWindowLong(hcboList, GWL_WNDPROC)
  SetWindowLong hcboList, GWL_WNDPROC, AddressOf WndProc
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
    SetWindowLong hcboList, GWL_WNDPROC, OldProc
End Sub
'IMPORTANT - this code use subclassing, so don't try to stop program from IDE, use [x] button on form instead

Cheers
0
 
LVL 14

Accepted Solution

by:
wsh2 earned 100 total points
ID: 2582689
In a Standard.Exe project.. add a ComboBox (Combo1) to Form1.. and create a top level menu item with the name mnuTest. To mnuTest add at at least one menu subitem. In Form1 paste the following...

<----- Form1 Begin ------->

Option Explicit

Private Sub Form_Load()
    ' Subclass Combo1
    Call Module1.xComboHook(Combo1.hwnd)
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
    ' Release Subclassing
    Call Module1.xComboUnhook(Combo1.hwnd)
End Sub

<----- Form1 End ----->

Next, from the Project Menu.. select AddModule (Module1) and in the code box paste the following..

<----- Module1 Begin ----->

Option Explicit

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

Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
    (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)

Public 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)
Public Const WM_MOUSEACTIVATE = &H21
Public Const WM_CONTEXTMENU = &H7B
Public Const WM_RBUTTONDOWN = &H204

Private mwndComboHandle As Long
Private mintMousePress As Integer

Public Function xComboCallback _
    (ByVal ihWnd As Long, _
    ByVal ilngMsg As Long, _
    ByVal ilngwParam As Long, _
    ByVal ilnglParam As Long) _
    As Long
   
    Select Case ilngMsg
       
        Case WM_MOUSEACTIVATE
           
            On Error Resume Next
            Call CopyMemory(mintMousePress, ByVal VarPtr(ilnglParam) + 2, 2)
            If mintMousePress = WM_RBUTTONDOWN Then
                Form1.PopupMenu Form1.mnuTest
                If (Err) _
                Then
                    Call xComboUnhook(ihWnd)
                    Exit Function
                End If
                SendKeys "{ESC}"
            End If
       
        Case WM_CONTEXTMENU
           
            On Error Resume Next
            Form1.PopupMenu Form1.mnuTest
            If (Err) _
            Then
                Call xComboUnhook(ihWnd)
                Exit Function
            End If
            SendKeys "{ESC}"
   
    End Select
   
    xComboCallback = CallWindowProc(mwndComboHandle, ihWnd, ilngMsg, ilngwParam, ilnglParam)

End Function

Public Function xComboHook _
(ByVal ihWnd As Long) _
As Long
    mwndComboHandle = SetWindowLong(ihWnd, GWL_WNDPROC, AddressOf Module1.xComboCallback)
    xComboHook = mwndComboHandle
End Function

Public Function xComboUnhook _
(ByVal ihWnd As Long) _
As Long
    mwndComboHandle = SetWindowLong(ihWnd, GWL_WNDPROC, mwndComboHandle)
    xComboUnhook = mwndComboHandle
End Function

<----- Module1 End ----->

Hit the Start Button.. Right Mouse click on Combo1.. and VOILE.. Popup Menu mnuTest appears.. <smile>.


0
 
LVL 14

Expert Comment

by:wsh2
ID: 2582698
Ooops.. don't want be rude.. LOL.. Changing answer to Comment.. <smile>
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 27

Expert Comment

by:Ark
ID: 2582725
wsh2: Sorry,I cannot check your code - it hang VB IDE. Only Ctrl+Alt+Del help.
chaos_59: Do you want to fire Right_Click event from Edit Part of ComboBox or from dropdown list of combobox? (they have different handles, so you need different code)
0
 
LVL 14

Expert Comment

by:wsh2
ID: 2582748
Ark.. I just reran it here.. and it works just fine.. <smile>. You may want to recheck your steps.. Recapping..

1.  Create a Standard.Exe Project

2.  In Form1..
    a.  Add a Combobox
    b.  Using the Menu Editor Create a top level menu item with the name mnuTest and uncheck its visible box.
    c.  Add at least one submenu item (an indented one) under mnuTest.. more if you like.
    d.  Copy the Form1 code from above into the Form1 code window.

3.  Add a basic Module (Project.. Add Module) and copy the Module1 code from above into the code window.

Good Luck... <smile>

0
 
LVL 14

Expert Comment

by:wsh2
ID: 2582751
Uh Ark.. it just occurred to me.. did you add and or modify anything in the xComboCallback procedure? As this is a subclass.. you want to be very careful adding anything that may cause the IDE to stop.. (ie breakpoints and other debug schtuff).. the results of doing so, can often lead to an Alt-Ctrl-Del.
0
 
LVL 27

Expert Comment

by:Ark
ID: 2582760
wsh2: Everything is OK - I forgot to add Menu. Sorry. I know about subclassing problems - my code do it almost the same way as yours, but I subclassed dropdown portion of ComboBox. I don't know, what part of combobox chaos_59 want to use.

Cheers :)
0
 
LVL 1

Author Comment

by:chaos_59
ID: 2584525
I haven't had time to test this. I tried it once and forgot your note about not stopping with the ide. It blew when I did, and I haven't tried it again. but I'm sure it will work. looks like what I need. I wish there was an easier way. Why would Microsoft leave the mouse events out of a control???
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

Have you ever wanted to restrict the users input in a textbox to numbers, and while doing that make sure that they can't 'cheat' by pasting in non-numeric text? Of course you can do that with code you write yourself but it's tedious and error-prone …
Most everyone who has done any programming in VB6 knows that you can do something in code like Debug.Print MyVar and that when the program runs from the IDE, the value of MyVar will be displayed in the Immediate Window. Less well known is Debug.Asse…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

762 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

19 Experts available now in Live!

Get 1:1 Help Now