Visual C++拖放问题

发布于 2024-10-07 06:15:48 字数 2511 浏览 1 评论 0原文

我正在制作一个“高科技”电话簿程序,如果我成功,用户将能够将一个号码、一个人或一个位置拖放到另一个人的个人资料页面,将它们链接在一起。

元素(如数字或人)由派生自 System::Windows::Forms::UserControl 的类表示(因此它本质上是一个带有标签的面板,有关所表示元素的数据存储在其成员变量中)。该面板被拖到一个窗口中,该窗口将其传递给另一个窗口的构造函数,从而在元素之间建立链接。如果单击此元素,它将在窗口中显示其个人资料页面。

提供拖放的元素的代码:

/* PhonebookElement.h */
private:
    System::Void PhonebookElement_Click(System::Object^  sender,
            System::EventArgs^  e) {
        doClick();
    }

    System::Void nameLabel_MouseDown(System::Object^  sender,
            System::Windows::Forms::MouseEventArgs^  e) {
        DragDropEffects dde = DoDragDrop(this, DragDropEffects::Copy);
        if(dde == DragDropEffects::None)
            doClick();
    }

接受拖放的配置文件页面窗口的代码:

/* PhonebookInfoWindow.h */
private:
    System::Void PhonebookInfoWindow_DragOver(System::Object^  sender,
            System::Windows::Forms::DragEventArgs^  e) {
        e->Effect = DragDropEffects::Copy;
    }

    System::Void PhonebookInfoWindow_DragDrop_1(System::Object^  sender,
            System::Windows::Forms::DragEventArgs^ e) {
        MakeRelationWindow^ mrw = gcnew MakeRelationWindow(this->m_hparent,
            (PhonebookElement^)e->Data->GetData(
                System::Windows::Forms::DataFormats::Serializable),this);
         mrw->Show();
    }

关系创建器窗口的构造函数:

/* MakeRelationWindow.h */
MakeRelationWindow(PhonebookElement^ first, PhonebookElement^ second, Object^ parent)
{
        InitializeComponent();
        //
        //TODO: Add the constructor code here
        //
        this->typeBox->MaxLength = LSTRINGLENGTH;

        this->first = first;
        this->second = second;
        this->parent = parent;

        this->descriptionBox->Text = "Linking together\r\n" +
            this->first->maindata + "\r\nand\r\n" + this->second->maindata;
}

我有两个问题:
1. 由于我已经为 PhonebookElement 实现了 MouseDown 操作,因此它无法识别点击。 (我尝试过 MouseClick 操作,但这也不起作用。)我已将 if(dde == DragDropEffects::None){doClick();} 部分放入 MouseDown操作作为一种解决方法,但它并不完美,因为如果用户将控件拖动到他不应该拖动的位置,它也会被视为单击。
2. 整个事情都不起作用:D
我不知道我做错了什么(可能是我使用了GetData()函数,我对DataFormats不太熟悉),但是MakeRelationsWindow的构造函数得到了一个“未定义的值” ”作为它的第二个参数。

我该如何纠正这两个问题?

PS我正在关注本教程: http://www.codeproject.com/KB/dotnet/ csdragndrop01.aspx
它适用于 C# 和拖放字符串,但仍然是我能找到的最好的。

I'm making a "hightech" phonebook program, where if I succeed, users will be able to drag and drop a number, or a person, or a location to another's profile page, linking them together.

Elements (like numbers or persons) are represented by a class derived from System::Windows::Forms::UserControl (so it's essentially a panel with labels on it and data about the represented element stored in its member variables). This panel gets dragged into a window, which passes it to the constructor of another window, which makes the link between the elements. If this element is clicked, it shows up its profile page in a window.

The code of the element, which provides the drag-drop:

/* PhonebookElement.h */
private:
    System::Void PhonebookElement_Click(System::Object^  sender,
            System::EventArgs^  e) {
        doClick();
    }

    System::Void nameLabel_MouseDown(System::Object^  sender,
            System::Windows::Forms::MouseEventArgs^  e) {
        DragDropEffects dde = DoDragDrop(this, DragDropEffects::Copy);
        if(dde == DragDropEffects::None)
            doClick();
    }

The code of the profile page window, which accepts the drag-drop:

/* PhonebookInfoWindow.h */
private:
    System::Void PhonebookInfoWindow_DragOver(System::Object^  sender,
            System::Windows::Forms::DragEventArgs^  e) {
        e->Effect = DragDropEffects::Copy;
    }

    System::Void PhonebookInfoWindow_DragDrop_1(System::Object^  sender,
            System::Windows::Forms::DragEventArgs^ e) {
        MakeRelationWindow^ mrw = gcnew MakeRelationWindow(this->m_hparent,
            (PhonebookElement^)e->Data->GetData(
                System::Windows::Forms::DataFormats::Serializable),this);
         mrw->Show();
    }

The constructor of the relation maker window:

/* MakeRelationWindow.h */
MakeRelationWindow(PhonebookElement^ first, PhonebookElement^ second, Object^ parent)
{
        InitializeComponent();
        //
        //TODO: Add the constructor code here
        //
        this->typeBox->MaxLength = LSTRINGLENGTH;

        this->first = first;
        this->second = second;
        this->parent = parent;

        this->descriptionBox->Text = "Linking together\r\n" +
            this->first->maindata + "\r\nand\r\n" + this->second->maindata;
}

I have two problems:
1. Since I have implemented the MouseDown action for the PhonebookElement, it doesn't recognise clicks. (I've tried the MouseClick action, but that didn't work either.) I've put the if(dde == DragDropEffects::None){doClick();} part into the MouseDown action as a workaround, but it's not perfect, because if the user drags the control somewhere s/he shouldn't, it will be treated as a click too.
2. The whole thing doesn't work :D
I don't know what am I doing wrong (probably it's my usage of the GetData() function, I'm not really familiar with DataFormats), but the constructor of the MakeRelationsWindow gets an "undefined value" as its second parameter.

How could I correct these two problems?

P.S. I was following this tutorial: http://www.codeproject.com/KB/dotnet/csdragndrop01.aspx
It's for C# and drag-dropping strings, but still the best I could find.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

楠木可依 2024-10-14 06:15:48

它不起作用,因为缺少 DragEnter 事件处理程序。您需要将 e->Effect 设置为 e->AllowedEffects 之一才能运行 DragDrop 事件。 DragOver 仅用于提供反馈。

在 MouseDown 上开始拖动确实会干扰 Click 事件,不会有鼠标向上事件来触发单击。如果您想同时支持两者,那么您需要使其更具选择性,并且仅在看到用户做出拖动动作时才开始拖动。这需要将鼠标位置存储在 MouseDown 事件中。使用 MouseMove 事件检查左键是否仍然按下。当您看到鼠标移动超过 SystemInformation::DoubleClickSize 时,调用 DoDragDrop()。

此外,您应该检查 DragEnter 事件处理程序是否正在拖动您知道如何处理的对象。比如说,您不想接受从资源管理器中拖动文件。

It doesn't work because the DragEnter event handler is missing. You need to set e->Effect to one of the e->AllowedEffects to get the DragDrop event to run. DragOver is only meant to provide feedback.

Starting a drag on MouseDown indeed interferes with the Click event, there won't be a mouse up event to trigger the click. If you want to support both then you need to make it more selective and only start the drag when you see the user making a dragging motion. That requires storing the mouse position in the MouseDown event. Use the MouseMove event to check if the left button is still down. And call DoDragDrop() when you see the mouse moved by more than SystemInformation::DoubleClickSize.

Furthermore, you should check in the DragEnter event handler that an object is being dragged that you know how to handle. You wouldn't want to, say, accept a drag a file from Explorer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文