cmake-d/samples/minwin_gtk/minwin/app.d

245 lines
6.3 KiB
D
Raw Normal View History

2007-08-28 16:16:58 +00:00
/* MinWin Application structure
*
* An Application encapsulates the global state provided by
* the OS when starting the application and it manages the event queue.
*
* Written by Ben Hinkle and released to the public domain, as
* explained at http://creativecommons.org/licenses/publicdomain
* Report comments and bugs at dsource: http://www.dsource.org/projects/minwin
*/
module minwin.app;
private {
import minwin.logging;
import minwin.multidg;
import minwin.event;
import std.string;
}
version(MinWin32) {
private import minwin.mswindows;
}
extern (C) void gc_init();
extern (C) void gc_term();
extern (C) void _minit();
extern (C) void _moduleCtor();
extern (C) void _moduleUnitTests();
extern (C) int MinWinMain(Application* app);
const int NO_ID = -1;
class MinWinException : Exception {
int id = NO_ID;
this(char[] msg) {
super(msg);
}
this(char[] msg, int id) {
this.id = id;
if (id == NO_ID)
super(msg);
else
super(format("%s (error code %x)",msg,id));
}
}
// Assert a condition is true and if not throw an exception.
void sysAssert(bool passed, char[] msg, int id = 0) {
if (!passed) {
version (MinWin32) {
if (GetVersion() < 0x80_00_00_00 || id != 0) {
throw new MinWinException(msg,id);
} else {
throw new MinWinException(msg,GetLastError());
}
} else {
throw new MinWinException(msg,id);
}
}
}
Application gApp;
version (MinWin32) {
extern (Windows)
void MinWinIdleProc(HWND hWnd, uint msg, uint id, DWORD time) {
gApp.idleDelegate();
}
struct Application {
char[] rsrc(char[] id, char[] group = "strings") {
wchar[] wres;
char[] cres;
if (useWfuncs)
wres.length = 64;
else
cres.length = 64;
int len;
for (;;) {
if (useWfuncs) {
len = cast(int)LoadStringW(gApp.hInstance,toUTF16z(id),wres.ptr,wres.length);
if (len < wres.length) break;
else wres.length = 2*wres.length;
}
else {
len = cast(int)LoadStringA(gApp.hInstance,toMBSz(id),cres.ptr,cres.length);
if (len < cres.length) break;
else cres.length = 2*cres.length;
}
}
if (useWfuncs)
return toUTF8(wres[0..len]);
else {
return fromMBSz(cres[0..len].ptr);
}
}
char[][] cmdLineArgs(){
// TODO: parse cmd line args
return parsedCmdLineArgs;
}
MultiDelegate!() idleDelegate;
private uint fTimerID;
private uint fIdleTime;
uint idleTime() {
return fIdleTime;
}
void idleTime(uint t) { // time 0 means stop
fIdleTime = t;
if (fTimerID) {
BOOL ok = KillTimer(null,fTimerID);
sysAssert(ok != false, "Failed to kill existing timer");
}
if (t) {
fTimerID = SetTimer(null,0,t,&MinWinIdleProc);
sysAssert(fTimerID != 0, "Failed to set timer");
}
}
int enterEventLoop() {
while (nextEvent(&event)) {
// TODO: check IsDialogMessage
dispatchEvent(&event);
}
return 1;
}
void exitEventLoop() {
PostQuitMessage(0);
}
HINSTANCE hInstance;
HINSTANCE hPrevInstance;
LPSTR lpCmdLine;
char[][] parsedCmdLineArgs;
int nCmdShow;
Event event;
}
extern (Windows)
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
int result;
gc_init(); // initialize garbage collector
_minit(); // initialize module constructor table
try
{
_moduleCtor(); // call module constructors
_moduleUnitTests(); // run unit tests (optional)
gApp.hInstance = hInstance;
gApp.hPrevInstance = hPrevInstance;
gApp.nCmdShow = nCmdShow;
version (LOG) log.writefln("about to enter MinWinMain");
result = MinWinMain(&gApp);
version (LOG) log.writefln("done with MinWinMain");
}
catch (Object o) // catch any uncaught exceptions
{
MessageBoxX(null, o.toString(), "Error",MB_OK | MB_ICONEXCLAMATION);
result = 0; // failed
}
version(LOG) log.close();
if (gApp.fTimerID) {
BOOL ok = KillTimer(null,gApp.fTimerID);
sysAssert(ok != false, "Failed to kill existing timer at exit");
}
gc_term(); // run finalizers; terminate garbage collector
return result;
}
} else version (GTK) {
private {
import minwin.gtk;
import std.string;
import std.file;
}
extern (C)
gboolean MinWinIdleProc(gpointer data) {
gApp.idleDelegate();
return true;
}
struct Application {
char[][] cmdLineArgs;
char[] rsrc(char[] id, char[] group = "strings") {
// TODO
return "";
}
char[] resourcePath;
int enterEventLoop() {
gtk_main();
return 1;
}
void exitEventLoop() {
gtk_main_quit();
}
MultiDelegate!() idleDelegate;
uint fIdleTime;
uint idleTime() {
return fIdleTime;
}
guint fTimerID;
static
void idleTime(uint t) {
gApp.fIdleTime = t;
if (gApp.fTimerID)
g_source_remove(gApp.fTimerID);
if (t)
gApp.fTimerID = g_timeout_add(t,&MinWinIdleProc,null);
}
}
int main(char[][] args) {
gApp.cmdLineArgs = args;
char*[] argv;
argv.length = args.length;
foreach (int n, char[] str; args) {
argv[n] = toStringz(str);
}
int argc = args.length;
char**argvp = argv.ptr;
gtk_init(&argc,&argvp);
int res = MinWinMain(&gApp);
version(LOG) log.close();
return res;
}
}