我目前正在尝试在gtk + 3中制作一个用于管理文件的应用程序。目标是拥有一个专门针对自己的工作流程的文件管理器,因为我发现Windows File Explorer例如太通用。
GTK当然支持拖放功能,这些已经设置并可以正常工作:
但是正如标题所暗示的那样,从我的文件列表视图拖放到Windows File Explorer或任何其他应用程序都无法正常工作,鼠标光标始终显示“被阻止”符号。
我也想支持Linux。因此,我已经在运行KDE Plasma的Manjaro虚拟机中进行了尝试。然后放入Dolphin文件管理器就可以了。
在Windows上,经过一番搜索,我认为这是一个安全问题。也许Windows不允许“不受信任”的应用程序在其他应用程序之间拖放。但是我做了一个发布版本,用一个受信任的自签名证书对其进行了签名,然后将我的应用程序放在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下接收文件但不发送文件? docs声明支持WM_DROPFILES协议,我可以通过在我的drop receive回调的上下文中调用gdk_drag_context_get_protocol
来确认选择了该协议。
因此,如果我想在自己的应用程序中支持此功能,则必须使用WM_DROPFILES来发送数据(我认为这无法通过gtk库完成)。或者,我需要与gtk分开实现自己的OLE2拖放。