I've been following the Sprite tutorial and the tutorial about integrating with Win32. I've made my code compile and whatnot, but all I get is a white window!
// TSO GUI.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "TSO GUI.h"
#include "UIScene.h"
#include <SFML/Graphics.hpp>
#define MAX_LOADSTRING 100
// Global Variables:
HWND g_hWnd; // The application's window.
HWND m_SFMLWindow; // The SFML window.
sf::RenderWindow m_SFMLView; // The SFML renderwindow.
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
UI::UIScene TestScene("gamedata\\uiscripts\\personselection.uis");
#define WINDOW_WIDTH 800 // Preferred width of the app
#define WINDOW_HEIGHT 600 // Preferred height of the app
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_TSOGUI, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
//InitDirect3d();
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TSOGUI));
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
m_SFMLView.Clear();
TestScene.Draw(&m_SFMLView);
m_SFMLView.Display();
}
}
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;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TSOGUI));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_TSOGUI);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HINSTANCE, 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.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Store instance handle in our global variable
g_hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0,
WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hInstance, NULL);
DWORD Style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS;
m_SFMLWindow = CreateWindow((LPCWSTR)"STATIC", NULL, Style, 50, 100, 300, 400, g_hWnd, NULL, hInst, NULL);
m_SFMLView.Create(m_SFMLWindow);
if (!g_hWnd)
{
return FALSE;
}
ShowWindow(g_hWnd, nCmdShow);
UpdateWindow(g_hWnd);
m_SFMLView.Show(true);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 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;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
//DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
/*case WM_PAINT:
m_SFMLView.Clear();
TestScene.Draw(&m_SFMLView);
m_SFMLView.Display();
break;*/
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
UIScene.cpp contains my rendering logic:
#include "stdafx.h"
#include "UIScene.h"
#include "Helpers.h"
namespace UI
{
string Crunch(string Str);
UIScene::UIScene(std::string ScriptPath)
{
ifstream UIScript(ScriptPath.c_str());
if(UIScript.is_open())
{
string CurrentLine;
vector<string> Params;
vector<UIProperty> Properties; //Shared properties for controls defined in a block.
cout << "Loaded UIScript: " << ScriptPath << "\r\n";
while(getline(UIScript, CurrentLine))
{
//Trim all leading and trailing spaces from a statement.
Helpers::Trim(CurrentLine);
CurrentLine = Crunch(CurrentLine);
if(CurrentLine != "")
{
Helpers::StringSplit(CurrentLine, " ", &Params);
//# == comment.
if(CurrentLine.substr(0, 1) != "#")
{
if(Params.size() > 1)
{
if(Params[0] == "DefineImage")
{
UIImage Img(Params[1], Params[3], ScriptPath);
m_Images.push_back(Img);
//TODO: Load imagedata from ID...
}
else if(Params[0] == "Begin" && Params[2] == "stringDir")
{
cout << "Found StringTable header!" << "\r\n";
//The SetSharedProperty 'function' for stringtables also includes a directory
//parameter, but all the text in the game is in the uitext directory anyways...
int TableID = atoi(Params[5].c_str());
m_StrTable = StringTable(TableID);
}
//The previous section that defines 'access' to the stringtable itself
//will always come before the strings, so it's safe to assume the table
//has been loaded at this point.
else if(Params[0] == "DefineString")
{
int StrID = atoi(Params[3].c_str());
//cout << "ID: " << StrID << "\r\n";
if(m_StrTable.GetStrFromID(StrID))
{
m_StrTable.GetStrFromID(StrID)->SetLabel(Params[1]);
//cout << "Label: " << Params[1] << "\r\n";
}
}
else if(Params[0] == "Begin" && Params[1] == "SetSharedProperties")
{
for(int i = (Params.size() - 1); i > 2; i = i - 2)
{
UIProperty Prop(Params[i - 1], Params[i]);
Properties.push_back(Prop);
}
}
else if(Params[0] == "End")
{
Properties.clear();
}
else if(Params[0] == "AddButton")
{
//Position looks like: 123,456
vector<string> XY;
Helpers::StringSplit(Params[5], ",", &XY);
UIButton Btn(Params[1], atoi(Params[3].c_str()),
atoi(XY[0].c_str()), atoi(XY[1].c_str()), &m_Images);
for(unsigned int i = 0; i < Properties.size(); i++)
{
Btn.AddProperty(Properties[i], &m_StrTable);
//cout << "Added property!" << "\r\n";
}
m_UIElements.push_back(Btn);
}
else if(Params[0] == "AddSlider")
{
vector<string> XY;
Helpers::StringSplit(Params[5], ",", &XY);
UISlider Slider(Params[1], atoi(Params[3].c_str()),
atoi(XY[0].c_str()), atoi(XY[1].c_str()), &m_Images);
for(unsigned int i = 0; i < Properties.size(); i++)
Slider.AddProperty(Properties[i], &m_StrTable);
m_UIElements.push_back(Slider);
}
}
}
}
Params.clear();
}
}
UIScript.close();
}
//Removes all extraneous tabs and spaces from within a string,
//in addition to removing all unneccessary and redundant characters
//from a string (<,>,=,").
string Crunch(string Str)
{
Helpers::Replace(Str, "(", " ");
Helpers::Replace(Str, ")", " ");
//Helpers::Replace(Str, ",", " ");
Helpers::Replace(Str, "<", " ");
Helpers::Replace(Str, ">", " ");
Helpers::Replace(Str, "=", " ");
Helpers::Replace(Str, "\"", " ");
stringstream StrStream(Str);
string Word;
string NewLine = "";
while(StrStream >> Word)
NewLine = NewLine + Word + " ";
return NewLine;
}
UIImage *UIScene::GetUIImage(std::string ImgLabel)
{
for(unsigned int i = 0; i < m_Images.size(); i++)
{
if(m_Images[i].GetLabel() == ImgLabel)
return &m_Images[i];
}
}
void UIScene::Draw(sf::RenderWindow *Wnd)
{
sf::Sprite Spr;
for(unsigned int i = m_UIElements.size(); i > 0; i--)
m_UIElements[i].Draw(Wnd);
}
}
UIButton.cpp derives from class UIElement and shows how I Draw() a Sprite.
#include "stdafx.h"
#include "UIButton.h"
#include "Helpers.h"
UIButton::UIButton(string Label, int ID, int X, int Y, vector<UIImage> *ImgList)
{
m_Label = Label;
m_ID = ID;
m_X = X;
m_Y = Y;
m_ImgList = ImgList;
}
void UIButton::Draw(sf::RenderWindow *Wnd)
{
sf::Sprite Spr;
Spr.SetImage(*(m_Img->GetImage()));
Spr.SetX(m_X);
Spr.SetY(m_Y);
Spr.SetBlendMode(sf::Blend::Mode::Alpha);
Wnd->Draw(Spr);
}
void UIButton::AddProperty(UIProperty Property, StringTable *StrTable)
{
if(Property.GetName() == "image")
{
for(unsigned int i = 0; i < (*m_ImgList).size(); i++)
{
if((*m_ImgList)[i].GetLabel() == Property.GetValue())
m_Img = &(*m_ImgList)[i];
}
}
else if(Property.GetName() == "tracking")
m_Tracking = atoi(Property.GetValue().c_str());
else if(Property.GetName() == "trigger")
m_Trigger = atoi(Property.GetValue().c_str());
else if(Property.GetName() == "tooltip")
m_ToolTip = *StrTable->GetStrFromLabel(Property.GetValue());
else if(Property.GetName() == "size")
{
vector<string> SplitString;
Helpers::StringSplit(Property.GetValue(), ",", &SplitString);
m_Width = atoi(SplitString[0].c_str());
m_Height = atoi(SplitString[1].c_str());
}
}
Any idea what's wrong?