2015-05-06 00:50:57 +00:00
|
|
|
#define _CRT_SECURE_NO_WARNINGS 1 /* STFU MSVC */
|
2015-08-31 03:40:58 +00:00
|
|
|
#ifndef WIN32_LEAN_AND_MEAN
|
|
|
|
#define WIN32_LEAN_AND_MEAN 1
|
|
|
|
#endif
|
2015-05-06 00:50:57 +00:00
|
|
|
#include <windows.h>
|
2015-08-31 03:40:58 +00:00
|
|
|
#include <shellapi.h>
|
2015-05-06 00:50:57 +00:00
|
|
|
#include <initguid.h>
|
|
|
|
#include <Usbiodef.h>
|
|
|
|
|
|
|
|
#include <unordered_map>
|
|
|
|
|
2015-08-31 03:40:58 +00:00
|
|
|
#include "boo/IApplication.hpp"
|
|
|
|
#include "boo/inputdev/DeviceFinder.hpp"
|
2015-05-06 00:50:57 +00:00
|
|
|
|
|
|
|
namespace boo
|
|
|
|
{
|
|
|
|
|
2015-08-31 03:40:58 +00:00
|
|
|
IWindow* _WindowWin32New(const SystemString& title);
|
2015-05-06 00:50:57 +00:00
|
|
|
|
2015-08-31 03:40:58 +00:00
|
|
|
class ApplicationWin32 final : public IApplication
|
2015-05-06 00:50:57 +00:00
|
|
|
{
|
|
|
|
const IApplicationCallback& m_callback;
|
2015-08-31 03:40:58 +00:00
|
|
|
const SystemString m_uniqueName;
|
|
|
|
const SystemString m_friendlyName;
|
|
|
|
const SystemString m_pname;
|
|
|
|
const std::vector<SystemString> m_args;
|
2015-05-06 00:50:57 +00:00
|
|
|
std::unordered_map<HWND, IWindow*> m_allWindows;
|
2015-05-13 22:21:13 +00:00
|
|
|
bool m_singleInstance;
|
2015-05-06 00:50:57 +00:00
|
|
|
|
|
|
|
void _deletedWindow(IWindow* window)
|
|
|
|
{
|
2015-08-31 03:40:58 +00:00
|
|
|
m_allWindows.erase(HWND(window->getPlatformHandle()));
|
2015-05-06 00:50:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
2015-08-31 03:40:58 +00:00
|
|
|
ApplicationWin32(const IApplicationCallback& callback,
|
|
|
|
const SystemString& uniqueName,
|
|
|
|
const SystemString& friendlyName,
|
|
|
|
const SystemString& pname,
|
|
|
|
const std::vector<SystemString>& args,
|
|
|
|
bool singleInstance)
|
2015-05-06 00:50:57 +00:00
|
|
|
: m_callback(callback),
|
2015-08-31 03:40:58 +00:00
|
|
|
m_uniqueName(uniqueName),
|
2015-05-06 00:50:57 +00:00
|
|
|
m_friendlyName(friendlyName),
|
|
|
|
m_pname(pname),
|
2015-05-13 22:21:13 +00:00
|
|
|
m_args(args),
|
|
|
|
m_singleInstance(singleInstance)
|
2015-05-06 00:50:57 +00:00
|
|
|
{}
|
|
|
|
|
|
|
|
EPlatformType getPlatformType() const
|
|
|
|
{
|
|
|
|
return PLAT_WIN32;
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT winHwndHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
/* Lookup boo window instance */
|
|
|
|
IWindow* window = m_allWindows[hwnd];
|
|
|
|
switch (uMsg)
|
|
|
|
{
|
|
|
|
case WM_CREATE:
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case WM_DEVICECHANGE:
|
2015-08-31 03:40:58 +00:00
|
|
|
return DeviceFinder::winDevChangedHandler(wParam, lParam);
|
2015-05-06 00:50:57 +00:00
|
|
|
|
|
|
|
default:
|
|
|
|
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-31 03:40:58 +00:00
|
|
|
void pump()
|
2015-05-06 00:50:57 +00:00
|
|
|
{
|
|
|
|
/* Pump messages */
|
|
|
|
MSG msg = {0};
|
|
|
|
while (GetMessage(&msg, NULL, 0, 0))
|
|
|
|
{
|
|
|
|
TranslateMessage(&msg);
|
|
|
|
DispatchMessage(&msg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-31 03:40:58 +00:00
|
|
|
const SystemString& getUniqueName() const
|
|
|
|
{
|
|
|
|
return m_uniqueName;
|
|
|
|
}
|
|
|
|
|
|
|
|
const SystemString& getFriendlyName() const
|
|
|
|
{
|
|
|
|
return m_friendlyName;
|
|
|
|
}
|
|
|
|
|
|
|
|
const SystemString& getProcessName() const
|
2015-05-06 00:50:57 +00:00
|
|
|
{
|
|
|
|
return m_pname;
|
|
|
|
}
|
|
|
|
|
2015-08-31 03:40:58 +00:00
|
|
|
const std::vector<SystemString>& getArgs() const
|
2015-05-06 00:50:57 +00:00
|
|
|
{
|
|
|
|
return m_args;
|
|
|
|
}
|
|
|
|
|
2015-08-31 03:40:58 +00:00
|
|
|
IWindow* newWindow(const SystemString& title)
|
2015-05-06 00:50:57 +00:00
|
|
|
{
|
2015-08-31 03:40:58 +00:00
|
|
|
IWindow* window = _WindowWin32New(title);
|
|
|
|
HWND hwnd = HWND(window->getPlatformHandle());
|
2015-05-06 00:50:57 +00:00
|
|
|
m_allWindows[hwnd] = window;
|
2015-08-31 03:40:58 +00:00
|
|
|
return window;
|
2015-05-06 00:50:57 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
IApplication* APP = NULL;
|
2015-08-31 03:40:58 +00:00
|
|
|
std::unique_ptr<IApplication>
|
|
|
|
ApplicationBootstrap(IApplication::EPlatformType platform,
|
|
|
|
IApplicationCallback& cb,
|
|
|
|
const SystemString& uniqueName,
|
|
|
|
const SystemString& friendlyName,
|
|
|
|
const SystemString& pname,
|
|
|
|
const std::vector<SystemString>& args,
|
|
|
|
bool singleInstance)
|
2015-05-06 00:50:57 +00:00
|
|
|
{
|
|
|
|
if (!APP)
|
|
|
|
{
|
|
|
|
if (platform != IApplication::PLAT_WIN32 &&
|
|
|
|
platform != IApplication::PLAT_AUTO)
|
|
|
|
return NULL;
|
2015-08-31 03:40:58 +00:00
|
|
|
APP = new ApplicationWin32(cb, uniqueName, friendlyName, pname, args, singleInstance);
|
2015-05-06 00:50:57 +00:00
|
|
|
}
|
2015-08-31 03:40:58 +00:00
|
|
|
return std::unique_ptr<IApplication>(APP);
|
2015-05-06 00:50:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static const DEV_BROADCAST_DEVICEINTERFACE_A HOTPLUG_CONF =
|
|
|
|
{
|
|
|
|
sizeof(DEV_BROADCAST_DEVICEINTERFACE_A),
|
|
|
|
DBT_DEVTYP_DEVICEINTERFACE,
|
|
|
|
0,
|
|
|
|
GUID_DEVINTERFACE_USB_DEVICE
|
|
|
|
};
|
|
|
|
static bool HOTPLUG_REGISTERED = false;
|
|
|
|
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
2015-08-31 03:40:58 +00:00
|
|
|
if (!HOTPLUG_REGISTERED && uMsg == WM_CREATE)
|
2015-05-06 00:50:57 +00:00
|
|
|
{
|
|
|
|
/* Register hotplug notification with windows */
|
|
|
|
RegisterDeviceNotificationA(hwnd, (LPVOID)&HOTPLUG_CONF, DEVICE_NOTIFY_WINDOW_HANDLE);
|
|
|
|
HOTPLUG_REGISTERED = true;
|
|
|
|
}
|
2015-08-31 03:40:58 +00:00
|
|
|
return static_cast<boo::ApplicationWin32*>(boo::APP)->winHwndHandler(hwnd, uMsg, wParam, lParam);
|
2015-05-06 00:50:57 +00:00
|
|
|
}
|
|
|
|
|
2015-08-31 03:40:58 +00:00
|
|
|
int wmain(int argc, wchar_t** argv);
|
|
|
|
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int)
|
2015-05-06 00:50:57 +00:00
|
|
|
{
|
|
|
|
#if DEBUG
|
|
|
|
/* Debug console */
|
|
|
|
AllocConsole();
|
|
|
|
freopen("CONOUT$", "w", stdout);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* One class for *all* boo windows */
|
|
|
|
WNDCLASS wndClass =
|
|
|
|
{
|
|
|
|
0,
|
|
|
|
WindowProc,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
hInstance,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
L"BooWindow"
|
|
|
|
};
|
|
|
|
|
|
|
|
RegisterClassW(&wndClass);
|
|
|
|
|
|
|
|
int argc = 0;
|
|
|
|
LPWSTR* argv = CommandLineToArgvW(lpCmdLine, &argc);
|
|
|
|
|
|
|
|
/* Call into the 'proper' entry point */
|
2015-08-31 03:40:58 +00:00
|
|
|
return wmain(argc, argv);
|
2015-05-06 00:50:57 +00:00
|
|
|
|
|
|
|
}
|