fix: the problem of window message loop blocking main loop
This commit is contained in:
parent
523262866a
commit
91508fd7cf
|
|
@ -19,17 +19,17 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#include "Game.h"
|
||||
#include "Scene.h"
|
||||
#include "Transition.h"
|
||||
#include "Image.h"
|
||||
#include "../utils/Player.h"
|
||||
#include "../math/Matrix.hpp"
|
||||
#include "logs.h"
|
||||
#include "render.h"
|
||||
#include "input.h"
|
||||
#include "audio.h"
|
||||
#include "modules.h"
|
||||
#include "Scene.h"
|
||||
#include "Transition.h"
|
||||
#include "../math/Matrix.hpp"
|
||||
#include <thread>
|
||||
#include <imm.h>
|
||||
#pragma comment (lib ,"imm32.lib")
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
|
|
@ -40,6 +40,8 @@ namespace easy2d
|
|||
, transition_(nullptr)
|
||||
, debug_enabled_(false)
|
||||
, initialized_(false)
|
||||
, hwnd_(nullptr)
|
||||
, window_inactived_(false)
|
||||
{
|
||||
::CoInitialize(nullptr);
|
||||
}
|
||||
|
|
@ -62,26 +64,41 @@ namespace easy2d
|
|||
|
||||
debug_enabled_ = options.debug;
|
||||
|
||||
Window::Instance()->Init(options.title, options.width, options.height, options.icon, debug_enabled_);
|
||||
devices::Graphics::Instance()->Init(Window::Instance()->GetHandle(), debug_enabled_);
|
||||
devices::Input::Instance()->Init(debug_enabled_);
|
||||
Window::Instance()->Init(
|
||||
options.title,
|
||||
options.width,
|
||||
options.height,
|
||||
options.icon,
|
||||
Game::WndProc,
|
||||
debug_enabled_
|
||||
);
|
||||
|
||||
const auto window = Window::Instance();
|
||||
hwnd_ = window->GetHandle();
|
||||
|
||||
::SetWindowLongW(hwnd_, GWLP_USERDATA, PtrToUlong(this));
|
||||
|
||||
devices::Graphics::Instance()->Init(hwnd_, debug_enabled_);
|
||||
devices::Input::Instance()->Init(hwnd_, window->GetContentScaleX(), window->GetContentScaleY(), debug_enabled_);
|
||||
devices::Audio::Instance()->Init(debug_enabled_);
|
||||
|
||||
// disable imm
|
||||
::ImmAssociateContext(hwnd_, nullptr);
|
||||
|
||||
HWND console = ::GetConsoleWindow();
|
||||
if (debug_enabled_)
|
||||
{
|
||||
if (console == nullptr)
|
||||
{
|
||||
// 显示一个新控制台
|
||||
if (::AllocConsole())
|
||||
{
|
||||
console = ::GetConsoleWindow();
|
||||
// 重定向输入输出
|
||||
FILE * stdoutStream, *stdinStream, *stderrStream;
|
||||
freopen_s(&stdoutStream, "conout$", "w+t", stdout);
|
||||
freopen_s(&stdinStream, "conin$", "r+t", stdin);
|
||||
freopen_s(&stderrStream, "conout$", "w+t", stderr);
|
||||
// 禁用控制台关闭按钮
|
||||
|
||||
// disable the close button of console
|
||||
HMENU hmenu = ::GetSystemMenu(console, FALSE);
|
||||
::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND);
|
||||
}
|
||||
|
|
@ -95,12 +112,6 @@ namespace easy2d
|
|||
}
|
||||
}
|
||||
|
||||
::SetWindowLongPtrW(
|
||||
Window::Instance()->GetHandle(),
|
||||
GWLP_USERDATA,
|
||||
PtrToUlong(this)
|
||||
);
|
||||
|
||||
initialized_ = true;
|
||||
}
|
||||
|
||||
|
|
@ -115,46 +126,14 @@ namespace easy2d
|
|||
next_scene_ = nullptr;
|
||||
}
|
||||
|
||||
const auto window = Window::Instance();
|
||||
::ShowWindow(window->GetHandle(), SW_SHOWNORMAL);
|
||||
::UpdateWindow(window->GetHandle());
|
||||
window->Poll();
|
||||
::ShowWindow(hwnd_, SW_SHOWNORMAL);
|
||||
::UpdateWindow(hwnd_);
|
||||
|
||||
const int64_t min_interval = 5;
|
||||
auto last = time::Now();
|
||||
|
||||
while (!quit_)
|
||||
MSG msg = {};
|
||||
while (::GetMessageW(&msg, nullptr, 0, 0) && !quit_)
|
||||
{
|
||||
auto now = time::Now();
|
||||
auto dur = now - last;
|
||||
|
||||
if (dur.Milliseconds() > min_interval)
|
||||
{
|
||||
const auto dt = now - last;
|
||||
last = now;
|
||||
|
||||
devices::Input::Instance()->Update(
|
||||
window->GetHandle(),
|
||||
window->GetContentScaleX(),
|
||||
window->GetContentScaleY()
|
||||
);
|
||||
|
||||
UpdateScene(dt);
|
||||
DrawScene();
|
||||
|
||||
window->Poll();
|
||||
}
|
||||
else
|
||||
{
|
||||
// ID2D1HwndRenderTarget 开启了垂直同步,在渲染时会等待显示器刷新,
|
||||
// 它起到了非常稳定的延时作用,所以大部分时候不需要手动挂起线程进行延时。
|
||||
// 下面的代码仅在一些情况下(例如窗口最小化时)挂起线程,防止占用过高 CPU 。
|
||||
int64_t wait = min_interval - dur.Milliseconds();
|
||||
if (wait > 1LL)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(wait));
|
||||
}
|
||||
}
|
||||
::TranslateMessage(&msg);
|
||||
::DispatchMessageW(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -201,31 +180,31 @@ namespace easy2d
|
|||
return curr_scene_;
|
||||
}
|
||||
|
||||
void Game::UpdateScene(Duration const& dt)
|
||||
void Game::Update()
|
||||
{
|
||||
static auto last = time::Now();
|
||||
|
||||
const auto now = time::Now();
|
||||
const auto dt = now - last;
|
||||
last = now;
|
||||
|
||||
devices::Input::Instance()->Update();
|
||||
|
||||
if (curr_scene_)
|
||||
{
|
||||
curr_scene_->Update(dt);
|
||||
}
|
||||
|
||||
if (next_scene_)
|
||||
{
|
||||
next_scene_->Update(dt);
|
||||
}
|
||||
|
||||
if (transition_)
|
||||
{
|
||||
transition_->Update(dt);
|
||||
|
||||
if (transition_->IsDone())
|
||||
{
|
||||
transition_ = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (next_scene_)
|
||||
{
|
||||
|
|
@ -241,32 +220,14 @@ namespace easy2d
|
|||
}
|
||||
}
|
||||
|
||||
void Game::Dispatch(MouseEvent const & e)
|
||||
{
|
||||
if (transition_)
|
||||
return;
|
||||
|
||||
if (curr_scene_)
|
||||
curr_scene_->Dispatch(e, false);
|
||||
}
|
||||
|
||||
void Game::Dispatch(KeyEvent const & e)
|
||||
{
|
||||
if (transition_)
|
||||
return;
|
||||
|
||||
if (curr_scene_)
|
||||
curr_scene_->Dispatch(e, false);
|
||||
}
|
||||
|
||||
void Game::DrawScene()
|
||||
void Game::Render()
|
||||
{
|
||||
auto graphics = devices::Graphics::Instance();
|
||||
graphics->BeginDraw(Window::Instance()->GetHandle());
|
||||
graphics->BeginDraw(hwnd_);
|
||||
|
||||
if (transition_)
|
||||
{
|
||||
transition_->Draw();
|
||||
transition_->Render();
|
||||
}
|
||||
else if (curr_scene_)
|
||||
{
|
||||
|
|
@ -292,5 +253,134 @@ namespace easy2d
|
|||
}
|
||||
|
||||
graphics->EndDraw();
|
||||
|
||||
if (!window_inactived_)
|
||||
::InvalidateRect(hwnd_, NULL, FALSE);
|
||||
}
|
||||
|
||||
void Game::Dispatch(MouseEvent const & e)
|
||||
{
|
||||
if (transition_)
|
||||
return;
|
||||
|
||||
if (curr_scene_)
|
||||
curr_scene_->Dispatch(e, false);
|
||||
}
|
||||
|
||||
void Game::Dispatch(KeyEvent const & e)
|
||||
{
|
||||
if (transition_)
|
||||
return;
|
||||
|
||||
if (curr_scene_)
|
||||
curr_scene_->Dispatch(e, false);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK Game::WndProc(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param)
|
||||
{
|
||||
LRESULT result = 0;
|
||||
bool was_handled = false;
|
||||
|
||||
Game * game = reinterpret_cast<Game*>(
|
||||
static_cast<LONG_PTR>(::GetWindowLongW(hwnd, GWLP_USERDATA))
|
||||
);
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_PAINT:
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
::BeginPaint(hwnd, &ps);
|
||||
|
||||
game->Update();
|
||||
game->Render();
|
||||
|
||||
::EndPaint(hwnd, &ps);
|
||||
}
|
||||
result = 0;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONDBLCLK:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_MBUTTONDBLCLK:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_RBUTTONDBLCLK:
|
||||
case WM_MOUSEMOVE:
|
||||
case WM_MOUSEWHEEL:
|
||||
{
|
||||
game->Dispatch(MouseEvent(msg, w_param, l_param));
|
||||
}
|
||||
result = 0;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
case WM_KEYDOWN:
|
||||
case WM_KEYUP:
|
||||
{
|
||||
game->Dispatch(KeyEvent(msg, w_param, l_param));
|
||||
}
|
||||
result = 0;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
case WM_SIZE:
|
||||
{
|
||||
if (SIZE_MAXHIDE == w_param || SIZE_MINIMIZED == w_param)
|
||||
game->window_inactived_ = true;
|
||||
else
|
||||
{
|
||||
game->window_inactived_ = false;
|
||||
::InvalidateRect(hwnd, nullptr, FALSE);
|
||||
}
|
||||
|
||||
UINT width = LOWORD(l_param);
|
||||
UINT height = HIWORD(l_param);
|
||||
|
||||
// 如果程序接收到一个 WM_SIZE 消息,这个方法将调整渲染
|
||||
// 目标的大小。它可能会调用失败,但是这里可以忽略有可能的
|
||||
// 错误,因为这个错误将在下一次调用 EndDraw 时产生
|
||||
devices::Graphics::Instance()->Resize(width, height);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_DISPLAYCHANGE:
|
||||
{
|
||||
::InvalidateRect(hwnd, nullptr, FALSE);
|
||||
}
|
||||
result = 0;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
case WM_CLOSE:
|
||||
{
|
||||
if (game->OnClose())
|
||||
{
|
||||
game->Quit();
|
||||
}
|
||||
}
|
||||
result = 0;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
{
|
||||
::PostQuitMessage(0);
|
||||
}
|
||||
result = 1;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (!was_handled)
|
||||
{
|
||||
result = ::DefWindowProcW(hwnd, msg, w_param, l_param);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -89,11 +89,10 @@ namespace easy2d
|
|||
// »ñÈ¡µ±Ç°³¡¾°
|
||||
spScene const& GetCurrentScene();
|
||||
|
||||
void DrawScene();
|
||||
private:
|
||||
void Render();
|
||||
|
||||
void UpdateScene(
|
||||
Duration const& dt
|
||||
);
|
||||
void Update();
|
||||
|
||||
void Dispatch(
|
||||
MouseEvent const& e
|
||||
|
|
@ -103,10 +102,14 @@ namespace easy2d
|
|||
KeyEvent const& e
|
||||
);
|
||||
|
||||
static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
|
||||
|
||||
private:
|
||||
bool initialized_;
|
||||
bool debug_enabled_;
|
||||
bool quit_;
|
||||
bool window_inactived_;
|
||||
HWND hwnd_;
|
||||
spScene curr_scene_;
|
||||
spScene next_scene_;
|
||||
spTransition transition_;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ namespace easy2d
|
|||
{
|
||||
InputDevice::InputDevice()
|
||||
: initialized(false)
|
||||
, hwnd_(nullptr)
|
||||
, scale_x_(1.f)
|
||||
, scale_y_(1.f)
|
||||
{
|
||||
ZeroMemory(keys_, sizeof(keys_));
|
||||
ZeroMemory(keys_cache_, sizeof(keys_cache_));
|
||||
|
|
@ -38,26 +41,30 @@ namespace easy2d
|
|||
E2D_LOG("Destroying input device");
|
||||
}
|
||||
|
||||
void InputDevice::Init(bool debug)
|
||||
void InputDevice::Init(HWND hwnd, float scale_x, float scale_y, bool debug)
|
||||
{
|
||||
if (initialized)
|
||||
return;
|
||||
|
||||
E2D_LOG("Initing input device");
|
||||
|
||||
hwnd_ = hwnd;
|
||||
scale_x_ = scale_x;
|
||||
scale_y_ = scale_y;
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
void InputDevice::Update(HWND hwnd, float scale_x, float scale_y)
|
||||
void InputDevice::Update()
|
||||
{
|
||||
memcpy(keys_cache_, keys_, sizeof(keys_cache_));
|
||||
GetKeyboardState(keys_);
|
||||
|
||||
POINT client_cursor_pos;
|
||||
GetCursorPos(&client_cursor_pos);
|
||||
ScreenToClient(hwnd, &client_cursor_pos);
|
||||
ScreenToClient(hwnd_, &client_cursor_pos);
|
||||
|
||||
mouse_pos_ = Point(client_cursor_pos.x * scale_x, client_cursor_pos.y * scale_y);
|
||||
mouse_pos_ = Point(client_cursor_pos.x * scale_x_, client_cursor_pos.y * scale_y_);
|
||||
}
|
||||
|
||||
bool InputDevice::IsDown(KeyCode code)
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ namespace easy2d
|
|||
E2D_DECLARE_SINGLETON(InputDevice);
|
||||
|
||||
public:
|
||||
void Init(bool debug);
|
||||
void Init(HWND hwnd, float scale_x, float scale_y, bool debug);
|
||||
|
||||
// 检测键盘某按键是否正被按下
|
||||
bool IsDown(
|
||||
|
|
@ -63,12 +63,7 @@ namespace easy2d
|
|||
// 获得鼠标坐标值
|
||||
Point GetMousePos();
|
||||
|
||||
// 刷新设备状态
|
||||
void Update(
|
||||
HWND hwnd,
|
||||
float scale_x,
|
||||
float scale_y
|
||||
);
|
||||
void Update();
|
||||
|
||||
protected:
|
||||
InputDevice();
|
||||
|
|
@ -77,6 +72,9 @@ namespace easy2d
|
|||
|
||||
protected:
|
||||
bool initialized;
|
||||
HWND hwnd_;
|
||||
float scale_x_;
|
||||
float scale_y_;
|
||||
BYTE keys_[256];
|
||||
BYTE keys_cache_[256];
|
||||
Point mouse_pos_;
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ namespace easy2d
|
|||
}
|
||||
}
|
||||
|
||||
void Transition::Draw()
|
||||
void Transition::Render()
|
||||
{
|
||||
auto graphics = devices::Graphics::Instance();
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ namespace easy2d
|
|||
|
||||
virtual void Update(Duration const& dt);
|
||||
|
||||
virtual void Draw();
|
||||
virtual void Render();
|
||||
|
||||
virtual void Stop();
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ namespace easy2d
|
|||
, fps_text_layout_(nullptr)
|
||||
, clear_color_(D2D1::ColorF(D2D1::ColorF::Black))
|
||||
, opacity_(1.f)
|
||||
, window_occluded(false)
|
||||
, initialized(false)
|
||||
{
|
||||
ZeroMemory(&d2d, sizeof(D2DResources));
|
||||
|
|
@ -130,11 +131,18 @@ namespace easy2d
|
|||
{
|
||||
CreateDeviceResources(hwnd);
|
||||
|
||||
window_occluded = !!(d2d.render_target->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED);
|
||||
|
||||
if (!window_occluded)
|
||||
{
|
||||
d2d.render_target->BeginDraw();
|
||||
d2d.render_target->Clear(clear_color_);
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsDevice::EndDraw()
|
||||
{
|
||||
if (!window_occluded)
|
||||
{
|
||||
HRESULT hr = d2d.render_target->EndDraw();
|
||||
|
||||
|
|
@ -153,6 +161,7 @@ namespace easy2d
|
|||
|
||||
ThrowIfFailed(hr);
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsDevice::ClearImageCache()
|
||||
{
|
||||
|
|
@ -375,6 +384,9 @@ namespace easy2d
|
|||
!d2d.render_target)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (window_occluded)
|
||||
return S_OK;
|
||||
|
||||
d2d.solid_brush->SetColor(border_color);
|
||||
d2d.render_target->DrawGeometry(
|
||||
geometry.Get(),
|
||||
|
|
@ -393,6 +405,9 @@ namespace easy2d
|
|||
if (!image->GetBitmap())
|
||||
return S_OK;
|
||||
|
||||
if (window_occluded)
|
||||
return S_OK;
|
||||
|
||||
d2d.render_target->DrawBitmap(
|
||||
image->GetBitmap().Get(),
|
||||
D2D1::RectF(0.f, 0.f, image->GetWidth(), image->GetHeight()),
|
||||
|
|
@ -427,6 +442,9 @@ namespace easy2d
|
|||
if (!d2d.render_target)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (window_occluded)
|
||||
return S_OK;
|
||||
|
||||
// Do not crop bitmap
|
||||
auto rect = D2D1::RectF(0.f, 0.f, bitmap->GetSize().width, bitmap->GetSize().height);
|
||||
d2d.render_target->DrawBitmap(
|
||||
|
|
@ -444,6 +462,9 @@ namespace easy2d
|
|||
if (!d2d.text_renderer)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (window_occluded)
|
||||
return S_OK;
|
||||
|
||||
return text_layout->Draw(nullptr, d2d.text_renderer.Get(), 0, 0);
|
||||
}
|
||||
|
||||
|
|
@ -452,6 +473,9 @@ namespace easy2d
|
|||
if (!d2d.render_target)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (window_occluded)
|
||||
return S_OK;
|
||||
|
||||
d2d.render_target->SetTransform(ConvertToD2DMatrix(clip_matrix));
|
||||
d2d.render_target->PushAxisAlignedClip(
|
||||
D2D1::RectF(0, 0, clip_size.width, clip_size.height),
|
||||
|
|
@ -465,6 +489,9 @@ namespace easy2d
|
|||
if (!d2d.render_target)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (window_occluded)
|
||||
return S_OK;
|
||||
|
||||
d2d.render_target->PopAxisAlignedClip();
|
||||
return S_OK;
|
||||
}
|
||||
|
|
@ -475,6 +502,9 @@ namespace easy2d
|
|||
!d2d.solid_brush)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (window_occluded)
|
||||
return S_OK;
|
||||
|
||||
d2d.render_target->PushLayer(
|
||||
D2D1::LayerParameters(
|
||||
properties.area,
|
||||
|
|
@ -495,6 +525,9 @@ namespace easy2d
|
|||
if (!d2d.render_target)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (window_occluded)
|
||||
return S_OK;
|
||||
|
||||
d2d.render_target->PopLayer();
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -194,6 +194,7 @@ namespace easy2d
|
|||
|
||||
protected:
|
||||
bool initialized;
|
||||
bool window_occluded;
|
||||
float opacity_;
|
||||
D2DResources d2d;
|
||||
D2D1_COLOR_F clear_color_;
|
||||
|
|
|
|||
|
|
@ -21,12 +21,7 @@
|
|||
#include "window.h"
|
||||
#include "render.h"
|
||||
#include "logs.h"
|
||||
#include "Game.h"
|
||||
#include "KeyEvent.h"
|
||||
#include "MouseEvent.h"
|
||||
#include "../math/scalar.hpp"
|
||||
#include <imm.h>
|
||||
#pragma comment (lib ,"imm32.lib")
|
||||
|
||||
#define WINDOW_STYLE WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME
|
||||
#define REGISTER_CLASS L"Easy2DApp"
|
||||
|
|
@ -38,8 +33,6 @@ namespace easy2d
|
|||
void GetContentScale(float* scale_x, float* scale_y);
|
||||
|
||||
Rect LocateWindow(int width, int height, float scale_x, float scale_y);
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param);
|
||||
}
|
||||
|
||||
WindowImpl::WindowImpl()
|
||||
|
|
@ -58,7 +51,7 @@ namespace easy2d
|
|||
::DestroyWindow(handle);
|
||||
}
|
||||
|
||||
void WindowImpl::Init(String title, int width, int height, LPCWSTR icon, bool debug)
|
||||
void WindowImpl::Init(String title, int width, int height, LPCWSTR icon, WNDPROC proc, bool debug)
|
||||
{
|
||||
if (initialized)
|
||||
return;
|
||||
|
|
@ -70,7 +63,7 @@ namespace easy2d
|
|||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
wcex.lpszClassName = REGISTER_CLASS;
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
|
||||
wcex.lpfnWndProc = WndProc;
|
||||
wcex.lpfnWndProc = proc;
|
||||
wcex.hIcon = nullptr;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = sizeof(LONG_PTR);
|
||||
|
|
@ -123,9 +116,6 @@ namespace easy2d
|
|||
throw std::runtime_error(err);
|
||||
}
|
||||
|
||||
// 禁用输入法
|
||||
::ImmAssociateContext(handle, nullptr);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
|
|
@ -220,17 +210,6 @@ namespace easy2d
|
|||
return scale_y;
|
||||
}
|
||||
|
||||
void WindowImpl::Poll()
|
||||
{
|
||||
static MSG msg = {};
|
||||
|
||||
while (::PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
|
||||
{
|
||||
::TranslateMessage(&msg);
|
||||
::DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
void GetContentScale(float* scale_x, float* scale_y)
|
||||
|
|
@ -276,109 +255,5 @@ namespace easy2d
|
|||
static_cast<float>(height)
|
||||
);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param)
|
||||
{
|
||||
LRESULT result = 0;
|
||||
bool was_handled = false;
|
||||
|
||||
Game * game = reinterpret_cast<Game*>(
|
||||
static_cast<LONG_PTR>(::GetWindowLongPtrW(hwnd, GWLP_USERDATA))
|
||||
);
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
|
||||
// 处理鼠标消息
|
||||
case WM_LBUTTONUP:
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONDBLCLK:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_MBUTTONDBLCLK:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_RBUTTONDBLCLK:
|
||||
case WM_MOUSEMOVE:
|
||||
case WM_MOUSEWHEEL:
|
||||
{
|
||||
game->Dispatch(MouseEvent(msg, w_param, l_param));
|
||||
}
|
||||
result = 0;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
// 处理按键消息
|
||||
case WM_KEYDOWN:
|
||||
case WM_KEYUP:
|
||||
{
|
||||
game->Dispatch(KeyEvent(msg, w_param, l_param));
|
||||
}
|
||||
result = 0;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
// 处理窗口大小变化消息
|
||||
case WM_SIZE:
|
||||
{
|
||||
UINT width = LOWORD(l_param);
|
||||
UINT height = HIWORD(l_param);
|
||||
|
||||
// 如果程序接收到一个 WM_SIZE 消息,这个方法将调整渲染
|
||||
// 目标的大小。它可能会调用失败,但是这里可以忽略有可能的
|
||||
// 错误,因为这个错误将在下一次调用 EndDraw 时产生
|
||||
devices::Graphics::Instance()->Resize(width, height);
|
||||
}
|
||||
break;
|
||||
|
||||
// 处理分辨率变化消息
|
||||
case WM_DISPLAYCHANGE:
|
||||
{
|
||||
// 重绘客户区
|
||||
::InvalidateRect(hwnd, nullptr, FALSE);
|
||||
}
|
||||
result = 0;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
// 重绘窗口
|
||||
case WM_PAINT:
|
||||
{
|
||||
game->DrawScene();
|
||||
::ValidateRect(hwnd, nullptr);
|
||||
}
|
||||
result = 0;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
// 窗口关闭消息
|
||||
case WM_CLOSE:
|
||||
{
|
||||
if (game->OnClose())
|
||||
{
|
||||
game->Quit();
|
||||
}
|
||||
}
|
||||
result = 0;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
// 窗口销毁消息
|
||||
case WM_DESTROY:
|
||||
{
|
||||
::PostQuitMessage(0);
|
||||
}
|
||||
result = 1;
|
||||
was_handled = true;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (!was_handled)
|
||||
{
|
||||
result = ::DefWindowProc(hwnd, msg, w_param, l_param);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ namespace easy2d
|
|||
int width,
|
||||
int height,
|
||||
LPCWSTR icon,
|
||||
WNDPROC proc,
|
||||
bool debug
|
||||
);
|
||||
|
||||
|
|
@ -65,8 +66,6 @@ namespace easy2d
|
|||
|
||||
float GetContentScaleY() const;
|
||||
|
||||
void Poll();
|
||||
|
||||
protected:
|
||||
WindowImpl();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue