Использование IPreviewHandler для предварительного просмотра изображений

Я пытаюсь использовать DLL, которая может просматривать изображение на панели предварительного просмотра файла. Я основываюсь на:

https://github.com/microsoft/Windows-classic-samples/tree/main/Samples/Win7Samples/winui/shell/appshellintegration/RecipePreviewHandler

Чтобы свести к минимуму мой текущий подход, я жестко прописываю путь к изображению, загружаю его как HBITMAP и отправляю в окно панели черезSendMessage(). Такой подход вызывает следующие проблемы:

  • Я не могу изменить размер HBITMAP без его перезагрузки, это кажется крайне неэффективным.

  • Я не могу изменить путь к растровому изображению в зависимости от того, какой файл я нажимаю. В идеале я хотел бы извлечь имя файла и использовать его для определения пути к растровому изображению в другой папке с тем же именем.

Если кто-нибудь знает или может подсказать мне лучший подход, пожалуйста, дайте мне знать. В идеале мне бы хотелось, чтобы он действовал так же, как VLC обрабатывает панели предварительного просмотра с изображением предварительного просмотра видео рядом с логотипом программного обеспечения.

========================РЕДАКТИРОВАНИЕ====================== ====

Вот как я реализовал вышесказанное:

Начиная сloadPreview()который загружает растровое изображение.

          boolean CRecipePreviewHandler::loadPreview
        (
        void
        )
    //*Description
    // change the bitmap control part of this to show the preview
    // from the file associated with m_bitmapFile
    {
        boolean r = TRUE;
        // Find dimension of bitmap
        std::ifstream file;
        file.open(m_bitmapFile, std::ios::binary);
        if (file.fail())
        {
            // File does not exist
            file.close();
            return r;
        }
        BITMAPINFOHEADER bmiHeader;
        file.seekg(sizeof(BITMAPFILEHEADER));
        file.read((char*)&bmiHeader, sizeof(BITMAPINFOHEADER));
        file.close();
        UINT cx = bmiHeader.biWidth;
        UINT cy = bmiHeader.biHeight;
        if (cx == 0 || cy == 0)
        {
            return r;
        }
    
    // transfer picture to dialog control
        m_b = (HBITMAP)LoadImage(NULL, m_bitmapFile, IMAGE_BITMAP, cx, cy, LR_LOADFROMFILE);
        r = FALSE;
        return r;
    }

Гдеm_bэто типHBITMAP, иm_bitmapFileэто типLPCWSTRсодержащий путь к растровому изображению.

Это называетсяDoPreview(), переопределение изIPreviewHandlerкласс, который отправляет растровое изображение в дочернее окно панели предварительного просмотра.

      HRESULT CRecipePreviewHandler::DoPreview()
{
    HRESULT hr = E_FAIL;
    if (_hwndPreview == NULL && _pStream) // cannot call more than once (Unload should be called before another DoPreview)
    {
        int border = 0;
        // Create the preview window
        _hwndPreview = CreateWindowExW(0, L"STATIC", NULL,
                                       SS_BITMAP | SS_CENTERIMAGE | SS_REALSIZECONTROL | WS_CHILDWINDOW,   // Always create read-only
                                       _rcParent.left+border, _rcParent.top+border, RECTWIDTH(_rcParent)+border, RECTHEIGHT(_rcParent)+border,
                                       _hwndParent, NULL, NULL, NULL);
        if (_hwndPreview == NULL)
        {
            hr = HRESULT_FROM_WIN32(GetLastError());
        }
        else
        {
            if (loadPreview())
            {
                hr = HRESULT_FROM_WIN32(GetLastError());
            }
            else
            {
                SendMessage(_hwndPreview, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)m_b);
                ShowWindow(_hwndPreview, SW_SHOW);
            }
        }
    }
    return hr;
}

Остальная часть кода довольно стандартна и включает инициализатор, деинициализатор и средство установки размера прямоугольника (в настоящее время я не меняю размер растрового изображения из-за его высокой стоимости).

0 ответов

Другие вопросы по тегам