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: 36896I'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: 36864I 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.