Advertisement

WndProc in Class

Started by May 03, 2001 10:39 AM
8 comments, last by Spartacus 23 years, 9 months ago
Hi! I have created a class like this:

class CApplication
{
private:
    ...

    LRESULT WINAPI MainWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)

public:
    ...
    CreateWindow(...);
}

CApplication::CreateWindow(...)
{
WNDCLASS wc;

wc.lpfnWndProc = this->MainWindowProc;
...
}
 
My problem is that the line where i assign wc.lpfnWndProc the address of CApplication::MainWindowProc gives a compiler error. It tells me that there is no acceptable conversion. Why isn''t this possible? Isn''t it possible to return the address of a class member function or what??? -Thanks

Real programmers don't document, if it was hard to write it should be hard to understand

Callback functions cannot be regular class member functions.
Try making MainWindowProc() a static member function.
When using the Windows calculator program, always remember to clear any values from memory before exiting to prevent burn-in.
Advertisement
I think you got a design flaw here...
shouldn''t CApplication be a singleton?
The types are incompatible. A pointer to a class member function (be it static or non-static) has a different type than a ''regular'' function.

If the WndProc function has to access class internals, make it a friend of the class.
callback functions cannot be in class
maybe because they use the register that has this pointer(ecx)
i have no other idea why
and maybe the OS doesn''t like a function that is called alot of times to be in a vtable .....

go figure

Arkon
[QSoft Systems]
Yes CApplication probably should be a singleton. Actually i dont really know what a singleton is , but i guess it is a class that i can only create one instance of.Am i right? So how do i make a class a singleton?

But i still have problems with the window procedure. I can declare the MainWindowProc() function as a friend to CApplication but how can the function then access the member data? I need it to access the member m_Active but i cant write something like this->m_Active. And i cant pass a pointer to the class instance as a parameter because MainWindowProc() is the window procedure. I hope someone can help me!

- Thanks

Real programmers don't document, if it was hard to write it should be hard to understand

Advertisement
Class methods have a hidden parameter, the ''this'' pointer. So to the compiler, your window proc looks like this:
LRESULT WINAPI MainWindowProc( CApplication* this, HWND, UINT, WPARAM, LPARAM );
This is what it cannot convert.

Take a look at Microsoft Knowledge base articles Q102352, Q130866. They are available online.
Also, a search on Google (formerly Deja News) for "C++ callback" returns a plethora of information on this topic.
When using the Windows calculator program, always remember to clear any values from memory before exiting to prevent burn-in.
the wndproc has a predefined prototype, it''s a callback function, so you don''t get to choose the arguments it takes,

the problem is that in C++ all members functions get an invisible first argument, the ''this'' pointer, that refers to the object the method belongs to

you can work around this by making the wndproc a ''static'' member function, this means that it''s a class function, it isn''t associated with an object, so the this pointer isn''t needed, you can call it by just using the classname, without an object

there are some problems with this approach, the most important one is that you cannot access any object specific data or methods anymore, you can only call other static methods or variables, so you''ll have to find a way to pass this info to the windowproc,

usually this is done by passing the ''this'' pointer as the last argument in CreateWindow(), then in your windowproc, intercept WM_CREATE (or WM_NCCREATE) and retrieve the CREATESTRUCT* in the lParam, the lpCreateParams in the CREATESTRUCT holds the ''this'' pointer you sent with CreateWindow(),

in addition, every window has some extra bytes that you can use to store some custom data, you can set this data by using SetWindowLong(GWL_USERDATA , data)

use this space to store the ''this'' pointer you retrieved in WM_CREATE, now every time you need some object specific data, or method, use GetWindowLong(GWL_USERDATA) to get your ''this'' pointer and you can use that to access your methods/data

however since your class is a singleton there isn''t really a problem here, since you only have one object

hope all of this means anything to you, if not, go check out the win32 tutorials at www.relisoft.com
Thanks to all of you!!! Now i have solved my problems. I never thought it would be that complicated . But now it works . Thanks!

-René

Real programmers don't document, if it was hard to write it should be hard to understand

This topic is closed to new replies.

Advertisement