V C++ Help.....

A

a_deano

Hi,
I am not totally new to programming for Windows but may have bitten off
more than I can chew.

My problem is, I would like to install a hook (using SetWindowsHookEx)
to monitor mouse movements as I am testing some new hardware we are
developing.

So, I decided to tackle the .net managed code realm for what I assumed
would be a pretty simple job (at least in my c builder exp most likely
an hour or less). Anyway two days later I am still going but am
completely stuck. See code below;
Basically, llMouseHook.h is a class that wraps up the calls to the API
function and defines an event to fire when said message is received.
The Form1.h is a visual interface with a button and a text box that I
plan to log the records of the mouse messages (assuming I can see
them). The code compiles but I don't seem to get any mouse messages
routed through, as well the important bits ie: the callback handler
aren't even linked in.....

Anyway the code is posted below, I hope someone out there takes pity on
me and gives me some pointers, as I hate being beaten by these things.
In the meantime it's off to the bookshop for some references and back
to builder to get the job done :)

Code:
llMouseHook.h
using namespace System;
using namespace System::Runtime::InteropServices;

namespace SystemHook
{


public ref class HookEventArgs : EventArgs
{
public: int HookCode;
IntPtr wParam;
IntPtr lParam;
};

public enum class HookType : int
{
WH_KEYBOARD_LL = 13,
WH_MOUSE_LL = 14
};

public delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);

[DllImport("user32.dll")]
extern IntPtr SetWindowsHookEx(HookType code,
HookProc ^func,
IntPtr hInstance,
int threadID);

[DllImport("user32.dll")]
extern int UnhookWindowsHookEx(IntPtr hhook);

[DllImport("user32.dll")]
extern int CallNextHookEx(IntPtr hhook,
int code,
IntPtr wParam,
IntPtr lParam);


public delegate void HookEventHandler(Object^ sender, HookEventArgs^
e);

public ref class LocalWindowsHook
{
HookEventHandler^ Hooked;
public:
event HookEventHandler^ HookInvoked {
void add(HookEventHandler^ Ev) {
Hooked += Ev;
}
void remove(HookEventHandler^ Ev) {
Hooked -= Ev;
}
void raise(Object^ sender, HookEventArgs^ e) {
if (Hooked) {
Hooked->Invoke(sender, e);
}
}
}

protected:
IntPtr m_hhook;
HookProc ^ m_filterFunc;
HookType m_hookType;

public:
int CoreHookProc(int code, IntPtr wParam, IntPtr lParam)
{
if (code < 0)
return CallNextHookEx(m_hhook, code, wParam, lParam);
HookEventArgs^ e = gcnew HookEventArgs();
e->HookCode = code;
e->wParam = wParam;
e->lParam = lParam;
HookInvoked(this, e);

return CallNextHookEx(m_hhook, code, wParam, lParam);
}

LocalWindowsHook(HookType hook)
{
m_hhook = IntPtr::Zero;
m_hookType = hook;
Hooked = nullptr;
m_filterFunc = gcnew HookProc(this,
&SystemHook::LocalWindowsHook::CoreHookProc);
}

void Install()
{
Threading::Thread^ MainThread = Threading::Thread::CurrentThread;
m_hhook = SetWindowsHookEx(
m_hookType,
m_filterFunc,
IntPtr::Zero,
MainThread->ManagedThreadId);
}

void Uninstall()
{
UnhookWindowsHookEx(m_hhook);
}
};
}

<Form1>
#pragma once


namespace MouseTracker
{
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace SystemHook;

/// <summary>
/// Summary for Form1
///
/// WARNING: If you change the name of this class, you will need to
change the
/// 'Resource File Name' property for the managed resource
compiler tool
/// associated with all .resx files this class depends on.
Otherwise,
/// the designers will not be able to interact properly with
localized
/// resources associated with this form.
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
LocalWindowsHook^ MseHook;
HookEventHandler^ Ev;
bool Running;
public:
Form1(void)
{
InitializeComponent();

MseHook = gcnew LocalWindowsHook(HookType::WH_MOUSE_LL);
Ev = gcnew HookEventHandler(this, &Form1::MouseEventReceived);
Running = false;
}

protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">"description of the parameter"</param>
virtual void Dispose(Boolean disposing) override
{
if (disposing && components)
{
delete components;
}
__super::Dispose(disposing);
}
private: System::Windows::Forms::RichTextBox^ rtbMouseLog;
protected:

private: System::Windows::Forms::Button^ butStart;
private: System::Windows::Forms::Button^ butClear;
private: System::Windows::Forms::Button^ butSave;


protected:
void MouseEventReceived(Object^ sender, HookEventArgs^ e)
{
System::Console::WriteLine("Mouse Event....");
}

private:
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
//REMOVED.......
#pragma endregion
private: System::Void butStart_Click(System::Object^ sender,
System::EventArgs^ e) {
butClear->Enabled = Running;
butSave->Enabled = Running;
Running = !Running;
if (Running) {
butStart->Text = "Stop";
MseHook->HookInvoked += Ev;
MseHook->Install();
}
else {
butStart->Text = "Start";
MseHook->HookInvoked -= Ev;
MseHook->Uninstall();
}

}
private: System::Void butClear_Click(System::Object^ sender,
System::EventArgs^ e) {
// rtbMouseLog->Lines->Clear;
}
};
}
 
D

David Ching

a_deano said:
Hi,
I am not totally new to programming for Windows but may have bitten off
more than I can chew.

My problem is, I would like to install a hook (using SetWindowsHookEx)
to monitor mouse movements as I am testing some new hardware we are
developing.

So, I decided to tackle the .net managed code realm for what I assumed
would be a pretty simple job (at least in my c builder exp most likely
an hour or less). Anyway two days later I am still going but am
completely stuck. See code below;

As your hook will be called each time the mouse is moved, you want to make
it as fast as possible. Managed code is not really appropriate for this,
since you incur a performance penalty to transition to/from managed code.
On top of that, it is far simpler to write a hook in native code, since
Windows supports native callbacks, and forcing it to go to a manged callback
is one more thing to worry about (and apparently is hard to get working from
your experience, besides).

-- David
http://www.dcsoft.com
 

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