From 524ba0c88c5ec88952d7f405b2062688e61ff5b8 Mon Sep 17 00:00:00 2001 From: Leighton Hancock Date: Mon, 14 Nov 2016 16:50:58 +1300 Subject: [PATCH] Add file drop functionality Adds the ability to drag and drop files from windows in order to attempt to execute them --- src/xenia/app/emulator_window.cc | 13 +++++++++++++ src/xenia/app/emulator_window.h | 1 + src/xenia/ui/ui_event.h | 12 ++++++++++++ src/xenia/ui/window.cc | 5 +++++ src/xenia/ui/window.h | 2 ++ src/xenia/ui/window_listener.h | 1 + src/xenia/ui/window_win.cc | 17 +++++++++++++++++ 7 files changed, 51 insertions(+) diff --git a/src/xenia/app/emulator_window.cc b/src/xenia/app/emulator_window.cc index e32e99111..a7b4c55c9 100644 --- a/src/xenia/app/emulator_window.cc +++ b/src/xenia/app/emulator_window.cc @@ -32,6 +32,7 @@ using xe::ui::KeyEvent; using xe::ui::MenuItem; using xe::ui::MouseEvent; using xe::ui::UIEvent; +using xe::ui::FileDropEvent; const std::wstring kBaseTitle = L"xenia"; @@ -81,6 +82,9 @@ bool EmulatorWindow::Initialize() { }); loop_->on_quit.AddListener([this](UIEvent* e) { window_.reset(); }); + window_->on_file_drop.AddListener( + [this](FileDropEvent* e) { FileDrop(e->filename()); }); + window_->on_key_down.AddListener([this](KeyEvent* e) { bool handled = true; switch (e->key_code()) { @@ -257,6 +261,15 @@ bool EmulatorWindow::Initialize() { return true; } +void EmulatorWindow::FileDrop(wchar_t* filename) { + std::wstring path = filename; + auto result = emulator_->LaunchPath(path); + if (XFAILED(result)) { + // TODO: Display a message box. + XELOGE("Failed to launch target: %.8X", result); + } +} + void EmulatorWindow::FileOpen() { std::wstring path; diff --git a/src/xenia/app/emulator_window.h b/src/xenia/app/emulator_window.h index 6a3b5e2e3..3d48279cb 100644 --- a/src/xenia/app/emulator_window.h +++ b/src/xenia/app/emulator_window.h @@ -42,6 +42,7 @@ class EmulatorWindow { bool Initialize(); + void FileDrop(wchar_t* filename); void FileOpen(); void CheckHideCursor(); void CpuTimeScalarReset(); diff --git a/src/xenia/ui/ui_event.h b/src/xenia/ui/ui_event.h index 0717e0fbe..156be1ece 100644 --- a/src/xenia/ui/ui_event.h +++ b/src/xenia/ui/ui_event.h @@ -26,6 +26,18 @@ class UIEvent { Window* target_ = nullptr; }; +class FileDropEvent : public UIEvent { + public: + FileDropEvent(Window* target, wchar_t* filename) + : UIEvent(target), filename_(filename) {} + ~FileDropEvent() override = default; + + wchar_t* filename() const { return filename_; } + + private: + wchar_t* filename_ = nullptr; +}; + class KeyEvent : public UIEvent { public: KeyEvent(Window* target, int key_code, int repeat_count, bool prev_state) diff --git a/src/xenia/ui/window.cc b/src/xenia/ui/window.cc index 0a3c1993b..91f4a8f67 100644 --- a/src/xenia/ui/window.cc +++ b/src/xenia/ui/window.cc @@ -213,6 +213,11 @@ void Window::OnPaint(UIEvent* e) { } } +void Window::OnFileDrop(FileDropEvent* e) { + on_file_drop(e); + ForEachListener([e](auto listener) { listener->OnFileDrop(e); }); +} + void Window::OnVisible(UIEvent* e) { ForEachListener([e](auto listener) { listener->OnVisible(e); }); } diff --git a/src/xenia/ui/window.h b/src/xenia/ui/window.h index eb14c9f89..107078be1 100644 --- a/src/xenia/ui/window.h +++ b/src/xenia/ui/window.h @@ -102,6 +102,7 @@ class Window { Delegate on_painting; Delegate on_paint; Delegate on_painted; + Delegate on_file_drop; Delegate on_key_down; Delegate on_key_up; @@ -128,6 +129,7 @@ class Window { virtual void OnResize(UIEvent* e); virtual void OnLayout(UIEvent* e); virtual void OnPaint(UIEvent* e); + virtual void OnFileDrop(FileDropEvent* e); virtual void OnVisible(UIEvent* e); virtual void OnHidden(UIEvent* e); diff --git a/src/xenia/ui/window_listener.h b/src/xenia/ui/window_listener.h index 0f07435fb..08f7a5c7e 100644 --- a/src/xenia/ui/window_listener.h +++ b/src/xenia/ui/window_listener.h @@ -31,6 +31,7 @@ class WindowListener { virtual void OnPainting(UIEvent* e) {} virtual void OnPaint(UIEvent* e) {} virtual void OnPainted(UIEvent* e) {} + virtual void OnFileDrop(UIEvent* e) {} virtual void OnVisible(UIEvent* e) {} virtual void OnHidden(UIEvent* e) {} diff --git a/src/xenia/ui/window_win.cc b/src/xenia/ui/window_win.cc index 22b7bc2c1..b5deac2a3 100644 --- a/src/xenia/ui/window_win.cc +++ b/src/xenia/ui/window_win.cc @@ -101,6 +101,8 @@ bool Win32Window::OnCreate() { // Enable DWM elevation. EnableMMCSS(); + // Enable file dragging from external sources + DragAcceptFiles(hwnd_, true); ShowWindow(hwnd_, SW_SHOWNORMAL); UpdateWindow(hwnd_); @@ -378,6 +380,21 @@ LRESULT Win32Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, } switch (message) { + case WM_DROPFILES: { + TCHAR lpszFile[MAX_PATH] = {0}; + UINT uFiles = 0; + HDROP hDrop = (HDROP)wParam; + // Get number of files dropped + uFiles = DragQueryFile(hDrop, -1, NULL, NULL); + + // Only getting first file dropped (other files ignored) + if (DragQueryFile(hDrop, 0, lpszFile, MAX_PATH)) { + auto e = FileDropEvent(this, lpszFile); + OnFileDrop(&e); + } + + DragFinish(hDrop); + } break; case WM_NCCREATE: break; case WM_CREATE: