#define _CRT_SECURE_NO_WARNINGS

#include <Windows.h>
#include <stdio.h>

	//http://www.vbforums.com/showthread.php?874127-Persistent-Debug-Print-Window

	int ENABLE_REMOTE_DEBUG = 1;

	int Warned = 0;
	HWND hServer = 0;

	HWND regFindWindow(void) {

		const char* baseKey = "Software\\VB and VBA Program Settings\\dbgWindow\\settings";
		char tmp[20] = { 0 };
		unsigned long l = sizeof(tmp);
		HWND ret = 0;
		HKEY h;

		printf("regFindWindow triggered\n");

		RegOpenKeyExA(HKEY_CURRENT_USER, baseKey, 0, KEY_READ, &h);
		RegQueryValueExA(h, "hwnd", 0, 0, (unsigned char*)tmp, &l);
		RegCloseKey(h);

		ret = (HWND)atoi(tmp);
		if (!IsWindow(ret)) ret = 0;
		return ret;
	}

	void FindVBWindow() {
		const char* vbIDEClassName = "ThunderFormDC";
		const char* vbEXEClassName = "ThunderRT6FormDC";
		const char* vbEXEClassName2 = "ThunderRT6Form";
		const char* vbWindowCaption = "Persistent Debug Print Window";

		hServer = FindWindowA(vbIDEClassName, vbWindowCaption);
		if (hServer == 0) hServer = FindWindowA(vbEXEClassName, vbWindowCaption);
		if (hServer == 0) hServer = FindWindowA(vbEXEClassName2, vbWindowCaption);
		if (hServer == 0) hServer = regFindWindow(); //if ide is running as admin

		if (hServer == 0) {
			if (!Warned) {
				//MessageBox(0,"Could not find msg window","",0);
				Warned = 1;
			}
		}
		else {
			if (!Warned) {
				//first time we are being called we could do stuff here...
				//printf("hServer = %x\n", hServer);
				Warned = 1;

			}
		}

	}

	int dbgmsg(const char* Buffer) {

		int ret = 0;
		COPYDATASTRUCT cpStructData;

		if (!ENABLE_REMOTE_DEBUG) return -1;

		if (!IsWindow(hServer)) hServer = 0;
		if (hServer == 0) FindVBWindow();

		memset(&cpStructData, 0, sizeof(struct tagCOPYDATASTRUCT));

		//_snprintf(msgbuf, 0x1000, "%x,%x,%s", myPID, GetCurrentThreadId(), Buffer);

		cpStructData.dwData = 3;
		cpStructData.cbData = strlen((char*)Buffer);
		cpStructData.lpData = (void*)Buffer;
		ret = SendMessage(hServer, WM_COPYDATA, 0, (LPARAM)&cpStructData);
		return ret; //log ui can send us a response msg to trigger special reaction in ret

	}

	int dbgmsgf(const char* format, ...)
	{
		char buf[1024];
		va_list args;
		DWORD dwErr = GetLastError();

		if (!ENABLE_REMOTE_DEBUG) return -1;

		if (format) {

			va_start(args, format);
			//try{
			_vsnprintf(buf, 1024, format, args);
			return dbgmsg(buf);
			//}
			//catch(...){}
		}

		SetLastError(dwErr);
	}

	void dbgclear() { dbgmsg("<clear>"); }
	void dbgdiv() { dbgmsg("<div>"); }

	int dbgloadcfg(const char* name) {
		char buf[1024];
		snprintf(buf, 1024, "<loadcfg:%s>", name);
		return dbgmsg(buf);
	}

	int dbgcfgval(const char* name) {
		char buf[1024];
		snprintf(buf, 1024, "<cfgval:%s>", name);
		return dbgmsg(buf);
	}
 