Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

farmersckn

Event Handlers and Classes. Wrappers and stuff.

This topic is 6544 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I''m writing my own game library, and I''m trying to make a wrapper for window handling, like CWnd, but i don''t know how to stick a WindowProc inside of a class. i tried to, but when i tried to assign it to the lpfnWndProc member of the WNDCLASS, the compiler said there was a conflict between the two. Does anyone have an idea? I know it''s possible that i could just write a seperate (non-class) event handler, and when i register the class just use that, and have it call (class) functions. so, instead of : class name { constructor/destructor... other methods... LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); }; i would do this: class name { constructor/destructor... other methods... }; LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); and in the registration method, i would assign the non-class-method WndProc, and have it call an Message Handling method, like NameOfClass::OnDestroy ()... whatever. i just don''t wanna do it that way, but i don''t have any other ideas... plz help if you can. tnx. Sometimes even chickens need to eat... Don't bang your head against a wall just to enjoy the good feeling when you stop.

Share this post


Link to post
Share on other sites
Advertisement
You can''t use a member function as a callback to Windows API functions . I tried a lot, but I wasn''t able to get it to work. It does only work by using a pointer to a global function or to a static function (At least I found no other way to get it to work).

ArgoN

Share this post


Link to post
Share on other sites
so do i have to make the member function static? or can you even do that? or are you saying it must be a stand-alone function? thanks


Sometimes even chickens need to eat... Don't bang your head against a wall just to enjoy the good feeling when you stop.

Share this post


Link to post
Share on other sites
I think a static member function would probably work. The reason a regular one won''t is because they always implicitly pass the ''this'' pointer as a parameter, which means the function signature isn''t the same as what the callback is looking for. Static member functions, however, do not pass a ''this'' pointer, so if you make one with the correct parameters, it should probably work as a callback.

I hope this was clear!

Share this post


Link to post
Share on other sites
Static would allow it to compile, however, it would also make ensure that you only operated on static members of the class within that class. Play with it so that you can learn about it, but I think for what you are trying to do, you''ll introduce more problems than you take care given you current plan of attack.

Share this post


Link to post
Share on other sites
Try declaring the function in the class as a friend, ie:

friend LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

I believe that will allow you to use it in the class, but I''m not positive.

Share this post


Link to post
Share on other sites
You need to declare a wndproc in your class that is static, and has "C" calling conventions. To get the ''this'' pointer for your window, use SetWindowLong(wnd,this) in your creation routine. In the event handler, use GetWindowLong(wnd) to retrieve the stored ''this'' pointer. Cast it to your window class and then redirect to the actual wndfunc.

Hope this helps.

-- Pryankster
(Check out my game, a work in progress: DigiBot)

Share this post


Link to post
Share on other sites
It's kind of tricky to get it working properly...I'll post the static function that I wrote so you can see how it works:

        
LRESULT CALLBACK Window:: Procedure(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
Window* pWindow = NULL;

if( nMsg == WM_CREATE )
{
// Extract the window pointer parameter.

CREATESTRUCT* pCS = (CREATESTRUCT*) lParam;
pWindow = (Window*) pCS->lpCreateParams;

// if we created it

if( pWindow )
{
// Save it in the window handle.

SetWindowLong(hWnd, GWL_USERDATA, (LONG) pWindow);

// Store the window handle in the object.

pWindow->m_hWnd = hWnd;
}
}
else
{
// Extract the object from the window handle.

pWindow = (Window*) GetWindowLong(hWnd, GWL_USERDATA);
}

if( pWindow )
{
// Set the object's message and parameters.

pWindow->m_nMsg = nMsg;
pWindow->m_wParam = wParam;
pWindow->m_lParam = lParam;

// Let the object handle it.

return pWindow->OnMessage();
}
else
{
// Just do the default if the window is not created yet.

return DefWindowProc(hWnd, nMsg, wParam, lParam);
}
}
[/source]


If you are baffled, here is a portion of the Window.hpp file that goes along with the previous code snippet:

[source]
public:
// Interface functions

static LRESULT CALLBACK Procedure(HWND, UINT, WPARAM, LPARAM);

protected:
// Helper functions

virtual LRESULT OnMessage();
virtual LRESULT Default();

protected:
// Data members

HWND m_hWnd;
UINT m_nMsg;
WPARAM m_wParam;
LPARAM m_lParam;




It's a lot to understand (a lot of fixes/hacks) but it works...let me know if you don't understand parts of it or if I'm just going mad.

Good Luck!


(for some reason the board won't do multiple source code snippets...)




- null_pointer
Sabre Multimedia


Edited by - null_pointer on June 23, 2000 8:18:49 AM

Share this post


Link to post
Share on other sites
Sometime in the past 4 months I read a really good article in C/C++ Users Journal (download the code at www.cuj.com) about Object Oriented State Machines. The article did a great job at explaining the syntax for pointers to member functions (it did a good job because the syntax was a little bizar and obscure at first).

                
SYNTAX:
decl-specifiers class-name :: * cv-qualifier-listopt dname ;

// For example

typedef static LRESULT (CMyWindow::* __stdcall) LPWINPROC( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam );
// Uh-Oh. Maybe I got it wrong.

// Don't flame me yet, wait until after I go check my old code.


More recently I found an article in MSDN that explained how to use the CWindow and CWindowImpl classes in the Active Template Library without using the app wizard to create a COM Server project. I have been using my CWindowImpl derivative as my the main window in my own DirectX projects ever since! Everything is encapsulated so there is far less code for me to write and ATL gives you all the window functionallity you need.

According to the MSDN documentation C++ templates such as the ones in ATL are very light weight (very little overhead compared to the CWnd derivatives in MFC). When compiled, they are just as if you had used straight Functional Oriented Win32 API without any Object encapsulation (I have also been trying to put my CDialogImpl derivatives on top of the full screen DirectDraw primary surface with full screen 3D animation and continuous game play going on in the backgound -- I'm so lazy I want Microsoft to do all the work for me)!


Edited by - Marsupial Rodentia on June 23, 2000 1:40:20 PM

Edited by - Marsupial Rodentia on June 23, 2000 1:43:44 PM

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!