Skip to main content
GameDev.net gamedev.net
🔒 Locked

Getting a pointer to a function from a class

Started by NorthWoodsman Jun 18, 2002 at 2:14 AM 9 replies 500+ views
Original Post
NorthWoodsman
NorthWoodsman
I have a class named OpenGLMgr, and it has a member WndProc that I want to use as a window handler. However, when I try to put the pointer to the function in WNDCLASS, it gives me a type-conversion error. Here''s the code: class OpenGLMgr { // Other stuff in here ... protected: // Internal Functions void oglmCreateWindow(void); LRESULT CALLBACK oglmWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); }; void OpenGLMgr::oglmCreateWindow(void) { // Other stuff... wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wc.lpfnWndProc = (WNDPROC)(this->oglmWndProc); wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = m_hInstance; } C:\GLTest\OpenGLMgr.cpp(81) : error C2440: ''type cast'' : cannot convert from '''' to ''long (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long)''
NorthWoodsman
NorthWoodsman
That''s precisely the situation I am trying to avoid. It breaks OO, and it also requires me to have a global class, which is a very unelegant solution, and one I''d prefer to avoid.
invective
invective
Looks like you have the dreaded pointer to member function problem. Basically, non static member functions have an implicit this parameter, so they aren''t really of the same type as another funtion with the same return value and parameter types. Use a static member function.
nomore_pf
nomore_pf
Look also at http://www.function-pointer.org/. There you can find lots of information about function pointers... both C and C++
www.polyfrag.com
abdulla
abdulla
There are more covuluted solutions about passing the this parametere in GWL_USERDATA (is that right? haven''t used windows in a while), but OO isn''t the best for everything, you don''t have to force yourself to use it, what difference will it make either way? Are you really going to use OO flexibility for wndproc anyway? Is it really worth the effort and will the end solution be graceful?
IndirectX
IndirectX
You can also check out some stuff on CBT hooks I posted here.

[edited by - IndirectX on June 18, 2002 9:11:09 AM]
---visit #directxdev on afternet <- not just for directx, despite the name
Qw3r7yU10p!
Qw3r7yU10p!
shouldn''t the line

wc.lpfnWndProc = (WNDPROC)(this->oglmWndProc);

use OpenGLMgr::oglmWndProc instead of this->oglmWndProc

the member function has to be static but i don''t know what windows CALLBACK macro does.
hammerstein_02
hammerstein_02
Making the windowproc static does allow the program to compile, yet to test, but I also use:

cInterface::WindowProc

Thanks for this posting, appropriate timing

[edited by - hammerstein_02 on June 18, 2002 10:02:08 AM]
IndirectX
IndirectX
quote:
wc.lpfnWndProc = (WNDPROC)(this->oglmWndProc);

Don''t cast function pointers unless you really really really know what you''re doing. If you do, don''t be surprised if you get random crashes and messages about stack corruption.

First, oglmWndProc must be either static member or out-of-class function. You can **NOT** give Windows a non-static member function as WndProc, at all. Remember this.

You might want to search the forums. This questions is asked very often. Once we had a large discussion in which many ways to solve this problem were presented. Or you can just wait for me to dig it out, if you''re lazy.
---visit #directxdev on afternet <- not just for directx, despite the name
IndirectX
IndirectX
As I said, you can''t have WndProc as a non-static member function. Probably the easiest solution is to use WM_CREATE or WM_NCCREATE and the last parameter of CreateWindow/CreateWindowEx to store "this" pointer in the per-window data, as outlined here. The problem with that method is that WM_NCCREATE isn''t the first message that your WndProc gets. this thread presents a "hack" to work around this inconvenience. Another way is to use a handle-to-object map, as described here. There has been a thread describing an implementation via global atoms (GlobalAddAtom and the such), but I can''t find it through the search, ah well. Magmai Kai Holmlor posted some stuff on observer pattern here, although it''s too complicated for me to understand. The way MFC handles member WndProcs and subclassing is through CBT hooks, about which you can read here. I don''t know how ATL handles WndProcs, didn''t get around to its source yet. You can find loads of other threads on this subject, but be careful what you believe. Many people just call SetWindowLong after CreateWindow, thus their member WndProc doesn''t get WM_CREATE at all. To me, CBT hooks offer the cleanest and safest solution, as they don''t rely on the order in which Windows messages are received at all and don''t make WndProc to take care of setting this pointer.
---visit #directxdev on afternet <- not just for directx, despite the name

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.