是否可以将数据从 gtk 应用程序拖到 Windows 下的其他应用程序?喜欢文件资源管理器?
Is it possible to drag data from a gtk app to other application under Windows? Like File Explorer?
我目前正在尝试在 gtk+3 中制作一个用于管理文件的应用程序。我的目标是拥有一个专门用于我自己的工作流程的文件管理器,因为我发现 Windows 文件资源管理器太通用了。
GTK 当然支持拖放功能,这些是已经设置好并且可以工作的东西:
- 作为拖动源的文件列表视图,将所选文件编码到 "drag-get"
上的文件 uri 列表中
- 出于测试目的,在文件列表视图旁边放置同一应用程序中的目标。将拖动数据打印到 std::cout.
- 从文件列表视图中删除会在输出 window 中显示 file-uri,所以这没问题
- 从 Windows 文件资源管理器中删除也会在输出 windows 中显示 file-uri!好吧
但是正如标题所暗示的那样,从我的文件列表视图中拖放到 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 拖放。
我目前正在尝试在 gtk+3 中制作一个用于管理文件的应用程序。我的目标是拥有一个专门用于我自己的工作流程的文件管理器,因为我发现 Windows 文件资源管理器太通用了。
GTK 当然支持拖放功能,这些是已经设置好并且可以工作的东西:
- 作为拖动源的文件列表视图,将所选文件编码到 "drag-get" 上的文件 uri 列表中
- 出于测试目的,在文件列表视图旁边放置同一应用程序中的目标。将拖动数据打印到 std::cout.
- 从文件列表视图中删除会在输出 window 中显示 file-uri,所以这没问题
- 从 Windows 文件资源管理器中删除也会在输出 windows 中显示 file-uri!好吧
但是正如标题所暗示的那样,从我的文件列表视图中拖放到 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 拖放。