{
protected:
private:
int myWidgetX; // <==
int myWidgetY; // <==
updateAlpha();
}
{
// Code for painting on a QPixmap rather than on screen
...
// If a move is needed with the resizing of the widget, no move there
// but update of the private integers, it will be synced in the native call
myWidgetX = newXPos; // <==
myWidgetY = newXPos; // <==
// Native call to handle semi-transparency on win32 (with the wonderful cheat for move&resize in one go)
updateAlpha()
}
{
// Let's suppose the widget should be moved but a repaint is not needed
// calling Qt move() but DON'T FORGET to update myWidgetX & myWidgetY to avoid OUT-OF-SYNC
// move(newXPos, newXPos); <= bad if you forget to update myWidgetX&Y
myWidgetX = newXPos; // <==
myWidgetY = newXPos; // <==
move(myWidgetX, myWidgetY); // real Qt move(), I don't need to do repaint there
}
void MyWidget::updateAlpha()
{
HBITMAP oldBitmap;
HBITMAP hBitmap;
SIZE size;
size.cx = widgetMask.width();
size.cy = widgetMask.height();
HDC screenDc = GetDC(NULL);
POINT pointSource;
pointSource.x = 0;
pointSource.y = 0;
POINT topPos;
topPos.x = myWidgetX; // <==
topPos.y = myWidgetY; // <==
HDC memDc = CreateCompatibleDC(screenDc);
BLENDFUNCTION blend;
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = alpha;
blend.AlphaFormat = AC_SRC_ALPHA;
hBitmap
= widgetMask.
toWinHBITMAP(QPixmap::PremultipliedAlpha);
oldBitmap = (HBITMAP)SelectObject(memDc, hBitmap);
UpdateLayeredWindow(winId(), screenDc, &topPos, &size, memDc, &pointSource, 0, &blend, ULW_ALPHA);
ReleaseDC( NULL, screenDc);
if (hBitmap!=NULL)
{
SelectObject(memDc, oldBitmap);
DeleteObject(hBitmap);
DeleteObject(hBitmap);
}
DeleteDC(memDc);
move(myWidgetX, myWidgetY); // <==
}
class MyWidget : public QWidget
{
protected:
void paintEvent(QPaintEvent *event);
void mouseMoveEvent(QMouseEvent *event);
private:
QPixmap widgetMask;
int myWidgetX; // <==
int myWidgetY; // <==
updateAlpha();
}
void MyWidget::paintEvent(QPaintEvent *event)
{
// Code for painting on a QPixmap rather than on screen
QPainter painter(&widgetMask);
...
// If a move is needed with the resizing of the widget, no move there
// but update of the private integers, it will be synced in the native call
myWidgetX = newXPos; // <==
myWidgetY = newXPos; // <==
// Native call to handle semi-transparency on win32 (with the wonderful cheat for move&resize in one go)
updateAlpha()
}
void mouseMoveEvent(QMouseEvent *event)
{
// Let's suppose the widget should be moved but a repaint is not needed
// calling Qt move() but DON'T FORGET to update myWidgetX & myWidgetY to avoid OUT-OF-SYNC
// move(newXPos, newXPos); <= bad if you forget to update myWidgetX&Y
myWidgetX = newXPos; // <==
myWidgetY = newXPos; // <==
move(myWidgetX, myWidgetY); // real Qt move(), I don't need to do repaint there
}
void MyWidget::updateAlpha()
{
HBITMAP oldBitmap;
HBITMAP hBitmap;
SIZE size;
size.cx = widgetMask.width();
size.cy = widgetMask.height();
HDC screenDc = GetDC(NULL);
POINT pointSource;
pointSource.x = 0;
pointSource.y = 0;
POINT topPos;
topPos.x = myWidgetX; // <==
topPos.y = myWidgetY; // <==
HDC memDc = CreateCompatibleDC(screenDc);
BLENDFUNCTION blend;
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = alpha;
blend.AlphaFormat = AC_SRC_ALPHA;
hBitmap = widgetMask.toWinHBITMAP(QPixmap::PremultipliedAlpha);
oldBitmap = (HBITMAP)SelectObject(memDc, hBitmap);
UpdateLayeredWindow(winId(), screenDc, &topPos, &size, memDc, &pointSource, 0, &blend, ULW_ALPHA);
ReleaseDC( NULL, screenDc);
if (hBitmap!=NULL)
{
SelectObject(memDc, oldBitmap);
DeleteObject(hBitmap);
DeleteObject(hBitmap);
}
DeleteDC(memDc);
move(myWidgetX, myWidgetY); // <==
}
To copy to clipboard, switch view to plain text mode
Bookmarks