2

我一直在尝试将 Windows 7 任务栏 API 合并到常规 MFC MDI(多文档界面)应用程序中。我正在使用 Visual Studio 2008,我已将 SDK 路径重定向到使用 Windows 7 SDK。

这个想法是为在应用程序内创建的每个子框架窗口提供自定义实时预览位图。虽然我已经取得了进步,但我正在经历一些挣扎,最终的点点滴滴似乎并不正确。只是想知道我是否遗漏了什么。

好的,

  1. 所以我们需要一个代理窗口,因为实时预览 API 只能在顶级窗口上工作(这令人失望)。此窗口处理 WM_DWMSENDICONICTHUMBNAIL 和 WM_DWMSENDICONICLIVEPREVIEWBITMAP,它们为 API 提供缩略图预览和实时预览所需的位图。

    case  WM_DWMSENDICONICTHUMBNAIL:
        // get the bitmap of the client window
        // set it as thumbnail 
            width = HIWORD(lParam);
            height = LOWORD(lParam);
            hBitmap = CreateBitmapFromHandleAndResize(hwnd, width, height);
            if (hBitmap)
            {
                SetThumbnail(hBitmap, hwnd);
                DeleteObject(hBitmap);
            }
        break;
    case WM_DWMSENDICONICLIVEPREVIEWBITMAP:
            hBitmap = CreateBitmapFromHandle(hwnd);
            if (hBitmap)
            {
                SetThumbnailForPreview(hBitmap, hwnd);
                DeleteObject(hBitmap);
            }
            break;
    
  2. 函数 CreateBitmapFromHandleAndResize 和 CreateBitmapFromHandle 创建一个 DIB 又名设备独立位图,它是 API DwmSetIconicThumbnail 和 DwmSetIconicLivePreviewBitmap 的食物。

面临的问题:我面临的问题是在以下代码工作的实时预览位图区域中。hBitmap 是一个 32 位深度的 DIB,当它保存在磁盘上时,它似乎是我想要显示的子窗口的正确屏幕截图。但是当我预览它时,不知何故,标题栏和位图似乎与窗口本身的质量不同。事实上,它看起来像是子窗口的失焦表示。我希望显示相同质量的图像,因为用户不应该感觉到差异。

目前,我打印包括框架在内的整个窗口,并将实时预览准确定位在现有窗口的顶部,这样当实时预览打开时,用户会被欺骗看到位图而不是实际的子窗口。

我希望这是实时预览的预期行为。如果我在这里错了,请告诉我。

另一个问题是偏移量。不确定我是否在这里做错了什么。但是当我只是对两个矩形进行比较时,它根本不起作用。8 和 14 的修正系数是通过试错法完成的!

    void SetThumbnailForPreview(HBITMAP hBitmap, HWND hWnd)
    {
     StateInfo *pState = (StateInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA);

         CWnd* pMainFrame = pState->m_pParentWnd->GetParent();

         pState->pTaskBar->SetTabActive(hWnd, pMainFrame->GetSafeHwnd(), 0);

         RECT rectClient, rectMainframe;
         pState->m_pParentWnd->GetClientRect(&rectClient);
         pState->m_pParentWnd->ClientToScreen(&rectClient);

         pMainFrame->GetWindowRect(&rectMainframe);

         POINT offset;
         offset.x = (rectClient.left - rectMainframe.left) - 8;
         offset.y = (rectClient.top - rectMainframe.top) + 14;

         HRESULT hr = DwmSetIconicLivePreviewBitmap(hWnd, hBitmap, &offset, 0);
       }

简而言之,我的问题:

  1. 无论如何要让位图以与窗口本身相同的质量显示,这样就不会感觉到差异。

  2. 偏移量计算是否正确。为什么它不适用于直接的 RECT 差异?

  3. 关于 MDI 应用程序中实时预览的行为,我的理解是否正确

    在缩略图预览区: MDI 主窗口始终与其他缩略图一起显示。
    缩略图是子窗口的单独表示。

    在实时预览区域: 如果您将鼠标悬停在单个缩略图上,实时预览将始终显示 MDI 主
    框架以及子窗口。这里的不同之处在于用户可以看到
    特定的子窗口(悬停所在的那个)获得焦点和突出显示。

  4. 我在这里做的是正确的事情,还是有一些我不知道的其他事情?

提前致谢!兰吉特

4

0 回答 0