-
My Win32 wrapper
How do you like my new wrapper? Who said Win32 is hard? :)
It's mostly inspired by .NET langauges where I normally work in professionally. I wrote this wrapper to build native games, but I thought of adding a simple GUI interace with basic controls. I have buttons right now but can add text boxes, radio buttons, etc. What's nice is the WndProc function isn't visible. It's called by default, but if a callback function is assigned, it calls that instead. Each common event has a callback function option. I also use references instead of regular pointers (C++ feature). Even though it makes it look cleaner, it's hard to tell on the surface. If X3DForm_StartGameMode(frm, myGameLogicFunc) is called, it starts in real-time mode and you do your game logic in myGameLogicFunc() or whatever you call it. If it's not called, it's just a regular event-driven application. It's fun to build on, but also keeps everything fairly simple and something I might share soon after.
Code:
#include "stdafx.h"
X3DFORM frm;
X3DBUTTON btnSubmit;
void myCommandFunc(int id)
{
if (btnSubmit.ID == id) {
// do work
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
X3DForm_Init(frm, hInstance);
X3DForm_OnCommand(frm, myCommandFunc);
// init button
X3DForm_CreateButton(frm, btnSubmit, "Submit", 50, 50);
X3DForm_AddButton(frm, btnSubmit);
X3DForm_Show(frm);
return 0;
}
-
You say it uses C++ references? Then why do I see a non-OO approach?
Also, you know that there are many GUI libraries out there already (ie Qt, wxWidgets, GTK, etc)?
-
Crazy, huh? Why didn't I pick your preferred paradigm or your selected choice of assembly language? Be a little less rude next time.
-
Not rude. A wonder. I'm sorry if you took it for a rude reply.
I'm just saying that if you are aiming this at C++ programmers, then your code is probably going to be criticized. If you're aiming at C programmers, then you can't use references.
Either way, it's up to you. I'm just saying.
My own opinion is that I would never use a non-OOP C++ solution. Can't say about others, though.
-
I thougt it over. One my long-term job targets uses OOP for their games (technically Python ontop of C++), so I thought of turning it into OO to see how it would work. It took about an hour to change. The result ended up being nicer. There's less to type to make something happen. Lot less "X3DForm_DoSomething(myobject, myVar)", which turned into myObject.DoSomething(myVar). This is just a rough change at this time. I think I'll stick with the OOP approach since its less cluttering.
Code:
#include "stdafx.h"
X3DForm frm;
X3DButton btnExit;
void myCommandFunc(int id)
{
if (btnExit.ID == id)
{
frm.Close();
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
frm.Init(hInstance);
frm.OnCommand(myCommandFunc);
btnExit.Init("Submit", 50, 50);
frm.Add(btnExit);
frm.Show();
return 0;
}
-
Thanks Elysia, I guess it had to sink into my brain a little and it made sense a bit after. Sorry for taking offense earlier. I was able to make events work much smoother. Rather than polling for ids in the previous example, I added events more similar to .NET.
I have a question though... I always have to put my classes out in the global area to make this code work. Is it normal for classes to be global? I would consider a global "i" to be more dangerous than something like btnClose. I can see a large GUI and there's several global controls in this case.
Code:
#include "stdafx.h"
using namespace X3D;
using namespace X3D::Win32;
Form frm;
Button btnClose;
void btnClose_Click()
{
frm.Close();
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
frm.Init(hInstance, "My form", 800, 600);
btnClose.Init("Close", 50, 50);
btnClose.OnClick(btnClose_Click);
frm.Add(btnClose);
frm.Show();
return 0;
}
-
Mmm, I don't know why they need to be global in this example.
Actually, if you ask me, I like the idea of requiring you to utilize the constructor to initialize the object. That way, you can avoid checks in your other functions to check if the object has been initialized.
Something like
Code:
#include "stdafx.h"
using namespace X3D::Win32 = w32;
void btnClose_Click()
{
frm.Close();
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
w32::Form frm(hInstance, "My form", 800, 600);
w32::Button btnClose("Close", 50, 50);
btnClose.OnClick(btnClose_Click);
frm.Add(&btnClose);
frm.Show();
return 0;
}
Isn't the idea that Show would block until the window closes?
If so, then there shouldn't be any problems that I see?
I don't see the need for globals in this case, but sometimes they may be required.
I like what I see so far, though! You're making inroads to making a nice GUI library.
-
Hmm, I tried it out and I get this error on the third line:
error C2143: syntax error : missing ';' before '='
Line: using namespace X3D::Win32 = w32;
The assignment syntax is new to me. Is that for a particular compiler?
-
No, it's just me who messed up the syntax, as usual.
It should be
namespace w32 = X3D::Win32;
-
Okay. It has one more compile issue with 'frm' being used in btnClose_Click(). It's not visible in the global scope so I'm figuring that's why. It would be ideal if they were all in the global namespace so the application can refer to the controls whenever needed ('frm' in this example), though I don't like a long list of global variables at the end either lol. It's meant to be a simple GUI anyway with the primary focus on games. Probably not a big deal then. Thanks for the help!
-
Mmm, that's what you get for not compiling.
But you could pass a reference to the event handler of the control in question.