LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Capture Events Not Sent to Panel

Is it possible to capture ALL mouse events sent to any application, not just the events directed to my panel?  Ideally I would also like to be able to cancel them so they do not get processed, or perhaps at least change the coordinates to (0, 0) so they don't do anything.

 

Tony G

0 Kudos
Message 1 of 9
(5,636 Views)

Hello Tony!

 

In order to catch the mouse events that are being sent to your application, you have to intercept each of them inside panel and control callbacks. The purpose of these callbacks is also to give the programmer the oportunity to react to UI events, before they actually take visible action inside the UI. You can supress these mouse events inside the callbacks by "swallowing" them:

http://zone.ni.com/reference/en-XX/help/370051V-01/cvi/uiref/cviswallowing_events/

 

You can also use the events sample application located in <CVI Installation Directory>\samples\userint\events.cws, and use it as a guideline on how to write such an application.

 

Best regards!

- Johannes

0 Kudos
Message 2 of 9
(5,627 Views)

I want to capture events that are NOT sent to my panel.  This would include events sent to any application, to the desktop, to the start button, to the task bar, to the status bar, etc.

 

TonyG

0 Kudos
Message 3 of 9
(5,618 Views)

One approach to capture events that are sent to other applications, is by taping Win32 messages (specifically mouse window messages). CVI libraries do not support capturing mouse events from other non-CVI applications, because CVI events are built on top of the Win32 messaging mechanism.

 

However, you could accomplish this by capturing Windows messages using the Win32 API. I think you probably want to do something similar to Spy++. This is a debugging utitlity that is able to capture and log specific messages that are sent to windows from the OS. To implement a similar feature in your application you could use the SetCapture Windows function, to tap a provided window.

 

There are also other open source projects and tutorials on the internet how to implement this mechanism. Search for "SetCapture", "capturing Win32 messages" and "Spy++ API" on the internet to do some research on this topic. You'll get plenty of results worth of useful tutorials and hints.

 

Best regards!

- Johannes

0 Kudos
Message 4 of 9
(5,601 Views)

I couldn't get SetCapture to report events outside my own window (perhaps I was doing something wrong).  But thanks to your suggestion, I did find a way to capture all mouse events using the SetWindowsHookEx.  For the future reference of anyone looking at this thread, here's some sample code that captures and displays all left mouse click messages (note that the coordinates are dektop coordinates, not panel coordinates).

 

LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam);

static int panelHandle;

int main (int argc, char *argv[])
{
    unsigned int ThreadId;
    HHOOK HookId;
    DWORD Error;
	
    if (InitCVIRTE (0, argv, 0) == 0)
        return -1;  /* out of memory */
    if ((panelHandle = LoadPanel (0, "Mouse Messages.uir", PANEL)) < 0)
        return -1;
	
    ThreadId = CmtGetCurrentThreadID();
    HookId = SetWindowsHookEx(WH_MOUSE_LL, HookProc, NULL, 0);
    Error = GetLastError();
			
    DisplayPanel (panelHandle);
    RunUserInterface ();
    DiscardPanel (panelHandle);

    UnhookWindowsHookEx(HookId);
	
    return 0;
}


LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
   if (wParam == WM_LBUTTONDOWN)
   {
        char Buff[1000];
	   
        MSLLHOOKSTRUCT *HookData = (MSLLHOOKSTRUCT *)lParam;
        int XCoord = HookData->pt.x;
        int YCoord = HookData->pt.y;
	   
        sprintf(Buff, "LEFT MOUSE DOWN  X = %4d   Y = %4d", XCoord, YCoord);
        InsertTextBoxLine (panelHandle, PANEL_txtMouse, 0, Buff);
   } /* if-then */
   
   return CallNextHookEx(NULL, nCode, wParam, lParam);
}

 Tony G

0 Kudos
Message 5 of 9
(5,582 Views)

Hello,

I have tried to test this piece of code, but there is a compilation problem:

Undeclared identifier WH_MOUSE_LL

I have tried WH_MOUSE instead: it is recognized, but SetWindowsEx return value is NULL, so no mouse events is intercepted.

 

Any idea?

 

My final goal is to implement a similar mechanism for keyboard, on a XP embedded product with sensitive touch panel that emulate standard keyboard. An independant soft from the other, with no focus on, is running and process keyboard events.

An i have the same compilation problem between WH_KEYBOARD ans WH_KEYBOARD_LL.

Thanx

0 Kudos
Message 6 of 9
(5,261 Views)

Precision:

CVI 9.0, Windows XP (and Windows Vista)

When I compile with WH_KEYBOARD,  and i compile the hook procedure in a DLL, pass module dll handle to SetWindowsHookEx. It works only when application has focus.

 

 

0 Kudos
Message 7 of 9
(5,257 Views)
#include <windows.h>
#include <ansi_c.h>
#include <utility.h>
#include <cvirte.h>

int __stdcall DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
	switch (fdwReason)
	{
		case DLL_PROCESS_ATTACH:
			if (InitCVIRTE (hinstDLL, 0, 0) == 0)
				return 0;	  /* out of memory */
			break;
		case DLL_PROCESS_DETACH:
			CloseCVIRTE ();
			break;
	}
	
	return 1;
}

BOOL __stdcall DllEntryPoint (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    return DllMain(hinstDLL, fdwReason, lpvReserved);
}

LRESULT DLLEXPORT CALLBACK KeyboardProc(int nCode,WPARAM wParam, LPARAM lParam)
{
    LRESULT RetVal = 0;
	char tcKeyb[256] = {0};            
 	
	GetKeyboardState (tcKeyb);
	printf ("%s - KeyboardProc\n", TimeStr());	
	
    RetVal = CallNextHookEx( NULL, nCode, wParam, lParam );	  
    return  RetVal;
}
															  

Main program code:

#include <windows.h>
#include <ansi_c.h>
#include <utility.h>
#include <cvirte.h>		
#include <userint.h>
#include "ihm.h"


LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);

static int panelHandle;

int CVICALLBACK Panel_CBk (int panel, int event, void *callbackData,
		int eventData1, int eventData2)
{
	switch (event)
	{
		case EVENT_GOT_FOCUS:

			break;
		case EVENT_LOST_FOCUS:

			break;
		case EVENT_CLOSE:
			QuitUserInterface (0);
			break;
	}
	return 0;
}

int main (int argc, char *argv[])
{
    unsigned int ThreadId;
    HHOOK HookId;
    DWORD Error;
	HMODULE moduleHandle = 0;
	
    if (InitCVIRTE (0, argv, 0) == 0)
        return -1;  /* out of memory */
    if ((panelHandle = LoadPanel (0, "ihm.uir", PANEL)) < 0)
        return -1;
	
 //   ThreadId = CmtGetCurrentThreadID();						   
 //   HookId = SetWindowsHookEx(WH_KEYBOARD_LL, HookProc, NULL, 0);
	moduleHandle = GetModuleHandle ("HookKeyboardDLL.dll");
    HookId = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, moduleHandle, 0);
    Error = GetLastError();
			
    DisplayPanel (panelHandle);
    RunUserInterface ();
    DiscardPanel (panelHandle);

    UnhookWindowsHookEx(HookId);
	
    return 0;
}
0 Kudos
Message 8 of 9
(5,256 Views)

OK, if i compile with hardcoded value WM_KEYBOARD_LL (13), it works fine.

0 Kudos
Message 9 of 9
(5,245 Views)