KáGé
KáGé

Reputation: 823

Visual C++ problems with drag drop

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.

Upvotes: 0

Views: 1961

Answers (1)

Hans Passant
Hans Passant

Reputation: 942099

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.

Upvotes: 2

Related Questions