diff --git a/src/kiwano/event/WindowEvent.cpp b/src/kiwano/event/WindowEvent.cpp index 1d07214d..b2bd4ac7 100644 --- a/src/kiwano/event/WindowEvent.cpp +++ b/src/kiwano/event/WindowEvent.cpp @@ -5,6 +5,7 @@ namespace kiwano WindowEvent::WindowEvent(const EventType& type) : Event(type) + , window(nullptr) { } diff --git a/src/kiwano/event/WindowEvent.h b/src/kiwano/event/WindowEvent.h index d0c5da83..40d59754 100644 --- a/src/kiwano/event/WindowEvent.h +++ b/src/kiwano/event/WindowEvent.h @@ -30,6 +30,8 @@ KGE_DECLARE_SMART_PTR(WindowFocusChangedEvent); KGE_DECLARE_SMART_PTR(WindowTitleChangedEvent); KGE_DECLARE_SMART_PTR(WindowClosedEvent); +class Window; + /** * \addtogroup Events * @{ @@ -40,6 +42,8 @@ KGE_DECLARE_SMART_PTR(WindowClosedEvent); class KGE_API WindowEvent : public Event { public: + Window* window; ///< 窗口 + WindowEvent(const EventType& type); }; diff --git a/src/kiwano/platform/Window.cpp b/src/kiwano/platform/Window.cpp index 3501ab6c..2e9c6d9a 100644 --- a/src/kiwano/platform/Window.cpp +++ b/src/kiwano/platform/Window.cpp @@ -27,6 +27,8 @@ Window::Window() : handle_(nullptr) , should_close_(false) , is_fullscreen_(false) + , pos_x_(0) + , pos_y_(0) , width_(0) , height_(0) , min_width_(0) @@ -56,6 +58,16 @@ String Window::GetTitle() const return title_; } +int Window::GetPosX() const +{ + return pos_x_; +} + +int Window::GetPosY() const +{ + return pos_y_; +} + Size Window::GetSize() const { return Size(float(width_), float(height_)); diff --git a/src/kiwano/platform/Window.h b/src/kiwano/platform/Window.h index af1f4422..58841950 100644 --- a/src/kiwano/platform/Window.h +++ b/src/kiwano/platform/Window.h @@ -133,6 +133,20 @@ public: */ String GetTitle() const; + /** + * \~chinese + * @brief 获取窗口横向位置 + * @return 横向位置 + */ + int GetPosX() const; + + /** + * \~chinese + * @brief 获取窗口纵向位置 + * @return 纵向位置 + */ + int GetPosY() const; + /** * \~chinese * @brief 获取窗口大小 @@ -258,6 +272,8 @@ protected: protected: bool should_close_; bool is_fullscreen_; + int pos_x_; + int pos_y_; uint32_t width_; uint32_t height_; uint32_t min_width_; diff --git a/src/kiwano/platform/win32/WindowImpl.cpp b/src/kiwano/platform/win32/WindowImpl.cpp index 2dac03be..1b2ab925 100644 --- a/src/kiwano/platform/win32/WindowImpl.cpp +++ b/src/kiwano/platform/win32/WindowImpl.cpp @@ -78,7 +78,7 @@ public: private: bool resizable_; - bool is_resizing_; + bool is_moving_or_resizing_; bool is_minimized_; CursorType mouse_cursor_; String device_name_; @@ -166,7 +166,7 @@ HICON Icon2HIcon(const Icon& icon) WindowWin32Impl::WindowWin32Impl() : resizable_(false) - , is_resizing_(false) + , is_moving_or_resizing_(false) , is_minimized_(false) , mouse_cursor_(CursorType::Arrow) , key_map_{} @@ -631,7 +631,7 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA is_minimized_ = false; Application::GetInstance().Resume(); } - else if (is_resizing_) + else if (is_moving_or_resizing_) { // DO NOTHING until the dragging / resizing has stopped. } @@ -641,6 +641,7 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA this->height_ = ((uint32_t)(short)HIWORD(lparam)); WindowResizedEventPtr evt = new WindowResizedEvent; + evt->window = this; evt->width = this->GetWidth(); evt->height = this->GetHeight(); this->PushEvent(evt); @@ -653,14 +654,14 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA case WM_ENTERSIZEMOVE: { - is_resizing_ = true; + is_moving_or_resizing_ = true; Application::GetInstance().Pause(); return 0; } case WM_EXITSIZEMOVE: { - is_resizing_ = false; + is_moving_or_resizing_ = false; Application::GetInstance().Resume(); // Send window resized event when client size changed @@ -677,8 +678,28 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA this->height_ = client_height; WindowResizedEventPtr evt = new WindowResizedEvent; - evt->width = this->GetWidth(); - evt->height = this->GetHeight(); + evt->window = this; + evt->width = client_width; + evt->height = client_height; + this->PushEvent(evt); + } + + RECT window_rect = { 0 }; + ::GetWindowRect(hwnd, &window_rect); + + int window_x = int(window_rect.left); + int window_y = int(window_rect.top); + if (window_x != this->GetPosX() || window_y != this->GetPosY()) + { + KGE_DEBUG_LOGF("Window moved to (%d, %d)", window_x, window_y); + + this->pos_x_ = window_x; + this->pos_y_ = window_y; + + WindowMovedEventPtr evt = new WindowMovedEvent; + evt->window = this; + evt->x = window_x; + evt->y = window_y; this->PushEvent(evt); } return 0; @@ -699,10 +720,26 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA case WM_MOVE: { - WindowMovedEventPtr evt = new WindowMovedEvent; - evt->x = GET_X_LPARAM(lparam); - evt->y = GET_Y_LPARAM(lparam); - this->PushEvent(evt); + if (is_moving_or_resizing_) + { + // DO NOTHING until the dragging / resizing has stopped. + } + else + { + int window_x = GET_X_LPARAM(lparam); + int window_y = GET_Y_LPARAM(lparam); + + KGE_DEBUG_LOGF("Window moved to (%d, %d)", window_x, window_y); + + this->pos_x_ = window_x; + this->pos_y_ = window_y; + + WindowMovedEventPtr evt = new WindowMovedEvent; + evt->window = this; + evt->x = window_x; + evt->y = window_y; + this->PushEvent(evt); + } } break; @@ -718,6 +755,7 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA bool active = (LOWORD(wparam) != WA_INACTIVE); WindowFocusChangedEventPtr evt = new WindowFocusChangedEvent; + evt->window = this; evt->focus = active; this->PushEvent(evt); } @@ -748,6 +786,7 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA this->title_ = strings::WideToNarrow(reinterpret_cast(lparam)); WindowTitleChangedEventPtr evt = new WindowTitleChangedEvent; + evt->window = this; evt->title = this->title_; this->PushEvent(evt); } @@ -776,6 +815,7 @@ LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARA KGE_DEBUG_LOGF("Window is closing"); WindowClosedEventPtr evt = new WindowClosedEvent; + evt->window = this; this->PushEvent(evt); this->SetShouldClose(true); return 0;