WindowProc and window class registration issue
-
Hi, I'm having a DLL that exports a class. Each instance of this class should be able to create its own window. Therefore I created a WindowProc class member to process messages to the created window. While trying to register a window class for my class I tried to configure the message processing by filling the lpfnWndProc field of WNDCLASSEX structure with a pointer to WindowProc. I couldn't get this to compile if the WindowProc function is not *static*. This is not acceptable because this means all instances of my class share the same WindowProc so I don't know which instance should process the messages. What is the appropriate design to do what I want ? Thanks
-
Hi, I'm having a DLL that exports a class. Each instance of this class should be able to create its own window. Therefore I created a WindowProc class member to process messages to the created window. While trying to register a window class for my class I tried to configure the message processing by filling the lpfnWndProc field of WNDCLASSEX structure with a pointer to WindowProc. I couldn't get this to compile if the WindowProc function is not *static*. This is not acceptable because this means all instances of my class share the same WindowProc so I don't know which instance should process the messages. What is the appropriate design to do what I want ? Thanks
This is because the functions don't have the same prototype: for the member function, there is a implicit parameter passed, the this parameter (allowing the function to know to which instance it belongs to). To overcome this problem, when you create your window (use CreateWindow), you can pass a pointer to user data. Pass the this parameter, so that the first time your static window procedure gets called, it will receive the instance of the class. Then, register this pointer with SetWindowLong (it will associate the instance pointer with the handle of the window):
if (Msg == WM_CREATE) SetWindowLong(hWnd, GWL_USERDATA,(long) ( (LPCREATESTRUCT(lParam))->lpCreateParams));
Then, after each call of your static procedure, you are able to retrieve the class instance and call a public non-static window procedure:CMyClass* pClass = (CMyClass*)GetWindowLong(hWnd,GWL_USERDATA);
hWnd is the handle of the window passed as parameter to the procedure. Check the different functions in the doc for more details. Hope this helps
Cédric Moonen Software developer
Charting control [v1.1] -
This is because the functions don't have the same prototype: for the member function, there is a implicit parameter passed, the this parameter (allowing the function to know to which instance it belongs to). To overcome this problem, when you create your window (use CreateWindow), you can pass a pointer to user data. Pass the this parameter, so that the first time your static window procedure gets called, it will receive the instance of the class. Then, register this pointer with SetWindowLong (it will associate the instance pointer with the handle of the window):
if (Msg == WM_CREATE) SetWindowLong(hWnd, GWL_USERDATA,(long) ( (LPCREATESTRUCT(lParam))->lpCreateParams));
Then, after each call of your static procedure, you are able to retrieve the class instance and call a public non-static window procedure:CMyClass* pClass = (CMyClass*)GetWindowLong(hWnd,GWL_USERDATA);
hWnd is the handle of the window passed as parameter to the procedure. Check the different functions in the doc for more details. Hope this helps
Cédric Moonen Software developer
Charting control [v1.1]Thanks, This solves my problem. I might be using a "std::map" instead to find the class instance knowing the hwnd but the idea is the same. I mostly wanted to check that it's not a bad design have the same WindowProc for all my instances and therefore have to lookup the class instance everytime.
-
Thanks, This solves my problem. I might be using a "std::map" instead to find the class instance knowing the hwnd but the idea is the same. I mostly wanted to check that it's not a bad design have the same WindowProc for all my instances and therefore have to lookup the class instance everytime.
Tnarol wrote:
I might be using a "std::map" instead
You'll have to make it static so that all instances share the same map than.
Cédric Moonen Software developer
Charting control [v1.1] -
Tnarol wrote:
I might be using a "std::map" instead
You'll have to make it static so that all instances share the same map than.
Cédric Moonen Software developer
Charting control [v1.1]