   Pointer to member of class
  i want to use a keyboard hook but i want the message loop to be a member of a classegHHOOK hHook;class C{public:  LRESULT CALLBACK KeyboardHook (int nCode, WPARAM wParam, LPARAM lParam )   {return CallNextHookEx(hHook, nCode, wParam, lParam);   }};WinMain(...){  hHook = SetWindowsHookEx(WH_KEYBOARD, *Pointer to C::KeyboardHook*, hInstance , 0);}Can this be done cause i cant get it to work?   
  Not directly, no. The callback must be a free function, so you can only do it indirectly by storing the appropriate object instance somewhere and dispatching to the member function from the free function.   ;  Thanks for the quick reply. I seem to have found a solution.change thisLRESULT CALLBACK KeyboardHook (int nCode, WPARAM wParam, LPARAM lParam )tostatic LRESULT CALLBACK KeyboardHook (int nCode, WPARAM wParam, LPARAM lParam )i dont know yet what side effects this could have with multiple instances of the class   ;Quote:Original post by hahahaThanks for the quick reply. I seem to have found a solution.*** Source Snippet Removed ***i dont know yet what side effects this could have with multiple instances of the classIf you were able to make that change without introducing any compilation errors, then your callback function must not access any non-static member data or functions, and there should be no side effects.That does raise the question though of why the callback needed to be a member function in the first place. Does it access any static data or member functions of the class? (Maybe you could just post it so we can see what you're doing...)   ;  I know this isnt the best way of doing things but im making a UI class for my game and i dont want to have to supply it with input so i want to set a keyboard hook and then check if the message is coming from my window then process it.Just a small example class to show what im doingstruct SomeWidget{  ...somedata};class UI{private:  SomeWidget *Widgets; //pointer to widget data  int NumWidgets;  static LRESULT CALLBACK KeyboardHook (int nCode, WPARAM wParam, LPARAM lParam );public:  UI(int numwidgets){Widgets = new SomeWidget[numwidgets];}  void AddWidget(SomeWidget Widget)  {    Widgets[NumWidgets] = Widget;    NumWidgets++;  }};Any ideas on a better way to do this will be greatly be appreciated   ;Quote:Original post by hahahaJust a small example class to show what im doing*** Source Snippet Removed ***... and what do you want the KeyboardHook to *do*? If it's supposed to, for example, add a widget to an object, then how are you doing to figure out which object to add it to?EDIT: Actually, I'm very worried about how you propose to "add widgets", anyway. Just use std::vector. Please. For everyone's sake.   ;  The way I work around that is to pass a pointer to my application class as the extra parameter of the CreateWindow() function. Then, when you process the WM_CREATE message you can retrieve that pointer and then store it in the USERDATA area of the Window. When you receive other messages (anything other than WM_CREATE, and maybe a few others not related to a window) you retrieve the pointer and pass that to your Hooks (I call them EventHandlers), along with the message type, wParam and lParam.Then, the app class is either the effected system of the message, or provides access to the effected system. What you're doing is essentially passing in the 'this' pointer yourself.It works great. Here are some relevant code snippets:Window Class registration & creationWNDCLASS wc; // Windows Class Structurewc.hInstance= app->GetInstanceHandle();    // Set The Instancewc.lpszClassName = m_Class.c_str();   // Set The Class Namewc.lpfnWndProc   = app->GetWindowProc().CallBack;    // Set the Window Procwc.style    = CS_VREDRAW | CS_HREDRAW;// Redraw On Movewc.hIcon    = NULL;    // Load The Default Iconwc.hCursor  = LoadCursor (NULL, IDC_ARROW);// Load The Arrow Pointerwc.lpszMenuName  = NULL;    // No Defualt Menu (not supported on Windows Mobile)wc.cbClsExtra    = NULL;    // No Extra Window Datawc.cbWndExtra    = NULL;    // No Extra Window Datawc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);    // No Background Required// Attempt to register the window classif (!RegisterClass(&wc)){MessageBox(NULL, TEXT("Failed to register the window class."), TEXT("STARTUP ERROR"), MB_OK | MB_ICONEXCLAMATION);return FALSE;}// Attempt to create the windowm_hWnd = CreateWindowEx(WS_EX_TOPMOST,// Extended style    m_Class.c_str(),   // Class Name    m_Title.c_str(),   // Window Title    WS_VISIBLE | WS_POPUP,  // Standard Style    0, 0,    // Window Position    GetSystemMetrics(SM_CXSCREEN),    // Adjusted Window Width    GetSystemMetrics(SM_CYSCREEN),    // Adjusted Window height    NULL,    // No Parent Window    NULL,    // No Default Window    app->GetInstanceHandle(),    // Instance    app);    // Pass App so we can access it from WndProc::CallBackWndProc classtemplate <typename OWNER>class WMWindowProc{public:// Event Handler Callbacktypedef LRESULT (*EventHandler)(OWNER * owner, UINT uMsg, WPARAM wParam, LPARAM lParam);// Static WndProcstatic LRESULT CALLBACKCallBack(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);// Event Handler Registrationvoid AssignEventHandler(UINT uMsg, EventHandler handler)    { m_Handlers[uMsg] = handler; }void RemoveEventHandler(UINT uMsg) { m_Handlers.erase(uMsg); }private:// typename is required to define EventHandlerMapItertypedef typename std::map< UINT, EventHandler > EventHandlerMap;typedef typename EventHandlerMap::iterator EventHandlerMapIter;EventHandlerMap m_Handlers;};/// ****************************************************************************/// <summary>The static WMWindowProc::CallBack method dispatches recieved/// messages to the registered WMWindowProc::EventHandler method. If no Handler/// has been registered, the message is dispatched to defWindowProc.</summary>/// <param name="hWnd">The window for which the message is intended.</param>/// <param name="uMsg">The message.</param>/// <param name="wParam">Specifies additional message-specific information. The/// contents of this parameter depend on the value of the Msg parameter.</param>/// <param name="lParam">Specifies additional message-specific information. The/// contents of this parameter depend on the value of the Msg parameter.</param>/// <returns>An LRESULT indicating how the message was handled.</returns>template <class OWNER>LRESULT CALLBACK WMWindowProc<OWNER>::CallBack(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){// owner refers to the class or base which impliments or who's derivitives// impliment the EventHandlers. Typically, this is the main application// class or its base.OWNER * owner = 0;if(uMsg == WM_CREATE){// On window creation, store the Window class pointer we specified as// the extra parameter perminantly in the window's USERDATA section.owner = reinterpret_cast< OWNER * >(((LPCREATESTRUCT)lParam)->lpCreateParams);SetWindowLong(hWnd, GWL_USERDATA, reinterpret_cast< LONG >(owner));}else{// Otherwise, retrieve the Window class pointer we stored in USERDATA.owner = reinterpret_cast< OWNER * >(GetWindowLong(hWnd, GWL_USERDATA));}// If this app doesn't exist, route to default WndProc.if(!owner)return DefWindowProc(hWnd, uMsg, wParam, lParam);// The WMWindowProc object must reference itself, but because this// is a static function, we must ask owner for our own reference.WMWindowProc< OWNER >& self = owner->GetWindowProc();// Call correct Framework instance's handlerEventHandlerMapIter curr = self.m_Handlers.find(uMsg);// Route message to its registered handler if one exists, otherwise route// to default WndProc.if(curr != self.m_Handlers.end())return self.m_Handlers[uMsg](owner, uMsg, wParam, lParam);elsereturn DefWindowProc(hWnd, uMsg, wParam, lParam);}and this is what an EventHandler looks like:// From class declaration ...class YourAppClass{public:...private:static LRESULT OnCommand(YourAppClass * app, UINT uMsg, WPARAM wParam, LPARAM lParam);...};/// ****************************************************************************/// <summary>Hook for responding to Command messages.</summary>/// <remarks>Command handling is defered to the current game state through the/// GameStateManager.</remarks>/// <param name="app">The address of the WMApp instance which is source/target/// of this message.</param>/// <param name="uMsg">The message type.</param>/// <param name="wParam">Contains the Notify and ID of the WM_COMMAND message.</param>/// <param name="lParam">Contains the window handle of the sender.</param>/// <returns>An LRESULT indicating how the message was handled.</returns>LRESULT SkiTime::OnCommand(YourAppClass * app, UINT uMsg, WPARAM wParam, LPARAM lParam){UNREFERENCED_PARAMETER(lParam);assert(uMsg == WM_COMMAND);// HIWORD(wParam) specifies the notification code if the message is from a//   control. If the message is from an accelerator, this parameter is 1. If//   the message is from a menu, this parameter is 0. // LOWORD(wParam) specifies the identifier of the menu item, control, or//   accelerator.// lParam specifies a handle to the control sending the message if the message is//   from a control. Otherwise, this parameter is NULL. static_cast<YourDerivedAppClass *>(app)->m_Game.DispatchCommandMsg(LOWORD(wParam), HIWORD(wParam));// An application should return zero if it processes this message. return 0;}The code above is taken from a Windows Mobile 6 application, so its nearly identical to equivalent desktop code. Off the top of my head, your window creation may be a bit different, and you'll want to use SetWindowLongPtr/GetWindowLongPtr instead of SetWindowLong/GetWindowLong because those functions are deprecated on Vista, Win2k/XP and possibly even further back.[Edited by - ravyne2001 on September 6, 2007 2:14:59 PM];  Wow thanks that seems like a much better way to do it   ;Quote:Original post by ravyne2001The way I work around that is to pass a pointer to my application class as the extra parameter of the CreateWindow() function. Then, when you process the WM_CREATE message you can retrieve that pointer and then store it in the USERDATA area of the Window. When you receive other messages (anything other than WM_CREATE, and maybe a few others not related to a window) you retrieve the pointer and pass that to your Hooks (I call them EventHandlers), along with the message type, wParam and lParam.I do something similar, but my EventHandlers look different, and my code is structured differently://eventhandler.hpptemplate<class WINDOW>class WindowEventHandler{    public:   typedef LRESULT (WINDOW::*handler_function)(WPARAM, LPARAM);   WindowEventHandler(WINDOW* wnd, handler_function func)  : _wnd(wnd), _func(func)   { }   virtual LRESULT operator() (WPARAM wParam, LPARAM lParam)   {  return ((_wnd->*_func)(wParam, lParam));   }    private:   WINDOW*_wnd;   handler_function _func;};//window.cpp//only relevant bits posted ;)//all windows inherit from this base class// I define a function OnEvent(WPARAM, LPARAM) for each event I want to handle// as private methods of a derived window class.// Then when initializeing the window, I use this function to register them.template<class WND> void Window::AddEventHandler(UINT msg, typename WindowEventHandler<WND>::handler_function func, WND* w){    WindowEventHandler<WND>*weh = new WindowEventHandler<WND>(w, func);    _event_registry[msg] = weh;}//Window::Procedure is declared static in the HPP fileLRESULT CALLBACK Window::Procedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){    Window* p_wnd;    //capture the pointer to the class and save it in a member variable for later use    if(msg == WM_NCCREATE)    {   p_wnd = reinterpret_cast<Window*>(reinterpret_cast<LPCREATESTRUCT>(lParam)->lpCreateParams);   p_wnd->_hwnd = hwnd;   SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<long>(p_wnd));    }    //get the pointer to the window's instance    p_wnd = reinterpret_cast<Window*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));    if(!p_wnd)   return false;    //search for a handler for the event,    //and call it if it exists    EventHandler* eh = p_wnd->GetHandler(msg);    if(eh)    {   return (*eh)(wParam, lParam);    }    //no handler is registered for the event,    return DefWindowProc(hwnd, msg, wParam, lParam);}I should note that this is far from original work. It is a synthesis of two or three articles I've reaad, plus some help form the GD.net forum.   ;  Originally, I had all my WndProc stuff as part of the Window class as well. However, what I discovered is that Windows Messages would often necessitate that the application perform some logic in response, such as when the window is resized or an input message is recieved, which would require that the Window class keep a pointer to the Application Class.Now personally, it seems more logical to me that the application should own both the Window and the WndProc, rather than the Window owning The application and the WndProc. Unfortunately, in part due to its event-driven, GUI focused nature, the Windows OS feels a bit inside-out because much of the interaction comes in the form of messages -- it feels almost as if it makes sense to have the Window/WndProc be the outside of your application; except that it doesn't [grin]Have you encountered the issue I noted above? How did you work around it?   