Click to See Complete Forum and Search --> : Click Detection


Off
August 8th, 2001, 10:47 AM
Hi,

i've an ActiveX on my form and i want to detect mouse cliks on this component. The problem is that it doesn't have an mouse click event.

How can i do it ?

Thanks in advance.
Your response will be rated

Clearcode
August 8th, 2001, 11:10 AM
You can subclass it...
What you do is download the brand new EventCtl.ocx from http://www.MerrionComputing.com and drop it's VBEventWindow control on your form that has the ActiveX control on it. Then in the form load event:


private Sub Form_Load()

VBEventWindow1.ParentForm = myCtl.hwnd

End Sub




Then put whatever you wish to happen on a click event in the following:

private Sub VBEventWindow1_WindowMessageFired(byval msg as WindowMessages, byval wParam as Long, byval lParam as Long, Cancel as Boolean, ProcRet as Long)

If msg = WM_LBUTTONUP then
'\\ Mouse up occured on your control...
End If

End Sub




Hope that helps,
Duncan

(P.S. It can be done without the downloaded dll, but it's much more complicated)

-------------------------------------------------
Ex. Datis: Duncan Jones
Merrion Computing Ltd
http://www.merrioncomputing.com
Check out the new downloads - ImageMap.ocx is the VB control that emulates an HTML image map, EventVB.OCX for adding new events to your VB form and adding System Tray support simply, MCL Hotkey for implemenmting system-wide hotkeys in your application...all with source code included.

Off
August 9th, 2001, 04:35 PM
I've tried this solution but it doesn't work. It gives me an error : "Object variable not set" and it points on the definition line in the form load.
In fact, i prefer the solution without an ActiveX because i don't want my program to be dependent to an externel application. And another factor with that solution is that the region where i have to detect the click is own by a control which asn't a "hWnd" parameter.
So if someone can give me solution with the Windows API, even if it is more compplicated it will be ok.

Thans in advance.

John G Duffy
August 9th, 2001, 07:16 PM
Tell us a little more about your ActiveX. If is is a user Control, you can add a click event using the ActiveX Interface wizard.

John G

Clearcode
August 10th, 2001, 02:51 AM
OK - then if you want subclassing code, here it is:
First we need a function to replace the window's default message function with

'\\ API Calls to pass on WM_ message to previous windows proc...
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 Function DefWindowProc Lib "user32" Alias "DefWindowProcA" (byval hwnd as Long, byval wMsg as Long, byval wParam as Long, byval lParam as Long) as Long

'\\ Window message constants - for WndProc(wMsg).
public Enum WindowMessages
WM_ACTIVATE = &H6 '(LOWORD) wp = WA_, (HIWORD) > 0 if minimized, lp =hwnd
WM_ACTIVATEAPP = &H1C
WM_ASKCBFORMATNAME = &H30C
WM_CANCELJOURNAL = &H4B
WM_CANCELMODE = &H1F
WM_CAPTURECHANGED = &H1F 'wParam = 0, lParam = new capture hWnd
WM_CHANGECBCHAIN = &H30D
WM_CHAR = &H102
WM_CHARTOITEM = &H2F
WM_CHILDACTIVATE = &H22
WM_CHOOSEFONT_GETLOGFONT = (&H400 + 1)
WM_CHOOSEFONT_SETFLAGS = (&H400 + 102)
WM_CHOOSEFONT_SETLOGFONT = (&H400 + 101)
WM_CLEAR = &H303
WM_CLOSE = &H10
WM_COMMAND = &H111
WM_COMPACTING = &H41
WM_COMPAREITEM = &H39
WM_CONVERTREQUESTEX = &H108
WM_COPY = &H301
WM_COPYDATA = &H4A
WM_CREATE = &H1
WM_CTLCOLORBTN = &H135
WM_CTLCOLORDLG = &H136
WM_CTLCOLOREDIT = &H133
WM_CTLCOLORLISTBOX = &H134
WM_CTLCOLORMSGBOX = &H132
WM_CTLCOLORSCROLLBAR = &H137
WM_CTLCOLORSTATIC = &H138
WM_CUT = &H300
WM_DDE_ACK = (&H3E0 + 4)
WM_DDE_ADVISE = (&H3E0 + 2)
WM_DDE_DATA = (&H3E0 + 5)
WM_DDE_EXECUTE = (&H3E0 + 8)
WM_DDE_FIRST = &H3E0
WM_DDE_INITIATE = &H3E0
WM_DDE_LAST = (&H3E0 + 8)
WM_DDE_POKE = (&H3E0 + 7)
WM_DDE_REQUEST = (&H3E0 + 6)
WM_DDE_TERMINATE = (&H3E0 + 1)
WM_DDE_UNADVISE = (&H3E0 + 3)
WM_DEADCHAR = &H103
WM_DELETEITEM = &H2D
WM_DESTROY = &H2
WM_DESTROYCLIPBOARD = &H307
WM_DEVMODECHANGE = &H1B
WM_DRAWCLIPBOARD = &H308
WM_DRAWITEM = &H2B
WM_DROPFILES = &H233
WM_ENABLE = &HA
WM_ENDSESSION = &H16
WM_ENTERIDLE = &H121
WM_ENTERMENULOOP = &H211
WM_ERASEBKGND = &H14 'wParam = 0, lParam = hDC of window. Return 0 if intercepted...
WM_EXITMENULOOP = &H212
WM_FONTCHANGE = &H1D
WM_GETDLGCODE = &H87
WM_GETFONT = &H31
WM_GETHOTKEY = &H33
WM_GETMINMAXINFO = &H24
WM_GETTEXT = &HD
WM_GETTEXTLENGTH = &HE
WM_HOTKEY = &H312
WM_HSCROLL = &H114
WM_HSCROLLCLIPBOARD = &H30E
WM_ICONERASEBKGND = &H27
WM_IME_CHAR = &H286
WM_IME_COMPOSITION = &H10F
WM_IME_COMPOSITIONFULL = &H284
WM_IME_CONTROL = &H283
WM_IME_ENDCOMPOSITION = &H10E
WM_IME_KEYDOWN = &H290
WM_IME_KEYLAST = &H10F
WM_IME_KEYUP = &H291
WM_IME_NOTIFY = &H282
WM_IME_SELECT = &H285
WM_IME_SETCONTEXT = &H281
WM_IME_STARTCOMPOSITION = &H10D
WM_INITDIALOG = &H110
WM_INITMENU = &H116
WM_INITMENUPOPUP = &H117
WM_KEYDOWN = &H100
WM_KEYUP = &H101
WM_KILLFOCUS = &H8 'wParam = hWnd of window about to lose focus.
WM_LBUTTONDBLCLK = &H203
WM_LBUTTONDOWN = &H201
WM_LBUTTONUP = &H202
WM_MBUTTONDBLCLK = &H209
WM_MBUTTONDOWN = &H207
WM_MBUTTONUP = &H208
WM_MDIACTIVATE = &H222
WM_MDICASCADE = &H227
WM_MDICREATE = &H220
WM_MDIDESTROY = &H221
WM_MDIGETACTIVE = &H229
WM_MDIICONARRANGE = &H228
WM_MDIMAXIMIZE = &H225
WM_MDINEXT = &H224
WM_MDIREFRESHMENU = &H234
WM_MDIRESTORE = &H223
WM_MDISETMENU = &H230
WM_MDITILE = &H226
WM_MEASUREITEM = &H2C
WM_MENUCHAR = &H120
WM_MENUSELECT = &H11F
WM_MOUSEACTIVATE = &H21
WM_MOUSEMOVE = &H200
WM_MOVE = &H3
WM_NCACTIVATE = &H86
WM_NCCALCSIZE = &H83
WM_NCCREATE = &H81
WM_NCDESTROY = &H82
WM_NCHITTEST = &H84
WM_NCLBUTTONDBLCLK = &HA3
WM_NCLBUTTONDOWN = &HA1
WM_NCLBUTTONUP = &HA2
WM_NCMBUTTONDBLCLK = &HA9
WM_NCMBUTTONDOWN = &HA7
WM_NCMBUTTONUP = &HA8
WM_NCMOUSEMOVE = &HA0
WM_NCPAINT = &H85
WM_NCRBUTTONDBLCLK = &HA6
WM_NCRBUTTONDOWN = &HA4
WM_NCRBUTTONUP = &HA5
WM_NEXTDLGCTL = &H28
WM_NULL = &H0
WM_PAINT = &HF
WM_PAINTCLIPBOARD = &H309
WM_PAINTICON = &H26
WM_PALETTECHANGED = &H311
WM_PALETTEISCHANGING = &H310
WM_PARENTNOTIFY = &H210
WM_PASTE = &H302
WM_PENWINFIRST = &H380
WM_PENWINLAST = &H38F
WM_POWER = &H48
WM_PSD_ENVSTAMPRECT = (&H400 + 5)
WM_PSD_FULLPAGERECT = (&H400 + 1)
WM_PSD_GREEKTEXTRECT = (&H400 + 4)
WM_PSD_MARGINRECT = (&H400 + 3)
WM_PSD_MINMARGINRECT = (&H400 + 2)
WM_PSD_PAGESETUPDLG = (&H400)
WM_PSD_YAFULLPAGERECT = (&H400 + 6)
WM_QUERYDRAGICON = &H37
WM_QUERYENDSESSION = &H11
WM_QUERYNEWPALETTE = &H30F
WM_QUERYOPEN = &H13
WM_QUEUESYNC = &H23
WM_QUIT = &H12
WM_RBUTTONDBLCLK = &H206
WM_RBUTTONDOWN = &H204
WM_RBUTTONUP = &H205
WM_RENDERALLFORMATS = &H306
WM_RENDERFORMAT = &H305
WM_SETCURSOR = &H20
WM_SETFOCUS = &H7
WM_SETFONT = &H30
WM_SETHOTKEY = &H32
WM_SETREDRAW = &HB
WM_SETTEXT = &HC
WM_SETTINGCHANGE = &H1A
WM_SHOWWINDOW = &H18
WM_SIZE = &H5
WM_SIZECLIPBOARD = &H30B
WM_SPOOLERSTATUS = &H2A
WM_SYSCHAR = &H106
WM_SYSCOLORCHANGE = &H15
WM_SYSCOMMAND = &H112
WM_SYSDEADCHAR = &H107
WM_SYSKEYDOWN = &H104
WM_SYSKEYUP = &H105
WM_TIMECHANGE = &H1E
WM_TIMER = &H113
WM_UNDO = &H304
WM_USER = &H400
WM_VKEYTOITEM = &H2E
WM_VSCROLL = &H115
WM_VSCROLLCLIPBOARD = &H30A
WM_WINDOWPOSCHANGED = &H47
WM_WINDOWPOSCHANGING = &H46
WM_WININICHANGE = &H1A
End Enum

Dim OldProcAddress as Long

'\\ --[VB_WindowProc]-------------------------------------------------------------------
'\\ 'typedef LRESULT (CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM);
'\\ Parameters:
'\\ hwnd - window handle receiving message
'\\ wMsg - The window message (WM_..etc.)
'\\ wParam - First message parameter
'\\ lParam - Second message parameter
'\\ Note:
'\\ When subclassing a window proc using this, set the eventhandler's
'\\ hOldWndProc property to the window's previous window proc address.
'\\ ----------------------------------------------------------------------------------------
'\\ You have a royalty free right to use, reproduce, modify, publish and mess with this code
'\\ I'd like you to visit http://www.merrioncomputing.com for updates, but won't force you
'\\ ----------------------------------------------------------------------------------------
public Function VB_WindowProc(byval hwnd as Long, byval wMsg as Long, byval wParam as Long, byval lParam as Long) as Long

on Local error resume next
Dim lRet as Long
static bMouseDown as boolean

If msg = WM_LBUTTONDOWN then
bMouseDown = true
End If

If msg = WM_LBUTTONUP then
If bMouseDown then
'process the 'click' event however you wish here...
bMouseDown = false
End If
End If


'You must pass the message on if you don't deal with it...
If OldProcAddress > 0 then
lRet = CallWindowProc(OldProcAddress, hwnd, wMsg, wParam, lParam)
else
lRet = DefWindowProc(hwnd, wMsg, wParam, lParam)
End If

VB_WindowProc = lRet

End Function




And then we need to tell the activeX control that we are going to subclass it:



'\\ get Window Long Indexes...
public Enum enGetWindowLong
GWL_EXSTYLE = (-20)
GWL_HINSTANCE = (-6)
GWL_HWNDPARENT = (-8)
GWL_ID = (-12)
GWL_STYLE = (-16)
GWL_USERDATA = (-21)
GWL_WNDPROC = (-4)
End Enum

private Declare Function SetWindowLongApi Lib "user32" Alias "SetWindowLongA" (byval hwnd as Long, byval nIndex as Long, byval dwNewLong as Long) as Long

'....use
OldProcAddress = SetWindowLongApi(mHwnd, GWL_WNDPROC, AddressOf VB_WindowProc)





Howwever you need to know the Window Handle of the ActiveX control you are subclassing. If it doesn't have a .hWnd member then you will need to find this using the FindWindowEx API
It is good practice for any control developer to include a .hWnd so that their control can be used in this manner.

Hope this helps,
Duncan

Warning: - Subclassing is tricky stuff and you may experience crashes if you place any breakpoints in the above code or use the End keyword or stop button.


-------------------------------------------------
Ex. Datis: Duncan Jones
Merrion Computing Ltd
http://www.merrioncomputing.com
Check out the new downloads - ImageMap.ocx is the VB control that emulates an HTML image map, EventVB.OCX for adding new events to your VB form and adding System Tray support simply, MCL Hotkey for implemenmting system-wide hotkeys in your application...all with source code included.