Ok, first off, programming is just a hobby of mine. I make programs that interest me and I don't usually share them. That being said I do try to write the code as correctly as possible. To include using UNICODE even though I have no intention on porting to another language.
I'm working on building a DirectX 9 Zombie Arena Game using pure Windows API and DIRECTX API calls. As usual, I started out with a simple skeleton class that simply creates a 800 x 800 window with a black background. Even though I have done this 1000 times, something decided to go wrong this time and every time I close the program it simply destroys the window and runs in the background.
I have a feeling I forgot or did something stupid and I am going to feel like a moron when you point it out, but here goes anyway. -- Steve
main.cpp
#include "Main.h"
int WINAPI wWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow){
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
WinClass *GameWindow = new WinClass(hInstance);
GameWindow->RegisterAppClass();
GameWindow->CreateAppWindow();
GameWindow->ShowAppWindow(nCmdShow);
MSG Message;
ZeroMemory(&Message, sizeof(MSG));
int ExitCode = GameWindow->Run(Message);
delete(GameWindow);
return ExitCode;
}
main.h
#define WINDOWS_LEAN_AND_MEAN
#define MAX_STRING 128
#include <Windows.h>
#include <string>
#include "WinClass.h"
WinClass.h
#pragma once
#include "Main.h"
class WinClass{
public:
WinClass(HINSTANCE);
~WinClass();
bool RegisterAppClass();
bool CreateAppWindow();
void ShowAppWindow(int);
int Error(int);
int Run(MSG Msg);
static LRESULT CALLBACK stWinProc(HWND, UINT, WPARAM, LPARAM);
virtual LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE ReturnAppInstance(void);
HWND ReturnWindowHandle(void);
private:
HWND WindowHandle;
HINSTANCE AppInstance;
std::wstring SetText(int);
};
WinClass.cpp
#include "Main.h"
#include "WinClass.h"
#define WINDOW_TITLE "Zombies" // Move to String Table
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 800
WinClass::WinClass(HINSTANCE Instance){
AppInstance = Instance;
}
WinClass::~WinClass(){
}
bool WinClass::RegisterAppClass(){
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wcex.lpfnWndProc = stWinProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = AppInstance;
wcex.hIcon = LoadIcon(AppInstance, IDI_APPLICATION);
wcex.hCursor = LoadCursor(AppInstance, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = TEXT(WINDOW_TITLE);
wcex.hIconSm = LoadIcon(AppInstance, IDI_APPLICATION);
if (!RegisterClassEx(&wcex)){
return false;
}
return true;
}
void WinClass::ShowAppWindow(int Show){
ShowWindow(WindowHandle, Show);
UpdateWindow(WindowHandle);
}
HINSTANCE WinClass::ReturnAppInstance(){
return AppInstance;
}
HWND WinClass::ReturnWindowHandle(){
return WindowHandle;
}
std::wstring WinClass::SetText(int TextID){
std::wstring Buffer(MAX_STRING, 0);
Buffer.resize(LoadString(AppInstance, TextID, &Buffer[0], Buffer.size()));
return Buffer;
}
int WinClass::Error(int ErrorID){
std::wstring CaptionBuffer = SetText(ErrorID);
std::wstring InformationBuffer = SetText(ErrorID + 1);
return MessageBox(NULL, InformationBuffer.c_str(), CaptionBuffer.c_str(), MB_OK |
MB_ICONERROR );
}
bool WinClass::CreateAppWindow(){
WindowHandle = CreateWindow(TEXT(WINDOW_TITLE), TEXT(WINDOW_TITLE), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH,
WINDOW_HEIGHT, 0, 0, AppInstance, 0 );
if(WindowHandle==NULL){
return false;
}
RECT rect = { 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT };
AdjustWindowRect(&rect, GetWindowLong(WindowHandle, GWL_STYLE), FALSE);
int x = rect.right - rect.left;
int y = rect.bottom - rect.top;
SetWindowPos(WindowHandle, 0, 0, 0, x, y, SWP_NOZORDER | SWP_NOMOVE );
return true;
}
LRESULT CALLBACK WinClass::stWinProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam){
WinClass* pWnd;
if(Msg==WM_NCCREATE){
SetWindowLong(hWnd, GWL_USERDATA, (long)((LPCREATESTRUCT(lParam))->lpCreateParams));
}
pWnd=(WinClass *)GetWindowLong(hWnd, GWL_USERDATA);
if(pWnd){
return pWnd->WinProc(hWnd, Msg, wParam, lParam);
}
else
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
int WinClass::Run(MSG Msg){
while (1) { if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE)) {
if (Msg.message == WM_QUIT)
break;
TranslateMessage( &Msg );
DispatchMessage ( &Msg );
}
else {
}
}
return (INT)Msg.wParam;
}
WinProc.cpp
#include "Main.h"
LRESULT CALLBACK WinClass::WinProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam){
switch(Msg){
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(WM_QUIT);
break;
default:
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
return 0;
}
Like I said before this is only the skeleton code I have to go and remove the defines. Some will move to a string table and other to a game data file, but feel free to make any suggestions you feel will make me a better programmer... Thank you in advance -- Steve. <tabs and="" bracket="" placements="" i="" am="" kinda="" set="" in="" my="" ways="" on.="">