Получение растрового изображения того, как будет выглядеть свернутое окно при нормализации - PullRequest
2 голосов
/ 25 февраля 2012

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

Я пробовал разные подходы, используя SendMessage с WM_PRINT и PrintWindow, но безуспешно.В следующем коде, использующем SendMessage, я знаю, что для создания растрового изображения используется правильный размер нормализованного окна.Я знаю, что обработка по умолчанию для WM_PRINT через DefWindowProc генерирует сообщение WM_PRINTCLIENT.hWnd - это дескриптор свернутого окна.

        HDC                 scrdc, memdc;
        HBITMAP             membit;
        WINDOWPLACEMENT     WP;
        EncoderParameters   encoderParameters;
        ULONG               quality;
        Status              status;
        RECT                Rect;

        WP.length  = sizeof (WP);
        WP.flags   = 0;
        WP.showCmd = 0;

        GetWindowPlacement (hWnd, &WP);
        int WPHeight = WP.rcNormalPosition.bottom - WP.rcNormalPosition.top;
        int WPWidth  = WP.rcNormalPosition.right  - WP.rcNormalPosition.left;

        scrdc = GetWindowDC (hWnd);                                 // source DC
        GetWindowRect(hWnd,&Rect);                                  //  source Rectangle
        int Height = Rect.bottom-Rect.top;                          //   source height
        int Width  = Rect.right-Rect.left;                          //    source width

        if (WP.showCmd == SW_SHOWMINIMIZED)
        {
            Height = WPHeight;
            Width  = WPWidth;
        }

        memdc = CreateCompatibleDC(scrdc);                          // destination DC
        membit = CreateCompatibleBitmap(scrdc, Width, Height);      //  destination bitmap
        HBITMAP hOldBitmap =(HBITMAP) SelectObject(memdc, membit);  //   add bitmap to DC

// copy screen to new BitMap

//      BitBlt(memdc, 0, 0, Width, Height, scrdc, 0, 0, SRCCOPY);   

//      PrintWindow (hWnd, memdc, 0);

        BitBlt 
        (
            memdc,
            0,
            0,
            GetDeviceCaps(memdc,HORZRES),
            GetDeviceCaps(memdc,VERTRES),
            NULL,
            NULL,
            NULL,
            WHITENESS
        );

        SendMessage (hWnd, WM_PRINT, unsigned int (memdc), PRF_CLIENT|PRF_NONCLIENT);

А вот код для обработчиков WM_PRINT, WM_PRINTCLIENT и WM_PAINT

    case WM_PRINT:
        return DefWindowProc (hWnd, message, wParam, lParam);

    case WM_PRINTCLIENT:
        Screen.WMPrint (hWnd, HDC (wParam), NULL);
        return true;
        return DefWindowProc (hWnd, message, wParam, lParam);

    case WM_PAINT:                          
        Screen.WMPaint (hWnd);
        break;

Я также знаю, что Screen.WMPrint пишетправильные вещи в HDC.

Так что, если кто-нибудь может дать мне несколько советов или предложить подход, я был бы очень признателен.Я мог бы использовать Screen.WMPaint, но тогда я получаю только клиентскую область и пропускаю панель команд и границы.

Я не хочу нормализовать окно, так как это раздражает пользователя.

Ответы [ 3 ]

0 голосов
/ 25 февраля 2012

В вашем обработчике WM_PAINT, предполагая, что вы используете двойную буферизацию, сделайте свой буфер буфера hdc глобальным, а затем, когда вы захотите сделать снимок вашей программы, просто добавьте этот HDC в битовый массив вне экрана, и вот он у вас.

Вот как должен выглядеть ваш обработчик WM_PAINT: http://pastebin.com/aNvtHiD6

0 голосов
/ 08 марта 2012

Это может быть просто возможно построить такую ​​битовую карту. Я думаю, что нужно было бы заглянуть на растровое изображение всего окна после каждой операции рисования, чтобы получить строку заголовка и границы. Затем можно стереть клиентскую область. Это даст отправную точку, в которой можно выполнять различные операции GDI. Дополнительным осложнением является то, что любые элементы управления, такие как полосы прокрутки, элементы управления датой, поля редактирования и т. Д., Должны быть индивидуально захвачены и добавлены в растровое изображение. Для своего приложения я решил, что не справлюсь с минимизированной ситуацией. У меня было достаточно проблем с получением элементов управления на новом растровом изображении. Проблема с элементами управления возникает из-за того, что нельзя просто сделать их дочерними по отношению к главному окну, потому что все, что у вас есть, это растровое изображение, само окно свернуто или элементы управления скрыты или находятся за экраном.

0 голосов
/ 25 февраля 2012

Это сложно, потому что, когда ваше окно свернуто, оно на самом деле не выглядит как само минимизированное.

WM_PRINT печатает не-клиентскую область вашего окна (поскольку вы передаете флаг), вызывая обычный обработчик WM_NCPAINT. И этот обработчик смотрит на состояние окна, поэтому, если оно свернуто, вы не получите то, что хотите. И затем он пытается напечатать клиентскую область, но (я подозреваю) и здесь минимизированное состояние приводит к тому, что эта часть пропускается - эффективное свернутое окно не имеет клиентской области.

Вызов вашей внутренней раскраски может быть самым простым решением. Да, это даст вам только клиентскую зону. Обратите внимание, что предварительные просмотры, которые вы видите на панели задач Windows 7 при наведении курсора на плитку для свернутого окна, также исключают не-клиентскую область. Я думаю, что это слишком сложно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...