
This commit temporarily disables tooltip functionality; it will be handled natively in a platform abstraction for windows using much simpler code.
81 lines
2.9 KiB
C++
81 lines
2.9 KiB
C++
//-----------------------------------------------------------------------------
|
|
// The Win32-based implementation of platform-dependent GUI functionality.
|
|
//
|
|
// Copyright 2018 whitequark
|
|
//-----------------------------------------------------------------------------
|
|
#include "solvespace.h"
|
|
// Include after solvespace.h to avoid identifier clashes.
|
|
#include <windows.h>
|
|
|
|
namespace SolveSpace {
|
|
namespace Platform {
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Windows API bridging
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#define sscheck(expr) do { \
|
|
SetLastError(0); \
|
|
if(!(expr)) \
|
|
CheckLastError(__FILE__, __LINE__, __func__, #expr); \
|
|
} while(0)
|
|
|
|
void CheckLastError(const char *file, int line, const char *function, const char *expr) {
|
|
if(GetLastError() != S_OK) {
|
|
LPWSTR messageW;
|
|
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
|
|
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
(LPWSTR)&messageW, 0, NULL);
|
|
|
|
std::string message;
|
|
message += ssprintf("File %s, line %u, function %s:\n", file, line, function);
|
|
message += ssprintf("Win32 API call failed: %s.\n", expr);
|
|
message += ssprintf("Error: %s", Narrow(messageW).c_str());
|
|
FatalError(message);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Timers
|
|
//-----------------------------------------------------------------------------
|
|
|
|
class TimerImplWin32 : public Timer {
|
|
public:
|
|
static HWND WindowHandle() {
|
|
static HWND hTimerWnd;
|
|
if(hTimerWnd == NULL) {
|
|
sscheck(hTimerWnd = CreateWindowExW(0, L"Message", NULL, 0, 0, 0, 0, 0,
|
|
HWND_MESSAGE, NULL, NULL, NULL));
|
|
}
|
|
return hTimerWnd;
|
|
}
|
|
|
|
static void CALLBACK TimerFunc(HWND hwnd, UINT msg, UINT_PTR event, DWORD time) {
|
|
sscheck(KillTimer(WindowHandle(), event));
|
|
|
|
TimerImplWin32 *timer = (TimerImplWin32*)event;
|
|
if(timer->onTimeout) {
|
|
timer->onTimeout();
|
|
}
|
|
}
|
|
|
|
void WindUp(unsigned milliseconds) override {
|
|
// FIXME(platform/gui): use SetCoalescableTimer when it's available (8+)
|
|
sscheck(SetTimer(WindowHandle(), (UINT_PTR)this,
|
|
milliseconds, &TimerImplWin32::TimerFunc));
|
|
}
|
|
|
|
~TimerImplWin32() {
|
|
// FIXME(platform/gui): there's a race condition here--WM_TIMER messages already
|
|
// posted to the queue are not removed, so this destructor is at most "best effort".
|
|
KillTimer(WindowHandle(), (UINT_PTR)this);
|
|
}
|
|
};
|
|
|
|
TimerRef CreateTimer() {
|
|
return std::unique_ptr<TimerImplWin32>(new TimerImplWin32);
|
|
}
|
|
|
|
}
|
|
}
|