This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
Why does this happen?
1>------ Build started: Project: Client, Configuration: Debug Win32 ------
1> WindowManager.cpp
1> Generating Code...
1> Compiling...
1> Main.cpp
1> Generating Code...
1>WindowManager.obj : error LNK2001: unresolved external symbol
"private: static int WindowManager::win_stat" (?win_stat#WindowManager##0HA)
1>C:\Users\user\documents\visual studio
2012\Projects\TalkToMe\Debug\Client.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
WindowManager.cpp
#include "WindowManager.h"
void WindowManager::PekMessage()
{
if(PeekMessage(&msg, window, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
bool WindowManager::isWindowOpen()
{
return win_stat != -1;
}
HWND WindowManager::textbox(int width, int height, int xPos, int yPos, LPCSTR content, bool edit_able)
{
int type = (edit_able) ? (WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL) : (WS_CHILD|WS_VISIBLE|WS_HSCROLL|ES_AUTOHSCROLL);
return CreateWindowEx(
WS_EX_CLIENTEDGE,
"EDIT",
content,
type,
xPos,
yPos,
width,
height,
window,
(HMENU)50,
GetModuleHandle(NULL),
NULL
);
}
HWND WindowManager::textbox(Vector size, Vector position, LPCSTR content, bool edit_able)
{
return textbox(size.getX(), size.getY(), position.getX(), position.getY(), content, edit_able);
}
LRESULT CALLBACK WindowManager::WindowProcedure(HWND winhan,UINT uint_Message,WPARAM parameter1,LPARAM parameter2)
{
switch(uint_Message)
{
case 16: // exit button
win_stat = -1;
break;
}
return DefWindowProc(winhan,uint_Message,parameter1,parameter2);
}
WindowManager::WindowManager(LPCTSTR title,int x, int y, int width, int height)
{
WNDCLASSEX wnd;
wnd.cbSize = sizeof(wnd);
wnd.style = CS_HREDRAW | CS_VREDRAW;
wnd.lpfnWndProc = WindowProcedure;
wnd.cbClsExtra = 0;
wnd.cbWndExtra = 0;
wnd.hInstance = GetModuleHandle(NULL);
wnd.hIcon = NULL;
wnd.hCursor = LoadCursor(NULL,IDC_ARROW);
wnd.hbrBackground = GetSysColorBrush(NULL);
wnd.lpszClassName = "TalkToMe";
wnd.lpszMenuName = NULL;
wnd.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassEx(&wnd);
window = CreateWindowEx(WS_EX_CONTROLPARENT, wnd.lpszClassName, title,
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE, x, y, width, height,NULL, NULL,
GetModuleHandle(NULL), NULL);
}
WindowManager::~WindowManager()
{
DestroyWindow(window);
}
WindowManager.h
#pragma once
#pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#include <Windows.h>
#include "Vector.h"
class WindowManager
{
private:
MSG msg;
HWND window;
static int win_stat;
public:
WindowManager(LPCTSTR title,int x, int y, int width, int height);
~WindowManager();
static LRESULT CALLBACK WindowProcedure(HWND winhan,UINT uint_Message,WPARAM parameter1,LPARAM parameter2);
HWND textbox(int width, int height, int xPos, int yPos, LPCSTR content, bool edit_able=true);
HWND textbox(Vector size, Vector position, LPCSTR content, bool edit_able=true);
bool isWindowOpen();
void PekMessage();
};
The part in the header
static int win_stat;
is only a declaration. You also have to add
int WindowManager::win_stat;
to the .cpp file, just like you define the member functions there.
Related
Got a LINK2019 error that I can't figure out. Error code: Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol __vsnprintf referenced in function "long __stdcall StringVPrintfWorkerA(char *,unsigned int,unsigned int *,char const *,char *)" (?StringVPrintfWorkerA##YGJPADIPAIPBD0#Z) Direct X C:\Visual Studio Programs\Direct X\Direct X\dxerr.lib(dxerra.obj) 1
main.cpp:
#include <Windows.h>
#include <memory>
#include "BlankDemo.h"
LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prevInstance,
LPWSTR cmdLine, int cmdShow)
{
UNREFERENCED_PARAMETER(prevInstance);
UNREFERENCED_PARAMETER(cmdLine);
WNDCLASSEX wndClass = { 0 };
wndClass.cbSize = sizeof(WNDCLASS);
wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WndProc;
wndClass.hInstance = hInstance;
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = "DX11BookWindowClass";
if (!RegisterClassEx(&wndClass))
return -1;
RECT rc = { 0, 0, 640, 480 };
AdjustWindowRect(&rc, WS_EX_OVERLAPPEDWINDOW, FALSE);
HWND hwnd = CreateWindowA("DX11BookWindowClass", "BlankWin32Window",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left,
rc.bottom - rc.top, NULL, NULL, hInstance, NULL);
if (!hwnd)
return -1;
ShowWindow(hwnd, cmdShow);
std::auto_ptr<Dx11DemoBase> demo(new BlankDemo());
// Demo Initialize
bool result = demo->Initialize(hInstance, hwnd);
// Error reporting if there is an issue
if (result == false)
return -1;
MSG msg = { 0 };
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
// Update and Draw
demo->Update(0.0f);
demo->Render();
}
}
// Demo Shutdown
demo->Shutdown();
return static_cast<int>(msg.wParam);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT paintStruct;
HDC hDC;
switch (message)
{
case WM_PAINT:
hDC = BeginPaint(hwnd, &paintStruct);
EndPaint(hwnd, &paintStruct);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
defualt:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
// implementation of the BlankDemo class
BlankDemo::BlankDemo()
{
}
BlankDemo::~BlankDemo()
{
}
bool BlankDemo::LoadContent()
{
return true;
}
void BlankDemo::UnloadContent()
{
}
void BlankDemo::Update(float dt)
{
}
void BlankDemo::Render()
{
if (d3dContext_ == 0)
return;
float clearColor[4] = { 0.0f, 0.0f, 0.25f, 1.0f };
d3dContext_->ClearRenderTargetView(backBufferTarget_, clearColor);
swapChain_->Present(0, 0);
}
BlankDemo.h file:
#pragma once
#ifndef _BLANK_DEMO_H_
#define _BLANK_DEMO_H_
#include "Dx11DemoBase.h"
class BlankDemo : public Dx11DemoBase
{
public:
BlankDemo();
virtual ~BlankDemo();
bool LoadContent();
void UnloadContent();
void Update(float dt);
void Render();
};
#endif // !_BLANK_DEMO_H_
Dx11DemoBase::Dx11DemoBase() : driverType_(D3D_DRIVER_TYPE_NULL),
featureLevel_(D3D_FEATURE_LEVEL_11_0), d3dDevice_(0), d3dContext_(0),
swapChain_(0), backBufferTarget_(0)
{
}
Dx11DemoBase::~Dx11DemoBase()
{
Shutdown();
}
bool Dx11DemoBase::LoadContent()
{
// Override with demo specifics, if any...
return true;
}
void Dx11DemoBase::UnloadContent()
{
// Override with demo specifics, if any...
}
void Dx11DemoBase::Shutdown()
{
UnloadContent();
if (backBufferTarget_) backBufferTarget_->Release();
if (swapChain_) swapChain_->Release();
if (d3dContext_) d3dContext_->Release();
if (d3dDevice_) d3dDevice_->Release();
d3dDevice_ = 0;
d3dContext_ = 0;
swapChain_ = 0;
backBufferTarget_ = 0;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
bool Dx11DemoBase::Initialize(HINSTANCE hInstance, HWND hwnd)
{
hInstance_ = hInstance;
hwnd_ = hwnd;
RECT dimensions;
GetClientRect(hwnd, &dimensions);
unsigned int width = dimensions.right - dimensions.left;
unsigned int height = dimensions.bottom - dimensions.top;
D3D_DRIVER_TYPE driverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_SOFTWARE
};
unsigned int totalDriverTypes = ARRAYSIZE(driverTypes);
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
};
unsigned int totalFeatureLevels = ARRAYSIZE(featureLevels);
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
swapChainDesc.BufferCount = 1;
swapChainDesc.BufferDesc.Width = width;
swapChainDesc.BufferDesc.Height = height;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.OutputWindow = hwnd;
swapChainDesc.Windowed = true;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
unsigned int creationFlags = 0;
#ifdef _DEBUG
creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
HRESULT result;
unsigned int driver = 0;
for (driver = 0; driver < totalDriverTypes; ++driver)
{
result = D3D11CreateDeviceAndSwapChain(0, driverTypes[driver], 0,
creationFlags, featureLevels, totalFeatureLevels, D3D11_SDK_VERSION,
&swapChainDesc, &swapChain_, &d3dDevice_, &featureLevel_, &d3dContext_);
if (SUCCEEDED(result))
{
driverType_ = driverTypes[driver];
break;
}
}
if (FAILED(result))
{
DXTRACE_MSG("Failed to create the Direct3d device!");
return false;
}
ID3D11Texture2D* backBufferTexture;
result = swapChain_->GetBuffer(0, _uuidof(ID3D11Texture2D), (LPVOID*)&backBufferTexture);
if (FAILED(result))
{
DXTRACE_MSG("Failed to get the swap chain back buffer!");
return false;
}
result = d3dDevice_->CreateRenderTargetView(backBufferTexture, 0, &backBufferTarget_);
if (backBufferTexture)
backBufferTexture->Release();
if (FAILED(result))
{
DXTRACE_MSG("Failed to create the render target view!");
return false;
}
d3dContext_->OMSetRenderTargets(1, &backBufferTarget_, 0);
D3D11_VIEWPORT viewport;
viewport.Width = static_cast<float>(width);
viewport.Height = static_cast<float>(height);
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
viewport.TopLeftX = 0.0f;
viewport.TopLeftY = 0.0f;
d3dContext_->RSSetViewports(1, &viewport);
return LoadContent();
}
And lastly, the Dx11DemoBase.h header:
#pragma once
#ifndef _DEMO_BASE_H_
#define _DEMO_BASE_H_
#include <d3d11.h>
#include <D3DX11.h>
#include <dxerr.h>
class Dx11DemoBase
{
public:
Dx11DemoBase();
virtual ~Dx11DemoBase();
bool Initialize(HINSTANCE hInstance, HWND hwnd);
void Shutdown();
virtual bool LoadContent();
virtual void UnloadContent();
virtual void Update(float dt) = 0;
virtual void Render() = 0;
protected:
HINSTANCE hInstance_;
HWND hwnd_;
D3D_DRIVER_TYPE driverType_;
D3D_FEATURE_LEVEL featureLevel_;
ID3D11Device* d3dDevice_;
ID3D11DeviceContext* d3dContext_;
IDXGISwapChain* swapChain_;
ID3D11RenderTargetView* backBufferTarget_;
};
#endif // !_DEMO_BASE_H_
Add legacy_stdio_definitions.lib to Additional dependencies list in the Project properties > Configuration Properties > Linker > Input as recommended in this answer: https://stackoverflow.com/a/34230122/6693304
The legacy DirectX SDK is deprecated, so it hasn't been officially updated since the release of Visual Studio 2010 RTM (June 2010). See Microsoft Docs
This has a few specific implications:
The Windows 8.0 SDK, Windows 8.1 SDK, and Windows 10 SDK all have newer headers than the legacy DirectX SDK where they overlap. You can still make use of it with VS 2012, 2013, 2015, or 2017 but you need to reverse the traditional include/lib path order in the VC++ Directories settings. There are a few other quirks covered at the bottom of this Microsoft Docs topic page. See also The Zombie DirectX SDK.
The DLL import libraries in the legacy DirectX SDK are missing some of the imports that are present in the Windows 8.x or Windows 10 SDK. They generally work fine with all C/C++ compilers because they are fairly standard Win32 without any version-specific CRT references.
Static libraries, however, are not guaranteed to be binary compatible from version to version of the C/C++ compiler. dxguid.lib just has some data in it, so it generally works, but dxerr.lib has actual code. Hence with the major changes in the C/C++ Runtime in VS 2015, it no longer works without link errors.
There are two basic solutions to the dxerr.lib problem:
Build your own copy of the code. It's available here. This is the most robust as it will always match your compiler toolset.
You can add legacy_stdio_definitions.lib, but keep in mind that you are already relying on very out-dated files so you should work to remove/minimize use of the legacy DirectX SDK over time.
Many online tutorials for DirectX 11 and books are outdated w.r.t. to the DirectX SDK and still use d3dx11 which is also deprecated. There are numerous open source replacements available for this functionality. See Living without D3DX.
All that said, this question has already been answered on StackOverflow and would have shown up if you just searched dxerr.
Here is the code and the output.
win_main.cpp
#include <Windows.h>
#include <tchar.h>
#include "d3d9_object.h"
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
WNDCLASSEX createWndClassEx(HINSTANCE);
HWND createWindow(const wchar_t *caption, HINSTANCE);
void exitWithFailure(const wchar_t *message, HINSTANCE);
const wchar_t gszWndClassName[] = L"MainWindowClassName";
WNDCLASSEX gWndClassEx;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, int iCmdShow)
{
HWND hwnd = NULL;
MSG msg = { 0 };
BOOL bReturn;
WNDCLASSEX wndClassEx = createWndClassEx(hInstance);
if (!RegisterClassEx(&wndClassEx)) exitWithFailure(L"Cannot create window class", hInstance);
hwnd = createWindow(L"£d \u018Fditor", hInstance);
if (!hwnd)
exitWithFailure(L"Cannot create window", hInstance);
if (gpd39o->init(hwnd) == false)
exitWithFailure(L"Cannot initilize Direct3D", hInstance);
ShowWindow(hwnd, SW_MAXIMIZE);
UpdateWindow(hwnd);
if (!gpd39o->clear()) MessageBox(hwnd, L"Cannot clear device to color", L"Error!", MB_OK | MB_ICONERROR);
while ((bReturn = GetMessage(&msg, hwnd, 0, 0))) {
if (bReturn == -1) {
exitWithFailure(L"Message loop error", hInstance);
}
else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
gpd39o->deinit();
UnregisterClass(gszWndClassName, hInstance);
return EXIT_SUCCESS;
}
void exitWithFailure(const wchar_t *message, HINSTANCE h)
{
MessageBox(NULL, message, L"Error!", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
gpd39o->deinit();
UnregisterClass(gszWndClassName, h);
exit(EXIT_FAILURE);
}
LRESULT CALLBACK WndProc(HWND h, UINT m, WPARAM w, LPARAM l)
{
if (m == WM_DESTROY) {
PostQuitMessage(0);
return 0;
}
return DefWindowProc(h, m, w, l);
}
HWND createWindow(const wchar_t *c, HINSTANCE h)
{
DWORD winStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME;
return CreateWindowEx(WS_EX_APPWINDOW, gszWndClassName, c, winStyle,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, h, NULL);
}
WNDCLASSEX createWndClassEx(HINSTANCE h)
{
WNDCLASSEX w = { 0 };
w.cbSize = sizeof(WNDCLASSEX);
w.hInstance = h;
w.style = CS_HREDRAW | CS_VREDRAW;
w.lpszClassName = (LPCWSTR)gszWndClassName;
w.lpfnWndProc = WndProc;
return w;
}
A class with all static members which causes problems.
#ifndef _D3D9_OBJECT_H_
#define _D3D9_OBJECT_H_
#include <d3d9.h>
#include <d3dx9.h>
#include <d3dx9math.h>
#include "vertex_types.h"
/*
- sm_ - static member
- d39 - Direct3D9
- f - float
*/
class D3D9Object
{
public:
D3D9Object() { }
static bool init(HWND);
static void deinit();
static bool clear(int color = D3DCOLOR_XRGB(0, 0, 0), float fZDepth = 1.0f);
static IDirect3D9 * sm_pId39;
static IDirect3DDevice9 * sm_pd39Device;
~D3D9Object() { }
private:
static HWND sm_hWnd;
static float sm_fAspectRatio;
static HRESULT sm_hResult;
static bool createDevice();
static void setPresentParams(D3DPRESENT_PARAMETERS &);
static bool setDefaultRenderState();
};
extern D3D9Object * gpd39o;
#endif
d3d9_object.cpp
#include "d3d9_object.h"
IDirect3D9 * D3D9Object::sm_pId39;
IDirect3DDevice9 * D3D9Object::sm_pd39Device;
HRESULT D3D9Object::sm_hResult;
HWND D3D9Object::sm_hWnd;
float D3D9Object::sm_fAspectRatio;
bool D3D9Object::init(HWND h)
{
if (!h) return false;
sm_hWnd = h;
if (!(sm_pId39 = Direct3DCreate9(D3D_SDK_VERSION))) return false;
if (!createDevice()) return false;
if (!setDefaultRenderState()) return false;
return true;
}
void D3D9Object::deinit()
{
if (sm_pId39) sm_pId39->Release();
if (sm_pd39Device) sm_pd39Device->Release();
sm_pId39 = NULL;
sm_pd39Device = NULL;
sm_hWnd = NULL;
}
bool D3D9Object::clear(int c, float z)
{
sm_hResult = sm_pd39Device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, c, z, 0);
return sm_hResult == D3D_OK;
}
bool D3D9Object::setDefaultRenderState()
{
sm_hResult = sm_pd39Device->SetRenderState(D3DRS_LIGHTING, FALSE);
if (sm_hResult != D3D_OK) return false;
sm_hResult = sm_pd39Device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
if (sm_hResult != D3D_OK) return false;
return true;
}
bool D3D9Object::createDevice()
{
if (sm_pd39Device || !sm_pId39) return false;
D3DPRESENT_PARAMETERS params = { 0 };
setPresentParams(params);
sm_fAspectRatio = (float)params.BackBufferWidth / (float)params.BackBufferHeight;
sm_hResult = sm_pId39->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, sm_hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING,
¶ms, &sm_pd39Device);
if (sm_hResult != D3D_OK) {
sm_hResult = sm_pId39->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, sm_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING,
¶ms, &sm_pd39Device);
if (sm_hResult != D3D_OK) return false;
}
return true;
}
void D3D9Object::setPresentParams(D3DPRESENT_PARAMETERS &p)
{
ZeroMemory(&p, sizeof(D3DPRESENT_PARAMETERS));
p.hDeviceWindow = sm_hWnd;
p.BackBufferCount = 1;
p.SwapEffect = D3DSWAPEFFECT_FLIP;
p.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
p.EnableAutoDepthStencil = TRUE;
p.AutoDepthStencilFormat = D3DFMT_D16;
RECT r = { 0 };
GetClientRect(sm_hWnd, &r);
p.Windowed = true;
p.BackBufferWidth = r.right;
p.BackBufferHeight = r.bottom;
p.BackBufferFormat = D3DFMT_UNKNOWN;
}
D3D9Object gd39Object;
extern D3D9Object * gpd39o = &gd39Object;
And here is the output
1>------ Build started: Project: 3DEditor, Configuration: Debug Win32 ------
1> win_main.cpp
1> d3d9_object.h
1> d3d9_object.cpp
1> Generating Code...
1>Debug\d3d9_object.obj : warning LNK4042: object specified more than once; extras ignored
1>win_main.obj : error LNK2019: unresolved external symbol "public: static bool __cdecl D3D9Object::init(struct HWND__ *)" (?init#D3D9Object##SA_NPAUHWND__###Z) referenced in function _WinMain#16
1>win_main.obj : error LNK2019: unresolved external symbol "public: static void __cdecl D3D9Object::deinit(void)" (?deinit#D3D9Object##SAXXZ) referenced in function "void __cdecl exitWithFailure(wchar_t const *,struct HINSTANCE__ *)" (?exitWithFailure##YAXPB_WPAUHINSTANCE__###Z)
1>win_main.obj : error LNK2019: unresolved external symbol "public: static bool __cdecl D3D9Object::clear(int,float)" (?clear#D3D9Object##SA_NHM#Z) referenced in function _WinMain#16
1>C:\Users\User\documents\visual studio 2013\Projects\3DEditor\Debug\3DEditor.exe : fatal error LNK1120: 3 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Could you tell me what could cause LNK4042? I don't get where the object is specified multiple times. And I tried to google LNK2019, but all the topics I found were syntax issues. I checked everything I could find, but the code seems to be good (i'd be glad if it wasn't and you'd just point my mistake to me). Sometimes, when I do minor changes to the code the linker succeeds, but after several compilations it fails again. Also, before I added "clear" function it was working, I added this one little function, and it worked only once since then (before I added this function sometimes the linker did fail, but now it sometimes succeeds). I know there are other ways to implement singleton, but I have code similar to this, and it works fine. Thanks
Your build output shows that you somehow managed to force the compiler to actually compile d3d9_object.h file. This is completely unacceptable. You are not supposed to compile header files. Header files are supposed to be included into .cpp files, not compiled by themselves.
Because of that problem, your d3d9_object.h, after being force-fed to compiler, produces d3d9_object.obj file, which clobbers (overwrites) the proper d3d9_object.obj file obtained from d3d9_object.cpp. This leads to LNK4042 and further linker errors.
Don't attempt to compile d3d9_object.h. Find out how it managed to get compiled and fix the problem.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I made a class for Win32 and I have no idea why this error happens.
This is the code:
main.cpp
using namespace std;
#include "WindowManager.h"
#define WIDTH 700
#define HEIGHT 500
#define VERSION 0.1
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPreviousInstance,LPSTR lpcmdline,int nCmdShow)
{
WindowManager window("TalkToMe", 100, 100, WIDTH, HEIGHT);
while(window.isWindowOpen())
{
window.PekMessage();
}
return 0;
}
WindowManager.h
#pragma once
#include <Windows.h>
class WindowManager
{
private:
MSG msg;
HWND window;
int stat;
public:
WindowManager(LPCTSTR title,int x, int y, int width, int height);
~WindowManager();
LRESULT CALLBACK WindowProcedure(HWND winhan,UINT uint_Message,WPARAM parameter1,LPARAM parameter2);
inline bool isWindowOpen() { return stat != -1; }
int getStat() { return stat; }
void PekMessage();
};
WindowManager.cpp
#include "WindowManager.h"
void WindowManager::PekMessage()
{
if(PeekMessage(&msg, window, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
LRESULT CALLBACK WindowManager::WindowProcedure(HWND winhan,UINT uint_Message,WPARAM parameter1,LPARAM parameter2)
{
switch(uint_Message)
{
case 16: // exit button
stat = -1;
break;
}
return DefWindowProc(winhan,uint_Message,parameter1,parameter2);
}
WindowManager::WindowManager(LPCTSTR title,int x, int y, int width, int height)
{
stat = 0;
WNDCLASSEX wnd;
wnd.cbSize = sizeof(wnd);
wnd.style = CS_HREDRAW | CS_VREDRAW;
wnd.lpfnWndProc = WindowProcedure;
wnd.cbClsExtra = 0;
wnd.cbWndExtra = 0;
wnd.hInstance = GetModuleHandle(NULL);
wnd.hIcon = NULL;
wnd.hCursor = LoadCursor(NULL,IDC_ARROW);
wnd.hbrBackground = GetSysColorBrush(NULL);
wnd.lpszClassName = "TalkToMe";
wnd.lpszMenuName = NULL;
wnd.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassEx(&wnd);
window = CreateWindowEx(WS_EX_CONTROLPARENT, wnd.lpszClassName, title,
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE, x, y, width, height,NULL, NULL,
GetModuleHandle(NULL), NULL);
}
WindowManager::~WindowManager()
{
DestroyWindow(window);
}
This is the weird build failure:
1>------ Build started: Project: Client, Configuration: Debug Win32 ------
1> WindowManager.cpp
1>c:\users\user\documents\visual studio 2012\projects\talktome\talktome\windowmanager.cpp(31): error C3867: 'WindowManager::WindowProcedure': function call missing argument list; use '&WindowManager::WindowProcedure' to create a pointer to member
1>c:\users\user\documents\visual studio 2012\projects\talktome\talktome\windowmanager.cpp(31): error C2440: '=' : cannot convert from 'LRESULT (__stdcall WindowManager::* )(HWND,UINT,WPARAM,LPARAM)' to 'WNDPROC'
1> There is no context in which this conversion is possible
1> Generating Code...
1> Compiling...
1> Main.cpp
1> Generating Code...
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
This is to be expected. WindowManager::WindowManager has a hidden this argument, thus it does not respect the definition required for wnd.lpfnWndProc.
To work around this issue, you need to define a helper function as follows:
LRESULT CALLBACK HelperWindowProcedure(HWND winhan,UINT uint_Message,WPARAM parameter1,LPARAM parameter2)
{
if (uint_Message == WM_CREATE)
{
/* Retrieve "this" sent through CreateWindowEx */
WindowManager *wm = (WindowManager *)(((LPCREATESTRUCT) lParam)->lpCreateParams);
/* And store it as window-private date */
SetWindowLongPtr(winhan, GWLP_USERDATA, wm);
}
/* Retrieve WindowManager from window-private data */
WindowManager *wm = (WindowManager *)GetWindowLongPtr(winhan, GWLP_USERDATA);
/* Forward window message to WindowManager */
wm->WindowProcedure(winhan, uint_Message, parameter1, parameter2);
}
WindowManager::WindowManager()
{
...
/* use helper window procedure */
wnd.lpfnWndProc = HelperWindowProcedure;
...
/* send "this" through WM_CREATE */
window = CreateWindowEx(WS_EX_CONTROLPARENT, wnd.lpszClassName, title,
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE, x, y, width, height,NULL, NULL,
GetModuleHandle(NULL), this);
}
As user1202136 mentioned, C++ class methods have implicit parameter that gets passed into the function whenever it is called. It holds the pointer to the class instance (this pointer) and allows you to access the class variables. In order to resolve this issue, you can make the WindowProcedure method static and use GWL_USERDATA within the window memory to store your class instance (this pointer). Look up GetWindowLongPtr for more information. When creating the window you'll need to pass this pointer via lpParam parameter, and store it using SetWindowLongPtr when you are handling WM_CREATE message.
check solutions:
wnd.lpfnWndProc = (WNDPROC)WindowProcedure;
or
LRESULT WNDPROC WindowManager::WindowProcedure(HWND winhan,UINT uint_Message,WPARAM parameter1,LPARAM parameter2)
I am having issues with my code. I am making a class to wrap around some WinAPI to create GUIs, however I am having issues when attempting to register the class.
My code:
inline Window::Window(const TCHAR *windowName, const int x, const int y, const int width, const int height, const TCHAR *className) : abstractWindow() {
Window(0, className, windowName, WS_OVERLAPPEDWINDOW, x, y, width, height, NULL, NULL, NULL, NULL);
}
Window::Window(const DWORD dwExStyle, const TCHAR *lpClassName, const TCHAR *lpWindowName, const DWORD dwStyle, const int x, const int y, const int nWidth, const int nHeight, const HWND hWndParent, const HMENU hMenu, const HINSTANCE hInstance, const LPVOID lpParam) : abstractWindow() {
_proc = (WNDPROC*) &abstractWindow::msgRouter;
_styleEx = dwExStyle;
_className = (!lpClassName) ? TEXT("MyGuiClass") : lpClassName;
_windowName = lpWindowName;
_style = dwStyle;
_x = x;
_y = y;
_width = nWidth;
_height = nHeight;
_hwndParent = hWndParent;
_hInstance = (!hInstance) ? ::GetModuleHandle(NULL) : hInstance;
_hMenu = hMenu;
_lpParam = lpParam;
_wndClassEx.cbSize = sizeof(_wndClassEx);
_wndClassEx.style = CS_HREDRAW | CS_VREDRAW;
_wndClassEx.lpfnWndProc = abstractWindow::msgRouter;
_wndClassEx.cbClsExtra = 0;
_wndClassEx.cbWndExtra = 0;
_wndClassEx.hInstance = _hInstance;
_wndClassEx.hIcon = ::LoadIcon(NULL, IDI_APPLICATION);
_wndClassEx.hCursor = ::LoadCursor(NULL, IDC_ARROW);
_wndClassEx.hbrBackground = (HBRUSH) COLOR_WINDOW;
_wndClassEx.lpszMenuName = NULL;
_wndClassEx.lpszClassName = _className;
_wndClassEx.hIconSm = ::LoadIcon(NULL, IDI_APPLICATION);
}
_wndClassEx is already defined in the class header as of WNDCLASSEX and the register function simply runs RegisterClassEx(&_wndClassEx).
The following are how I call these classes: (However only one is called at a time)
Window gui (TEXT("Title"), 10, 10, 500, 250);
Window gui (0, NULL, TEXT("Title"), WS_OVERLAPPEDWINDOW, 10, 10, 500, 200, NULL, NULL, hInstance, NULL);
The second one works perfectly fine, however when I call the first (shorter parameters, which puts it through to the second) class registration fails. I have completely written the _wndClassEx as well as gone through every single one and modified it to no success. I have gone through with a debugger and everything seems fine. So I have absolutely no idea what to do.
By the way, abstractWindow::msgRouter is static.
Thanks.
The problem is with this constructor:
inline Window::Window(const TCHAR *windowName, const int x, const int y, const int width, const int height, const TCHAR *className) : abstractWindow() {
Window(0, className, windowName, WS_OVERLAPPEDWINDOW, x, y, width, height, NULL, NULL, NULL, NULL);
}
You can't call a constructor from another constructor like that. What ends up happening is that a temporary object is created and then immediatly discarded. The way to achieve that (this only works if you have a compiler which implements this feature from the new C++11 Standard) is if you say
inline Window::Window(const TCHAR *windowName, const int x, const int y, const int width, const int height, const TCHAR *className) : Window(0, className, windowName, WS_OVERLAPPEDWINDOW, x, y, width, height, NULL, NULL, NULL, NULL) {};
Another way would be to do what #aztaroth said: create a separate method and call it from both constructors (that works even with an older compiler).
Write a method that initializes the window (basically cut and paste the second constructor), then call it with proper values from both constructors.
I have a book : "Introduction to 3D game programming with DirectX 9.0c– a shader approach" by Frank Luna.
The official site is dead and I can't seem to find 3 main files used for all the projects.
d3dApp.h
d3dApp.cpp
d3dUtil.h
Does someone know where can I get them?
All I have found was this :
http://www.d3dcoder.net/
http://www.d3dcoder.net/phpBB/
But there is no source there.
Also I've found some fragments
//A sample directX demo outputting some flashing color text
#include "d3dApp.h"
#include <tchar.h>
#include <crtdbg.h>
//Our application is derived from the D3DAPP class, making setup for a game
//or other program easier in the long run
class HelloD3DApp : public D3DApp
{
public:
HelloD3DApp(HINSTANCE hInstance, std::string winCaption, D3DDEVTYPE devType, DWORD requestedVP);
~HelloD3DApp();
bool checkDeviceCaps();
void onLostDevice();
void onresetDevice();
void updateScene(float dt);
void drawScene();
private:
ID3DXFont* mFont;
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance,
PSTR cmdLine, int showCmd)
{
// Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
HelloD3DApp app(hInstance, "Hello Direct3D", D3DDEVTYPE_HAL, D3DCREATE_HARDWARE_VERTEXPROCESSING);
gd3dApp = &app;
return gd3dApp->run();
}
HelloD3DApp::HelloD3DApp(HINSTANCE hInstance, std::string winCaption, D3DDEVTYPE devType, DWORD requestedVP)
: D3DApp(hInstance, winCaption, devType, requestedVP)
{
srand(time_t(0));
if(!checkDeviceCaps())
{
MessageBox(0, "checkDeviceCaps() Failed", 0, 0);
PostQuitMessage(0);
}
LOGFONTA font;
font.lfHeight = 80;
font.lfWidth = 40;
font.lfEscapement = 0;
font.lfOrientation = 0;
font.lfWeight = FW_BOLD;
font.lfItalic = true;
font.lfUnderline = false;
font.lfStrikeOut = false;
font.lfCharSet = DEFAULT_CHARSET;
font.lfOutPrecision = OUT_DEFAULT_PRECIS;
font.lfClipPrecision = CLIP_CHARACTER_PRECIS;
font.lfQuality = DEFAULT_QUALITY;
font.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
_tcscpy(font.lfFaceName, _T("Times New Roman"));
HR(D3DXCreateFontIndirect(gd3dDevice, &font, &mFont));
}
HelloD3DApp::~HelloD3DApp()
{
ReleaseCOM(mFont);
}
bool HelloD3DApp::checkDeviceCaps()
{
// Nothing to check.
return true;
}
void HelloD3DApp::onLostDevice()
{
HR(mFont->OnLostDevice());
}
void HelloD3DApp::onresetDevice()
{
HR(mFont->onresetDevice());
}
void HelloD3DApp::updateScene(float dt)
{
}
void HelloD3DApp::drawScene()
{
HR(gd3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(255, 255, 255), 1.0f, 0));
RECT formatRect;
GetClientRect(mhMainWnd, &formatRect);
HR(gd3dDevice->BeginScene());
mFont->DrawText(TEXT("Hello </DIC>!"), -1,
&formatRect, DT_CENTER | DT_VCENTER,
D3DCOLOR_XRGB(rand() % 256, rand() % 256, rand() % 256));
HR(gd3dDevice->EndScene());
HR(gd3dDevice->Present(0, 0, 0, 0));
}
But these does not help me either.
d3dApp.h
d3dApp.cpp
d3dUtil.h
These are the same files as in the zip file.