是否可以将数据从 gtk 应用程序拖到 Windows 下的其他应用程序?喜欢文件资源管理器?

Is it possible to drag data from a gtk app to other application under Windows? Like File Explorer?

我目前正在尝试在 gtk+3 中制作一个用于管理文件的应用程序。我的目标是拥有一个专门用于我自己的工作流程的文件管理器,因为我发现 Windows 文件资源管理器太通用了。

GTK 当然支持拖放功能,这些是已经设置好并且可以工作的东西:

但是正如标题所暗示的那样,从我的文件列表视图中拖放到 Windows 文件资源管理器或与此相关的任何其他应用程序都不起作用,鼠标光标一直显示 'blocked' 符号.

我也想支持Linux。所以我在 运行s KDE Plasma 的 Manjaro 虚拟机中尝试了这个。放入 Dolphin 文件管理器工作正常。

在 Windows 上,经过一番搜索,我认为这是一个安全问题。也许 Windows 不允许 'untrusted' 应用程序在其他应用程序之间拖放。但我制作了一个发布版本,使用受信任的 self-signed 证书对其进行签名,并将我的应用程序放在 C:\Program Files 中。从那里我 运行 它,但它仍然不起作用。

这是设置选择数据的代码

#define _BYTE   8

static void
drag_data_get_handl
(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data,
        guint target_type, guint time, gpointer user_data)
{
    const auto* unmarshalledUserdata = static_cast<DragAndDrop::GetDragData_Userdata*>(user_data);

        const gchar *name = gtk_widget_get_name (widget);
        const auto string_data = unmarshalledUserdata == nullptr ? "": unmarshalledUserdata->GetData();

        g_print ("%s: drag_data_get_handl\n", name);
        g_assert (selection_data != NULL);

        g_print (" Sending ");
        switch (target_type)
        {
                /* case TARGET_SOME_OBJECT:
                 * Serialize the object and send as a string of bytes.
                 * Pixbufs, (UTF-8) text, and URIs have their own convenience
                 * setter functions */

        case TARGET_STRING:
                g_print ("string: %s", string_data.c_str());
                gtk_selection_data_set
                (
                        selection_data,
                        gtk_selection_data_get_target(selection_data),
                        _BYTE,
                        (guchar*) string_data.c_str(), //for example file:///C:/Projects/tabspls_build_msvc/TabsPlsMain/TabsPlsMain.sln
                        static_cast<gint>(string_data.size())
                );
                break;

        default:
                /* Default to some a safe target instead of fail. */
                g_assert_not_reached ();
        }

        g_print (".\n");
}

不知道有没有这个必要,但是整个项目都可以找到on github。这链接到我目前正在撰写的修订版。

我自己一直在查看 gtk 源代码和文档,我想我找到了答案。

对于初学者来说,docs 声明未实现 OLE2 拖放协议。这需要在 Windows.

上的应用程序之间拖放

那么为什么我的 gtk 应用程序可以接收文件但不能在 Windows 下发送文件?文档声明支持 WM_DROPFILES 协议,我可以通过在我的 drop receive 回调的上下文中调用 gdk_drag_context_get_protocol 来确认选择了这个协议。

所以如果我想在我自己的应用程序中支持它,我将不得不使用 WM_DROPFILES 来发送数据(我认为这不能通过 gtk 库来完成)。或者我需要独立于 gtk 实现我自己的 OLE2 拖放。