?? gdkdnd-win32.c
字號:
/* GDK - The GIMP Drawing Kit * Copyright (C) 1995-1999 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/. */#include <config.h>#include <string.h>/* #define OLE2_DND */#define INITGUID#include "gdkdnd.h"#include "gdkproperty.h"#include "gdkinternals.h"#include "gdkprivate-win32.h"#ifdef OLE2_DND#include <ole2.h>#else#include <objbase.h>#endif#include <shlobj.h>#include <shlguid.h>#include <gdk/gdk.h>typedef struct _GdkDragContextPrivateWin32 GdkDragContextPrivateWin32;typedef enum { GDK_DRAG_STATUS_DRAG, GDK_DRAG_STATUS_MOTION_WAIT, GDK_DRAG_STATUS_ACTION_WAIT, GDK_DRAG_STATUS_DROP} GtkDragStatus;typedef enum { GDK_DRAG_SOURCE, GDK_DRAG_TARGET} GdkDragKind;#ifdef OLE2_DND#define PRINT_GUID(guid) \ g_print ("guid = %.08lx-%.04x-%.04x-%.02x%.02x-%.02x%.02x%.02x%.02x%.02x%.02x", \ ((gulong *) guid)[0], \ ((gushort *) guid)[2], \ ((gushort *) guid)[3], \ ((guchar *) guid)[8], \ ((guchar *) guid)[9], \ ((guchar *) guid)[10], \ ((guchar *) guid)[11], \ ((guchar *) guid)[12], \ ((guchar *) guid)[13], \ ((guchar *) guid)[14], \ ((guchar *) guid)[15]);static FORMATETC *formats;static int nformats;#endif /* OLE2_DND *//* Structure that holds information about a drag in progress. * this is used on both source and destination sides. */struct _GdkDragContextPrivateWin32 {#ifdef OLE2_DND gint ref_count;#endif guint16 last_x; /* Coordinates from last event */ guint16 last_y; HWND dest_xid; guint drag_status : 4; /* Current status of drag */ guint drop_failed : 1; /* Whether the drop was unsuccessful */};#define GDK_DRAG_CONTEXT_PRIVATE_DATA(context) ((GdkDragContextPrivateWin32 *) GDK_DRAG_CONTEXT (context)->windowing_data)static GdkDragContext *current_dest_drag = NULL;static void gdk_drag_context_init (GdkDragContext *dragcontext);static void gdk_drag_context_class_init (GdkDragContextClass *klass);static void gdk_drag_context_finalize (GObject *object);static gpointer parent_class = NULL;static GList *contexts;GTypegdk_drag_context_get_type (void){ static GType object_type = 0; if (!object_type) { static const GTypeInfo object_info = { sizeof (GdkDragContextClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gdk_drag_context_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (GdkDragContext), 0, /* n_preallocs */ (GInstanceInitFunc) gdk_drag_context_init, }; object_type = g_type_register_static (G_TYPE_OBJECT, "GdkDragContext", &object_info, 0); } return object_type;}static voidgdk_drag_context_init (GdkDragContext *dragcontext){ GdkDragContextPrivateWin32 *private = g_new0 (GdkDragContextPrivateWin32, 1); dragcontext->windowing_data = private;#ifdef OLE2_DND private->ref_count = 1;#endif contexts = g_list_prepend (contexts, dragcontext);}static voidgdk_drag_context_class_init (GdkDragContextClass *klass){ GObjectClass *object_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); object_class->finalize = gdk_drag_context_finalize;}static voidgdk_drag_context_finalize (GObject *object){ GdkDragContext *context = GDK_DRAG_CONTEXT (object); GdkDragContextPrivateWin32 *private = GDK_DRAG_CONTEXT_PRIVATE_DATA (context); GDK_NOTE (DND, g_print ("gdk_drag_context_finalize\n")); g_list_free (context->targets); if (context->source_window) { g_object_unref (context->source_window); } if (context->dest_window) g_object_unref (context->dest_window); contexts = g_list_remove (contexts, context); if (context == current_dest_drag) current_dest_drag = NULL; g_free (private); G_OBJECT_CLASS (parent_class)->finalize (object);}/* Drag Contexts */GdkDragContext *gdk_drag_context_new (void){ return g_object_new (gdk_drag_context_get_type (), NULL);}voidgdk_drag_context_ref (GdkDragContext *context){ g_return_if_fail (GDK_IS_DRAG_CONTEXT (context)); g_object_ref (context);}voidgdk_drag_context_unref (GdkDragContext *context){ g_return_if_fail (GDK_IS_DRAG_CONTEXT (context)); g_object_unref (context);}static GdkDragContext *gdk_drag_context_find (gboolean is_source, GdkWindow *source, GdkWindow *dest){ GList *tmp_list = contexts; GdkDragContext *context; GdkDragContextPrivateWin32 *private; while (tmp_list) { context = (GdkDragContext *)tmp_list->data; private = GDK_DRAG_CONTEXT_PRIVATE_DATA (context); if ((!context->is_source == !is_source) && ((source == NULL) || (context->source_window && (context->source_window == source))) && ((dest == NULL) || (context->dest_window && (context->dest_window == dest)))) return context; tmp_list = tmp_list->next; } return NULL;}typedef struct {#ifdef OLE2_DND IDropTarget idt;#endif GdkDragContext *context;} target_drag_context;typedef struct {#ifdef OLE2_DND IDropSource ids;#endif GdkDragContext *context;} source_drag_context;#ifdef OLE2_DNDtypedef struct { IDataObject ido; int ref_count;} data_object;typedef struct { IEnumFORMATETC ief; int ref_count; int ix;} enum_formats;static enum_formats *enum_formats_new (void);static ULONG STDMETHODCALLTYPEidroptarget_addref (LPDROPTARGET This){ target_drag_context *ctx = (target_drag_context *) This; GdkDragContextPrivateWin32 *private = GDK_DRAG_CONTEXT_PRIVATE_DATA (ctx->context); int ref_count = ++private->ref_count; gdk_drag_context_ref (ctx->context); GDK_NOTE (DND, g_print ("idroptarget_addref %p %d\n", This, ref_count)); return ref_count;}static HRESULT STDMETHODCALLTYPEidroptarget_queryinterface (LPDROPTARGET This, REFIID riid, LPVOID *ppvObject){ GDK_NOTE (DND, g_print ("idroptarget_queryinterface %p\n", This)); *ppvObject = NULL; PRINT_GUID (riid); if (IsEqualGUID (riid, &IID_IUnknown)) { g_print ("...IUnknown\n"); idroptarget_addref (This); *ppvObject = This; return S_OK; } else if (IsEqualGUID (riid, &IID_IDropTarget)) { g_print ("...IDropTarget\n"); idroptarget_addref (This); *ppvObject = This; return S_OK; } else { g_print ("...Huh?\n"); return E_NOINTERFACE; }}static ULONG STDMETHODCALLTYPEidroptarget_release (LPDROPTARGET This){ target_drag_context *ctx = (target_drag_context *) This; GdkDragContextPrivateWin32 *private = GDK_DRAG_CONTEXT_PRIVATE_DATA (ctx->context); int ref_count = --private->ref_count; gdk_drag_context_unref (ctx->context); GDK_NOTE (DND, g_print ("idroptarget_release %p %d\n", This, ref_count)); if (ref_count == 0) g_free (This); return ref_count;}static HRESULT STDMETHODCALLTYPE idroptarget_dragenter (LPDROPTARGET This, LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect){ GDK_NOTE (DND, g_print ("idroptarget_dragenter %p\n", This)); return E_UNEXPECTED;}static HRESULT STDMETHODCALLTYPEidroptarget_dragover (LPDROPTARGET This, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect){ GDK_NOTE (DND, g_print ("idroptarget_dragover %p\n", This)); return E_UNEXPECTED;}static HRESULT STDMETHODCALLTYPEidroptarget_dragleave (LPDROPTARGET This){ GDK_NOTE (DND, g_print ("idroptarget_dragleave %p\n", This)); return E_UNEXPECTED;}static HRESULT STDMETHODCALLTYPEidroptarget_drop (LPDROPTARGET This, LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect){ GDK_NOTE (DND, g_print ("idroptarget_drop %p\n", This)); return E_UNEXPECTED;}static ULONG STDMETHODCALLTYPEidropsource_addref (LPDROPSOURCE This){ source_drag_context *ctx = (source_drag_context *) This; GdkDragContextPrivateWin32 *private = GDK_DRAG_CONTEXT_PRIVATE_DATA (ctx->context); gdk_drag_context_ref (ctx->context); GDK_NOTE (DND, g_print ("idropsource_addref %p %d\n", This, private->ref_count)); return private->ref_count;}static HRESULT STDMETHODCALLTYPEidropsource_queryinterface (LPDROPSOURCE This, REFIID riid, LPVOID *ppvObject){ GDK_NOTE (DND, g_print ("idropsource_queryinterface %p\n", This)); *ppvObject = NULL; PRINT_GUID (riid); if (IsEqualGUID (riid, &IID_IUnknown)) { g_print ("...IUnknown\n"); idropsource_addref (This); *ppvObject = This; return S_OK; } else if (IsEqualGUID (riid, &IID_IDropSource)) { g_print ("...IDropSource\n"); idropsource_addref (This); *ppvObject = This; return S_OK; } else { g_print ("...Huh?\n"); return E_NOINTERFACE; }}static ULONG STDMETHODCALLTYPEidropsource_release (LPDROPSOURCE This){ source_drag_context *ctx = (source_drag_context *) This; GdkDragContextPrivateWin32 *private = GDK_DRAG_CONTEXT_PRIVATE_DATA (ctx->context); int ref_count = --private->ref_count; gdk_drag_context_unref (ctx->context); GDK_NOTE (DND, g_print ("idropsource_release %p %d\n", This, ref_count)); if (ref_count == 0) g_free (This); return ref_count;}static HRESULT STDMETHODCALLTYPEidropsource_querycontinuedrag (LPDROPSOURCE This, BOOL fEscapePressed, DWORD grfKeyState){ GDK_NOTE (DND, g_print ("idropsource_querycontinuedrag %p\n", This)); return E_UNEXPECTED;}static HRESULT STDMETHODCALLTYPEidropsource_givefeedback (LPDROPSOURCE This, DWORD dwEffect){ GDK_NOTE (DND, g_print ("idropsource_givefeedback %p\n", This)); return E_UNEXPECTED;}static ULONG STDMETHODCALLTYPEidataobject_addref (LPDATAOBJECT This){ data_object *dobj = (data_object *) This; int ref_count = ++dobj->ref_count; GDK_NOTE (DND, g_print ("idataobject_addref %p %d\n", This, ref_count)); return ref_count;}static HRESULT STDMETHODCALLTYPEidataobject_queryinterface (LPDATAOBJECT This, REFIID riid, LPVOID *ppvObject){ GDK_NOTE (DND, g_print ("idataobject_queryinterface %p\n", This)); *ppvObject = NULL; PRINT_GUID (riid); if (IsEqualGUID (riid, &IID_IUnknown)) { g_print ("...IUnknown\n"); idataobject_addref (This); *ppvObject = This; return S_OK; } else if (IsEqualGUID (riid, &IID_IDataObject)) { g_print ("...IDataObject\n"); idataobject_addref (This); *ppvObject = This; return S_OK; } else { g_print ("...Huh?\n"); return E_NOINTERFACE; }}static ULONG STDMETHODCALLTYPEidataobject_release (LPDATAOBJECT This){ data_object *dobj = (data_object *) This; int ref_count = --dobj->ref_count; GDK_NOTE (DND, g_print ("idataobject_release %p %d\n", This, ref_count)); if (ref_count == 0) g_free (This); return ref_count;}static HRESULT STDMETHODCALLTYPEidataobject_getdata (LPDATAOBJECT This, LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium){ GDK_NOTE (DND, g_print ("idataobject_getdata %p\n", This)); return E_UNEXPECTED;}static HRESULT STDMETHODCALLTYPEidataobject_getdatahere (LPDATAOBJECT This, LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium){ GDK_NOTE (DND, g_print ("idataobject_getdatahere %p\n", This)); return E_UNEXPECTED;}static HRESULT STDMETHODCALLTYPEidataobject_querygetdata (LPDATAOBJECT This, LPFORMATETC pFormatEtc){ int i; GDK_NOTE (DND, g_print ("idataobject_querygetdata %p %#x", This, pFormatEtc->cfFormat)); for (i = 0; i < nformats; i++) if (pFormatEtc->cfFormat == formats[i].cfFormat) { GDK_NOTE (DND, g_print (" S_OK\n")); return S_OK; } GDK_NOTE (DND, g_print (" DV_E_FORMATETC\n")); return DV_E_FORMATETC;}static HRESULT STDMETHODCALLTYPEidataobject_getcanonicalformatetc (LPDATAOBJECT This, LPFORMATETC pFormatEtcIn, LPFORMATETC pFormatEtcOut){ GDK_NOTE (DND, g_print ("idataobject_getcanonicalformatetc %p\n", This)); return E_FAIL;}static HRESULT STDMETHODCALLTYPEidataobject_setdata (LPDATAOBJECT This, LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium, BOOL fRelease){ GDK_NOTE (DND, g_print ("idataobject_setdata %p\n", This)); return E_UNEXPECTED;}static HRESULT STDMETHODCALLTYPEidataobject_enumformatetc (LPDATAOBJECT This, DWORD dwDirection, LPENUMFORMATETC *ppEnumFormatEtc){ GDK_NOTE (DND, g_print ("idataobject_enumformatetc %p\n", This)); if (dwDirection != DATADIR_GET) return E_NOTIMPL; *ppEnumFormatEtc = &enum_formats_new ()->ief; return S_OK;}static HRESULT STDMETHODCALLTYPEidataobject_dadvise (LPDATAOBJECT This, LPFORMATETC pFormatetc, DWORD advf, LPADVISESINK pAdvSink, DWORD *pdwConnection){ GDK_NOTE (DND, g_print ("idataobject_dadvise %p\n", This)); return E_FAIL;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -