Buongiorno, sto tentando di scrivere una classe contenente delle utility per il mouse, tra queste utility ho bisogno di includere la possibilità di ottenere il delta dello scroll della rotella del mouse.
L'ambiente sul quale sviluppo è Windows, ed utilizzo C++14.
Cercando un po' in giro sono arrivato ad impostare la classe in questo modo:
Class MouseUtils
{
private:
HHOOK mh;
int delta;
LRESULT CALLBACK MouseCB(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode < 0)
{
return CallNextHookEx(mh, nCode, wParam, lParam);
}
MSLLHOOKSTRUCT* pMouseStruct = (MSLLHOOKSTRUCT*)lParam;
if (pMouseStruct != NULL)
{
if (wParam == WM_MOUSEWHEEL)
{
if (HIWORD(pMouseStruct->mouseData) == 120)
{
delta = 1;
}
else
{
delta = -1;
}
}
else
{
delta = 0;
}
}
return CallNextHookEx(mh, nCode, wParam, lParam);
}
public:
int GetWheelScroll()
{
using namespace std::placeholders;
delta = 0;
if (!(mh = SetWindowsHookExA(WH_MOUSE_LL, std::bind(&MouseUtils::MouseCB, this, _1, _2, _3), NULL, 0))) // Qui ho l'errore su std::bind
{
delta = -404;
}
MSG message;
bool peek = true;
long tm = time(0);
while (peek)
{
PeekMessage(&message, NULL, 0, 0, PM_REMOVE);
if (~delta == 0 || tm < time(0))
{
peek = false;
}
}
UnhookWindowsHookEx(mh);
return delta;
}
}
Il problema si presenta quando devo passare il metodo di Callback MouseCB a SetWindowsHookExA, essendo all'interno di una classe ho trovato 3 modi per rendere possibile ciò:
- Rendere il metodo statico, ma così facendo non potrei più usare gli attributi condivisi tra i due metodi MouseCB e GetWheelScroll.
- Utilizzare boost::bind, però il progetto è già molto pesante ed ho la necessità di mantenere tutte le librerie statiche quindi non voglio appesantirlo ulteriormente con altre librerie.
- Utilizzare std::bind, è la soluzione che ho deciso di adottare in questo caso, però, come da documentazione di Microsoft, SetWindowsHookExA vuole come secondo argomento un puntatore HOOKPROC, quindi passargli direttamente std::bind restituisce un errore.
Il problema su cui non riesco a venire a capo è trovare un modo per passare std::bind alla funzione SetWindowsHookExA. A dirla tutta non credo sia nemmeno possibile farlo, ma magari mi sto perdendo qualche dettaglio che non riesco bene ad inquadrare.
L'errore che mi viene restituito è il seguente:
no suitable conversion function from "std::_Binder<std::_Unforced, LRESULT (__stdcall MouseUtils::*)(int nCode, WPARAM wParam, LPARAM lParam), MouseUtils *, const std::_Ph<1> &, const std::_Ph<2> &, const std::_Ph<3> &>" to "HOOKPROC" exists