CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 13 of 13
  1. #1
    Join Date
    Feb 2013
    Posts
    29

    count mouse clicks

    hi everyone,
    I want to insert in this cobe something to count every mouse click (not only in the front form) and display them when start button is pressed
    Code:
    public: System::Void StartB_Click(System::Object^  sender, System::Windows::Forms::MouseEventArgs e)
    			 {
    
    				if (e.Button == ::MouseButtons::Left)
    				{
    					l++;
    				}
    				else if (e.Button == ::MouseButtons::Right)
    				{
    					r++;
    				}
    				else if (e.Button == ::MouseButtons::Middle)
    				{
    					m++;
    				} 
    			 }
    I tryied this but it doesn't seem to work...

  2. #2
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: count mouse clicks

    There are three considerable syntactical issues in your code snippet, two of which may well be a result of confusing syntactical concepts of C++/CLI and C#.

    But I'll skip that for now since there's a much more fundamental open question: Do you want to globally (with respect to concrete forms) count mouse clicks regarding your own Windows Forms app only or regarding the entire Windows desktop it's running on? It's tricky either way, but that makes up the decision between quite tricky and extremely tricky.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  3. #3
    Join Date
    Feb 2013
    Posts
    29

    Re: count mouse clicks

    well, i think the second is what i'm looking for but i'm ready to consider the quite tricky way aswell. i have this native code
    Code:
    #pragma comment( lib, "user32.lib" )
    #include <windows.h>
    #include <stdio.h>
    #include <vector>	
    
    
    using namespace std;
    
        HHOOK hMouseHook;
    	int leftcounter=0, rightcounter=0, middlecounter=0;
    	vector<int> times(1);
    
        LRESULT CALLBACK KeyboardEvent (int nCode, WPARAM wParam, LPARAM lParam);
    	void MessageLoop();
        DWORD WINAPI MyMouseLogger(LPVOID lpParm);
    
    
    
        int main(int argc, char** argv)
        {
    		HANDLE hThread;
    		DWORD dwThread;
    
    		//	leftcounter=0; rightcounter=0; middlecounter=0;
    
    		hThread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE) MyMouseLogger, (LPVOID) argv[0], NULL, &dwThread);
    		
    		
    
    
    		if (hThread)
    			return WaitForSingleObject(hThread,INFINITE);
    		else return 1;
        }
    
    
    	 LRESULT CALLBACK KeyboardEvent (int nCode, WPARAM wParam, LPARAM lParam)
        {
    		if(wParam == WM_LBUTTONDOWN)
    		{
    			leftcounter++;
    			printf("\nLeft Mouse clicks: %d", leftcounter);
    		}
    		if(wParam == WM_RBUTTONDOWN)
    		{
    			rightcounter++;
    			printf("\nRight Mouse clicks: %d", rightcounter);
    		}
    		if(wParam == WM_MBUTTONDOWN)
    		{
    			middlecounter++;
    			printf("\nMiddle Mouse clicks: %d", middlecounter);
    		}
    		;
    		return CallNextHookEx(hMouseHook,nCode,wParam,lParam);
        }
    
    	 void MessageLoop()
        {
    		MSG message;
    		while (GetMessage(&message,NULL,0,0))
    		{
    			TranslateMessage( &message );
    			DispatchMessage( &message );
    		}
        }
    
    
        DWORD WINAPI MyMouseLogger(LPVOID lpParm)
        {
    		HINSTANCE hInstance = GetModuleHandle(NULL);
    		if (!hInstance) hInstance = LoadLibrary((LPCSTR) lpParm);
    		if (!hInstance) return 1;
    		hMouseHook = SetWindowsHookEx (WH_MOUSE_LL, (HOOKPROC) KeyboardEvent, hInstance, NULL);
    		MessageLoop();
    		UnhookWindowsHookEx(hMouseHook);
    		return 0;
        }
    you can run it and see what it does, either i'll find a way to do what this code does in managed, or i'm going to mix them... dut i've heard all kind of bad things about mixing native and managed codes so....
    Last edited by The_Sire; March 14th, 2013 at 08:31 AM.

  4. #4
    Join Date
    Jul 2002
    Posts
    2,543

    Re: count mouse clicks

    There are no mouse hooks in .NET, you need to add this code to your .NET application. You don't need to create thread with message loop, because Windows Forms application already has message loop. Just add SetWindowsHookEx call and KeyboardEvent function.

  5. #5
    Join Date
    Feb 2013
    Posts
    29

    Re: count mouse clicks

    can you be a little more specific i've learned so many things last week that i may confuse things(i hope that make sense :P)...

  6. #6
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: count mouse clicks

    I think it's worth mentioning that for a global hook, the hook function (here: KeyboardEvent()) must be implemented in a DLL because it is to be injected into the address space of any monitored app by the OS. In the specific case of your app, you should prefer to make that a purely native DLL (i.e. no CLR support) to avoid injecting all that .NET runtime stuff along with the few bytes of your hooking code.

    If it's sufficient to count mouse clicks only on the forms of your own app, it can be done in a purely .NET way (the demo implenetation merely borrows a few constant #defines from <Windows.h>) using a message filter, which is a hub through which all window messages your app receives are routed:

    Code:
    // MouseStats.h
    
    #pragma once
    
    namespace MouseStatsDemo
    {
    using namespace System;
    using namespace System::Windows::Forms;
    
    public ref class MouseStats : public Windows::Forms::IMessageFilter
    {
    public:
      MouseStats();
    
      ~MouseStats();
    
      virtual bool PreFilterMessage(Message %msg);
    
      void Reset();
    
    public:
      static property MouseStats ^AppGlobal { MouseStats ^get() { return s_mstGlobalInstance; } }
    
      property int LeftClicks { int get() { return m_nLeftClicks; } }
      property int RightClicks { int get() { return m_nRightClicks; } }
      property int MiddleClicks { int get() { return m_nMiddleClicks; } }
    
    public:
      event EventHandler ^Updated;
    
    private:
      static MouseStats ^s_mstGlobalInstance = gcnew MouseStats;
    
      int m_nLeftClicks;
      int m_nRightClicks;
      int m_nMiddleClicks;
    };
    
    }
    Code:
    // MouseStats.cpp
    
    #include "StdAfx.h"
    
    #include "MouseStats.h"
    
    #include <Windows.h>  // Defines the message constants
    
    using namespace MouseStatsDemo;
    
    MouseStats::MouseStats()
    {
      Application::AddMessageFilter(this);
    }
    
    MouseStats::~MouseStats()
    {
      Application::RemoveMessageFilter(this);
    }
    
    bool MouseStats::PreFilterMessage(Message %msg)
    {
      switch (msg.Msg)
      {
        case WM_LBUTTONDOWN:
          ++m_nLeftClicks;
          break;
        case WM_RBUTTONDOWN:
          ++m_nRightClicks;
          break;
        case WM_MBUTTONDOWN:
          ++m_nMiddleClicks;
          break;
        default:
          return false;  // Bypasses raising the Updated event
      }
      Updated(this, EventArgs::Empty);
      return false;
    }
    
    void MouseStats::Reset()
    {
      m_nLeftClicks = 0;
      m_nRightClicks = 0;
      m_nMiddleClicks = 0;
    }
    The Updated event can be used to notify client code of changes in the statistical data, and here's a simple example of an event handler making use of it:

    Code:
    void Form1::MouseStatsUpdatedHandler(Object ^sender, EventArgs ^e)
    {
      MouseStats ^stats = safe_cast<MouseStats ^>(sender);
      lblStats->Text = String::Format("{0} left clicks, {1} right clicks, {2} middle clicks",
        stats->LeftClicks, stats->RightClicks, stats->MiddleClicks);
    }
    Finally, this is how the handler is attached to the statistics object, for instance in the form class constructor:

    Code:
        Form1()
        {
          InitializeComponent();
          //
          //TODO: Konstruktorcode hier hinzufügen.
          //
    
          MouseStats::AppGlobal->Updated += gcnew EventHandler(this, &Form1::MouseStatsUpdatedHandler);
        }
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  7. #7
    Join Date
    Jul 2002
    Posts
    2,543

    Re: count mouse clicks

    Eri 253: WH_MOUSE_LL does not require Dll. All he needs is just to add SetWindowsHookEx call and KeyboardEvent to the program.

  8. #8
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: count mouse clicks

    Ah, that's good news! I once already heard that the need for a DLL had been eliminated for this sort of hook, but discarded that as a supposed rumor when I saw that requirement mentioned again in the MSDN doc on SetWindowsHookEx(). I'd just have to go one click furter to LowLevelMouseProc() in order to know better, but didn't... I don't have any hands-on experience of my own regarding message hooking, since, in fact I never had the need to use it in any of my programs.

    And, of course, sorry to the OP for the misinformation.
    Last edited by Eri523; March 15th, 2013 at 09:39 PM.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  9. #9
    Join Date
    Feb 2013
    Posts
    29

    Re: count mouse clicks

    oh thanks!! that works pretty smoothly!! would i complicate things a lot if i was to handle all mouse events or it would be easier to just lock the mouse pointer to a certain location? furthermore i'm getting an error c2678 on this part of the code
    Code:
    private: System::Void searchbox_KeyPress(System::Object^  sender, System::Windows::Forms::KeyPressEventArgs^  e) 
    		 {
    			 if (e->KeyChar == Keys::Enter) //Error	1	error C2678: binary '==' : no operator found which takes a left-hand operand of type 'wchar_t'
                            {
    				 Void search_Click(System::Object^  sender, System::EventArgs^  e) ;
    			 }
    		 }
    any ideas??

  10. #10
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: count mouse clicks

    Well, now that the DLL requirement is gone, setting up a global mouse counter becomes yet simpler. I'd say by now the extra effort would be moderate. By now my main reason to advocate against the global variant is avoiding unnecessary(?) native code in a C++/CLI program. Whether a global click counter actually woud be a substantial benefit eventually depends on why you're counting clicks and what you want to do with the results, which you didn't explain yet.

    IIRC at least some of the underlying integral values of the Keys enum match the corresponding ASCII code. If that holds true for Enter you're probably able to compare to static_cast<Char>(Keys::Enter). (Can't check that currently since I'm not at the Windows box. The correct code should be decimal 13.)
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  11. #11
    Join Date
    Feb 2013
    Posts
    29

    Re: count mouse clicks

    i replaced Keys::Enter with static_cast<Char>(Keys::Enter) and it compiled! the reason for going global is that i want to use the mouse as a HID to measure human reactions. i intent to use a HID some time but for now the mouse does the work. i'm currently trying to add a plot graph for the results but it seems that every thing is for C# or VB...
    Last edited by The_Sire; March 15th, 2013 at 01:12 PM.

  12. #12
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: count mouse clicks

    Quote Originally Posted by The_Sire View Post
    the reason for going global is that i want to use the mouse as a HID to measure human reactions. i intent to use a HID some time but for now the mouse does the work.
    So currently your app still is in an experimental stage and it is no problem to simply maximize the app to extend mouse click monitoring to the entire screen?

    Maybe later, in practical operation, desktop-wide mouse monitoring will be required or would at least be quite useful?

    i'm currently trying to add a plot graph for the results but it seems that every thing is for C# or VB...
    Have you considered the Chart control? IMO its great for using it with C++/CLI. Here's a not-so-trivial example of what it can do: http://forums.codeguru.com/showthrea...21#post2092221
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  13. #13
    Join Date
    Feb 2013
    Posts
    29

    Re: count mouse clicks

    Eri i think i owe you big time, how about naming the program after you :P ...i'll try to work with Chart! hopefully it will suit my goal!! in the meanwhile i was trrying to make a setup using installCreator and VS12 installShield LE but the result was the same. the setup was created, the install was complited be the app wasn't running in my mates pc!! no dll missing or any other error. i tried changing the runtime lidrary from project properties to multy-threaded degub (no dll) but then it returns this error D8016: '/clrure' and '/MTd' command-line options are incompatible....

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured