?? gdkdnd-win32.c
字號:
tmp_event.dnd.y_root = y_root; (GDK_DRAG_CONTEXT_PRIVATE_DATA (current_dest_drag))->last_x = x_root; (GDK_DRAG_CONTEXT_PRIVATE_DATA (current_dest_drag))->last_y = y_root; GDK_DRAG_CONTEXT_PRIVATE_DATA (context)->drag_status = GDK_DRAG_STATUS_MOTION_WAIT; gdk_event_put (&tmp_event); }}static voidlocal_send_drop (GdkDragContext *context, guint32 time){ GdkEvent tmp_event; if ((current_dest_drag != NULL) && (current_dest_drag->protocol == GDK_DRAG_PROTO_LOCAL) && (current_dest_drag->source_window == context->source_window)) { GdkDragContextPrivateWin32 *private; private = GDK_DRAG_CONTEXT_PRIVATE_DATA (current_dest_drag); /* Pass ownership of context to the event */ tmp_event.dnd.type = GDK_DROP_START; tmp_event.dnd.window = current_dest_drag->dest_window; tmp_event.dnd.send_event = FALSE; tmp_event.dnd.context = current_dest_drag; tmp_event.dnd.time = GDK_CURRENT_TIME; tmp_event.dnd.x_root = private->last_x; tmp_event.dnd.y_root = private->last_y; current_dest_drag = NULL; gdk_event_put (&tmp_event); }}static voidgdk_drag_do_leave (GdkDragContext *context, guint32 time){ if (context->dest_window) { GDK_NOTE (DND, g_print ("gdk_drag_do_leave\n")); switch (context->protocol) { case GDK_DRAG_PROTO_LOCAL: local_send_leave (context, time); break; default: break; } g_object_unref (context->dest_window); context->dest_window = NULL; }}GdkDragContext * gdk_drag_begin (GdkWindow *window, GList *targets){#ifndef OLE2_DND GList *tmp_list; GdkDragContext *new_context; g_return_val_if_fail (window != NULL, NULL); new_context = gdk_drag_context_new (); new_context->is_source = TRUE; new_context->source_window = window; g_object_ref (window); tmp_list = g_list_last (targets); new_context->targets = NULL; while (tmp_list) { new_context->targets = g_list_prepend (new_context->targets, tmp_list->data); tmp_list = tmp_list->prev; } new_context->actions = 0; return new_context;#else source_drag_context *ctx; GList *tmp_list; data_object *dobj; HRESULT hResult; DWORD dwEffect; HGLOBAL global; STGMEDIUM medium; g_return_val_if_fail (window != NULL, NULL); GDK_NOTE (DND, g_print ("gdk_drag_begin\n")); ctx = source_context_new (); ctx->context->protocol = GDK_DRAG_PROTO_OLE2; ctx->context->source_window = window; g_object_ref (window); tmp_list = g_list_last (targets); ctx->context->targets = NULL; while (tmp_list) { ctx->context->targets = g_list_prepend (ctx->context->targets, tmp_list->data); tmp_list = tmp_list->prev; } ctx->context->actions = 0; dobj = data_object_new (); global = GlobalAlloc (GMEM_FIXED, sizeof (ctx)); memcpy (&global, ctx, sizeof (ctx)); medium.tymed = TYMED_HGLOBAL; medium.hGlobal = global; medium.pUnkForRelease = NULL; dobj->ido.lpVtbl->SetData (&dobj->ido, &formats[1], &medium, TRUE); hResult = DoDragDrop (&dobj->ido, &ctx->ids, DROPEFFECT_MOVE|DROPEFFECT_COPY, &dwEffect); GDK_NOTE (DND, g_print ("DoDragDrop returned %s\n", (hResult == DRAGDROP_S_DROP ? "DRAGDROP_S_DROP" : (hResult == DRAGDROP_S_CANCEL ? "DRAGDROP_S_CANCEL" : (hResult == E_UNEXPECTED ? "E_UNEXPECTED" : g_strdup_printf ("%#.8lx", hResult)))))); dobj->ido.lpVtbl->Release (&dobj->ido); ctx->ids.lpVtbl->Release (&ctx->ids); return ctx->context;#endif}guint32gdk_drag_get_protocol_for_display (GdkDisplay *display, guint32 xid, GdkDragProtocol *protocol){ GdkWindow *window; GDK_NOTE (DND, g_print ("gdk_drag_get_protocol\n")); window = gdk_window_lookup (xid); if (GPOINTER_TO_INT (gdk_drawable_get_data (window, "gdk-dnd-registered"))) { *protocol = GDK_DRAG_PROTO_LOCAL; return xid; } return 0;}typedef struct { gint x; gint y; HWND ignore; HWND result;} find_window_enum_arg;static BOOL CALLBACKfind_window_enum_proc (HWND hwnd, LPARAM lparam){ RECT rect; POINT tl, br; find_window_enum_arg *a = (find_window_enum_arg *) lparam; if (hwnd == a->ignore) return TRUE; if (!IsWindowVisible (hwnd)) return TRUE; tl.x = tl.y = 0; ClientToScreen (hwnd, &tl); GetClientRect (hwnd, &rect); br.x = rect.right; br.y = rect.bottom; ClientToScreen (hwnd, &br); if (a->x >= tl.x && a->y >= tl.y && a->x < br.x && a->y < br.y) { a->result = hwnd; return FALSE; } else return TRUE;}voidgdk_drag_find_window_for_screen (GdkDragContext *context, GdkWindow *drag_window, GdkScreen *screen, gint x_root, gint y_root, GdkWindow **dest_window, GdkDragProtocol *protocol){ find_window_enum_arg a; a.x = x_root - _gdk_offset_x; a.y = y_root - _gdk_offset_y; a.ignore = drag_window ? GDK_WINDOW_HWND (drag_window) : NULL; a.result = NULL; EnumWindows (find_window_enum_proc, (LPARAM) &a); if (a.result == NULL) *dest_window = NULL; else { *dest_window = gdk_win32_handle_table_lookup (GPOINTER_TO_UINT (a.result)); if (*dest_window) { *dest_window = gdk_window_get_toplevel (*dest_window); g_object_ref (*dest_window); } if (context->source_window) *protocol = GDK_DRAG_PROTO_LOCAL; else *protocol = GDK_DRAG_PROTO_WIN32_DROPFILES; } GDK_NOTE (DND, g_print ("gdk_drag_find_window: %p +%d+%d: %p: %p %d\n", (drag_window ? GDK_WINDOW_HWND (drag_window) : NULL), x_root, y_root, a.result, (*dest_window ? GDK_WINDOW_HWND (*dest_window) : NULL), *protocol));}gbooleangdk_drag_motion (GdkDragContext *context, GdkWindow *dest_window, GdkDragProtocol protocol, gint x_root, gint y_root, GdkDragAction suggested_action, GdkDragAction possible_actions, guint32 time){ GdkDragContextPrivateWin32 *private; g_return_val_if_fail (context != NULL, FALSE); GDK_NOTE (DND, g_print ("gdk_drag_motion\n")); private = GDK_DRAG_CONTEXT_PRIVATE_DATA (context); if (context->dest_window != dest_window) { GdkEvent temp_event; /* Send a leave to the last destination */ gdk_drag_do_leave (context, time); private->drag_status = GDK_DRAG_STATUS_DRAG; /* Check if new destination accepts drags, and which protocol */ if (dest_window) { context->dest_window = dest_window; g_object_ref (context->dest_window); context->protocol = protocol; switch (protocol) { case GDK_DRAG_PROTO_LOCAL: local_send_enter (context, time); break; default: break; } context->suggested_action = suggested_action; } else { context->dest_window = NULL; context->action = 0; } /* Push a status event, to let the client know that * the drag changed */ temp_event.dnd.type = GDK_DRAG_STATUS; temp_event.dnd.window = context->source_window; /* We use this to signal a synthetic status. Perhaps * we should use an extra field... */ temp_event.dnd.send_event = TRUE; temp_event.dnd.context = context; temp_event.dnd.time = time; gdk_event_put (&temp_event); } else { context->suggested_action = suggested_action; } /* Send a drag-motion event */ private->last_x = x_root; private->last_y = y_root; if (context->dest_window) { if (private->drag_status == GDK_DRAG_STATUS_DRAG) { switch (context->protocol) { case GDK_DRAG_PROTO_LOCAL: local_send_motion (context, x_root, y_root, suggested_action, time); break; case GDK_DRAG_PROTO_NONE: g_warning ("GDK_DRAG_PROTO_NONE is not valid in gdk_drag_motion()"); break; default: break; } } else return TRUE; } return FALSE;}voidgdk_drag_drop (GdkDragContext *context, guint32 time){ g_return_if_fail (context != NULL); GDK_NOTE (DND, g_print ("gdk_drag_drop\n")); if (context->dest_window) { switch (context->protocol) { case GDK_DRAG_PROTO_LOCAL: local_send_drop (context, time); break; case GDK_DRAG_PROTO_NONE: g_warning ("GDK_DRAG_PROTO_NONE is not valid in gdk_drag_drop()"); break; default: break; } }}voidgdk_drag_abort (GdkDragContext *context, guint32 time){ g_return_if_fail (context != NULL); GDK_NOTE (DND, g_print ("gdk_drag_abort\n")); gdk_drag_do_leave (context, time);}/* Destination side */voidgdk_drag_status (GdkDragContext *context, GdkDragAction action, guint32 time){ GdkDragContextPrivateWin32 *private; GdkDragContext *src_context; GdkEvent tmp_event; g_return_if_fail (context != NULL); private = GDK_DRAG_CONTEXT_PRIVATE_DATA (context); context->action = action; src_context = gdk_drag_context_find (TRUE, context->source_window, context->dest_window); if (src_context) { GdkDragContextPrivateWin32 *private = GDK_DRAG_CONTEXT_PRIVATE_DATA (src_context); if (private->drag_status == GDK_DRAG_STATUS_MOTION_WAIT) private->drag_status = GDK_DRAG_STATUS_DRAG; tmp_event.dnd.type = GDK_DRAG_STATUS; tmp_event.dnd.window = context->source_window; tmp_event.dnd.send_event = FALSE; tmp_event.dnd.context = src_context; tmp_event.dnd.time = GDK_CURRENT_TIME; /* FIXME? */ if (action == GDK_ACTION_DEFAULT) action = 0; src_context->action = action; gdk_event_put (&tmp_event); }}void gdk_drop_reply (GdkDragContext *context, gboolean ok, guint32 time){ g_return_if_fail (context != NULL); GDK_NOTE (DND, g_print ("gdk_drop_reply\n")); if (context->dest_window) { switch (context->protocol) { case GDK_DRAG_PROTO_WIN32_DROPFILES: _gdk_dropfiles_store (NULL); break; default: break; } }}voidgdk_drop_finish (GdkDragContext *context, gboolean success, guint32 time){ GdkDragContextPrivateWin32 *private; GdkDragContext *src_context; GdkEvent tmp_event; g_return_if_fail (context != NULL); GDK_NOTE (DND, g_print ("gdk_drop_finish")); private = GDK_DRAG_CONTEXT_PRIVATE_DATA (context); src_context = gdk_drag_context_find (TRUE, context->source_window, context->dest_window); if (src_context) { tmp_event.dnd.type = GDK_DROP_FINISHED; tmp_event.dnd.window = src_context->source_window; tmp_event.dnd.send_event = FALSE; tmp_event.dnd.context = src_context; gdk_event_put (&tmp_event); }}#ifdef OLE2_DNDstatic GdkFilterReturngdk_destroy_filter (GdkXEvent *xev, GdkEvent *event, gpointer data){ MSG *msg = (MSG *) xev; if (msg->message == WM_DESTROY) { IDropTarget *idtp = (IDropTarget *) data; GDK_NOTE (DND, g_print ("gdk_destroy_filter: WM_DESTROY: %p\n", msg->hwnd));#if 0 idtp->lpVtbl->Release (idtp);#endif RevokeDragDrop (msg->hwnd); CoLockObjectExternal (idtp, FALSE, TRUE); } return GDK_FILTER_CONTINUE;}#endifvoidgdk_window_register_dnd (GdkWindow *window){#ifdef OLE2_DND target_drag_context *ctx; HRESULT hres;#endif g_return_if_fail (window != NULL); if (GPOINTER_TO_INT (gdk_drawable_get_data (window, "gdk-dnd-registered"))) return; gdk_drawable_set_data (window, "gdk-dnd-registered", GINT_TO_POINTER(TRUE), NULL); GDK_NOTE (DND, g_print ("gdk_window_register_dnd: %p\n", GDK_WINDOW_HWND (window))); /* We always claim to accept dropped files, but in fact we might not, * of course. This function is called in such a way that it cannot know * whether the window (widget) in question actually accepts files * (in gtk, data of type text/uri-list) or not. */ gdk_window_add_filter (window, gdk_dropfiles_filter, NULL); DragAcceptFiles (GDK_WINDOW_HWND (window), TRUE);#ifdef OLE2_DND /* Register for OLE2 d&d */ ctx = target_context_new (); ctx->context->protocol = GDK_DRAG_PROTO_OLE2; hres = CoLockObjectExternal ((IUnknown *) &ctx->idt, TRUE, FALSE); if (!SUCCEEDED (hres)) OTHER_API_FAILED ("CoLockObjectExternal"); else { hres = RegisterDragDrop (GDK_WINDOW_HWND (window), &ctx->idt); if (hres == DRAGDROP_E_ALREADYREGISTERED) { g_print ("DRAGDROP_E_ALREADYREGISTERED\n");#if 0 ctx->idt.lpVtbl->Release (&ctx->idt);#endif CoLockObjectExternal ((IUnknown *) &ctx->idt, FALSE, FALSE); } else if (!SUCCEEDED (hres)) OTHER_API_FAILED ("RegisterDragDrop"); else { gdk_window_add_filter (window, gdk_destroy_filter, &ctx->idt); } }#endif}/************************************************************* * gdk_drag_get_selection: * Returns the selection atom for the current source window * arguments: * * results: *************************************************************/GdkAtomgdk_drag_get_selection (GdkDragContext *context){ if (context->protocol == GDK_DRAG_PROTO_LOCAL) return _local_dnd; else if (context->protocol == GDK_DRAG_PROTO_WIN32_DROPFILES) return _gdk_win32_dropfiles; else if (context->protocol == GDK_DRAG_PROTO_OLE2) return _gdk_ole2_dnd; else return GDK_NONE;}gboolean gdk_drag_drop_succeeded (GdkDragContext *context){ GdkDragContextPrivateWin32 *private; g_return_val_if_fail (context != NULL, FALSE); private = GDK_DRAG_CONTEXT_PRIVATE_DATA (context); /* FIXME: Can we set drop_failed when the drop has failed? */ return !private->drop_failed;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -