Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How do I create pixmap (or HBITMAP) from data in QDragEnterEvent::mimeData - dragging from Windows Explorer to my Qt App



  • When dragging a file from Windows Explorer (on Windows 7) I get a nice drag icon. As soon as I drag it over my Qt application, it disappears. I would like to use that icon by setting it in my class's override of QWidget::dragEnterEvent(QDragEnterEvent e)*.

    The data exists in the event's mimeData().
    @void MainWindow::dragEnterEvent(QDragEnterEvent * e)
    {
    const QString dibStr("application/x-qt-windows-mime;value="DragImageBits"");

    const QMimeData* md = e->mimeData();
    
    if (md->hasFormat(dibStr)) {
        QByteArray ba(md->data(dibStr));
    
        qDebug() << "Format:  " << dibStr;
        qDebug() << "Size: " << ba.size();
    
        QBitmap bmp = toPixmapFromShellImage(ba);
        // ...
    }
    

    }@

    returns this below
    Format: application/x-qt-windows-mime;value="DragImageBits"
    Size: 36896

    I've been able to extract the data to get the the size and other information based on information from "link1":http://stackoverflow.com/questions/3479020/what-do-various-clipboard-drag-and-drop-formats-mean/3489048#3489048 and "link2":http://stackoverflow.com/questions/8442085/receiving-an-image-dragged-from-web-page-to-wpf-window/8468171#8468171.
    @
    #define ReadInt(b, pos)
    b[pos] + (b[pos + 1] << 8) + (b[pos + 2] << 16) + (b[pos + 3] << 24)

    QBitmap MainWindow::toPixmapFromShellImage(const QByteArray &b)
    {
    // Size of the image
    int w = ReadInt(b, 0);
    int h = ReadInt(b, 4);
    qDebug() << "w, h: (" << w << ", " << h << ")";

    // Pos of cursor relative to top-left of drag-image
    int offX = ReadInt(b, 8);
    int offY = ReadInt(b, 12);
    qDebug() << "x, y:     (" << offX << ", " << offY << ")";
    
    int dataSize = ReadInt(b, 16); // Unused ?
    int crColorKey = ReadInt(b, 20); // Unused ?
    
    // Number of bytes corresponding to a line in the BMP
    int stride = w * 4;
    
    QBuffer buff;
    buff.setData(b);
    buff.open(QIODevice::ReadOnly);
    buff.seek(24); // Skip the first 24 bytes read above
    
    // This will contain the actual image data
    QBuffer hbm;
    hbm.open(QIODevice::WriteOnly);
    char* cbuf = new char[stride];
    // The image is supposedly inverted vertically - hence reading it like this
    for (int i = (h-1)*stride; i  >= 0; i -= stride) {
        buff.read(cbuf, stride);
        hbm.write(cbuf, stride);
    }
    delete [] cbuf;
    qDebug() << "Bytes in buffer: " << hbm.size();
    
    // Qt does NOT support this
    //return QBitmap::fromData(QSize(w,h), (uchar*)(hbm.data().data()), QImage::Format_ARGB32);
    return QBitmap();
    

    }@

    The debug windows shows
    w, h: ( 96 , 96 )
    x, y: ( 48 , 89 )
    Bytes in buffer: 36864

    I was wondering how to exactly create the bitmap in Qt from the bytes in the byte-arrayhbm in the code. I'm not a Win32 API guy so the rest of what I found on the web was not always comprehensible.

    Thanks

    B



  • Have you tried to see if the QMimeData::hasImage()?



  • Tried that. QMimeData::hasImage() returns false.

    Based on what I've read on the net Windows puts the drag icon in the mimeData associated with application/x-qt-windows-mime;value="DragImageBits".



  • Ever figure out the solution to this problem?



  • Unfortunately no. I was hoping someone in the Qt community would have an answer.


Log in to reply