Jump to content
  • Advertisement

Archived

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

rgk_quaker

Why a static WindowProc function ?

This topic is 5319 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

Hello, This is a Window FrameWork program from "Game Programming All in One" book by de sousa i am confused that why he uses 'WndProc' as a static function thanks in advance here are the header ,implementation and example which uses this framework
================================================================

/* 'mrWindows.h' */

 /* Mirus base types header */
#include "mrDatatypes.h"
/* Windows header file */
#include <windows.h> 

 /* Include this file only once */
#pragma once

 /* Mirus window framework */
class mrWindow
{
protected:
 WNDCLASS  m_kWndClass;
 HWND      m_hWindow;
 MSG       m_kMessage;

public:
	/* Constructor / Destructor */
 mrWindow (void);
 ~mrWindow (void);

  /* Window manipulation functions */
 mrError32 Create (HINSTANCE hInstance, LPSTR szTitle, 
                   mrInt iWidth = CW_USEDEFAULT, 
                   mrInt iHeight = CW_USEDEFAULT, 
                   mrUInt32 iStyle = WS_OVERLAPPEDWINDOW | WS_VISIBLE);
 static LRESULT CALLBACK WndProc (HWND hWindow, UINT iMessage, 
                         WPARAM wParam, LPARAM lParam);
 void Run (void);

  /* Custom functions */
 virtual mrBool32 MessageHandler (UINT iMessage, WPARAM wParam, 
                                  LPARAM lParam);
 virtual mrBool32 Frame (void) = 0;

  /* More functions */
 void SetPosition (mrInt iWidth, mrInt iHeight);
 POINT GetPosition (void);
 void SetSize (mrInt iWidth, mrInt iHeight);
 POINT GetSize (void);
 void Show (mrInt iShow);
};

======================================================= 

/* 'mrWindows.cpp' */

 /* Complement header file */
#include "mrWindow.h"

 /* Default constructor */
mrWindow::mrWindow (void)
{
 /* Do nothing */
}

 /* Default destructor */
mrWindow::~mrWindow (void)
{
 /* Do nothing */
}

 /* Create the window */
mrError32 mrWindow::Create (HINSTANCE hInstance, LPSTR szTitle, mrInt iWidth, 
                            mrInt iHeight, mrUInt32 iStyle)
{
  /* 'Visual' proprieties */
 m_kWndClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
 m_kWndClass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
 m_kWndClass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);

  /* System proprieties */
 m_kWndClass.hInstance     = hInstance;
 m_kWndClass.lpfnWndProc   = WndProc;
 m_kWndClass.lpszClassName = "Mirus Window";

  /* Extra proprieties */
 m_kWndClass.lpszMenuName  = NULL;

 m_kWndClass.cbClsExtra = NULL;
 m_kWndClass.cbWndExtra = NULL;
 m_kWndClass.style      = NULL;

  /* Try to register class */
 if (!RegisterClass (&m_kWndClass))
 {
  return mrErrorRegisterClass;
 }

  /* Create the window */
 m_hWindow = CreateWindow ("Mirus Window", szTitle, iStyle, CW_USEDEFAULT,
                           CW_USEDEFAULT, iWidth, iHeight, 
                           NULL, NULL, hInstance, (void *) this);
 SetWindowText (m_hWindow, szTitle);

 return mrNoError;
}

 /* Normal message handler - direct messages to our own*/
LRESULT CALLBACK mrWindow::WndProc (HWND hWindow, UINT iMessage, 
                                    WPARAM wParam, LPARAM lParam)
{
 mrWindow * pkWindow   = NULL;
 mrBool32   bProcessed = mrFalse;

 switch (iMessage)
 {
  /* Window is creating - set custom information */
 case WM_NCCREATE:
  SetWindowLong (hWindow, GWL_USERDATA, 
                 (long)((LPCREATESTRUCT(lParam))->lpCreateParams));
  break;
  /* Window message - Let our handler process it */
 default:
   pkWindow = (mrWindow *) GetWindowLong (hWindow, GWL_USERDATA);
   if (NULL != pkWindow)
   {
    bProcessed = pkWindow->MessageHandler (iMessage, wParam, lParam);
   }
  break;
 }
   /* Message not processed - let windows handle it */
 if (mrFalse == bProcessed)
 {
  return DefWindowProc (hWindow, iMessage, wParam, lParam);
 }
 return 0;
}

 /* Real time message loop */
void mrWindow::Run (void)
{
 while (1)
 {
   /* Query to see if there is any message in the queue */
  if (PeekMessage (&m_kMessage, m_hWindow, 0, 0, PM_REMOVE))
  {
    /* If it is the WM_QUIT message, quit the loop */
   if (WM_QUIT == m_kMessage.message)
   {
    break;
   }
    /* Process the message normally */
   else
   {
    TranslateMessage (&m_kMessage);
    DispatchMessage (&m_kMessage);
   }
  }
    /* No message, do frame */
  else
  {
   Frame ();
  }
 }
}

 /* Our message handler */
mrBool32 mrWindow::MessageHandler (UINT iMessage, WPARAM wParam, 
                                   LPARAM lParam)
{
 switch (iMessage)
 {
  /* Close window */
 case WM_CLOSE:
  PostQuitMessage (0);
  return mrTrue;
 break;
  /* Not handled - let Windows handle */
 default:
  return mrFalse;
 break;
 }
}


void mrWindow::SetPosition (mrInt iX, mrInt iY)
{
  /* Set window position */
 SetWindowPos(m_hWindow, HWND_TOP, iX, iY, 0, 0, SWP_NOSIZE);
}


POINT mrWindow::GetPosition (void)
{
 RECT  rcWindow;
 POINT pPosition;
  /* Get window position */
 GetWindowRect (m_hWindow, &rcWindow);

 pPosition.x = rcWindow.left;
 pPosition.y = rcWindow.top;
 
 return pPosition;
}


void mrWindow::SetSize (mrInt iWidth, mrInt iHeight)
{
  /* Set window position */
 SetWindowPos(m_hWindow, HWND_TOP, 0, 0, iWidth, iHeight, SWP_NOMOVE);
}


POINT mrWindow::GetSize (void)
{
 RECT  rcWindow;
 POINT pSize;
  /* Get window position */
 GetWindowRect (m_hWindow, &rcWindow);

 pSize.x = rcWindow.right  - rcWindow.left;
 pSize.y = rcWindow.bottom - rcWindow.top;
 
 return pSize;
}


void mrWindow::Show (mrInt iShow)
{
  /* Change window visibility */
 ShowWindow (m_hWindow, iShow);
}

================================================================

  /* '04 Main.h' */

 /* Mirus window framework header */
#include "mrWindow.h"

 /* Custom derived class */
class CustomWindow : public mrWindow
{
public:
  /* Constructor / Destructor */
 CustomWindow (void) {};
 ~CustomWindow (void) {};

  /* Window manipulation functions */
 mrBool32 Frame (void) {return mrTrue;} ;
};

 /* "WinMain Vs. main" */
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInst, 
                    LPSTR lpCmdLine, int nShowCmd)
{
  /* Our window */
 CustomWindow		kWindow;

  /* Create window */
 kWindow.Create (hInstance, "04 Mirus Example");
	/* Enter message loop */
 kWindow.Run ();

	return 0;
}

======================================================================
[edited by - rgk_quaker on February 27, 2004 1:20:00 AM] [edited by - rgk_quaker on February 27, 2004 1:20:56 AM]

Share this post


Link to post
Share on other sites
Advertisement
Because it''s cleaner to make any symbol that doesn''t need to be linkage visible outside the translation unit, static. That what it''s for.

Share this post


Link to post
Share on other sites
static functions aren''t __thiscall allowing them to be used where other calling conventions (like __stdcall [CALLBACK] in this case).


Thanks Salsa!Colin Jeanne | Invader''s Realm
"I forgot I had the Scroll Lock key until a few weeks ago when some asshole program used it. It even used it right" - Conner McCloud

Share this post


Link to post
Share on other sites
A method of a class passes the "this" pointer as a parameter when it is called. That is how it "knows" about the data members of the object.

Windows API is in C so it dosent supprt _thiscall ( the calling convention used for methods of objects in C++ )

When you make a method static you tell it not to pass the this pointer so it wont know how the variables in that object have changed. A static method can only access static variables, while a regular method can access bot static and non static variables.


class A
{
public:
A( void ) : i( int()) {};
void Amethod( void )
{
i++;
}
int i;
};


A AnOjectofA;

When you call
AnOjectofA.Amethod()

it actually is more like:
AnOjectofA.Amethod( &AnOjectofA )

&AnOjectofA is the this pointer.

If Amethod was declared static then the this pointer would not have been passed so it would be like:
AnOjectofA.Amethod()

Also since it did not get the this pointer it couldnot increment i. You would get a compiler error.

Win32 has several calling conventions, I can rember _stdcall and _fastcall but I think they are others. A calling convention tells the compiler how the parameters are passed to the function. Sometimes the parameters are passed from left to right and sometimes from right to left. If I rember correctly _fastcall useses the registers to store parameters.

Win32 is in C and C does not have the _thiscall calling convention because C dosent have classes.

hope this helps

[edited by - try_catch_this on February 27, 2004 1:56:53 AM]

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!