Pls Can u explain me how this code works?

Started by
3 comments, last by EvilNando 19 years, 9 months ago
Hello ive been doing my directx tutorials and im stuck trying to figure out how the window framework is done here the part i dont get: first it is CMyApplication class wich is base for CGame class now the tricky part is that in both clases is defined this function: virtual LRESULT WINAPI MessageProcedure(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam); now since the function is virtual from what i know the compiler will dynamically compile that function if its found on the derived class but look CMyApplication

#include "MyApplication.h"

// First part I dont get //

// This header is so we can assign this message handler to the WNDCLASSEX structure
LRESULT WINAPI MainMessageProcedure(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam);

// The class continues.... 

LRESULT WINAPI CMyApplication::MessageProcedure(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
    // iMsg is what is going to have all our messages.
    switch(iMsg) 
	{
        // Check to see if it is a WM_ACTIVATE message
        // WM_ACTIVATE is invoked when the application
        // is either deactivated, or activated. ie: when
        // a user clicks outside our window.
	case WM_ACTIVATE:
		switch(wParam)
		{
		case WA_ACTIVE:         // The application was activated somehow, so Activate

            // When you are activating your app, set m_bActive = TRUE
            // so that rendering will start again.
            
            // Make the application active.
            m_bActive = TRUE;

			break;
		case WA_CLICKACTIVE:    // The app was activated by someone clicking in it. Activate.
			
            // Make the application active.
            m_bActive = TRUE;

			break;
		case WA_INACTIVE:       // The application has lost focus. de-activate everything

            // Deactivate the application
            m_bActive = FALSE;
            
			break;
		}
		return 0;
		break;

        // WM_DESTROY is invoked when the window is being destroyed
        // also take note that if you have any child windows
        // then they will get this message *AFTER* the parent window.
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
		break;

        // For when the size of our window changes ... namely
        // maximized, minimized, or restored.
	case WM_SIZE:
		switch(wParam)
		{
		case SIZE_MINIMIZED:    // The window was minimized. Stop stuff (de-activate)

            m_bActive = FALSE;
			break;
		case SIZE_RESTORED:     // Window restored, so activate
			m_bActive = TRUE;
			break;
		case SIZE_MAXIMIZED:    // Window was maximized, so activate
			m_bActive = TRUE;
			break;
		}
		return 0;
		break;

        // This is for when a key is pressed.
        // You can also check WM_KEYUP for when a key is released
        // or WM_CHAR for when a key is pressed AND released
	case WM_KEYDOWN:
		switch(wParam)
		{
		case VK_ESCAPE:             // user pressed escape. Exit application
                                    // You can acomplish the same thing by seeting
                                    // m_bAlive to FALSE.
			PostQuitMessage(0);
			break;
		case VK_PAUSE:              // User pressed pause button. If the app was paused
                                    // then unpause it, and vice-versa.

            // Switch the values, so if m_bPaused was TRUE
            // it will switch to FALSE after negating it
			m_bPaused = !m_bPaused;

            break;
		}
		return 0;
		break;

        // Send all the rest of the messages to the 
        // default message handler. Since we cant handle every
        // single message that could be produced, we send
        // all the unwanted messages to DefWindowProc, and
        // let windows do whatever it wants to with them.
	default: return DefWindowProc(hWnd, iMsg, wParam, lParam);
	}
}

now the base class message procedures is in charge of handling the key inputs (namely Esc button) and minimize buttons amongs other things but.. since its virtual its never called but.. surprise ... the application does respond to esc key presses CGame.h

class CGame : public CMyApplication
{
public:
	CGame();
	~CGame();

    // These are all the virtual functions in the base class.
    LRESULT WINAPI MessageProcedure(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam);

    BOOL FirstInitialize();
    BOOL FinalCleanup();
    BOOL PreRender();
    BOOL Render();

private:


};
CGame.cpp

LRESULT WINAPI CGame::MessageProcedure(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
    // Dont forget to pass the messages to our base class
    // message handler so that all the default messages 
    // are handled along with our apps official messages.
    return CMyApplication::MessageProcedure(hWnd, iMsg, wParam, lParam);
}
the Application entry point

/* .. continued .. */
LRESULT WINAPI MainMessageProcedure(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
    return g_pGame->MessageProcedure(hWnd, iMsg, wParam, lParam);
}

/* .. continues .. */ 
sorry for making this too long but if looked everywhere and cant figure this out thanks! ;)
Advertisement
post the code for MyApplication.h.
here it is
#include <windows.h>class CMyApplication  {public:	CMyApplication();	virtual ~CMyApplication();    void Run();    virtual LRESULT WINAPI MessageProcedure(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam);protected:    // This function creates a window    BOOL InitializeWindow(int iWidth, int iHeight, BOOL bWindowed);    // The game-loop is where our app stays until it's terminated    void MyGameLoop();    virtual BOOL FirstInitialize() { return TRUE; }     // Called at the beginning    virtual BOOL FinalCleanup() { return TRUE; }        // Called at the end    virtual BOOL PreRender() { return TRUE; }           // Called before rendering    virtual BOOL Render() { return TRUE; }              // Called after rendering        HWND m_hWnd;            // The handle to our window    BOOL m_bPaused;         // If the application is paused or not    BOOL m_bActive;         // If the application is in an active state or not    BOOL m_bAlive;          // If the appliaction is alive or not    BOOL m_bWindowed;       // Is the application windowed or fullscreen    UINT m_iWndWidth;       // Windowed width    UINT m_iWndHeight;      // Windowed height    char m_strTitle[128];   // Our applications title    char m_strClass[128];   // Our applications unique class name};#endif // !defined(AFX_MYAPPLICATION_H__143B0E6B_546C_4B77_BF3C_4B5797349D77__INCLUDED_)
I hope I got this right, you are asking why it still handles the ESC key?

Because the base class message handler is called in CGame::MessageProcedure by the line
'return CMyApplication::MessageProcedure(hWnd, iMsg, wParam, lParam);'
.

ahhh ok
i never new such a thing was possible with the scope resolution
i thought that function since its virtual its dead for the new class

now what i dont get is that if the derived class calls the base class message procedure how the derived message procedure also gets called?

thanks a lot

This topic is closed to new replies.

Advertisement