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
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.