Click here to Skip to main content
15,886,664 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
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
C++
#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
C++
//  Main Include

#define WINDOWS_LEAN_AND_MEAN
#define MAX_STRING 128

#include <Windows.h>
#include <string>

#include "WinClass.h"


WinClass.h

C++
#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

C++
#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) {		 // Only render when there are no messages
		if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE)) {
			if (Msg.message == WM_QUIT) 
			break;
		TranslateMessage( &Msg ); 
		DispatchMessage ( &Msg );
		} 

		else {
						// Render a frame
		}
	}
  return (INT)Msg.wParam;
}


WinProc.cpp

C++
#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.="">
Posted
Comments
Sergey Alexandrovich Kryukov 8-Dec-15 16:13pm    
And..? Do you have any questions?
—SA
drkwlf 8-Dec-15 16:59pm    
Yes, why does it run in the background instead of ending the program when closed.
Sergey Alexandrovich Kryukov 8-Dec-15 17:09pm    
Not quite clear. What "it"? What do you mean by "background"? Do you simply mean that your application continues to run without any UI and never terminates? Do you create any additional threads?
Probably, GameWindow->Run never returned. Is that so? Such things are easy enough to debug...
—SA
drkwlf 8-Dec-15 17:21pm    
Yes the game runs in the background... It looks as though, as mentioned in the solution below, that the actual WinProc() function is not being called.
drkwlf 8-Dec-15 17:21pm    
By background I mean it runs as a process without a gui

1 solution

C++
WindowHandle = CreateWindow(TEXT(WINDOW_TITLE), TEXT(WINDOW_TITLE), WS_OVERLAPPEDWINDOW,
                           CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH,
                           WINDOW_HEIGHT, 0, 0, AppInstance, 0 );


C++
WindowHandle = CreateWindow(TEXT(WINDOW_TITLE), TEXT(WINDOW_TITLE), WS_OVERLAPPEDWINDOW,
                           CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH,
                           WINDOW_HEIGHT, 0, 0, AppInstance, (void *)this );


I knew I would feel like a moron. :)
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900