receive_windows_message
This commit is contained in:
parent
c4f35f6e4c
commit
8061092d8e
|
|
@ -27,18 +27,18 @@ WindowHandle::
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowHandle::send_keyboard_event
|
||||
// Function: WindowHandle::send_windows_message
|
||||
// Access: Published
|
||||
// Description: Call this method on a parent WindowHandle to deliver
|
||||
// a button event to the current child window, if any.
|
||||
// a Windows message to the current child window, if any.
|
||||
// This is used in the web plugin system to deliver
|
||||
// button events detected directly by the browser system
|
||||
// into Panda.
|
||||
// into Panda, which is particularly necessary on Vista.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WindowHandle::
|
||||
send_keyboard_event(const ButtonEvent &event) {
|
||||
send_windows_message(unsigned int msg, int wparam, int lparam) {
|
||||
if (_keyboard_window != NULL) {
|
||||
_keyboard_window->receive_keyboard_event(event);
|
||||
_keyboard_window->receive_windows_message(msg, wparam, lparam);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -106,13 +106,14 @@ request_keyboard_focus(WindowHandle *child) {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowHandle::receive_keyboard_event
|
||||
// Function: WindowHandle::receive_windows_message
|
||||
// Access: Public, Virtual
|
||||
// Description: Called on a child handle to deliver a keyboard button
|
||||
// event generated in the parent window.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WindowHandle::
|
||||
receive_keyboard_event(const ButtonEvent &event) {
|
||||
receive_windows_message(unsigned int msg, int wparam, int lparam) {
|
||||
nout << "receive_windows_message(" << msg << ", " << wparam << ", " << lparam << ")\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@
|
|||
#include "typedReferenceCount.h"
|
||||
#include "pointerTo.h"
|
||||
|
||||
class ButtonEvent;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : WindowHandle
|
||||
// Description : This object represents a window on the desktop, not
|
||||
|
|
@ -50,7 +48,7 @@ PUBLISHED:
|
|||
INLINE OSHandle *get_os_handle() const;
|
||||
INLINE void set_os_handle(OSHandle *os_handle);
|
||||
|
||||
void send_keyboard_event(const ButtonEvent &event);
|
||||
void send_windows_message(unsigned int msg, int wparam, int lparam);
|
||||
|
||||
size_t get_int_handle() const;
|
||||
|
||||
|
|
@ -62,7 +60,7 @@ public:
|
|||
virtual void detach_child(WindowHandle *child);
|
||||
|
||||
virtual void request_keyboard_focus(WindowHandle *child);
|
||||
virtual void receive_keyboard_event(const ButtonEvent &event);
|
||||
virtual void receive_windows_message(unsigned int msg, int wparam, int lparam);
|
||||
|
||||
PUBLISHED:
|
||||
// This internal pointer within WindowHandle stores the actual
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
|
||||
TypeHandle WinGraphicsWindow::_type_handle;
|
||||
TypeHandle WinGraphicsWindow::WinWindowHandle::_type_handle;
|
||||
|
||||
WinGraphicsWindow::WindowHandles WinGraphicsWindow::_window_handles;
|
||||
WinGraphicsWindow *WinGraphicsWindow::_creating_window = NULL;
|
||||
|
|
@ -117,6 +118,9 @@ WinGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
WinGraphicsWindow::
|
||||
~WinGraphicsWindow() {
|
||||
if (_window_handle != (WindowHandle *)NULL) {
|
||||
DCAST(WinWindowHandle, _window_handle)->clear_window();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -437,6 +441,20 @@ open_window() {
|
|||
Rid.hwndTarget = _hWnd;
|
||||
pRegisterRawInputDevices(&Rid, 1, sizeof (Rid));
|
||||
}
|
||||
|
||||
// Create a WindowHandle for ourselves
|
||||
_window_handle = NativeWindowHandle::make_win(_hWnd);
|
||||
|
||||
// Actually, we want a WinWindowHandle.
|
||||
_window_handle = new WinWindowHandle(this, *_window_handle);
|
||||
|
||||
// And tell our parent window that we're now its child.
|
||||
if (_parent_window_handle != (WindowHandle *)NULL) {
|
||||
_parent_window_handle->attach_child(_window_handle);
|
||||
}
|
||||
|
||||
// set us as the focus window for keyboard input
|
||||
set_focus();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -741,6 +759,9 @@ open_fullscreen_window()
|
|||
_properties.set_size(640, 480);
|
||||
}
|
||||
|
||||
// No parent window for a fullscreen window.
|
||||
_parent_window_handle = NULL;
|
||||
|
||||
HWND hDesktopWindow = GetDesktopWindow();
|
||||
HDC scrnDC = GetDC(hDesktopWindow);
|
||||
DWORD cur_bitdepth = GetDeviceCaps(scrnDC, BITSPIXEL);
|
||||
|
|
@ -888,6 +909,7 @@ open_regular_window() {
|
|||
}
|
||||
}
|
||||
}
|
||||
_parent_window_handle = window_handle;
|
||||
|
||||
if (!_hparent) {
|
||||
_hWnd = CreateWindow(wclass._name.c_str(), title.c_str(), window_style,
|
||||
|
|
@ -905,13 +927,11 @@ open_regular_window() {
|
|||
y_origin = _properties.get_y_origin();
|
||||
}
|
||||
|
||||
nout << "Creating embedded window\n";
|
||||
_hWnd = CreateWindow(wclass._name.c_str(), title.c_str(),
|
||||
WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS ,
|
||||
x_origin,y_origin,
|
||||
x_size, y_size,
|
||||
_hparent, NULL, hinstance, 0);
|
||||
nout << "Done creating embedded window, _hwnd = " << _hWnd << "\n";
|
||||
|
||||
if (_hWnd) {
|
||||
// join our keyboard state with the parents
|
||||
|
|
@ -920,9 +940,6 @@ open_regular_window() {
|
|||
// It causes problems with the browser plugin--it deadlocks when
|
||||
// the parent process is waiting on the child process.
|
||||
//AttachThreadInput(GetWindowThreadProcessId(_hparent,NULL), GetCurrentThreadId(),TRUE);
|
||||
|
||||
// set us as the focus window for keyboard input
|
||||
SetFocus(_hWnd);
|
||||
|
||||
WindowProperties properties;
|
||||
properties.set_foreground(true);
|
||||
|
|
@ -1038,8 +1055,52 @@ track_mouse_leaving(HWND hwnd) {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinGraphicsWindow::window_proc
|
||||
// Function: WinGraphicsWindow::set_focus
|
||||
// Access: Private
|
||||
// Description: Attempts to set this window as the "focus" window, so
|
||||
// that keyboard events come here.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinGraphicsWindow::
|
||||
set_focus() {
|
||||
if (SetFocus(_hWnd) == NULL && GetLastError() != 0) {
|
||||
// If the SetFocus() request failed, maybe we're running in the
|
||||
// plugin environment on Vista, with UAC enabled. In this case,
|
||||
// we're not allowed to assign focus to the Panda window for some
|
||||
// stupid reason. So instead, we have to ask the parent window
|
||||
// (in the browser process) to proxy our keyboard events for us.
|
||||
if (_parent_window_handle != NULL && _window_handle != NULL) {
|
||||
_parent_window_handle->request_keyboard_focus(_window_handle);
|
||||
} else {
|
||||
// Otherwise, something is wrong.
|
||||
windisplay_cat.error()
|
||||
<< "SetFocus failed: " << GetLastError() << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinGraphicsWindow::receive_windows_message
|
||||
// Access: Public
|
||||
// Description: This is called to receive a keyboard event generated
|
||||
// by proxy by another window in a parent process. This
|
||||
// hacky system is used in the web plugin system to
|
||||
// allow the Panda window to receive keyboard events on
|
||||
// Vista, which doesn't allow the Panda window to set
|
||||
// keyboard focus to itself.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinGraphicsWindow::
|
||||
receive_windows_message(unsigned int msg, int wparam, int lparam) {
|
||||
// Well, we'll just deliver this directly to window_proc(),
|
||||
// supplying our own window handle. For the most part, we don't
|
||||
// care about the window handle anyway, but this might become an
|
||||
// issue for the IME. TODO: investigate IME issues.
|
||||
|
||||
window_proc(_hWnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinGraphicsWindow::window_proc
|
||||
// Access: Public, Virtual
|
||||
// Description: This is the nonstatic window_proc function. It is
|
||||
// called to handle window events for this particular
|
||||
// window.
|
||||
|
|
@ -1226,7 +1287,9 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
SetCapture(hwnd);
|
||||
_input_devices[0].set_pointer_in_window(translate_mouse(LOWORD(lparam)), translate_mouse(HIWORD(lparam)));
|
||||
_input_devices[0].button_down(MouseButton::button(0), get_message_time());
|
||||
SetFocus(hwnd); // [gjeon] to get the keyboard event
|
||||
|
||||
// A button-click in the window means to grab the keyboard focus.
|
||||
set_focus();
|
||||
break;
|
||||
|
||||
case WM_MBUTTONDOWN:
|
||||
|
|
@ -1236,7 +1299,8 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
SetCapture(hwnd);
|
||||
_input_devices[0].set_pointer_in_window(translate_mouse(LOWORD(lparam)), translate_mouse(HIWORD(lparam)));
|
||||
_input_devices[0].button_down(MouseButton::button(1), get_message_time());
|
||||
SetFocus(hwnd); // [gjeon] to get the keyboard event
|
||||
// A button-click in the window means to grab the keyboard focus.
|
||||
set_focus();
|
||||
break;
|
||||
|
||||
case WM_RBUTTONDOWN:
|
||||
|
|
@ -1246,7 +1310,8 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
SetCapture(hwnd);
|
||||
_input_devices[0].set_pointer_in_window(translate_mouse(LOWORD(lparam)), translate_mouse(HIWORD(lparam)));
|
||||
_input_devices[0].button_down(MouseButton::button(2), get_message_time());
|
||||
SetFocus(hwnd); // [gjeon] to get the keyboard event
|
||||
// A button-click in the window means to grab the keyboard focus.
|
||||
set_focus();
|
||||
break;
|
||||
|
||||
case WM_XBUTTONDOWN:
|
||||
|
|
@ -2469,6 +2534,45 @@ register_window_class(const WindowProperties &props) {
|
|||
return wclass;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinGraphicsWindow::WinWindowHandle::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WinGraphicsWindow::WinWindowHandle::
|
||||
WinWindowHandle(WinGraphicsWindow *window, const WindowHandle ©) :
|
||||
WindowHandle(copy),
|
||||
_window(window)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinGraphicsWindow::WinWindowHandle::clear_window
|
||||
// Access: Public
|
||||
// Description: Should be called by the WinGraphicsWindow's
|
||||
// destructor, so that we don't end up with a floating
|
||||
// pointer should this object persist beyond the
|
||||
// lifespan of its window.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinGraphicsWindow::WinWindowHandle::
|
||||
clear_window() {
|
||||
_window = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinGraphicsWindow::WinWindowHandle::receive_windows_message
|
||||
// Access: Public, Virtual
|
||||
// Description: Called on a child handle to deliver a keyboard button
|
||||
// event generated in the parent window.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinGraphicsWindow::WinWindowHandle::
|
||||
receive_windows_message(unsigned int msg, int wparam, int lparam) {
|
||||
if (_window != NULL) {
|
||||
_window->receive_windows_message(msg, wparam, lparam);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// pops up MsgBox w/system error msg
|
||||
void PrintErrorMessage(DWORD msgID) {
|
||||
LPTSTR pMessageBuffer;
|
||||
|
|
@ -2535,5 +2639,3 @@ void get_client_rect_screen(HWND hwnd, RECT *view_rect) {
|
|||
view_rect->right = lr.x;
|
||||
view_rect->bottom = lr.y;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ public:
|
|||
|
||||
virtual void process_events();
|
||||
virtual void set_properties_now(WindowProperties &properties);
|
||||
void receive_windows_message(unsigned int msg, int wparam, int lparam);
|
||||
virtual LONG window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
static LONG WINAPI static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
virtual bool handle_mouse_motion(int x, int y);
|
||||
|
|
@ -97,6 +98,8 @@ private:
|
|||
void handle_raw_input(HRAWINPUT hraw);
|
||||
void track_mouse_leaving(HWND hwnd);
|
||||
|
||||
void set_focus();
|
||||
|
||||
static void process_1_event();
|
||||
|
||||
INLINE void handle_keypress(ButtonHandle key, int x, int y, double time);
|
||||
|
|
@ -213,6 +216,41 @@ private:
|
|||
static int _window_class_index;
|
||||
|
||||
static const WindowClass ®ister_window_class(const WindowProperties &props);
|
||||
private:
|
||||
// This subclass of WindowHandle is stored in _window_handle to
|
||||
// represent this particular window. We use it to add hooks for
|
||||
// communicating with the parent window, in particular to receive
|
||||
// keyboard events from the parent window when necessary.
|
||||
class WinWindowHandle : public WindowHandle {
|
||||
public:
|
||||
WinWindowHandle(WinGraphicsWindow *window,
|
||||
const WindowHandle ©);
|
||||
void clear_window();
|
||||
|
||||
protected:
|
||||
virtual void receive_windows_message(unsigned int msg, int wparam, int lparam);
|
||||
|
||||
private:
|
||||
// Not reference-counted, to avoid a circular reference count.
|
||||
WinGraphicsWindow *_window;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
WindowHandle::init_type();
|
||||
register_type(_type_handle, "WinWindowHandle",
|
||||
WindowHandle::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
|
@ -222,6 +260,7 @@ public:
|
|||
GraphicsWindow::init_type();
|
||||
register_type(_type_handle, "WinGraphicsWindow",
|
||||
GraphicsWindow::get_class_type());
|
||||
WinWindowHandle::init_type();
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
|
|
|
|||
Loading…
Reference in New Issue