Hi, I just wanted to post this here (I hope this is the right topic).
Anyway, I found that sometimes working with Win32 can be a little bit (a bunch!!) like annoying. So I tried to make my own class that managed the main windows things for a game, nothing to "Extravagant".
I hope somebody can find it useful, I know I would have some week ago :). So you can use it freely, and don't have to give credit if you don't want to.
So here it goes:
//////////////////////////////////////////////////////////////////////////////////////////
// Date: 21/08/2006 //
// Header file for managing most used Windows functions and aplications. //
// Version : WIN 2.5 //
//////////////////////////////////////////////////////////////////////////////////////////
// DEFINES ///////////////////////////////////////////////////////////////////////////////
#ifndef GUARD_WINCLASS_H // This is for guarding that the header file will not be
#define GUARD_WINCLASS_H // loaded more than once.
#ifndef WIN32_LEAN_AND_MEAN // This is for only including most used Windows functions
#define WIN32_LEAN_AND_MEAN
#endif
#define WINCLASS_VERSION 0x19 // The version number of the class
// MACROS ////////////////////////////////////////////////////////////////////////////////
#define KeyState(vk) ((GetAsyncKeyState(vk) & 0x8000) ? TRUE : FALSE)
// INCLUDES //////////////////////////////////////////////////////////////////////////////
#include <Windows.h> // Main Windows header file
class WINCLASS{
public:
// PUBLIC METHODS ////////////////////////////////////////////////////////////////////////
// Puts all the variables to zero values
WINCLASS();
// Calls the Release() method
~WINCLASS();
// Initializes the class
BOOL Initialize(BOOL bWindowed,
CONST CHAR* ClassName,
CONST CHAR* WinTitle = "Default Window",
UINT window_width = 800,
UINT window_height = 600,
HINSTANCE hInstance = GetModuleHandle(NULL),
LRESULT CALLBACK MessageHandler(HWND, UINT, WPARAM, LPARAM) = MsgHandler);
// Releases the class
MSG Release();
// Handles a single message
BOOL HandleMsg();
// Returns TRUE if the class is active
inline BOOL Active();
// Changes the show mode of the window. (SW_MINIMIZE, SW_MAXIMIZE...)
void WindowShow(INT Show);
// GET- FUNCTIONS ////////////////////////////////////////////////////////////////////////
// Returns the handler for the window
HWND GetWindow();
// Returns a copy of the last Msg struct
MSG GetMsg() const;
// Returns the X position of the window on the desktop
UINT GetXPos() const;
// Returns the Y position of the window on the desktop
UINT GetYPos() const;
// Returns the X size of the window
UINT GetXSize() const;
// Returns the Y size of the window
UINT GetYSize() const;
// Returns the state of the window focus
BOOL GetFocus() const;
// OTHER /////////////////////////////////////////////////////////////////////////////////
// Default MsgHandler for the class
friend LRESULT CALLBACK MsgHandler(HWND hWindow, UINT Msg,
WPARAM wParam, LPARAM lParam);
private:
// PRIVATE METHODS ///////////////////////////////////////////////////////////////////////
// Creates, fills and registers the WNDCLASSEX to Windows
BOOL ClassRegister(LRESULT CALLBACK MessageHandler(HWND, UINT, WPARAM, LPARAM));
// Unregisters the WNDCLASSEX from windows
BOOL ClassUnRegister();
// Creates a new window with the default settings
BOOL WinCreate(DWORD dwFlags);
// Destroys the main window
BOOL WinDestroy();
// PRIVATE VARIABLES /////////////////////////////////////////////////////////////////////
// Main aplication instance handler
HINSTANCE m_hMainInstance;
// Handler to the main window
HWND m_hMainWindow;
// Keeps record if the "Class Registration" and the "Window Creation" succeeded
BOOL m_bClassRegistered, m_bWindowCreated;
// Keeps record of the focus on the window
BOOL m_bFocus;
// Structure for handling the messages
MSG m_Msg;
// Integers for keeping record of the window dimensions and position. Only for
// windowed mode
UINT m_nYPOS, m_nXPOS, m_nYSIZE, m_nXSIZE;
// Name of the class and the window
CHAR* m_sClassName, *m_sWindowTitle;
};
// WinClass REFERENCE CLASS //////////////////////////////////////////////////////////////
static class WINCLASS_REF
{
public:
// Set the reference
VOID SetRef(WINCLASS* WinClass)
{
m_pWinClass = WinClass;
}
// Get the reference
WINCLASS* GetRef()
{
return m_pWinClass;
}
private:
// Pointer to the WINCLASS class
WINCLASS* m_pWinClass;
}DEF_WINCLASS;
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////// IMPLEMENTATION //////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// DEFAULT CONSTRUCTOR AND DESTRUCTOR //
//////////////////////////////////////////////////////////////////////////////////////////
// WINCLASS : Default constructor. Sets to zero all the variables of the class. //
//////////////////////////////////////////////////////////////////////////////////////////
WINCLASS::WINCLASS()
{
// Zero out all the variables
m_hMainWindow = NULL;
m_bClassRegistered = FALSE;
m_bWindowCreated = FALSE;
ZeroMemory(&m_Msg, sizeof(MSG));
m_nYPOS = 20;
m_nXPOS = 20;
m_nXSIZE = 320;
m_nYSIZE = 240;
m_sClassName = NULL;
m_sWindowTitle = NULL;
// Set the reference to the class
DEF_WINCLASS.SetRef(this);
}
//////////////////////////////////////////////////////////////////////////////////////////
// ~WINCLASS : Default destructor. Calls the Release() method. //
//////////////////////////////////////////////////////////////////////////////////////////
WINCLASS::~WINCLASS()
{
// Call the release method
Release();
// Release the char* of the Window title and the class name
try{
if (m_sClassName)
delete [] m_sClassName;
m_sClassName = NULL;
if (m_sWindowTitle)
delete [] m_sWindowTitle;
m_sWindowTitle = NULL;
}catch(...){
MessageBox(NULL, "Error handling the strings, some memory wasn't freed",
"Release error", MB_OK | MB_ICONSTOP);
OutputDebugString("***ERROR: releasing the class strings. Memory not freed***\n");
}
}
// INITIALIZATION AND RELEASE FUNCTIONS //
//////////////////////////////////////////////////////////////////////////////////////////
// Initialize : Initializes the class and the main window. //
//////////////////////////////////////////////////////////////////////////////////////////
BOOL WINCLASS::Initialize(BOOL bWindowed,
CONST CHAR* ClassName,
CONST CHAR* WinTitle,
UINT window_width,
UINT window_height,
HINSTANCE hInstance,
LRESULT CALLBACK MessageHandler(HWND, UINT, WPARAM, LPARAM))
{
if (Active()) // If the class is already active then release it first
Release();
// Make a copy for the ClassName and WindowTitle strings
// CLASS NAME
if (m_sClassName) // Check that is not a valid pointer
delete [] m_sClassName; // Delete in case of
m_sClassName = NULL;
m_sClassName = new char[strlen(ClassName)+1]; // Reserve the space
strcpy (m_sClassName, ClassName); // Copy the string
// WINDOW TITLE
if (m_sWindowTitle) // Check that is not a valid pointer
delete [] m_sWindowTitle; // Delete in case of
m_sWindowTitle = NULL;
m_sWindowTitle = new char[strlen(WinTitle)+1]; // Reserve space
strcpy(m_sWindowTitle, WinTitle); // Copy the title
// Set the values for the HINSTANCE. It's just in case.
if (hInstance != NULL) // This is just for protection :)
m_hMainInstance = hInstance;
else
m_hMainInstance = GetModuleHandle(NULL);
if (!ClassRegister(MessageHandler)) // Registers the class to windows
return FALSE;
// Set the values for screen height and width
m_nXSIZE = window_width;
m_nYSIZE = window_height;
DWORD dwFlags = NULL; // Variable to hold the flags given to the
// window creation function
if (bWindowed) // Check is going to be windowed or full screen
dwFlags = (WS_VISIBLE | WS_OVERLAPPEDWINDOW);
else
dwFlags = (WS_VISIBLE | WS_POPUP);
if (!WinCreate(dwFlags)) // Creates a new window
return FALSE;
return TRUE; // SUCCESS
}
//////////////////////////////////////////////////////////////////////////////////////////
// Release : Releases the window and unregisters the class. //
//////////////////////////////////////////////////////////////////////////////////////////
MSG WINCLASS::Release()
{
if (!WinDestroy()) // Destroy the main window
OutputDebugString("***FAILED: Destroying the window***\n");
if (!ClassUnRegister()) // Unregister the class from windows
OutputDebugString("***FAILED: Unregistering WNDCLASSEX***\n");
return GetMsg(); // Return the last message
}
//////////////////////////////////////////////////////////////////////////////////////////
// ClassRegister : Creates, fills and registers the WNDCLASSEX struct on Windows. //
//////////////////////////////////////////////////////////////////////////////////////////
BOOL WINCLASS::ClassRegister(LRESULT CALLBACK MessageHandler(HWND, UINT, WPARAM, LPARAM))
{
ClassUnRegister(); // If it was registered -> unregister then
// *** DEBUG OPTION *** //
// Unregister the class if there's one registered
// while (UnregisterClass(m_sClassName.c_str(), m_hMainInstance));
WNDCLASSEX MainClass; // struct of the instance to register
ZeroMemory(&MainClass, sizeof(WNDCLASSEX)); // Set to NULL
MainClass.cbSize = sizeof(WNDCLASSEX); // Size of the structure
MainClass.style = CS_DBLCLKS | CS_OWNDC | // Style flags
CS_HREDRAW | CS_VREDRAW;
MainClass.lpfnWndProc = MessageHandler; // Function pointer to the MsgHandler
MainClass.cbClsExtra = 0;
MainClass.cbWndExtra = 0;
MainClass.hInstance = m_hMainInstance; // Handle to the instance handle
MainClass.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Default icon
MainClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO); // Default small icon
MainClass.hCursor = LoadCursor(NULL, IDC_ARROW); // Default pointer
MainClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
MainClass.lpszMenuName = NULL; // No menus
MainClass.lpszClassName = m_sClassName; // Name of the class
if (!RegisterClassEx(&MainClass))
{
OutputDebugString("***Failed to register de WNDCLASSEX struct.***\n");
MessageBox(NULL, "Failed to register the class on Windows",
"Initialization error", MB_OK | MB_ICONSTOP | MB_TOPMOST);
return FALSE; // Failed to register
}
m_bClassRegistered = TRUE; // Class registration succeeded
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////////////////
// ClassUnRegister : Un-Registers de WNDCLASSEX struct from Windows. //
//////////////////////////////////////////////////////////////////////////////////////////
BOOL WINCLASS::ClassUnRegister()
{
if (m_bClassRegistered)
{
BOOL result = UnregisterClass(m_sClassName,m_hMainInstance);
if (!result)
return FALSE; // Failed to un-register
}
m_bClassRegistered = FALSE; // Class un-registration succeeded
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////////////////
// WinCreate : Creates a new window with the default parameters. //
//////////////////////////////////////////////////////////////////////////////////////////
BOOL WINCLASS::WinCreate(DWORD dwFlags)
{
if (m_bWindowCreated) // Destroy the window if one already exists
WinDestroy();
// Create the extended styles window
m_hMainWindow = CreateWindowEx(NULL, //WS_EX_TOPMOST,
m_sClassName,
m_sWindowTitle,
dwFlags,
m_nXPOS, m_nYPOS,
m_nXSIZE, m_nYSIZE,
NULL,
NULL,
m_hMainInstance,
NULL);
if (!m_hMainWindow) // On failure
{
DWORD dwERROR = GetLastError();
OutputDebugString("***Failed to create the (ex)window.***\n ");
// DEBUG WINDOW, TRY TO CREATE A NON-EXTENDED STYLES WINDOW //////////////////////
m_hMainWindow = CreateWindow(m_sClassName,
m_sWindowTitle,
dwFlags,
m_nXPOS, m_nYPOS,
m_nXSIZE, m_nYSIZE,
NULL,
NULL,
m_hMainInstance,
NULL);
if (!m_hMainWindow) // Failed completely. Terminate
{
dwERROR = GetLastError();
OutputDebugString("***FAILED TO CREATE DEBUG WINDOW. TERMINATING.***\n");
// Report the failure to the user
MessageBox(NULL,
"Failed to create the window. TERMINATING...",
"Initialization", MB_OK | MB_ICONSTOP | MB_TOPMOST);
return FALSE; // Failed to create the window
}
}
HandleMsg(); // Handle the WM_CREATE msg
m_bWindowCreated = TRUE; // Set the flag to true
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////////////////
// WinDestroy : Destroys the main window. //
//////////////////////////////////////////////////////////////////////////////////////////
BOOL WINCLASS::WinDestroy()
{
if (m_bWindowCreated) // Check if the window was created
DestroyWindow(m_hMainWindow); // Destroy the window
m_bWindowCreated = FALSE;
return TRUE;
}
// MESSAGE HANDLING //
//////////////////////////////////////////////////////////////////////////////////////////
// HandleMsg : Handles a single message from the queve. //
//////////////////////////////////////////////////////////////////////////////////////////
BOOL WINCLASS::HandleMsg()
{
if (PeekMessage(&m_Msg, m_hMainWindow, 0, 0, PM_REMOVE)) // Get a message from the
{ // queve.
if (m_Msg.message == WM_QUIT) // Closes the entire aplication
Release();
TranslateMessage(&m_Msg); // Translate the new message.
DispatchMessage(&m_Msg); // Sends the message to the message handler
return TRUE;
}
return FALSE;
}
// STATE FUNCTIONS //
//////////////////////////////////////////////////////////////////////////////////////////
// Active : Returns true if the class is still active. //
//////////////////////////////////////////////////////////////////////////////////////////
BOOL WINCLASS::Active()
{
if (m_bClassRegistered && m_bWindowCreated) // The class is only active if the
return TRUE; // WNDCLASSEX struct is registered to
// Windows and there's an active window
return FALSE;
}
//////////////////////////////////////////////////////////////////////////////////////////
// WindowShow : Changes the display mode (show) of the window. (Minimize, Maximized..) //
//////////////////////////////////////////////////////////////////////////////////////////
void WINCLASS::WindowShow(INT Show)
{
// Sets a
ShowWindow(m_hMainWindow, Show);
}
// GET- FUNCTIONS //
//////////////////////////////////////////////////////////////////////////////////////////
// GetMsg : Returns a copy of the m_Msg struct. //
//////////////////////////////////////////////////////////////////////////////////////////
MSG WINCLASS::GetMsg() const
{
return m_Msg;
}
//////////////////////////////////////////////////////////////////////////////////////////
// GetWindow : Returns the handle to the main window. //
//////////////////////////////////////////////////////////////////////////////////////////
HWND WINCLASS::GetWindow()
{
return m_hMainWindow;
}
//////////////////////////////////////////////////////////////////////////////////////////
// GetXPOS, GetYPOS, GetXSIZE, GetYSIZE : Returns the window size and position. //
//////////////////////////////////////////////////////////////////////////////////////////
UINT WINCLASS::GetXPos() const
{
return m_nXPOS;
}
UINT WINCLASS::GetYPos() const
{
return m_nYPOS;
}
UINT WINCLASS::GetXSize() const
{
return m_nXSIZE;
}
UINT WINCLASS::GetYSize() const
{
return m_nYSIZE;
}
//////////////////////////////////////////////////////////////////////////////////////////
// GetFocus : Returns TRUE if the main window is active. //
//////////////////////////////////////////////////////////////////////////////////////////
BOOL WINCLASS::GetFocus() const
{
return m_bFocus;
}
//////////////////////////////////////////////////////////////////////////////////////////
// MsgHandler : Default class message handler. //
//////////////////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK MsgHandler(HWND hWindow, UINT Msg,
WPARAM wParam, LPARAM lParam)
{
// Get the pointer
WINCLASS* WinClass = DEF_WINCLASS.GetRef();
switch (Msg){
case WM_ACTIVATE: // When the window gains or looses focus
if(LOWORD(wParam) == WA_INACTIVE)
WinClass->m_bFocus = FALSE;
else
WinClass->m_bFocus = TRUE;
break;
case WM_MOVE: // When the window changes it's position
WinClass->m_nXPOS = LOWORD(lParam);
WinClass->m_nYPOS = HIWORD(lParam);
break;
case WM_SIZE: // When the window changes it's dimensions
WinClass->m_nXSIZE = LOWORD(lParam);
WinClass->m_nYSIZE = HIWORD(lParam);
break;
case WM_PAINT: // When the window needs repainting
ValidateRect(WinClass->m_hMainWindow, NULL);
break;
case WM_CLOSE: // When the user want's to close the aplication
PostQuitMessage(0); // The user "wants" to quit
break;
case WM_DESTROY: // The main window was destroyed
PostQuitMessage(0);
break;
default: // Other messages
return DefWindowProc(hWindow, Msg, wParam, lParam);
}
return 0; // Message handled succesful
}
#endif
It includes:
- A class for managing Windows basic things
- A default Message Proc
- "Get" functions. For knowing the window properties (size, position, focus)
- "Get" function for retrieving the window handle (HWND).
- A message handler (WINCLASS::HandleMsg())
- An Initialize function with default parameters. So you can change only what you want, and let as default the other things.
NOTES:
- The only thing that changes when initializing as "windowed" true, is that the window is "Overlapped window", or if is false, then it's a "Popup window".
- If you want to use another Message Procedure you can add it in the WINCLASS::Initialize(...) function. (It's the last parameter)
- There's another class called "WINCLASS_REF". That's only to link the default message proc and the WINCLASS. But in case you need to access the WINCLASS out of it's scope, e.g. you want the HWND in a function (although is not the best practice) you can do DEF_WINCLASS.GetRef()->GetWindow(). As "DEF_WINCLASS" is an static instance of the WINCLASS_REF class.
So for example to make a simple application you write:
[source lang = "cpp"]
#include <WinClass.h>
INT WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR sCmdLine,
INT nShow)
{
WINCLASS WinClass;
WinClass.Initialize(TRUE, "Class Name", "Window Title");
while(WinClass.Active())
{
WinClass.HandleMsg();
if (KeyState(VK_ESCAPE))
PostQuitMessage(0);
}
return (INT)WinClass.Release().wParam;
}
Simple as that!!
lease any comments for making this better, are welcome :).
And I hope it helps to someone!!
[Edited by - jorelmb on March 24, 2007 11:07:19 PM]
------------------------------"Carpe Diem!""Failure is the prequel of success"_.-:Jimbo:-._