I was trying to program a program that would display teapots that move around on the screen so that i could test my collision detector and physics engine. After completing the code initially and after debugging it, it worked as I had expected. But then, Windows XP gave me a message saying that some file (probably OS related) was corrupted and suggested running scandisk. So i did with the auto fix on. Next thing, when i had rebooted the computer, the program wouldn't run. And when i tried to run it with the debugger, it gave me an access violation when using the CreateWindow() function. I think that it's a problem with the hInstance variable that's being passed into the CreateWindow function because the other values are just flags and strings. I would greatly appreciate help on this.
here's the windows api related part of the code:
note: stdafx.h and collisiontester2.1.h contain the essential include files needed to run this program
Thanks
// CollisionTest2.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "CollisionTester2.1.h"
#include <d3d9.h>
#include <d3dx9.h>
//#include <d3dx9tex.h>
#include <dinput.h>
#include <ctime>
#define MAX_LOADSTRING 100
#define KEYDOWN(name, key) (name[key] & 0x80)
#define BOX_SIZEX 10
#define BOX_SIZEY 10
#define BOX_SIZEZ 10
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
LPDIRECT3D9 pD3D; // Direct3D object
LPDIRECT3DDEVICE9 pd3dDevice; // Direct3D display device
LPDIRECTINPUT8 DI_Object; // DirectInput object
LPDIRECTINPUTDEVICE8 DI_Device; // DirectInput device
LPD3DXMESH * objlist; // Pointer to list of objects
int objlistlen = 1; // Number of objects
D3DXVECTOR3 * translist; // List of translations for objects
D3DXVECTOR3 * movelist; // List of all the object move values
HRESULT hr; // Error container variable
bool allowrender; // Allows rendering to occur
D3DMATERIAL9 univmat; // Material for all the objects
bool rendering; // True if currently rendering
bool CKEYDWN; // True if the C key is pressed
bool CKEYDWN2; // True if the C key has been released
bool allow_move; // True if movement is allowed
bool allow_move2;
bool wireframeon; // True if wireframe rendering is on
bool wireframe2;
LPDIRECT3DVERTEXBUFFER9 buffer = NULL;
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
HWND InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
void render(HWND, LPD3DXMESH **);
void releaseD3D(LPD3DXMESH ** pobjlist);
void initD3D(HWND);
void CreateObj(LPD3DXMESH ** pobjlist, HWND hWnd);
void MoveObj();
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
HWND hWnd;
char buffer[256];
MSG msg;
ZeroMemory(&msg,sizeof(MSG));
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_COLLISIONTESTER21, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
allowrender = false;
srand(static_cast<unsigned>(time(0)));
// Perform application initialization:
hWnd = InitInstance (hInstance, nCmdShow);
initD3D(hWnd );
D3DXVECTOR3 tempv(-10 + float(20.0 * rand()/(RAND_MAX+1.0)),
-10 + float(20.0 * rand()/(RAND_MAX+1.0)),
-10 + float(20.0 * rand()/(RAND_MAX+1.0)));
D3DXVECTOR3 tempm(-4 + float(8.0 * rand()/(RAND_MAX+1.0)),
-4 + float(8.0 * rand()/(RAND_MAX+1.0)),
-4 + float(8.0 * rand()/(RAND_MAX+1.0)));
translist = new D3DXVECTOR3[1];
movelist = new D3DXVECTOR3[1];
objlist = new LPD3DXMESH[1];
*translist = tempv;
*movelist = tempm;
hr = D3DXCreateTeapot(pd3dDevice, objlist, 0);
if(!FAILED(hr))
{
//MessageBox(hWnd, "Successfully created box using D3DXCreateBox", "UM...", NULL);
}
else
{
switch(hr)
{
case D3DERR_INVALIDCALL:
MessageBox(hWnd, "The method call is invalid. For example, a method's parameter may have an invalid value",
"ERROR", NULL);
break;
case D3DXERR_INVALIDDATA:
MessageBox(hWnd, "The data is invalid", "ERROR", NULL);
break;
case E_OUTOFMEMORY:
MessageBox(hWnd, "Microsoft Direct3D could not allocate sufficient memory to complete the call",
"ERROR", NULL);
break;
}
PostQuitMessage(0);
}
CKEYDWN = false;
CKEYDWN2 = true;
allow_move = true;
wireframeon = true;
wireframe2 = true;
D3DXCOLOR blue(0,0,1,1);
D3DXCOLOR darkblue(0,0,.25,1);
D3DXCOLOR red(1,0,0,1);
D3DXCOLOR green(0,1,0,1);
D3DXCOLOR nothing(0,0,0,1);
univmat.Ambient = blue;
univmat.Diffuse = green;
univmat.Emissive = nothing;
univmat.Specular = green;
univmat.Power = 1;
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_COLLISIONTESTER21);
// Main message loop:
while( msg.message!=WM_QUIT )
{
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
//dinput stuff
DI_Device->GetDeviceState(sizeof(buffer),(LPVOID) &buffer);
if(KEYDOWN(buffer, DIK_C))
{
if(CKEYDWN2 == true)
{
CKEYDWN = true;
CKEYDWN2 = false;
}
}
else
{
CKEYDWN2 = true;
}
if(KEYDOWN(buffer, DIK_R))
{
if(wireframe2)
{
if(!wireframeon)
{
pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
wireframeon = true;
}
else
{
pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
wireframeon = false;
}
}
wireframe2 = false;
}
else
{
wireframe2 = true;
}
if(KEYDOWN(buffer, DIK_M))
{
if(allow_move2)
{
if(allow_move)
allow_move = false;
else
allow_move = true;
allow_move2 = false;
}
}
else
{
allow_move2 = true;
}
if(CKEYDWN == true)
{
if(!rendering)
{
CreateObj(&objlist, hWnd);
}
CKEYDWN = false;
}
render(hWnd, &objlist);
if(allow_move)
{
MoveObj();
}
}
}
return (int) msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage are only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_COLLISIONTESTER21);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCTSTR)IDC_COLLISIONTESTER21;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
HWND InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return hWnd;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
switch (message)
{
case WM_CREATE:
allowrender = true;
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_DESTROY:
releaseD3D(&objlist);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Message handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
here's the windows api related part of the code:
note: stdafx.h and collisiontester2.1.h contain the essential include files needed to run this program
Thanks
// CollisionTest2.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "CollisionTester2.1.h"
#include <d3d9.h>
#include <d3dx9.h>
//#include <d3dx9tex.h>
#include <dinput.h>
#include <ctime>
#define MAX_LOADSTRING 100
#define KEYDOWN(name, key) (name[key] & 0x80)
#define BOX_SIZEX 10
#define BOX_SIZEY 10
#define BOX_SIZEZ 10
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
LPDIRECT3D9 pD3D; // Direct3D object
LPDIRECT3DDEVICE9 pd3dDevice; // Direct3D display device
LPDIRECTINPUT8 DI_Object; // DirectInput object
LPDIRECTINPUTDEVICE8 DI_Device; // DirectInput device
LPD3DXMESH * objlist; // Pointer to list of objects
int objlistlen = 1; // Number of objects
D3DXVECTOR3 * translist; // List of translations for objects
D3DXVECTOR3 * movelist; // List of all the object move values
HRESULT hr; // Error container variable
bool allowrender; // Allows rendering to occur
D3DMATERIAL9 univmat; // Material for all the objects
bool rendering; // True if currently rendering
bool CKEYDWN; // True if the C key is pressed
bool CKEYDWN2; // True if the C key has been released
bool allow_move; // True if movement is allowed
bool allow_move2;
bool wireframeon; // True if wireframe rendering is on
bool wireframe2;
LPDIRECT3DVERTEXBUFFER9 buffer = NULL;
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
HWND InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
void render(HWND, LPD3DXMESH **);
void releaseD3D(LPD3DXMESH ** pobjlist);
void initD3D(HWND);
void CreateObj(LPD3DXMESH ** pobjlist, HWND hWnd);
void MoveObj();
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
HWND hWnd;
char buffer[256];
MSG msg;
ZeroMemory(&msg,sizeof(MSG));
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_COLLISIONTESTER21, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
allowrender = false;
srand(static_cast<unsigned>(time(0)));
// Perform application initialization:
hWnd = InitInstance (hInstance, nCmdShow);
initD3D(hWnd );
D3DXVECTOR3 tempv(-10 + float(20.0 * rand()/(RAND_MAX+1.0)),
-10 + float(20.0 * rand()/(RAND_MAX+1.0)),
-10 + float(20.0 * rand()/(RAND_MAX+1.0)));
D3DXVECTOR3 tempm(-4 + float(8.0 * rand()/(RAND_MAX+1.0)),
-4 + float(8.0 * rand()/(RAND_MAX+1.0)),
-4 + float(8.0 * rand()/(RAND_MAX+1.0)));
translist = new D3DXVECTOR3[1];
movelist = new D3DXVECTOR3[1];
objlist = new LPD3DXMESH[1];
*translist = tempv;
*movelist = tempm;
hr = D3DXCreateTeapot(pd3dDevice, objlist, 0);
if(!FAILED(hr))
{
//MessageBox(hWnd, "Successfully created box using D3DXCreateBox", "UM...", NULL);
}
else
{
switch(hr)
{
case D3DERR_INVALIDCALL:
MessageBox(hWnd, "The method call is invalid. For example, a method's parameter may have an invalid value",
"ERROR", NULL);
break;
case D3DXERR_INVALIDDATA:
MessageBox(hWnd, "The data is invalid", "ERROR", NULL);
break;
case E_OUTOFMEMORY:
MessageBox(hWnd, "Microsoft Direct3D could not allocate sufficient memory to complete the call",
"ERROR", NULL);
break;
}
PostQuitMessage(0);
}
CKEYDWN = false;
CKEYDWN2 = true;
allow_move = true;
wireframeon = true;
wireframe2 = true;
D3DXCOLOR blue(0,0,1,1);
D3DXCOLOR darkblue(0,0,.25,1);
D3DXCOLOR red(1,0,0,1);
D3DXCOLOR green(0,1,0,1);
D3DXCOLOR nothing(0,0,0,1);
univmat.Ambient = blue;
univmat.Diffuse = green;
univmat.Emissive = nothing;
univmat.Specular = green;
univmat.Power = 1;
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_COLLISIONTESTER21);
// Main message loop:
while( msg.message!=WM_QUIT )
{
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
//dinput stuff
DI_Device->GetDeviceState(sizeof(buffer),(LPVOID) &buffer);
if(KEYDOWN(buffer, DIK_C))
{
if(CKEYDWN2 == true)
{
CKEYDWN = true;
CKEYDWN2 = false;
}
}
else
{
CKEYDWN2 = true;
}
if(KEYDOWN(buffer, DIK_R))
{
if(wireframe2)
{
if(!wireframeon)
{
pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
wireframeon = true;
}
else
{
pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
wireframeon = false;
}
}
wireframe2 = false;
}
else
{
wireframe2 = true;
}
if(KEYDOWN(buffer, DIK_M))
{
if(allow_move2)
{
if(allow_move)
allow_move = false;
else
allow_move = true;
allow_move2 = false;
}
}
else
{
allow_move2 = true;
}
if(CKEYDWN == true)
{
if(!rendering)
{
CreateObj(&objlist, hWnd);
}
CKEYDWN = false;
}
render(hWnd, &objlist);
if(allow_move)
{
MoveObj();
}
}
}
return (int) msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage are only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_COLLISIONTESTER21);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCTSTR)IDC_COLLISIONTESTER21;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
HWND InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return hWnd;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
switch (message)
{
case WM_CREATE:
allowrender = true;
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_DESTROY:
releaseD3D(&objlist);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Message handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}