After much
pain, and using another
resource, I finally got my window wrapper to actually compile. Much happiness ensued.
yet, when I run my code, CreateWindow(...) fails. The API call within the TWindow::Show() call.
There are warnings generated about pointer truncation, which I would love to be solved as well.
So, I'm going to post my whole code in the hopes that someone with more experience can point me in the right direction, as I am getting very frustrated with this! Which is never good!
So if you have any idea, post!!! I will be very grateful!
TWindow.h
#ifndef TWINDOW_H
#define TWINDOW_H
#include <Windows.h>
#include <WindowsX.h>
#include <map>
#include "TRESULT.h"
#define CLASSNAME "TWindow"
class TWindow;
typedef long (* tyMessageHandler)(TWindow &,HWND, long, long);
typedef std::map<long, tyMessageHandler> tyMessageMap;
typedef tyMessageMap::iterator tyMessageIterator;
class TWindow
{
public:
TWindow(HINSTANCE hInstance);
TRESULT Create(DWORD style,int width, int height);
static LRESULT CALLBACK dfMsgRouter(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
//LRESULT CALLBACK MsgRouter(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
tyMessageIterator GetMessageHandler(long message);
tyMessageHandler RegisterMessageHandler(long message,tyMessageHandler handler);
void SetHWND(HWND hwnd);
bool IsExit();
TRESULT Show();
bool TWindow::HandleMessages();
//static member functions
static long OnClose(TWindow &wnd,HWND hwnd, long param0, long param1);
static long OnDestroy(TWindow &wnd, HWND hwnd, long param0, long param1);
int ExitCode();
void SetExitCode(long code);
private:
tyMessageMap m_MsgHandlers;
bool m_exit; // true = exiting
HWND m_hwnd;
WNDCLASSEX m_winClass; //Main windows class
HINSTANCE m_hInstance;
long m_exitCode;
DWORD m_style;
int m_height;
int m_width;
};
#endif
TWindow.cpp
#include "TWindow.h"
void TWindow::SetHWND(HWND hwnd)
{
m_hwnd = hwnd;
}
bool TWindow::IsExit()
{
return m_exit;
}
// Window::OnClose is a static method called in response to WM_CLOSE
long TWindow::OnClose(TWindow &wnd,HWND hwnd, long param0, long param1)
{
DestroyWindow(hwnd);
return 0;
}
// Window::OnDestroy is a static method called in response to WM_DESTROY
long TWindow::OnDestroy(TWindow &wnd,HWND hwnd, long param0, long param1)
{
PostQuitMessage(0);
return 0;
}
TRESULT TWindow::Create(DWORD style,int width, int height)
{
HWND hwnd = 0;
m_winClass.cbSize = sizeof(WNDCLASSEX);
m_winClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
m_winClass.lpfnWndProc = TWindow::dfMsgRouter;
m_winClass.cbClsExtra = 0;
m_winClass.cbWndExtra = 4;
m_winClass.hInstance = this->m_hInstance;
m_winClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
m_winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
m_winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
m_winClass.lpszMenuName = NULL;
m_winClass.lpszClassName = "TWindow";
m_winClass.hIconSm = LoadIcon(NULL,IDI_APPLICATION);
//register the window
if (!RegisterClassEx (&m_winClass))
{
MessageBox (NULL, TEXT ("RegisterClassEx failed!"), "Error", MB_ICONERROR);
return(T_WND_CREATE_FAIL);
}
this->SetHWND(hwnd);
this->RegisterMessageHandler(WM_CLOSE,&TWindow::OnClose);
this->RegisterMessageHandler(WM_DESTROY,&TWindow::OnDestroy);
m_style = style;
m_height = height;
m_width = width;
return(T_OK);
}
// Window::HandleMessage ties everything together
bool TWindow::HandleMessages()
{
static MSG msg;
if(!m_hwnd)
{
m_exitCode = -1;
//throw std::runtime_error(std::string("Window not yet created"));
return false;
}
PeekMessage(&msg, m_hwnd, 0, 0, PM_REMOVE);
::TranslateMessage(&msg);
::DispatchMessage(&msg);
if(IsExit())
{
SetExitCode((long)msg.lParam);
return false;
}
return true;
}
void TWindow::SetExitCode(long code)
{
m_exitCode = code;
}
TWindow::TWindow(HINSTANCE hInstance)
{
m_hInstance = hInstance;
m_exitCode = 0;
}
tyMessageIterator TWindow::GetMessageHandler(long message)
{
// m_MsgHandlers is a tyMessageMap instance
tyMessageIterator it = m_MsgHandlers.find(message);
if(it == m_MsgHandlers.end())
return NULL;
return it;
}
tyMessageHandler TWindow::RegisterMessageHandler(long message,
tyMessageHandler handler)
{
tyMessageHandler m = NULL;
tyMessageIterator it = m_MsgHandlers.find(message);
if(it != m_MsgHandlers.end())
m = it->second;
m_MsgHandlers.insert(std::pair<long,tyMessageHandler>(message, handler));
return m;
}
TRESULT TWindow::Show()
{
if(!(m_hwnd = CreateWindow(NULL, "TWindow", m_style, 0,0,m_width,m_height, NULL, NULL, m_hInstance, (void*)this)))
return(T_WND_CREATE_FAIL);
UpdateWindow (m_hwnd);
return(T_OK);
}
LRESULT CALLBACK TWindow::dfMsgRouter(HWND hwnd, UINT message,
WPARAM wparam, LPARAM lparam)
{
TWindow* pWnd;
if (message == WM_NCCREATE)
::SetWindowLong(hwnd, GWL_USERDATA, (long)((LPCREATESTRUCT(lparam))->lpCreateParams));
// get the pointer to the window
pWnd = (TWindow *)GetWindowLong(hwnd, GWL_USERDATA);
// if we have the pointer, go to the message handler of the window
// else, use DefWindowProc
if(pWnd)
{
tyMessageIterator it;
it = pWnd->GetMessageHandler(message);
if(it != NULL)
return (it->second)((*pWnd), hwnd, wparam, lparam);
}
return DefWindowProc(hwnd, message, wparam, lparam);
}
int TWindow::ExitCode()
{
return m_exitCode;
}
main.cpp
//#include <windows.h>
#include "TWindow.h"
static TWindow *g_wnd;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
g_wnd = new TWindow(hInstance);
g_wnd->Create(WS_OVERLAPPEDWINDOW|WS_VISIBLE,400,400);
if(!g_wnd)
return -1;
g_wnd->Show(); //this call fails
while(true)
{
if(!g_wnd->HandleMessages()) //thus the check in this call fails, killing the app.
break;
}
return g_wnd->ExitCode();
}
The error code thing is
#ifndef TRESULT_H
#define TRESULT_H
/************************************************************************/
/* Defines the return codes used by the tempest endinge */
/************************************************************************/
typedef unsigned int TRESULT;
#define T_OK 0x0 //generic ok
#define T_ERROR 0x1 //generic error
#define T_WND_CREATE_FAIL 0x2 //window failed to create
#endif
1>------ Build started: Project: Tempest, Configuration: Debug Win32 ------
1>Compiling...
1>TWindow.cpp
1>c:\documents and settings\chris\my documents\programming\c++\tempest\working source\twindow.cpp(162) : warning C4311: 'type cast' : pointer truncation from 'LPVOID' to 'long'
1>c:\documents and settings\chris\my documents\programming\c++\tempest\working source\twindow.cpp(166) : warning C4312: 'type cast' : conversion from 'LONG' to 'TWindow *' of greater size
1>c:\documents and settings\chris\my documents\programming\c++\tempest\working source\twindow.cpp(175) : warning C4244: 'argument' : conversion from 'LPARAM' to 'long', possible loss of data
1>c:\documents and settings\chris\my documents\programming\c++\tempest\working source\twindow.cpp(175) : warning C4244: 'argument' : conversion from 'WPARAM' to 'long', possible loss of data
1>Linking...
1>Embedding manifest...
1>Build log was saved at "file://c:\Documents and Settings\Chris\My Documents\Programming\C++\Tempest\Builds\Intermediate\BuildLog.htm"
1>Tempest - 0 error(s), 4 warning(s)
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
Many thanks!!