📄 gdkevents-win32.c
字号:
/* GDK - The GIMP Drawing Kit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * Copyright (C) 1998-2002 Tor Lillqvist * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//* * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS * file for a list of people on the GTK+ Team. See the ChangeLog * files for a list of changes. These files are distributed with * GTK+ at ftp://ftp.gtk.org/pub/gtk/. *//* Cannot use TrackMouseEvent, as the stupid WM_MOUSELEAVE message * doesn't tell us where the mouse has gone. Thus we cannot use it to * generate a correct GdkNotifyType. Pity, as using TrackMouseEvent * otherwise would make it possible to reliably generate * GDK_LEAVE_NOTIFY events, which would help get rid of those pesky * tooltips sometimes popping up in the wrong place. * * Update: a combination of TrackMouseEvent, GetCursorPos and * GetWindowPos can and is actually used to get rid of those * pesky tooltips. It should be possible to use this for the * whole ENTER/LEAVE NOTIFY handling but some platforms may * not have TrackMouseEvent at all (?) --hb */#include <config.h>#include <glib/gprintf.h>#if defined (__GNUC__) && defined (HAVE_DIMM_H)/* The w32api imm.h clashes a bit with the IE5.5 dimm.h */# define IMEMENUITEMINFOA hidden_IMEMENUITEMINFOA# define IMEMENUITEMINFOW hidden_IMEMENUITEMINFOW#endif#include "gdk.h"#include "gdkprivate-win32.h"#include "gdkinput-win32.h"#include "gdkkeysyms.h"#include <windowsx.h>#ifdef G_WITH_CYGWIN#include <fcntl.h>#include <errno.h>#endif#include <objbase.h>#include <imm.h>#if defined (__GNUC__) && defined (HAVE_DIMM_H)# undef IMEMENUITEMINFOA# undef IMEMENUITEMINFOW#endif#ifdef HAVE_DIMM_H#include <dimm.h>#endif#ifndef XBUTTON1#define XBUTTON1 1#define XBUTTON2 2#endif#ifndef VK_XBUTTON1#define VK_XBUTTON1 5#define VK_XBUTTON2 6#endif#ifndef MK_XBUTTON1#define MK_XBUTTON1 32#define MK_XBUTTON2 64#endif/* * Private function declarations */static GdkFilterReturn gdk_event_apply_filters(MSG *msg, GdkEvent *event, GList *filters);static gboolean gdk_event_translate (GdkDisplay *display, MSG *msg, gint *ret_valp);static void handle_wm_paint (MSG *msg, GdkWindow *window, gboolean return_exposes, GdkEvent **event);static gboolean gdk_event_prepare (GSource *source, gint *timeout);static gboolean gdk_event_check (GSource *source);static gboolean gdk_event_dispatch (GSource *source, GSourceFunc callback, gpointer user_data);static void append_event (GdkDisplay *display, GdkEvent *event);/* Private variable declarations */static GdkWindow *p_grab_window = NULL; /* Window that currently holds * the pointer grab */static GdkWindow *p_grab_confine_to = NULL;static GdkWindow *k_grab_window = NULL; /* Window the holds the * keyboard grab */static GList *client_filters; /* Filters for client messages */static gboolean p_grab_automatic;static GdkEventMask p_grab_mask;static gboolean p_grab_owner_events, k_grab_owner_events;static HCURSOR p_grab_cursor;static GSourceFuncs event_funcs = { gdk_event_prepare, gdk_event_check, gdk_event_dispatch, NULL};GPollFD event_poll_fd;static GdkWindow *current_window = NULL;static gint current_x, current_y;#if 0static UINT gdk_ping_msg;#endifstatic UINT msh_mousewheel;static UINT client_message;#ifdef HAVE_DIMM_Hstatic IActiveIMMApp *active_imm_app = NULL;static IActiveIMMMessagePumpOwner *active_imm_msgpump_owner = NULL;#endif#if 0static HKL latin_locale = NULL;#endifstatic gboolean in_ime_composition = FALSE;static UINT resize_timer;static int debug_indent = 0;static voidassign_object (gpointer lhsp, gpointer rhs){ if (*(gpointer *)lhsp != rhs) { if (*(gpointer *)lhsp != NULL) g_object_unref (*(gpointer *)lhsp); *(gpointer *)lhsp = rhs; if (rhs != NULL) g_object_ref (rhs); }}static voidtrack_mouse_event (DWORD dwFlags, HWND hwnd){ typedef BOOL (WINAPI *PFN_TrackMouseEvent) (LPTRACKMOUSEEVENT); static PFN_TrackMouseEvent p_TrackMouseEvent = NULL; static gboolean once = FALSE; if (!once) { HMODULE user32; HINSTANCE commctrl32; user32 = GetModuleHandle ("user32.dll"); if ((p_TrackMouseEvent = (PFN_TrackMouseEvent)GetProcAddress (user32, "TrackMouseEvent")) == NULL) { if ((commctrl32 = LoadLibrary ("commctrl32.dll")) != NULL) p_TrackMouseEvent = (PFN_TrackMouseEvent) GetProcAddress (commctrl32, "_TrackMouseEvent"); } once = TRUE; } if (p_TrackMouseEvent) { TRACKMOUSEEVENT tme; tme.cbSize = sizeof(TRACKMOUSEEVENT); tme.dwFlags = dwFlags; tme.hwndTrack = hwnd; tme.dwHoverTime = HOVER_DEFAULT; /* not used */ if (!p_TrackMouseEvent (&tme)) WIN32_API_FAILED ("TrackMouseEvent"); else if (dwFlags == TME_LEAVE) GDK_NOTE (EVENTS, g_print(" (TrackMouseEvent %p)", hwnd)); else if (dwFlags == TME_CANCEL) GDK_NOTE (EVENTS, g_print(" (cancel TrackMouseEvent %p)", hwnd)); }}gulong_gdk_win32_get_next_tick (gulong suggested_tick){ static gulong cur_tick = 0; if (suggested_tick == 0) suggested_tick = GetTickCount (); if (suggested_tick <= cur_tick) return cur_tick; else return cur_tick = suggested_tick;}static voidgenerate_focus_event (GdkWindow *window, gboolean in){ GdkEvent *event; event = gdk_event_new (GDK_FOCUS_CHANGE); event->focus_change.window = window; event->focus_change.in = in; append_event (gdk_drawable_get_display (window), event);}static LRESULT inner_window_procedure (HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam){ GdkDisplay *display = gdk_display_get_default (); MSG msg; DWORD pos;#ifdef HAVE_DIMM_H LRESULT lres;#endif gint ret_val = 0; msg.hwnd = hwnd; msg.message = message; msg.wParam = wparam; msg.lParam = lparam; msg.time = _gdk_win32_get_next_tick (0); pos = GetMessagePos (); msg.pt.x = GET_X_LPARAM (pos); msg.pt.y = GET_Y_LPARAM (pos); if (gdk_event_translate (display, &msg, &ret_val)) { /* If gdk_event_translate() returns TRUE, we return ret_val from * the window procedure. */ return ret_val; } else { /* Otherwise call DefWindowProc(). */ GDK_NOTE (EVENTS, g_print (" DefWindowProc"));#ifndef HAVE_DIMM_H return DefWindowProc (hwnd, message, wparam, lparam);#else if (active_imm_app == NULL || (*active_imm_app->lpVtbl->OnDefWindowProc) (active_imm_app, hwnd, message, wparam, lparam, &lres) == S_FALSE) return DefWindowProc (hwnd, message, wparam, lparam); else return lres;#endif }}LRESULT CALLBACK_gdk_win32_window_procedure (HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam){ LRESULT retval; GDK_NOTE (EVENTS, g_print ("%s%*s%s %p", (debug_indent > 0 ? "\n" : ""), debug_indent, "", _gdk_win32_message_to_string (message), hwnd)); debug_indent += 2; retval = inner_window_procedure (hwnd, message, wparam, lparam); debug_indent -= 2; GDK_NOTE (EVENTS, g_print (" => %ld%s", retval, (debug_indent == 0 ? "\n" : ""))); return retval;}void _gdk_events_init (void){ GSource *source;#ifdef HAVE_DIMM_H HRESULT hres;#endif#if 0 int i, j, n; /* List of languages that use a latin keyboard. Somewhat sorted in * "order of least surprise", in case we have to load one of them if * the user only has arabic loaded, for instance. */ static int latin_languages[] = { LANG_ENGLISH, LANG_SPANISH, LANG_PORTUGUESE, LANG_FRENCH, LANG_GERMAN, /* Rest in numeric order */ LANG_CZECH, LANG_DANISH, LANG_FINNISH, LANG_HUNGARIAN, LANG_ICELANDIC, LANG_ITALIAN, LANG_DUTCH, LANG_NORWEGIAN, LANG_POLISH, LANG_ROMANIAN, LANG_SLOVAK, LANG_ALBANIAN, LANG_SWEDISH, LANG_TURKISH, LANG_INDONESIAN, LANG_SLOVENIAN, LANG_ESTONIAN, LANG_LATVIAN, LANG_LITHUANIAN, LANG_VIETNAMESE, LANG_AFRIKAANS, LANG_FAEROESE#ifdef LANG_SWAHILI ,LANG_SWAHILI#endif };#endif#if 0 gdk_ping_msg = RegisterWindowMessage ("gdk-ping"); GDK_NOTE (EVENTS, g_print ("gdk-ping = %#x\n", gdk_ping_msg));#endif /* This is the string MSH_MOUSEWHEEL from zmouse.h, * http://www.microsoft.com/mouse/intellimouse/sdk/zmouse.h * This message is used by mouse drivers than cannot generate WM_MOUSEWHEEL * or on Win95. */ msh_mousewheel = RegisterWindowMessage ("MSWHEEL_ROLLMSG"); client_message = RegisterWindowMessage ("GDK_WIN32_CLIENT_MESSAGE");#if 0 /* Check if we have some input locale identifier loaded that uses a * latin keyboard, to be able to get the virtual-key code for the * latin characters corresponding to ASCII control characters. */ if ((n = GetKeyboardLayoutList (0, NULL)) == 0) WIN32_API_FAILED ("GetKeyboardLayoutList"); else { HKL *hkl_list = g_new (HKL, n); if (GetKeyboardLayoutList (n, hkl_list) == 0) WIN32_API_FAILED ("GetKeyboardLayoutList"); else { for (i = 0; latin_locale == NULL && i < n; i++) for (j = 0; j < G_N_ELEMENTS (latin_languages); j++) if (PRIMARYLANGID (LOWORD (hkl_list[i])) == latin_languages[j]) { latin_locale = hkl_list [i]; break; } } g_free (hkl_list); } if (latin_locale == NULL) { /* Try to load a keyboard layout with latin characters then. */ i = 0; while (latin_locale == NULL && i < G_N_ELEMENTS (latin_languages)) { char id[9]; g_sprintf (id, "%08x", MAKELANGID (latin_languages[i++], SUBLANG_DEFAULT)); latin_locale = LoadKeyboardLayout (id, KLF_NOTELLSHELL|KLF_SUBSTITUTE_OK); } } GDK_NOTE (EVENTS, g_print ("latin_locale = %08x\n", (guint) latin_locale));#endif source = g_source_new (&event_funcs, sizeof (GSource)); g_source_set_priority (source, GDK_PRIORITY_EVENTS);#ifdef G_WITH_CYGWIN event_poll_fd.fd = open ("/dev/windows", O_RDONLY); if (event_poll_fd.fd == -1) g_error ("can't open \"/dev/windows\": %s", g_strerror (errno));#else event_poll_fd.fd = G_WIN32_MSG_HANDLE;#endif event_poll_fd.events = G_IO_IN; g_source_add_poll (source, &event_poll_fd); g_source_set_can_recurse (source, TRUE); g_source_attach (source, NULL);#ifdef HAVE_DIMM_H hres = CoCreateInstance (&CLSID_CActiveIMM, NULL, CLSCTX_ALL, &IID_IActiveIMMApp, (LPVOID *) &active_imm_app); if (hres == S_OK) { GDK_NOTE (EVENTS, g_print ("IActiveIMMApp created %p\n", active_imm_app)); (*active_imm_app->lpVtbl->Activate) (active_imm_app, TRUE); hres = (*active_imm_app->lpVtbl->QueryInterface) (active_imm_app, &IID_IActiveIMMMessagePumpOwner, (void **) &active_imm_msgpump_owner); GDK_NOTE (EVENTS, g_print ("IActiveIMMMessagePumpOwner created %p\n", active_imm_msgpump_owner)); (active_imm_msgpump_owner->lpVtbl->Start) (active_imm_msgpump_owner); }#endif}gbooleangdk_events_pending (void){ MSG msg; GdkDisplay *display = gdk_display_get_default (); return (_gdk_event_queue_find_first (display) || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE));}GdkEvent*gdk_event_get_graphics_expose (GdkWindow *window){ MSG msg; GdkEvent *event = NULL; g_return_val_if_fail (window != NULL, NULL); GDK_NOTE (EVENTS, g_print ("gdk_event_get_graphics_expose\n")); if (PeekMessage (&msg, GDK_WINDOW_HWND (window), WM_PAINT, WM_PAINT, PM_REMOVE)) { handle_wm_paint (&msg, window, TRUE, &event); if (event != NULL) { GDK_NOTE (EVENTS, g_print ("gdk_event_get_graphics_expose: got it!\n")); return event; } } GDK_NOTE (EVENTS, g_print ("gdk_event_get_graphics_expose: nope\n")); return NULL; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -