вторник, 20 июля 2010 г.

Почему я не могу получить пиксели окна, которое не видимо на экране?

Это перевод Why can't I get the pixels of a window that isn't visible on screen? Автор: Реймонд Чен.

Если окно не показано на экране, то эти пиксели просто не существуют.

Модель рисования в Windows следует принципу "Не сохраняй ничего, что ты можешь пересчитать". Посмотрите: у вас есть монитор 640x480 в 16-ти цветовой схеме. Это - 150 Кб видео памяти. Теперь возьмите четыре копии Блокнота и распахните окно каждой на полный экран. Если бы каждая из этих копий Блокнота требовала бы внеэкранной копии своего изображения, вы бы использовали 450 Кб памяти просто чтобы хранить эти биты. Если на вашей машине было всего 640 Кб, то у вас не оставалось много памяти для чего-то ещё.

Подумайте о том, что программам нужно показывать. В большинстве случаев программа так или иначе уже отслеживает информацию, которая показывается на экране - и, обычно, в намного более компактной форме. Блокнот, к примеру, имеет элемент управления edit, который хранит отображаемый текст. Видимый он или нет, но edit должен хранить где-то этот текст (не будет же Блокнот использовать распознавание текста по рисунку, чтобы сконвертировать текст и изображения окна обратно в буфер!). Любая программа, у которой есть scroll bar, нуждается в отслеживании информации, которая невидима на экране. Не будет так уж тяжело заставить её отслеживать и видимую информацию.

Если вы хотите получить пиксели окна, которое невидимо на экране, то вы можете попробовать отправить ему сообщение WM_PRINT, хотя это будет работать, только если окно поддерживает сообщение WM_PRINT (многие просто не заморачиваются с этим). Если вы используете Windows XP или выше, вы можете использовать функцию PrintWindow (прим.пер.: я так понял, что это простая обёртка к отправке WM_PRINT).

9 комментариев:

  1. Анонимный21 июля 2010 г., 11:05

    [q]PrintWindow (прим.пер.: я так понял, что это простая обёртка к отправке WM_PRINT).[/q]

    Разве? Через WM_PRINT можно видеть окно без WS_VISIBLE, а через PrintWindow - нет.

    kero

    ОтветитьУдалить
  2. Я не пробовал - ориентировался на описание функции, где сказано, что PrintWindow отправляет окну WM_PRINT или WM_PRINTCLIENT.

    ОтветитьУдалить
  3. Почитал комментарии к исходному посту. Последний коммент от... Allen Bauer! В котором говорится, что он не сумел использовать PrintWindow для частично закрытого окна. Правда, не сказано, помогла ли прямая отправка WM_PRINT (т.е. это или действительно есть разница или просто окно не поддерживает WM_PRINT).

    ОтветитьУдалить
  4. Анонимный21 июля 2010 г., 17:08

    [q]Последний коммент от... Allen Bauer! В котором говорится, что он не сумел использовать PrintWindow для частично закрытого окна.[/q]

    И что характерно - Раймонд Чен не отреагировал :)
    Гипотеза: неприятная для него тема, ибо PrintWindow реально недоделана.

    Allen заметил "partially clipped child window", которое у PrintWindow выходило черным. Но "частичная закрытость" окна тут как раз несущественна.
    Суть же в том, что PrintWindow не жалует наличие у дочернего окна битов CS_PARENTDC, CS_OWNDC и CS_CLASSDC, а top-level окно может за это и угробить.
    Когда-то даже постил по этому поводу: "Attention: PrintWindow" (http://www.asmcommunity.net/board/index.php?topic=22427.0 :).

    kero

    ОтветитьУдалить
  5. Реймонд Чен открыл Suggestion Box 4 - так что у вас есть шанс спросить его лично, и, может быть, он даже ответит, если сочтёт этот вопрос "issue of general interest".

    ОтветитьУдалить
  6. P.S. Чтобы не писать подпись можно вместо анонимной отправки использовать "Название/URL". Название - это ник. URL - любая ссылка на ваш выбор. Можно www.example.com в отсутствие лучших кандидатов :)

    ОтветитьУдалить
  7. Ага, про SugBox4 знаю и уже PrintWindow заказал (на стр.7) :) Но сильно сомневаюсь насчет ответа:
    1) SugBox3 Раймонд растянул на годы.
    2) А чем я лучше Allen Bauer ? :)

    P.S. Не подумываете о переводе "Practical Development Throughout the Evolution of Windows"?

    ОтветитьУдалить
  8. Эта книга вроде бы не более чем сборник постов с блога Реймонда Чена. Я тогда не понимаю, в чём конкретно будет заключаться её перевод. Разве я сейчас не это делаю?

    ОтветитьУдалить
  9. P.S. Suggestion box растягивают на годы всё же читатели блога, а не Реймонд. В частности там много тех, кто не может сложить два плюс два, и Реймонд, видимо, считает, что этот вопрос следует обжевать. Поэтому в блоге часто можно видеть похожие посты.

    К примеру, вот недавно была тема про кооперативную многозаданость в Win16 vs вытесняющая многозадачность в Win32. Этот топик уже освещался, но в контексте другого вопроса.

    Ещё пример. Вот я читаю SB4: вижу вопрос, почему управление фокусом в Windows - такой отстой. Ты что-то печатаешь и тут всплывает окно, которое забирает у тебя фокус (я уверен, что если бы автор писал это где-то ещё он бы добавил Windows sucks, Bill Gates must die, etc).

    Тема с фокусом и злоупотреблениями им не раз освещалась Реймондом (я не помню, успел ли я перевести эти заметки, или меня это ожидает). Хотя конкретно такого вопроса вроде бы не было. Если включить голову, то несложно сделать вывод, что такое поведение - результат злоупотребления программ. Windows вообще-то пытается помешать этому, но ведь мы все знаем, как людям не нравится, когда вы их ограничиваете и они пытаются всеми силами это обойти.

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.