Определение размера окна, видимой области и начальной позиции.


Определение размера окна, видимой области и начальной позиции.

Размер и позиция окна

Размер и позиция окна выражены как ограниченный прямоугольник, данный в координатах относительно экрана или родительского окна. Координаты окна верхнего уровня отсчитываются относительно верхнего левого угла экрана; координаты дочернего окна отсчитываются относительно верхнего левого угла родительского окна. Прикладная программа определяет начальный размер окна и позицию, когда она создает окно, но она может изменять размер и расположение окна в любое время. Для получения дополнительной информации об ограниченных прямоугольниках, см. Закраска фигур .

Javascript размер окна, определение размеров видимой части страницы

Чтобы определить с помощью javascript размер окна видимой части страницы, можно использовать несколько различных методов. Но для того, чтобы JavaScript — код работал в различных браузерах, придется эти методы комбинировать:

Определяем высоту видимой части страницы:

function windowHeight () <
var wh = document.documentElement;
return self.innerHeight | | (wh && wh.clientHeight) | | document.body.clientHeight;

Определяем в j avascript размер окна ширины видимой части страницы:

function windowWidth () <
var ww = document.documentElement;
return self.innerWidth | | (ww && ww.clientWidth) | | document.body.clientWidth;
>

На этом все. Теперь Вы знаете как определить размер видимой части страницы.

Методы управления размером и положением окна

Эти методы изменяют положение и размеры окна. Положение левого верхнего угла окна задантся координатами x,y, а размеры шириной nWidth и высотой nHeight. Параметр bRepaint определяет, будет ли инициироваться перерисовка. Если он равен TRUE, окну будет послано сообщение WM_PAINT, в противном случае сообщение не посылается, и перерисовка не производится. Эти действия применяются как к клиентской, так и неклиентской области окна, а также к частям родительского окна, открывшимся при перемещении.

Новое положение и размеры окна можно задать и с помощью структуры типа RECT или объекта класса CRect, передав в качестве параметра ссылку на структуру или объект класса.

Для окна, у которого нет родителя, координаты указываются относительно левого верхнего угла экрана, а для имеющего такового — относительно верхнего левого угла родительского окна.

BOOL SetWindowPos(const CWnd* pWndInsertAfter, int x, int y, int cx, int cy, UINT nFgags);

Изменяет положение, размеры и место окна в Z-упорядочении (порядке изображения окон в слоях изображения). Параметры x, y, cx, cy задают новое положение левой стороны, новое положение верхней стороны, новую длину и новую высоту соответственно.

Параметр pWndInsertAfter определяет окно, за которым нужно поместить исходное окно в Z-упорядочении. Этот параметр может быть либо указателем на объект класса CWnd, либо одним из следующих значений:

  • wndBottom поместить окно в конец Z-упорядочения, т.е. позади всех окон на экране;
  • wndTop поместить окно в начало Z-упорядочения, т.е. впереди всех окон на экране;
  • wndTopMost поместить окно на ближайшее место, делающее окно неперекрытым. Окно перемещается на неперекрытое место, даже если оно неактивно;
  • wndNoTopMost поместить окно на ближайшее место позади всех неперекрытых окон. Окно, перекрытое в момент вызова этого метода, не перемещается.

Параметр nFlags задает режим изменения размера и положения окна и может быть следующей комбинацией флагов:

  • SWP_DRAWFRAME изображать вокруг окна рамку (определенную при его создании);
  • SWP_HIDEWINDOW скрыть окно;
  • SWP_NOACTIVE не делать окно активным. Если этот флаг не установлен, окно делается активным и помещается впереди, либо на место в Z-упорядочении, определяемое параметром pWndInsertAfter;
  • SWP_NOMOVE сохранить текущее положение окна, проигнорировав параметры x и y;
  • SWP_NOREDRAW не перерисовывать измененное окно. Если этот флаг установлен, то после выполнения функции окно с новыми установками на экране не появится, а старое изображение окна не будет стерто с родительского окна;
  • SWP_NOSIZE сохранить текущий размер окна, проигнорировав параметры cx и cy;
  • SWP_NOZORDER сохранить текущее Z-упорядочение, проигнорировав параметр pWndInsertAfter;
  • SWP_SHOWWINDOW показать окно (сделать окно видимым и перерисовать).

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

void GetWindowRect(LPRECT lpRect) const;

Копирует параметры прямоугольника, ограничивающего окно, в структуру типа RECT или объект класса CRect, заданные параметром lpRect. Этот прямоугольник включает все — и клиентскую и системную часть окна. Параметры даются относительно левого верхнего угла экрана. При вызове метода значением фактического параметра может быть либо ссылка на (не константную) структуру типа RECT либо объект класса CRect.

void GetClientRect(LPRECT lpRect) const);

Копирует параметры прямоугольника, ограничивающего клиентскую часть окна, в структуру типа RECT или объект класса CRect, определенные параметром lpRect. Параметры даются относительно левого верхнего угла клиентской области окна, поэтому левая и верхняя составляющие будут равны нулю, а правая и нижняя — ширине и длине клиентской области. При вызове метода параметр lpRect может быть либо указателем на структуру типа RECT, либо переменной класса CRect.

Не нашли то, что искали? Воспользуйтесь поиском:

Лучшие изречения: Увлечёшься девушкой-вырастут хвосты, займёшься учебой-вырастут рога 9790 — | 7665 — или читать все.

Управление размерами и положением окна

Пользователь может менять размеры окна, представленного на экране, перемещать его на другое место, создавать на экране несколько окон. Каждое окно работает независимо. Размеры и положение окна можно изменить мышью, с клавиатуры, командами оконного меню.

Для изменения размеров стандартного окна указатель мыши устанавливают на линии его границы. Он приобретает вид двух соединенных между собой стрелок, направленных в противоположные стороны: вверх-вниз – при перемещении верхней или нижней границы окна и вправо-влево при перемещении правой или левой границы. Рамку перетаскивают в требуемую сторону, удерживая нажатой левую кнопку мыши. Новый размер окна фиксируется после освобождения кнопки мыши.

Размер окна изменяется одновременно по высоте и ширине при перетаскивании любого из его углов с помощью мыши. В этом случае указатель принимает вид двунаправленной стрелки, расположенной под углом к границам окна.

Для изменения положения окна на экране указатель устанавливают на строке заголовка и, удерживая нажатой левую кнопку мыши, перемещают окно в требуемое положение.

Если пользователь открыл одновременно несколько окон, то эти окна могут располагаться на экране рядом друг с другом, на некотором расстоянии, частично (рис. 4.11) или полностью перекрывая друг друга.

Окно, с которым работает пользователь в данный момент, называется активным. Активное окно располагается на переднем плане поверх остальных окон. Его заголовок отличается цветом или текстурой, например, он может быть написан белыми буквами на синем фоне.

Рис. 4.11. Отображение на экране нескольких частично перекрывающих друг друга окон

Любая команда, выбранная пользователем, относится к активному окну, которое работает в приоритетном режиме.

При работе с несколькими окнами одновременно возникает необходимость в переходе от одного окна к другому. Наиболее простой способ перейти в другое окно – щелкнуть любую видимую его часть. Если на экране одновременно видны не все окна, то переход к другому окну можно выполнить несколькими способами:

1) щелкнуть мышью на панели задач кнопку с названием нужного окна;

2) одновременно нажать на клавиши Alt+Tab – в середине экрана высветится окно со значками запущенных программ, открытых папок и документов. Одна из программ будет обведена рамкой, а строчкой ниже будет приведено название выбранного документа и программы. Можно, не отпуская клавишу Alt, повторно нажать на клавишу Tab – рамка переместится к другому значку. Продолжая нажимать клавишу Tab, можно “по кругу” просмотреть все работающие программы. После выбора нужного значка следует отпустить обе клавиши;

3) нажать на комбинацию клавиш Alt+Esc. Активным станет другое открытое окно. При использовании этой комбинации клавиш не меняется форма представления окна, поэтому, если окно свернуто, то оно не будет отображено на экране;

4) нажать клавиши Ctrl+F6 для перехода к другому открытому документу этой же программы, если программа может работать одновременно с несколькими документами.

Расположение нескольких открытых окон можно упорядочить на экране с помощью контекстного меню, которое отображается на экране после щелчка правой кнопкой мыши пустого места панели задач


Это меню содержит следующие команды.

Окна каскадом – располагает открытые окна каскадом (уступом) одно над другим с перекрытием (рис. 4.12). При таком расположении видны все заголовки и отдельные участки большого количества окон. Целиком видно только первое окно. Для перемещения окна на передний план щелкните любой его видимый участок. Окно станет активным.

Окна сверху вниз располагает открытые окна подряд, без перекрытия в один или несколько рядов.

Окна слева направо располагает открытые окна в один горизонтальный ряд без промежутка или перекрытия.

Следует учитывать, что командами меню можно упорядочить только те окна, которые не свернуты. Свернутые или закрытые окна на экране не отображаются.

Рис. 4.12. Расположение окон по команде Каскадом

Завершить работу с программой (закрыть окно) можно следующими способами.

1. Нажать кнопку закрытия окна в верхнем правом углу окна.

2. В меню Файл выбрать команду Выход.

3. Дважды щелкнуть мышью кнопку оконного меню.

4. Выбрать команду Закрыть в оконном меню.

5. Щелкнуть правой кнопкой мыши кнопку окна на панели задач. В контекстном меню выбрать команду Закрыть.

6. Нажать клавиши Alt+F4.

Работающая программа, открытый документ занимают часть оперативной памяти. Поэтому для экономии ресурсов компьютера и увеличения свободной площади экрана закройте окна, с которыми вы не собираетесь работать.

Как получить размеры и положение всего окна?

03.11.2014, 12:06

Как в C++ задать размеры консольного окна, используя пространство имен System
Здрасти, вашему вниманию предлагается кусочек кода на C# Console.WindowTop = 0;.

Как получить положение курсора в текстовой строке?
Можно ли получить положение курсора в текстовой строке окна Edit Box и можно ли установить курсор в.

Как получить размеры экрана за вычетом панелей?
Как получить размеры экрана за вычетом панелей?

Два, рядом стоящие эллипса, изменяют размеры, цвета заливки, положение одного относительно другого
Нужна помощь с написанием кода: Два, рядом стоящие эллипса, изменяют размеры, цвета заливки.

Как установить размеры и положение нового окна?
Новое окно создается вот таким кодом:

03.11.2014, 13:43 2 03.11.2014, 13:46 [ТС] 3 03.11.2014, 13:50 4

Без тебя на форуме скучно..

03.11.2014, 13:50
03.11.2014, 14:35 [ТС] 5
03.11.2014, 15:14 6

Quite — это тихий, Quit — это выход.

Добавлено через 21 секунду
Лично я не понял где там -8 .
Не совсем по теме:
Зачем каждый раз вызывать DefWindowProc?
Зачем каждый раз сохранять размер и позицию?
Куда записывается позиция, как читается и как устанавливается?

Quite — это тихий, Quit — это выход.

03.11.2014, 15:41 [ТС] 7

После выполнения 5-й и 10-й строк.

Добавлено через 23 секунды

Добавлено через 18 секунд

Добавлено через 41 секунду

03.11.2014, 15:51 8
03.11.2014, 16:09 [ТС] 9
03.11.2014, 16:25 10

Теперь хоть что-то понятно. Рамка ушла за приделы экрана, поэтому координаты отрицательные.

Когда ты жмёшь на кнопку «Развернуть», окно получает сообщение WM_SIZE с кодом SIZE_MAXIMIZED в wParam. Если окно «развёрнуто» то информацию об этом тоже нужно сохранить в файл конфигурации, чтобы потом его можно было развернуть с помощью функции ShowWindow( hWnd, SW_MAXIMIZE );

Добавлено через 15 секунд

Теперь хоть что-то понятно. Рамка ушла за приделы экрана, поэтому координаты отрицательные.

Когда ты жмёшь на кнопку «Развернуть», окно получает сообщение WM_SIZE с кодом SIZE_MAXIMIZED в wParam. Если окно «развёрнуто» то информацию об этом тоже нужно сохранить в файл конфигурации, чтобы потом его можно было развернуть с помощью функции ShowWindow( hWnd, SW_MAXIMIZE );


03.11.2014, 16:26 [ТС] 11
03.11.2014, 16:30 [ТС] 12
03.11.2014, 16:33 [ТС] 13
03.11.2014, 16:36 14
03.11.2014, 16:47 [ТС] 15

Добавлено через 1 минуту

03.11.2014, 16:52 16
03.11.2014, 16:55 17
03.11.2014, 17:00 [ТС] 18

А где я по-вашему прочитал минус восемь?

Добавлено через 1 минуту

03.11.2014, 17:26 19
03.11.2014, 17:30 20

Я бы, наверно, выбрал сохранять еще флаг окна(развернуто, свернуто) и показывать с ним. А может сделал бы по другому, тут что вам нужно, способ тысяча. Влом вникать дальше. Можете проверять wParam; // resizing flag
и делать расчеты, как вам кажется правильно или брать ширину клиентскую, или взять ширину монитора. Сами придумайте способ.

Добавлено через 16 секунд
Я бы, наверно, выбрал сохранять еще флаг окна(развернуто, свернуто) и показывать с ним. А может сделал бы по другому, тут что вам нужно, способ тысяча. Влом вникать дальше. Можете проверять wParam; // resizing flag
и делать расчеты, как вам кажется правильно или брать ширину клиентскую, или взять ширину монитора. Сами придумайте способ.

03.11.2014, 17:30
03.11.2014, 17:30

Как получить размеры клиентской области окна-родителя в функции дочернего окна?
задание такое: имеется дочернее окно,которое «убегает» от курсора мыши в пределах родительского.

Как в апплете получить размеры окна броузера?
Как в апплете получить размеры окна броузера и отловить событие изменения размеров окна эксплорера.

Как помимо сообщения WM_SIZE получить размеры клиентской области окна?
Как помимо сообщения WM_SIZE получить размеры клиенсткой области окна?

4. Метрики Windows

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

В приложении WSTYLE мы указывали абсолютные значения координат и размеров создаваемых окон. Однако Windows может работать в режимах с различным разрешением видеоадаптера. Если вы подберете все размеры для разрешения 640 х 480 точек, в режиме 1200 х 1024 все ваше изображение окажется в верхнем левом углу экрана и вам придется напрягать зрение для того, чтобы что-нибудь рассмотреть. Было бы логичнее определять размеры и расположение создаваемых окон исходя из общего размера экрана, определяя последние динамически при работе приложения.

Метрики системных компонент Windows можно определить при помощи функции GetSystemMetrics, имеющей следующий прототип:

Единственный параметр функции (nIndex) выбирает параметр, значение которого необходимо определить. Значение параметра возвращается функцией GetSystemMetrics.

Для определения компоненты Windows в файле windows.h имеются символические константы с префиксом SM_:

Имя константы Описание
SM_CXBORDER Ширина рамки для окна, размеры которого нельзя изменять
SM_CXCURSOR Ширина курсора
SM_CXDLGFRAME Ширина рамки окна, имеющего стиль WS_DLGFRAME
SM_CXDOUBLECLK Ширина прямоугольника, внутри которого должны быть сделаны два щелчка мышью, для того чтобы они могли распознаваться как один двойной щелчок (double click). Эта константа определена только для Windows версии 3.1
SM_CXFRAME Ширина рамки для окна, размеры которого можно изменять
SM_CXFULLSCREEN Ширина внутренней поверхности окна, увеличенного до предела (maximised)
SM_CXHSCROLL Ширина битового образа стрелки горизонтальной полосы просмотра
SM_CXHTHUMB Ширина ползунка горизонтальной полосы просмотра
SM_CXICON Ширина пиктограммы
SM_CXICONSPACING Ширина прямоугольника, используемого для расположения пиктограммы с заголовком. Эта константа определена только для Windows версии 3.1
SM_CXMIN Минимальная ширина окна
SM_CXMINTRACK Минимальная ширина окна, которая может быть установлена при помощи мыши (Minimum tracking width of a window)
SM_CXSCREEN Ширина экрана
SM_CXSIZE Ширина полосы битового образа (bitmap) заголовка окна (title bar)
SM_CXVSCROLL Ширина битового образа стрелки вертикальной полосы просмотра
SM_CYBORDER Высота рамки для окна, размеры которого нельзя изменять
SM_CYCAPTION Высота заголовка окна
SM_CYCURSOR Высота курсора
SM_CYDLGFRAME Высота рамки окна, имеющего стиль WS_DLGFRAME
SM_CYDOUBLECLK Высота прямоугольника, внутри которого должны быть сделаны два щелчка мышью, для того чтобы они могли распознаваться как один двойной щелчок (double click). Эта константа определена только для Windows версии 3.1
SM_CYFRAME Высота рамки для окна, размеры которого можно изменять
SM_CYFULLSCREEN Высота внутренней поверхности окна, увеличенного до предела (maximised)
SM_CYHSCROLL Высота битового образа стрелки горизонтальной полосы просмотра
SM_CYICON Высота пиктограммы
SM_CYICONSPACING Высота прямоугольника, используемого для расположения пиктограммы с заголовком. Эта константа определена только для Windows версии 3.1
SM_CYKANJIWINDOW Высота окна Kanji
SM_CYMENU Высота одной строки в полосе меню
SM_CYMIN Минимальная высота окна
SM_CYMINTRACK Минимальная высота окна, которая может быть установлена при помощи мыши (Minimum tracking width of a window)
SM_CYSCREEN Высота экрана
SM_CYSIZE Высота полосы битового образа заголовка окна
SM_CYVSCROLL Высота битового образа стрелки вертикальной полосы просмотра
SM_CYVTHUMB Высота ползунка горизонтальной полосы просмотра
SM_DBCSENABLED Флаг использования символов, состоящих из двух байт (используется в тех языках, где для представления всех символов не хватает 8-разрядной сетки). Эта константа определена только для Windows версии 3.1
SM_DEBUG Флаг отладочной версии Windows. Он не равен нулю, если работает отладочная версия Windows (поставляется вместе с Microsoft SDK или Microsoft Visual C++)
SM_MENUDROPALIGNMENT Флаг типа выравнивания временного меню (pop-up menu). Если флаг равен нулю, левая сторона меню выравнена по левой стороне соответствующего элемента строки меню. В противном случае левая сторона меню выравнена по правой стороне соответствующего элемента строки меню. Эта константа определена только для Windows версии 3.1
SM_MOUSEPRESENT Флаг не равен нулю, если компьютер оборудован мышью
SM_PENWINDOWS Идентификатор библиотеки динамической загрузки DLL Pen Windows или 0, если Pen Windows не используется. Эта константа определена только для Windows версии 3.1
SM_RESERVED1 Зарезервировано
SM_RESERVED2 Зарезервировано
SM_RESERVED3 Зарезервировано
SM_RESERVED4 Зарезервировано
SM_SWAPBUTTON Если флаг не равен нулю, действия левой и правой клавиши мыши поменялись местами, то есть вместо левой клавиши используется правая и наоборот, вместо правой — левая

Наше следующее приложение представляет собой пример простейшей программы для Windows, не создающей главного окна, не обрабатывающей сообщения, но тем не менее выполняющей некоторую полезную работу.

Задача приложения SMETRICS заключается в вызове функции GetSystemMetrics для всех возможных параметров, перечисленных в предыдущем разделе. Исходный текст приложения представлен в листинге 4.1.

Листинг 4.1. Файл smetricssmetrics.cpp

В приложении SMETRICS определен массив структур SMTable, в котором для каждой константы хранится ее символическое имя в виде текстовой строки.

Алгоритм работы понятен без дополнительных объяснений. Заметим только, что мы впервые в приложении Windows использовали функции для работы с файлами. Возможно, мы вас немного порадуем, сообщив, что для работы с файлами вы по- прежнему можете использовать хорошо знакомые вам из MS-DOS функции потокового ввода/вывода. Действительно, функции потокового ввода/вывода будут работать в приложениях Windows. Однако лучше использовать специальные функции файлового ввода/вывода, которые мы рассмотрим позже, в одном из следующих томов «Библиотеки системного программиста».

Вы также можете пользоваться известной вам функцией sprintf (но не printf!). Эту функцию мы использовали для формирования текстовой строки.

Исходный текст файла определения модуля представлен в листинге 4.2.

Листинг 4.2. Файл smetricssmetrics.def

В листинге 4.3 приведен образец выходного файла, полученного при работе приложения при разрешении 640 х 480 точек.

Листинг 4.3. Образец файла sysmet.txt

Общие размеры экрана определяются метриками SM_CXSCREEN и SM_CYSCREEN. В приведенном выше листинге эти значения соответствуют разрешению 640 х 480. Максимальный размер внутренней области окна можно определить из метрик SM_CXFULLSCREEN и SM_CYFULLSCREEN. В нашем случае максимальная ширина внутренней области окна равна максимальной ширине экрана (640), в то время как максимальная высота меньше на высоту заголовка окна. Высота заголовка определяется метрикой SM_CYCAPTION и в нашем случае равна 20.

При разрешении 1024 х 768 метрики SM_CXSCREEN, SM_CYSCREEN, SM_CXFULLSCREEN и SM_CYFULLSCREEN изменили свое значение:

Остальные метрики не изменились и соответствовали значениям для разрешения 640 х 480.

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

Обратите внимание на метрики SM_CXICON и SM_CYICON, определяющие размеры пиктограммы. Эти размеры потребуются вам при необходимости нарисовать в окне пиктограмму. Программный интерфейс Windows имеет специальную функцию DrawIcon, позволяющую нарисовать в окне приложения пиктограмму.

Метрика SM_MOUSEPRESENT позволяет приложению определить, есть ли в составе оборудования компьютера мышь. К сожалению, в Windows не предусмотрено никакого средства для определения количества клавиш, имеющихся на корпусе мыши.

В программном интерфейсе Windows имеется функция GetDeviceCaps, позволяющая по контексту определить возможности и параметры драйвера, обслуживающего устройство ввода/вывода.


Функция GetDeviceCaps имеет следующий прототип:

Первый параметр функции (hdc) задает контекст устройства, для которого необходимо получить информацию о его возможностях. Вы можете, например, указать значение, полученное от функции BeginPaint или GetDC.

Второй параметр (iCapability) определяет параметр устройства, значение которого необходимо получить.

Приведем список возможных значений для второго параметра функции GetDeviceCaps. Все эти значения определены как символьные константы в файле windows.h.

Имя константы Описание
ASPECTX Относительная ширина отдельного пиксела, который используется при рисовании линий
ASPECTXY Относительная длина диагонали отдельного пиксела, который используется при рисовании линий
ASPECTY Относительная высота отдельного пиксела, который используется при рисовании линий
BITSPIXEL Количество бит, используемых для представления цвета в одном пикселе
CLIPCAPS Возможности устройства по ограничению области вывода:
CP_NONE вывод не ограничивается;
CP_RECTANGLE вывод ограничивается прямоугольной областью;CP_REGION вывод ограничивается произвольной областью
COLORRES Цветовое разрешение устройства в битах на пиксел. Это значение можно использовать только для устройств, использующих цветовые палитры, что можно определить при помощи константы RASTERCAPS.
Данную константу можно использовать только для драйверов версии 3.0 и более поздних версий
CURVECAPS Способность устройства рисовать различные кривые линии и геометрические фигуры. Возвращаемое значение представляет собой набор битовых масок, установленных в 1, если устройство может само рисовать различные фигуры:
CC_CIRCLES окружности;
CC_CHORD сегмент эллипса;
CC_ELLIPSES эллипсы;
CC_INTERIORS устройство может закрашивать внутреннюю область геометрических фигур;
CC_NONE устройство не может рисовать кривые линии и геометрические фигуры;
CC_PIE секторы эллипса;
CC_ROUNDRECT прямоугольники со скругленными углами;
CC_STYLED устройство может рисовать рамки с использованием различных стилей (штриховые, пунктирные, штрих-пунктирные и т.д.);
CC_WIDE широкие рамки;
CC_WIDESTYLED устройство может рисовать широкие рамки с использованием различных стилей (штриховые, пунктирные, штрих-пунктирные и т. д.)
DRIVERVERSION Номер версии драйвера устройства. Значение 0x300 соответствует версии 3.0, значение 0x30a — версии 3.1
HORZRES Ширина экрана в пикселах. Для принтеров — ширина рабочей области, в пределах которой может выполняться печать
HORZSIZE Стандартная для данного разрешения ширина дисплея в миллиметрах
LINECAPS Способности устройства рисовать линии. Возвращаемое значение представляет собой набор битовых масок, установленных в 1, если устройство может само рисовать линии различного типа:
LC_INTERIORS устройство может закрашивать внутреннюю область;
LC_MARKER маркеры;
LC_NONE устройство не может рисовать линии;
LC_POLYLINE ломаные линии;
LC_POLYMARKER линии polymarker;
LC_STYLED устройство может рисовать линии с использованием различных стилей (штриховые, пунктирные, штрих пунктирные и т.д.);
LC_WIDE широкие линии;
LC_WIDESTILED устройство может рисовать широкие линии с использованием различных стилей (штриховые, пунктирные, штрих-пунктирные и т. д.)
LOGPIXELSX Количество пикселов на один логический дюйм по горизонтали
LOGPIXELSY Количество пикселов на один логический дюйм по вертикали
NUMBRUSHES Количество кистей, поддерживаемых устройством
NUMCOLORS Количество цветов, зарезервированных Windows для использования в цветовых палитрах устройства, то есть количество чистых цветов, которые может использовать устройство. Для драйверов монохромных устройств возвращается значение 2. Для плоттеров это значение соответствует количеству цветных перьев
NUMFONTS Количество шрифтов, поддерживаемых устройством
NUMMARKERS Количество маркеров, поддерживаемых устройством
NUMPENS Количество перьев, поддерживаемых устройством
NUMRESERVED Количество зарезервированных элементов в системной палитре. Это значение определено только для устройств, использующих цветовые палитры, что можно выяснить при помощи константы RASTERCAPS.
Данную константу можно использовать только для драйверов версии 3.0 и более поздних версий
PDEVICESIZE Размер внутренней структуры данных PDEVICE
PLANES Количество цветовых слоев
POLYGONALCAPS Способности устройства рисовать многоугольники. Возвращаемое значение представляет собой набор битовых масок, установленных в 1, если устройство может само рисовать многоугольники различного типа:
PC_INTERIORS устройство может закрашивать внутреннюю область;
PC_NONE устройство не может рисовать многоугольники;
PC_RECTANGLE прямоугольники;
PC_SCANLINES устройство может выполнять сканирование линий растра;
PC_STYLED устройство может рисовать рамки с использованием различных стилей (штриховые, пунктирные, штрих-пунктирные и т. д.);
PC_WIDE широкие рамки;
PC_WIDESTILED устройство может рисовать широкие рамки с использованием различных стилей (штриховые, пунктирные, штрих-пунктирные и т. д.)
PC_WINDPOLYGON многоугольники с заполнением в режиме WINDING
RASTERCAPS Набор битовых масок, определяющих способность устройства выполнять растровые операции:
RC_BANDING для устройства требуется поддержка операции banding — функции GDI должны выводить данные небольшими сегментами, формирующими изображение (используется устройствами печати);
RC_BIGFONT устройство поддерживает шрифты, размером большем чем 64 Кбайт;
RC_BITBLT устройство может выполнять перемещение участков изображения в виде битовых образов (bitmap);
RC_BITMAP64 устройство может работать с битовыми образами большого размера (больше 64 Кбайт);
RC_DEVBITS есть поддержка битовых образов со стороны устройства;
RC_DI_BITMAP устройство поддерживает выполнение функций SetDIBits и GetDIBits;
RC_DIBTODEV устройство поддерживает выполнение функции SetDIBitsToDevice;
RC_FLOODFILL устройство может выполнять заливку фигур;
RC_GDI20_OUTPUT драйвер устройства поддерживает особенности Windows версии 2.0;
RC_GDI20_STATE контекст устройства содержит блок состояния устройства;
RC_NONE устройство не выполняет растровых операций;
RC_OP_DX_OUTPUT устройство поддерживает режим непрозрачности и массив DX;
RC_PALETTE устройство использует палитры цветов;
RC_SAVEBITMAP устройство может локально сохранять битовые образы (bitmap);
RC_SCALING поддерживается операция масштабирования;
RC_STRETCHBLT устройство поддерживает функцию StretchBlt;
RC_STRETCHDIB устройство поддерживает функцию StretchDIBits
SIZEPALETTE Размер таблицы палитры. Это значение можно использовать только для устройств, использующих цветовые палитры, что можно определить при помощи константы RASTERCAPS
TECHNOLOGY Тип устройства или технология, с использованием которой сделано устройство:
DT_CHARSTREAM устройство работает с потоком символов;
DT_DISPFILE файл отображения;
DT_METAFILE метафайл;
DT_PLOTTER векторный плоттер;
DT_RASDISPLAY растровый дисплей;
DT_RASPRINTER растровый принтер;
DT_RASCAMERA растровая камера
TEXTCAPS Набор битовых масок, определяющих способность устройства выполнять операции с текстом:
TC_OP_CHARACTER точность соответствия запрашиваемого и предоставленного шрифта. Если установлен этот бит, устройство может обеспечить запрошенные атрибуты символов;TC_OP_STROKE устройство может обеспечить необходимую высоту, ширину, ориентацию и атрибуты текста;
TC_CP_STROKE точность вывода допускает обрезание символов шрифта для того, чтобы текст появился только внутри заданной области ограничения;
TC_CR_90 устройство может поворачивать символы только на угол, кратный 90 градусам;
TC_CR_ANY устройство может поворачивать символы на любой угол;
TC_SF_X_YINDEP устройство может масштабировать свой шрифт по вертикальной и горизонтальной оси;
TC_SA_DOUBLE устройство может удваивать размер своего шрифта;
TC_SA_INTEGER устройство может увеличивать размер своего шрифта в любое целое количество раз;
TC_SA_CONTIN устройство может выполнять произвольное масштабирование своего шрифта, сохраняя отношение между вертикальным и горизонтальным размером шрифта;
TC_EA_DOUBLE устройство может увеличивать жирность своего шрифта в два раза;
TC_IA_ABLE устройство может делать свой шрифт наклонным (italic);
TC_UA_ABLE устройство может делать свой шрифт подчеркнутым;
TC_SO_ABLE устройство может делать свой шрифт перечеркнутым;
TC_RA_ABLE устройство способно перечислять растровые шрифты или шрифты TrueType при вызове функций EnumFonts или EnumFontFamilies;
TC_VA_ABLE устройство способно перечислять векторные шрифтов при вызове функций EnumFonts или EnumFontFamilies;
TC_RESERVED не используется
VERTRES Высота дисплея в пикселах. Для принтеров — высота рабочей области, в которой принтер способен выполнять печать
VERTSIZE Стандартная высота дисплея в миллиметрах

Не все перечисленные выше значения будут сразу вам нужны, поэтому мы остановимся только на некоторых из них.

Значения ASPECTX, ASPECTY, ASPECTXY определяют размеры пиксела. Зачем вам могут понадобиться размеры пиксела? Дело в том, что пикселы не всегда квадратные (или круглые). Поэтому в некоторых режимах работы видеоадаптера масштаб изображения по оси x может отличаться от масштаба по оси y. Размеры пиксела позволят вам вычислить отношение сторон пиксела и выполнить правильное масштабирование. В этом случае отображаемые вами окружности будут круглыми, а квадраты — квадратными.

Иногда бывает важно знать цветовое разрешение устройства вывода. Для этого можно использовать значение BITSPIXEL, которое соответствует количеству бит, используемых для представления цвета. Если возвести число 2 в степень значения BITSPIXEL, получится количество цветов, которое может быть представлено одним пикселом.

Некоторые устройства работают с цветовыми плоскостями. Количество этих плоскостей можно определить, пользуясь значением PLANES. Об использовании цветовых плоскостей можно прочитать в третьем томе «Библиотеки системного программиста», который называется «Программирование видеоадаптеров CGA, EGA и VGA». Отметим, что количество цветов, которые могут быть представлены устройством с цветовыми плоскостями, равно 2n, где n — количество цветовых плоскостей.

Если устройство работает с цветовыми плоскостями и использует несколько бит для представления цвета одного пиксела, количество одновременно отображаемых цветов можно определить по формуле:

где nPixel — количество битов, используемых для представления цвета пиксела (значение BITSPIXEL); nPlanes — количество цветовых плоскостей (значение PLANES).

Значение NUMCOLORS равно количеству цветов при использовании одной палитры. Так как палитра может быть перегружена, фактически вы можете использовать больше цветов, чем указано в NUMCOLORS. Но в этом случае вы должны сами перезагружать палитру. Для устройств, работающих с палитрами, правильное количество используемых цветов возвращается при использовании значения COLORRES.

Для проведения экспериментов и демонстрации возможностей функции GetDeviceCaps мы подготовили приложение DCAPS (листинг 4.4).

Листинг 4.4. Файл dcapsdcaps.cpp

Это приложение интересно тем, что оно получает контекст устройства (видеоадаптера) новым для вас способом — при помощи функции CreateDC:

Контекст, полученный этим способом, может быть использован для рисования на всей поверхности экрана видеомонитора, а не только в окне приложения. В качестве первого параметра функции CreateDC указывается имя драйвера устройства. Драйвер видеоадаптера имеет имя DISPLAY.

Перед завершением работы приложения мы уничтожаем созданный нами контекст:

Для вывода числовых характеристик драйвера устройства в шестнадцатеричном формате используется функция PrintH, для вывода в десятичном формате — функция PrintD. Обе эти функции формируют и выводят в заранее открытый текстовый файл строку, содержащую имя параметра и значение, полученное от функции GetDeviceCaps.

Для отображения параметров, представленных набором флагов, используется функция PrintFlag. Функция записывает в файл имя флага и его состояние. Если флаг сброшен (значение равно 0), он помечается знаком «-«, в противном случае — знаком «+».

Для отображения технологии, использованной драйвером, выполняется анализ значения, возвращаемого функцией GetDeviceCaps при передаче ей параметра TECHNOLOGY. В файл записывается возвращаемое этой функцией значение и его символьная расшифровка.

Файл определения модуля для приложения DCAPS представлен в листинге 4.5.

Листинг 4.5. Файл dcapsdcaps.def

В листинге 4.6 приведен результат работы программы при использовании стандартного драйвера видеоконтроллера VGA, поставляющегося вместе с Windows версии 3.1.

Листинг 4.6. Образец файла devcap.txt для драйвера VGA, разрешение 640×480, 16 цветов

В поле DRIVERVERSION стоит значение 30a, что соответствует версии драйвера 3.1.

Для вывода используется квадратный пиксел с размерами (36, 36), так что никаких мер для обеспечения равного масштаба по осям x и y принимать не надо.

Стандартный драйвер обеспечивает вывод 16 цветов. Из приведенного выше листинга видно, что для представления цвета пиксела используется один бит (значение BITSPIXEL равно 1). Количество цветовых плоскостей (значение PLANES) равно 4, следовательно, количество возможных цветов будет равно 24, или 16.

Значение бита RC_PALETTE значения RASTERCAPS равно нулю, следовательно, драйвер не использует палитры. Поэтому значение COLORRES (цветовое разрешение в битах на пиксел) равно нулю. Значение SIZEPALETTE также равно 0.

Количество возможных цветов, определяемых при помощи NUMCOLORS, равно 16. Это значение согласуется с полученным при помощи BITSPIXEL и PLANES.

Для сравнения приведем возможности драйверов контроллера Cirrus Logic в режимах с использованием 65536 цветов и 16,7 млн. цветов (точное значение — 224 цветов). Результаты работы нашего приложения для этих драйверов приведены соответственно в листинге 4.7 и 4.8.

Листинг 4.7. Образец файла devcap.txt для драйвера Cirrus Logic, разрешение 640×480, 65536 цветов

Из листинга 4.7 видно, что драйвер использует для представления цвета пиксела 16 бит (значение BITSPIXEL). Количество цветовых слоев равно 1 (значение PLANES), поэтому общее количество доступных цветов равно 65536.

Тем не менее значение NUMCOLORS равно 4096, что не соответствует цветовым возможностям данного драйвера. Здесь нет ошибки, дело в том, что, как мы уже говорили, значение NUMCOLORS соответствует количеству цветов в одной палитре, но не количеству доступных цветов.

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

Листинг 4.8. Образец файла devcap.txt для драйвера Cirrus Logic, разрешение 640×480, 16,7 млн. цветов

Для этого режима цвет одного пиксела определяется 24 битами (значение BITSPIXEL) при использовании одной цветовой плоскости (значение PLANES). Поэтому общее количество доступных цветов равно 224, или, примерно 16,7 млн.

Значение NUMCOLORS по-прежнему равно 4096.

Приведем сравнительную таблицу параметров, связанных с размерами экрана и пикселов в различных режимах и для различных типов видеоадаптеров.

Параметр функции GetDeviceCaps CGA EGA VGA SVGA 800 x 600 8514/A SVGA 1024 x 768
HORZRES 640 640 640 800 1024 1024
VERTRES 200 350 480 600 760 768
HORZSIZE 240 240 208 208 280 208
VERTSIZE 180 175 156 152 210 152
ASPECTX 5 38 36 36 10 36
ASPECTY 12 48 36 36 14 36
ASPECTXY 13 61 51 51 14 51
LOGPIXELSX 96 96 96 96 120 96
LOGPIXELSY 48 72 96 96 120 96

Размеры экрана в миллиметрах (HORZSIZE и VERTSIZE) относятся скорее к стандартному типу видеомонитора, чем к конкретному типу видеомонитора, подключенного к вашему компьютеру. В любом из перечисленных выше режимов вы можете использовать как 14-дюймовые, так и 17- или даже 20-дюймовые видеомониторы. В любом случае функция GetDeviceCaps будет возвращать значения размеров экрана, приведенные в таблице.

Из таблицы также видно, что для наиболее часто встречающихся типов видеоадаптеров (VGA, SVGA 800 x 600, SVGA 1024 x 768) используются квадратные пикселы с размером (36,36). В то же время видеоадаптеры CGA, EGA и 8514/A используют пикселы в форме прямоугольника.

Некоторые программы (например, Microsoft Word for Windows) способны рисовать дюймовые или миллиметровые линейки, которые можно использовать для измерения размеров объектов в естественных для человека единицах измерения (но не в пикселах). Значения LOGPIXELSX и LOGPIXELSY определяют количество пикселов в так называемом логическом дюйме. Логический дюйм не является «настоящим» дюймом, имеющим длину 25,4 мм. Его размеры искусственно увеличены примерно в 1,5 раза для удобства изображения текста на экране обычного размера (14 дюймов по диагонали). Если бы размер логического дюйма был равен в точности одному «физическому» дюйму, буквы, набранные шрифтом стандартного размера (порядка 10 — 12 пунктов) были бы слишком мелкими.

Программы MS-DOS работали с экраном, который имел фиксированные размеры. В зависимости от видеорежима они использовали либо текстовый экран размером 80 х 25 символов, либо графический экран размером от 640х200 для видеоконтроллеров CGA, до 1024 х 768 или больше для SVGA.

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


Существует два принципиально разных метода определения размера окна. Первый метод основан на том факте, что, когда вы изменяете размер окна мышью, функция окна получает сообщение с кодом WM_SIZE, параметры которого передают функции новые размеры окна. Второй метод заключается в вызове функций, возвращающих размеры окна по его идентификатору. Например, для определения размеров окна можно воспользоваться функцией GetClientRect. Мы приведем исходные тексты приложения WSIZE, демонстрирующего использование обоих методов.

Приложение WSIZE состоит из трех файлов. Первый файл с именем wsize.cpp (листинг 4.9) создает главное окно приложения и запускает цикл обработки сообщений. Файл wndproc.cpp (листинг 4.10) содержит исходный текст функции окна, выполняющий всю интересную для нас работу по определению и отображению текущих размеров главного окна приложения. И наконец, файл wsize.def (листинг 4.11) является файлом определения модуля для нашего приложения.

Листинг 4.9. Файл wsizewsize.cpp

Файл wsize.cpp не имеет никаких дополнительных особенностей по сравнению с аналогичными файлами предыдущих приложений. Поэтому мы не будем его описывать, а перейдем сразу к функции окна (листинг 4.10).

Листинг 4.10. Файл wsizewndproc.cpp

В области данных функции окна определены статические переменные, предназначенные для хранения размера окна и способа изменения этих размеров (о способах изменения размеров окна мы расскажем немного позже):

При обработке сообщения WM_PAINT содержимое этих переменных выводится в левом верхнем углу окна. Вам может показаться странным, что перед выводом содержимого переменных по сообщению WM_PAINT сами переменные не инициализируются. Это не совсем так.

Рассмотрим последовательность действий при создании и отображении окна и перечислим сообщения, получаемые функцией окна на разных стадиях создания.

Окно создается функцией CreateWindow. При этом функция окна получает следующие сообщения:

Код сообщения Описание сообщения
WM_GETMINMAXINFO При обработке этого сообщения приложение может изменить заданные по умолчанию размеры, расположение, а также минимальные и максимальные размеры окна, которые могут быть получены при изменении этих размеров с помощью мыши
WM_NCCREATE Сообщение оповещает функцию окна о начале процесса создания окна
WM_NCCALCSIZE При обработке этого сообщения приложение может определить размеры внутренней области окна (client area)
WM_CREATE Это сообщение оповещает приложение о том, что окно создано и что приложение может выполнять дополнительные действия по инициализации данных, связанных с окном

Обычно все эти сообщения (кроме последнего) передаются функции DefWindowProc. В некоторых случаях, когда с окном связаны структуры данных, требующие инициализации при создании окна, функция окна перехватывает сообщение WM_CREATE, определяя по нему момент завершения создания окна и выполняя собственные инициализирующие действия.

Для того, чтобы сделать окно видимым, наше приложение вызывает функцию ShowWindow. Эта функция посылает в функцию окна целый каскад сообщений:

Код сообщения Описание сообщения
WM_SHOWWINDOW Сообщение оповещает функцию окна о том, что окно будет отображено или скрыто
WM_WINDOWPOSCHANGING Это сообщение посылается окну при изменении его размеров, расположения на экране или взаимного расположения вдоль оси Z (то есть когда окно перекрывается другими окнами или само перекрывает другие окна; воображаемая ось Z направлена перпендикулярно к плоскости экрана, окна могут перекрывать друг друга, при этом считается, что каждое окно имеет свою «Z-координату»)
WM_ACTIVATEAPP Это сообщение посылается окну верхнего уровня (то есть главному окну приложения) и говорит о создании в Windows нового приложения (нового процесса)
WM_NCACTIVATE Сообщение посылается окну, которое должно перерисовать свою внешнюю область (non client area), включающую заголовок, рамку, кнопки изменения размера и т. п.)
WM_GETTEXT Копирование текста заголовка окна
WM_ACTIVATE Сообщение посылается окну, которое изменяет свое состояние из неактивного в активное или наоборот
WM_SETFOCUS Окно получает фокус ввода (все сообщения от клавиатуры направляются в это окно)
WM_NCPAINT Сообщение посылается окну, требующему перерисовки рамки. Приложение может перехватить это сообщение и нарисовать вокруг окна собственную рамку
WM_GETTEXT Копирование текста заголовка окна
WM_ERASEBKGND Сообщение посылается окну при стирании фона его внутренней области
WM_WINDOWPOSCHANGED Это сообщение посылается окну, изменившему свои размеры, расположение на экране или расположение вдоль оси Z
WM_SIZE Сообщение посылается окну после изменения размеров окна
WM_MOVE Сообщение посылается окну после его перемещения

Все эти сообщения, кроме двух последних, обычно передаются функции DefWindowProc. Если функция окна должна реагировать на изменение размеров или расположения окна, она должна обрабатывать сообщения WM_SIZE и WM_MOVE.

При вызове функции UpdateWindow функция окна получает единственное сообщение WM_PAINT (только в том случае, если окно содержит области, помеченные для обновления).

Так как при отображении окна функцией ShowWindow функция окна получает в числе прочих сообщение WM_SIZE, и наше приложение WSIZE его обрабатывает, мы можем инициализировать переменные fwSizeType, nWidth и nHeight до прихода сообщения WM_PAINT, что мы и делаем в нашем обработчике сообщения WM_SIZE:

Как мы говорили раньше, вместе с сообщением обычно приходит дополнительная информация, которая передается функции окна через параметры wParam и lParam. До сих пор мы игнорировали эту информацию. Теперь она нам нужна, так как новые размеры окна передаются функции окна вместе с сообщением WM_SIZE именно через параметры wParam и lParam.

В операционной системе Windows версии 3.1 тип WPARAM соответствует 16-разрядному слову, а тип LPARAM — 32-разрядному двойному слову. Однако не следует думать, что так будет и в других версиях Windows. Операционная система Windows NT, например, использует для типа WPARAM 32-разрядное слово.

Через параметр lParam передается два значения. В операционной системе Windows версии 3.1 эти значения соответствуют младшему и старшему слову lParam. Для обеспечения совместимости со следующими версиями Windows не следует самостоятельно извлекать эти два значения. Нужно пользоваться специально предназначенными для этого макросами LOWORD и HIWORD. Эти макросы определены в файле windows.h:

Параметры сообщения WM_SIZE описывают новый размер окна и способ, которым окно изменило свой размер:

Параметр Описание
wParam Способ, при помощи которого окно изменило свой размер
LOWORD(lParam) Новая ширина окна
HIWORD(lParam) Новая высота окна

Параметр wParam может принимать одно из нескольких значений, символические имена которых начинаются с префикса SIZE_ и определены в файле windows.h следующим образом:

Параметр Значение Описание
SIZE_RESTORED Окно изменило свои размеры, но оно не было максимизировано или минимизировано
SIZE_MINIMIZED 1 Размеры окна уменьшены до предела (окно минимизировано)
SIZE_MAXIMIZED 2 Размеры окна увеличены до предела (окно максимизировано)
SIZE_MAXSHOW 3 Сообщение WM_SIZE с этим значением парамера wParam посылается всем временным (pop-up) окнам, когда восстанавливается размер других окон
SIZE_MAXHIDE 4 Сообщение WM_SIZE с этим значением парамера wParam посылается всем временным (pop-up) окнам, когда размер других окон увеличивается до предела

После сохранения параметров сообщения WM_SIZE функция окна нашего приложения посылает сама себе сообщение WM_PAINT. Для этого при помощи функции InvalidateRect она объявляет все окно как требующее обновления и затем вызывает функцию UpdateWindow:

Функция InvalidateRect добавляет прямоугольную область, заданную в качестве параметра, к областям окна, требующим обновления (перерисовки). Эта функция имеет следующий прототип:

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

Второй параметр — дальний указатель на структуру типа RECT, описывающую координаты области. Если в качестве этого параметра использовать значение NULL (как в нашем примере), вся внутренняя область окна (client area) будет объявлена как требующая обновления.

Третий параметр указывает, нужно ли при обновлении стирать фон окна. Если указать значение TRUE, фон окна будет стерт. Для того чтобы оставить фон окна без изменения, укажите в качестве третьего параметра значение FALSE.

Функция UpdateWindow вызывается в нашем приложении после того, как вся внутренняя область окна объявлена как требующая обновления, поэтому она передает функции окна сообщение WM_PAINT. Обработчик этого сообщения выводит в левом верхнем углу окна новые координаты окна и код способа, которым были изменены размеры окна.

Функция окна нашего приложения обрабатывает сообщение WM_LBUTTONDOWN. Это сообщение передается функции окна, когда вы располагаете курсор мыши над окном и нажимаете левую клавишу мыши. Обработчик этого сообщения с помощью функции GetClientRect определяет текущие размеры окна и выводит их в левом верхнем углу окна под строкой, выведенной обработчиком сообщения WM_PAINT:

Функция GetClientRect предназначена для определения координат внутренней области окна и имеет следующий прототип:

Первый параметр функции (hwnd) определяет идентификатор окна, для которого требуется определить координаты внутренней области.

Второй параметр (lprc) является дальним указателем на структуру типа RECT, в которую записываются координаты внутренней области окна. Эти координаты вычисляются относительно левого верхнего угла внутренней области окна, поэтому в полях left и top структуры RECT всегда записываются нулевые значения. Поля right и bottom содержат соответственно ширину и высоту внутренней области окна.

На рис. 4.1 показан внешний вид главного окна приложения WSIZE после того, как в нем щелкнули левой клавишей мыши.

Рис. 4.1. Главное окно приложения WSIZE

Из рисунка видно, что оба способа определения размера окна (при обработке сообщения WM_SIZE и при помощи функции GetClientRect) дали одинаковые результаты.

Файл определения модуля, который был использован при создании приложения WSIZE, не имеет никаких особенностей и приведен в листинге 4.11.

Листинг 4.11. Файл wsizewsize.def

В предыдущем разделе мы научили вас определять размеры окна. Другая важная задача — определение расположения окна на экране видеомонитора.

Когда вы перемещаете окно (например, при помощи мыши), функция окна получает сообщение WM_MOVE. Вместе с этим сообщением функция окна получает новые координаты внутренней области окна:

Параметр Описание
wParam Не используется
LOWORD(lParam) Новая X-координата верхнего левого угла внутренней области окна
HIWORD(lParam) Новая Y-координата верхнего левого угла внутренней области окна

Для перекрывающихся (overlapped) и временных (pop-up) окон координаты отсчитываются от верхнего левого угла экрана. Для дочерних (child) окон эти координаты отсчитываются от верхнего левого угла внутренней области родительского окна.

В любой момент времени приложение может определить расположение и размеры окна, вызвав функцию GetWindowRect. Эта функция имеет следующий прототип:


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

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

Для демонстрации использования сообщения WM_MOVE и функции GetWindowRect мы подготовили приложение WPOS. Это приложение по своей структуре аналогично приложению WSIZE, которое было рассмотрено в предыдущем разделе.

В файле wpos.cpp (листинг 4.12) расположена функция WinMain, создающая главное окно приложения и цикл обработки сообщений.

Листинг 4.12. Файл wposwpos.cpp

Функция окна (листинг 4.13) обрабатывает сообщения WM_PAINT, WM_MOVE, WM_SIZE, WM_LBUTTONDOWN и, конечно, WM_DESTROY.

Листинг 4.13. Файл wposwndproc.cpp

Сообщение WM_MOVE передается окну, когда оно отображается функцией ShowWindow, или при изменении размера окна. Наш обработчик сообщения WM_MOVE сохраняет экранные координаты внутренней области окна в переменных с именами xPos и yPos. После сохранения координат функция окна объявляет все окно как требующее обновления и посылает само себе сообщение WM_PAINT, для чего вызывает функцию UpdateWindow:

Обработчик сообщения WM_PAINT выводит координаты в левом верхнем углу внутренней области окна. Перемещая окно при помощи мыши, вы можете проследить за изменением текущих координат внутренней области окна.

Для сообщений WM_SIZE и WM_LBUTTONDOWN используется общий обработчик. Он вызывает функцию GetWindowRect, с помощью которой определяет координаты и размер прямоугольной области, ограничивающей окно. Координаты левого верхнего угла и правого нижнего угла этой области выводятся во второй строке внутренней области окна (рис. 4.2).

Рис. 4.2. Главное окно приложения WPOS

При перемещении главного окна приложения WPOS первая строка обновляется автоматически, при этом вторая строка стирается. Если после перемещения сделать щелчок мышью внутри окна или изменить его размер, появится вторая строка. В ней будут отображены координаты прямоугольной области, ограничивающей окно.

Для создания приложения был использован файл определения модуля, приведенный в листинге 4.14.

Листинг 4.14. Файл wposwpos.def

Программный интерфейс операционной системы Windows версии 3.1 содержит еще одну функцию, полезную при определении расположения на экране и размеров окна. Эта функция имеет имя GetWindowPlacement и следующий прототип:

Первый параметр функции (hwnd) задает идентификатор окна, для которого нужно определить расположение и размеры.

Второй параметр (lpwndpl) является дальним указателем на структуру типа WINDOWPLACEMENT, определенную в файле windows.h:

Поле length определяет размер структуры WINDOWPLACEMENT в байтах.

Поле flags после вызова функции GetWindowPlacement всегда равно нулю. Это поле содержит флаги, определяющие положение минимизированного окна и способ, которым окно будет восстановлено.

Поле showCmd после вызова функции GetWindowPlacement имеет значение SW_SHOWMAXIMIZED для максимизированного окна, SW_SHOWMINIMIZED для минимизированного окна и SW_SHOWNORMAL в остальных случаях.

Поле ptMinPosition определяет положение верхнего левого угла окна, когда оно минимизировано.

Поле ptMaxPosition определяет положение верхнего левого угла окна, когда оно максимизировано.

Поле rcNormalPosition определяет положение верхнего левого угла окна, размеры которого восстановлены до нормальных.

Для указания положения верхнего левого угла максимизированного и минимизированного окна используется структура POINT, определенная в файле windows.h:

Операционная система Windows содержит в себе сложную подсистему для работы со шрифтами. В деталях эта система будет описана позже, так как она нетривиальна.

Приложения Windows могут выводить текст с использованием различных шрифтов. Многие программы, такие, как текстовые процессоры, позволяют выбирать произвольную (до некоторой степени) высоту букв. Но характеристики шрифтов в Windows не ограничиваются высотой и шириной букв. Для точного определения внешнего вида шрифта используется больше дюжины различных характеристик.

Прежде всего следует отметить, что все шрифты в Windows можно разделить на две группы. К первой группе относятся шрифты с фиксированной шириной букв (fixed-pitch font). Все буквы (и знаки, такие, как запятая, точка и т. д.) такого шрифта имеют одинаковую ширину. Вторая группа шрифтов — шрифты с переменной шириной букв (variable-pitch font). Для таких шрифтов каждая буква имеет свою ширину. Буква «Ш», например, шире буквы «i».

Кроме того, шрифты Windows можно разделить на растровые (raster font), контурные (stroke font) и масштабируемые (типа TrueType). Образцы этих шрифтов представлены на рис. 4.3.

Рис. 4.3. Растровый, контурный и масштабируемый шрифты

Растровые шрифты состоят из отдельных пикселов и используются при выводе текста на экран видеомонитора или принтер. Для обеспечения приемлемого качества текста в Windows имеется набор одинаковых растровых шрифтов для нескольких размеров букв. Если попытаться выполнить масштабирование растрового шрифта в сторону увеличения размера букв, наклонные линии и закругления будут изображаться в виде «лестницы» (см. рис. 4.3).

Контурные шрифты больше подходят для плоттеров. При масштабировании таких шрифтов можно достигнуть лучших результатов, чем при масштабировании растровых. Однако при большом размере букв результат все равно получается неудовлетворительный.

Масштабируемые шрифты TrueType сохраняют начертание символов при любом изменении размера, поэтому они чаще всего используются, например, при подготовке текстовых документов.

Любой из перечисленных выше шрифтов может быть с фиксированной или переменной шириной букв.

Первое время в наших примерах приложений мы будем использовать так называемый системный шрифт SYSTEM_FONT. Этот шрифт выбран в контекст отображения по умолчанию, поэтому нам не потребуются никакие функции для выбора шрифта. Системный шрифт используется в Windows, например, для текста в заголовках окон, меню и диалоговых панелях.

Системный шрифт относится к растровым шрифтам с переменной шириной букв.

Так как ширина букв переменная, вы не сможете выполнять вывод таблицы в несколько столбцов, ориентируясь на ширину букв. Вам придется либо выводить каждый столбец таблицы по отдельности, начиная с некоторой позиции в окне, либо подсчитывать длину каждой ячейки и дополнять ее пробелами до некоторой фиксированной ширины (первый способ нам кажется удобнее).

Переменная ширина букв усложняет задачу вывода текста, так как длина текстовой строки зависит не только от количества букв в строке, но и от того, из каких букв состоит строка. К счастью, в составе программного интерфейса Windows имеется специальная функция GetTextExtent, предназначенная для подсчета длины текстовой строки.

Для получения информации о шрифте, выбранном в контекст устройства, предназначена функция GetTextMetrics. Она имеет следующий прототип:

Первый параметр функции (hdc) указывает контекст устройства, для которого требуется получить информацию о метрике шрифта. В качестве этого параметра можно использовать значение, возвращаемое функцией BeginPaint или GetDC.

Второй параметр функции (lptm) является дальним указателем на структуру типа TEXTMETRIC, в которую будет записана информация о метриках шрифта, выбранного в указанный контекст устройства.

В случае успешного завершения функция возвращает значение TRUE, в противном случае — FALSE.

Структура TEXTMETRIC описана в файле windows.h следующим образом:

Описание этой структуры мы начнем с полей, определяющих вертикальные размеры шрифта. Программисты MS-DOS пользовались, как правило, одним параметром — высотой букв шрифта. Для приложений Windows используются целых пять параметров, имеющих отношение к вертикальным размерам букв (рис. 4.4).

Рис. 4.4. Метрики шрифта


Отсчет всех размеров выполняется от так называемой базовой линии шрифта.

Общая высота букв находится в поле tmHeight структуры TEXTMETRIC. Эта высота складывается из двух компонент — tmAscent и tmDescent. Компонента tmAscent представляет собой высоту букв от базовой линии с учетом таких элементов, как тильда в букве «Й». Компонента tmDescent определяет пространство, занимаемое буквами ниже базовой линии. Сумма tmAscent и tmDescent в точности равна tmHeight.

Величина tmInternalLeading определяет размер выступающих элементов букв. Эта величина может быть равно нулю.

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

А как определить ширину букв?

В структуре TEXTMETRIC есть два поля с именами tmAveCharWidth и tmMaxCharWidth. Поле tmAveCharWidth содержит среднее значение ширины строчных букв шрифта. Это значение приблизительно соответствует ширине латинской буквы «x». Поле tmMaxCharWidth определяет ширину самой широкой буквы в шрифте. Для шрифта с фиксированной шириной букв поля tmAveCharWidth и tmMaxCharWidth содержат одинаковые значения, которые зависят от самого шрифта.

Хорошо спроектированные приложения позволяют вам выбирать для отображения текста произвольные шрифты. Поэтому приложение никогда не должно ориентироваться на конкретные размеры шрифта. Вместо этого следует определять эти размеры динамически во время работы приложения с помощью специально предназначенных для этого средств, таких, как функция GetTextMetrics.

Другие поля структуры TEXTMETRIC мы рассмотрим позже, в главе, посвященной шрифтам.

Для иллюстрации использования метрик шрифта мы подготовили приложение TMETRICS. Главный файл приложения, содержащий функцию WinMain, приведен в листинге 4.15.

Листинг 4.15. Файл tmetricstmetrics.cpp

При регистрации класса окна мы, указав стиль класса окна, потребовали, чтобы при изменении горизонтального или вертикального размера окна окно отмечалось как требующее обновления:

Функция окна будет получать сообщение WM_PAINT при изменении ширины или высоты окна.

Как и раньше, вся полезная работа выполняется функцией главного окна приложения (листинг 4.16).

Листинг 4.16. Файл tmetricswndproc.cpp

Как вы уже знаете, при создании окна в функцию окна передается сообщение WM_CREATE. Это сообщение удобно использовать для инициализации данных, имеющих отношение к окну. В нашем случае при получении сообщения WM_CREATE функция окна получает контекст отображения (с помощью функции GetDC) и вызывает функцию GetTextMetrics, которая записывает сведения о метрике текущего выбранного в контекст шрифта в структуру с именем tm.

На основании информации, хранящейся в этой структуре, вычисляются значения переменных cxChar и cyChar, используемых соответственно в качестве ширины и высоты символов.

Далее в обработчике сообщения WM_CREATE инициализируются переменные, которые будут использованы для указания текущей позиции вывода текста:

Перед возвратом обработчик сообщения WM_CREATE освобождает полученный контекст, вызывая функцию ReleaseDC.

Обработчик сообщения WM_PAINT выполняет инициализацию текущей позиции вывода текста и получает контекст отображения (с помощью функции BeginPaint). Вслед за этим с помощью функции Print, определенной в нашем приложении, обработчик выводит в окно названия параметров и их значения.

Функция Print выводит параметры в виде таблицы, состоящей из двух колонок. Для этого она вызывает уже знакомую вам функцию TextOut два раза для каждого параметра. В первый раз выводится название параметра, во второй — знак «=» и значение параметра.

Перед возвратом из функции текущая позиция вывода текста по вертикали увеличивается на одну строку:

Файл определения модуля для приложения TMETRICS приведен в листинге 4.17.

Листинг 4.17. Файл tmetricstmetrics.def

Внешний вид главного окна приложения TMETRICS показан на рис. 4.5.

Рис. 4.5. Главное окно приложения TMETRICS

Из этого рисунка видно, что для системного шрифта, выбранного по умолчанию, значение tmExternalLeading равно нулю, поэтому возможно «слипание» строк, содержащих символы с «хвостиками», тильдами и надстрочными точками.

При уменьшении размера окна может получиться так, что часть строк будет обрезана нижней или правой границей окна (рис. 4.6).

Рис. 4.6. Окно уменьшенного размера

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

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

Нужно определить, что низ элемента на странице достиг нижнего края видимой области браузера и зафиксировать его фиксированной позицией к низу окна.

UPD: Забыл уточнить: элемент намного выше видимой области. Перечисленные решения DeLaVega, подходят частично. Они видимо не считают положение элемента при начальном положении(высот намного ниже видимой области), т.е. низ элемента за областью видимости. Или я не так понял как ими пользоваться.

Класс Window

Класс Window унаследован от класса ContentControl. Это означает, что он может содержать только одного потомка (каковым обычно является контейнер компоновки наподобие элемента управления Grid) и что его фон можно закрашивать с помощью кисти путем установки свойства Background.

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

— это область внутри окна. Именно в ней размещается содержимое. К не клиентской области относится граница и строка заголовка в верхней части окна. За управление этой областью отвечает операционная система.

Помимо этого, класс Window имеет небольшой набор членов, знакомых любому программисту для Windows. Наиболее очевидными из них являются свойства, которые касаются внешнего вида и позволяют изменять способ отображения не клиентской части окна. Основные члены класса Window перечислены ниже:

Если установлено в true, класс Window позволяет другим окнам «проглядывать» через данное при условии, что для фона был установлен прозрачный цвет. В случае установки в false (поведение по умолчанию), находящееся позади данного окна содержимое не «просматривается», и прозрачный цвет фона визуализируется как черный. В случае использования в комбинации со свойством WindowsStyle, установленным в None, это свойство позволяет создавать окна, имеющие необычную форму.

Icon

Объект imageSource, идентифицирующий значок, который должен использоваться для данного окна. Значки отображаются в левом верхнем углу окна (если в нем применяется один из стандартных стилей границ), в панели задач (если свойство ShowInTaskBar установлено в true) и в окне выбора, которое появляется, когда пользователь нажимает комбинацию клавиш для перехода между работающими приложениями. Поскольку эти значки имеют разные размеры, в используемом для них файле .ico должны содержаться изображения с размерами как минимум 16×16 и 32×32 пикселя.

В последних версиях ОС Windows (Windows Vista и Windows 7) добавлен новый стандарт для значков 48×48 и 256×256 пикселей, размер которых можно изменять. Если свойство Icon установлено в null, окно получает тот же значок, что и приложение (значок для которого можно указать в Visual Studio, дважды щелкнув на узле Properties (Свойства) в окне Solution Explorer и перейдя на вкладку Application (Приложение)). Если свойство вообще опущено, WPF для изображения окна будет использовать стандартный, но непримечательный значок

Тор и Left

Определяют расстояние между левым верхним углом окна и левыми верхними краями экрана (в независимых от устройства единицах). При изменении любого из них генерируется событие LocationChanged. Если свойство WindowStartupPosition установлено в Manual, значения этих свойств можно указывать до появления окна для определения, задавая его начальную позицию. Какое бы значение не использовалось для WindowStartupPosition, эти свойства можно устанавливать в любой момент после отображения окна, изменяя его текущую позицию

ResizeMode


Принимает значение перечисления ResizeMode, которое определяет, может ли пользователь изменять размеры окна. Также влияет на видимость кнопок, отвечающих за разворачивание и сворачивание окна. Чтобы полностью заблокировать размеры окна, используйте значение NoResize. Чтобы пользователь мог только сворачивать окно, применяйте значение CanMinimize. Чтобы пользователь мог изменять размер окна всеми возможными способами, указываете значение CanResize. Чтобы в правом нижнем углу окна отображалась еще и визуальная подсказка, указывающая, что размеры окна разрешено изменять, задавайте значение CanResizeWithGrip.

RestoreBounds

Предоставляет границы окна. Если окно в текущий момент развернуто или свернуто, это свойство отражает границы, которые использовались последними перед развертыванием или свертыванием. Это чрезвычайно удобно, когда необходимо сохранить информацию о позиции и размерах окна.

ShowInTaskBar

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

SizeToContent

Позволяет создать окно, которое автоматически увеличивается в соответствии с размерами содержимого. Это свойство принимает значение перечисления SizeToContent. Чтобы отключить автоматическое изменение размеров окна, используйте значение Manual. Чтобы окно могло увеличиваться в различных направлениях в соответствии с размерами динамического содержимого, применяйте, соответственно, значение Height, Width или WidthAndHeight. При установке значения SizeToContent окно может увеличиваться в размерах в соответствии с содержимым так, что будет выходить за пределы экрана.

Title

Заголовок, который отображается в строке заголовка окна (и в панели задач)

Topmost

Если установлено в true, окно всегда отображается поверх остальных окон в приложении (если только у них это свойство также не равно true). Такая настройка очень удобна для палитр, которые обычно должны «плавать» над другими окнами

WindowStartupLocation

Принимает значение перечисления WindowStartupLocation. Для размещения окна в конкретной позиции с помощью свойств Left и Тор используйте значение Manual. Для размещения окна по центру экрана применяйте значение CenterScreen. Для размещения окна с учетом позиции того окна, которое его запустило, указывайте значение CenterOwner. При отображении немодального окна с использованием значения CenterOwner удостоверьтесь, что свойство Owner нового окна установлено перед тем, как показывать его.

WindowState

Принимает значение перечисления WindowState. Информирует о том, в каком состоянии находится окно: развернутом, свернутом или обычном (и позволяет изменить его). При изменении значения этого свойства генерируется событие StateChanged

WindowStyle

Принимает значение перечисления WindowStyle, которое определяет внешний вид границы окна. Возможные значения: SingleBorderWindow (по умолчанию), ThreeDBorderWindow (граница визуализируется несколько иным образом в Windows ХР), ToolWindow (отображается тонкая граница, удобная для «плавающих» окон с инструментами без кнопок сворачивания и разворачивания) и None (визуализируется очень тонкая приподнятая граница без области для строки заголовка). Увидеть разницу можно на рисунке ниже:

Элемент позиции относительно окна независимо от размера окна

Как я могу позиционировать элемент в том же относительном положении в видимой области окна независимо от размера окна?

Например, элемент, который должен быть:

  • 30% ширины окна слева от страницы и
  • 50% высоты окна вверху страницы.

В большинстве случаев это можно сделать только с помощью CSS. Вы пытались использовать position: fixed ?

Вы можете использовать абсолютное позиционирование и процентную длину vh просмотра, где единица vh составляет 1% от высоты видимой области, а один vw — 1% от ширины видимой области.

Длины в процентах в окне просмотра определяют значение относительно размера окна просмотра, то есть видимую часть документа.

Указание размеров с помощью окна «Размер и положение»

На вкладке Вид в группе Показать выберите пункт Области задач, а затем — пункт Размер и положение.

Выделите фигуру, чтобы просмотреть и изменить сведения о ней.

Указание высоты и ширины фигуры

В окне Размер и положение есть поля высоты и ширины, в которые можно ввести точную величину и единицу измерения.

Допустим, нужно поместить небольшой прямоугольный стол в схему офиса. Поверхность стола имеет размер 1 фут 9 дюймов на 1 фут 5 дюймов. При перетаскивании прямоугольного стола из набора элементов Офисная мебель устанавливается размер 3 фута 6 дюймов на 6 футов. Вместо того, чтобы использовать маркеры изменения размера, для ввода точного размера можно использовать окно Размер и положение.

Выделите фигуру стола на странице документа.

В окне Размер и положение выделите значение в поле Ширина (3 фута 6 дюймов) и введите значение 1 фут 9 дюймов, а затем нажмите клавишу ВВОД.

Для разделения единиц измерения, например, метров и сантиметров, не допускается использовать запятую, иначе Visio выведет ошибку.

Чтобы использовать другую единицу измерения, нужно ввести ее название. Например, можно ввести значение 21 дюйм или даже 0,583 ярда.

Выделите значение в поле Высота (6 футов) и замените его на значение 1 фут 5 дюймов.

Теперь фигура точно представляет размер настоящего стола.

Установка значений с помощью формул

Значения в полях окна Размер и положение можно устанавливать, вводя математические выражения с использованием операторов, подобных указанным ниже:

Чтобы посчитать конечный результат и применить его к фигуре, нажмите клавишу ВВОД.

Координаты и положение булавки

Значения в полях X и Y показывают расстояние от начала координат схемы до положения булавки на выбранной фигуре.

Как правило, начало координат находится в левом нижнем углу страницы, но в некоторых шаблонах оно может располагаться в других местах. Чтобы найти начало координат, выделите фигуру и введите в поля X и Y значение 0 (ноль). Фигура переместится так, что ее положение булавки будет находиться непосредственно в начале координат.

Положение булавки определяет не только то, как значения X и Y влияют на положение фигуры, но и точку, вокруг которой вращается фигура. Например, если фигуру нужно вращать вокруг угла, а не вокруг центра, с помощью раскрывающегося списка в поле Положение булавки можно указать этот угол.

Илон Маск рекомендует:  Что такое код asp nocache
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL