窗口

56 阅读1分钟

Win 任务栏自定义图标

使用QWinThumbnailToolBar设置任务栏缩略图

//设置任务栏缩略图接口
QWinThumbnailToolBar::setIconicThumbnailPixmap
设置实时预览缩略图接口
QWinThumbnailToolBar::setIconicLivePreviewPixmap

自己对弹窗截图 然后设置到系统任务栏

//多屏幕拼接的一张截图 弹窗跨屏展示时仍能正常截图
QPixmap desktopScreenshot(QWidget *target)
{
    QList<QScreen*> screens = QGuiApplication::screens();
    QRect desktopRect;
    for (QScreen *screen : screens) {
        desktopRect = desktopRect.united(screen->geometry());
    }
    QPixmap desktopPixmap = QGuiApplication::primaryScreen()->grabWindow(0, desktopRect.x(), desktopRect.y(), desktopRect.width(), desktopRect.height());
    return desktopPixmap;
    
}

也可以使用win api截图(Screen capture)

没有查到系统封装的任务栏hover消息类型 调试发现WM_GETICON消息 在hover任务栏时会触发 可以在此时更新缩略图

使用qt设置缩略图 虽然窗口是无标题 但是缩略图会给一个默认标题

inline void QWinThumbnailToolBarPrivate::updateIconicLivePreview(const MSG *message)
{
    if (!iconicLivePreview)
        return;
    RECT rect;
    GetClientRect(message->hwnd, &rect);
    const QSize maxSize(rect.right, rect.bottom);
    POINT offset = {0, 0};
    if (const HBITMAP bitmap = iconicLivePreview.bitmap(maxSize)) {
        const HRESULT hr = DwmSetIconicLivePreviewBitmap(message->hwnd, bitmap, &offset, dWM_SIT_DISPLAYFRAME);
        if (FAILED(hr))
            qWarning() << QWinThumbnailToolBarPrivate::msgComFailed("DwmSetIconicLivePreviewBitmap", hr);
    }
}

查阅源码知DwmSetIconicLivePreviewBitmap(dwmapi.h) qt里面使用了参数DWM_SIT_DISPLAYFRAME在提供的位图周围显示一个框架 解决办法:参数改为0

自定义实时预览缩略图在窗口最小化后展示尺寸异常 可以使用其他方法自己算一个尺寸给接口

inline void QWinThumbnailToolBarPrivate::updateIconicLivePreview(const MSG *message)
{
    if (!iconicLivePreview)
        return;

    QSize rectSize;
    WINDOWPLACEMENT wp;
    wp.length = sizeof(WINDOWPLACEMENT);
    if (!GetWindowPlacement(message->hwnd, &wp) || wp.showCmd == SW_SHOWMINIMIZED) {
        rectSize = iconicLivePreview.pixmap().size();
    } else {
        RECT rect;
        GetClientRect(message->hwnd, &rect);
        rectSize = {rect.right, rect.bottom};
    }

    const QSize maxSize(rectSize);
    POINT offset = {0, 0};
    if (const HBITMAP bitmap = iconicLivePreview.bitmap(maxSize)) {
        const HRESULT hr = DwmSetIconicLivePreviewBitmap(message->hwnd, bitmap, &offset, 0);
        if (FAILED(hr))
            qWarning() << QWinThumbnailToolBarPrivate::msgComFailed("DwmSetIconicLivePreviewBitmap", hr);
    }
}

Mac窗口应用系统效果

  NSView * view = (__bridge NSView *)reinterpret_cast<void *>(this->winId());
    NSWindow *nsWindow = view.window;
    [nsWindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];

效果 源代码 11.png 22.png