Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Programming_Windows_95_Part_I.pdf
Скачиваний:
96
Добавлен:
05.06.2014
Размер:
4.61 Mб
Скачать

109

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

— это всегда точка (32767, 32767) независимо от размеров. Если рабочая область не квадратная, то логические координаты x и y будут иметь различные физические размерности.

Впредыдущем разделе говорилось о том, что в режиме отображения MM_ISOTROPIC в рабочей области можно создавать изображения, подобные изображению программы ANACLOCK, где оси x и y ранжированы от -1000 до 1000. Вы можете сделать нечто похожее в режиме MM_ANISOTROPIC:

SetMapMode(hdc, MM_ANISOTROPIC);

SetWindowExtEx(hdc, 1000, 1000, NULL);

SetViewportExtEx(hdc, cxClient / 2, -cyClient / 2, NULL);

SetViewportOrgEx(hdc, cxClient / 2, cyClient / 2, NULL);

Разница состоит в том, что в режиме MM_ANISOTROPIC часы, как правило, представлены в виде эллипса, а не окружности.

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

SetMapMode(hdc, MM_ANISOTROPIC);

SetWindowExtEx(hdc, 1, 1, NULL);

SetViewportExtEx(hdc, cxChar, cyChar, NULL);

(Здесь предполагается, что cxChar и cyChar — ширина и высота символа в пикселях для непропорционального шрифта.) Теперь вы можете в вызове функции TextOut задавать координаты символов как строку и столбец, не используя пиксельные координаты. Например, следующая инструкция выводит текст "Hello" с отступом в три символа слева и два символа сверху:

TextOut(hdc, 3, 2, "Hello", 5);

Это очень похоже на работу в среде MS DOS, а не Windows.

Когда вы впервые устанавливаете режим отображения MM_ANISOTROPIC, он всегда наследует значения протяженностей от предыдущего установленного режима. Это может быть очень удобно. Режим MM_ANISOTROPIC как бы снимает "блокировку" протяженности, т. е. позволяет изменять значения протяженностей. В этом его отличие от полностью принудительных метрических режимов отображения. Например, предположим, используется режим отображения MM_LOENGLISH, и требуется, чтобы логическая единица измерения равнялась 0.01 дюйма. Причем нежелательно, чтобы значения по координате y увеличивались при движении вверх, нужно, чтобы, как в режиме MM_TEXT, значения координаты y увеличивались при движении вниз. Ниже приведен код, реализующий это:

SIZE size;

[другие строки программы]

SetMapMode(hdc, MM_LOENGLISH); SetMapMode(hdc, MM_ANISOTROPIC);

GetViewportExtEx(hdc, &size);

SetViewportExtEx(hdc, size.cx, -size.cy, NULL );

Сначала мы устанавливаем режим отображения MM_LOENGLISH. Затем мы даем возможность изменять протяженности, устанавливая режим отображения MM_ANISOTROPIC. Функция GetViewportExtEx записывает протяженности области вывода в поля структуры SIZE. Затем мы вызываем функцию SetViewportExtEx с теми же значениями протяженностей, за исключением того, что протяженность по оси y делается отрицательной.

Программа WHATSIZE

Мы будем использовать различные режимы отображения по мере того, как будем далее изучать функции GDI в следующих главах. Сейчас же давайте взглянем на размер рабочей области в терминах дюймов и миллиметров. Программа WHATSIZE, приведенная на рис. 4.19, отображает размер рабочей области в терминах единиц, ассоциированных с шестью полностью принудительными режимами отображения: MM_TEXT, MM_LOMETRIC, MM_HIMETRIC, MM_LOENGLISH, MM_HIENGLISH и MM_TWIPS.

WHATSIZE.MAK

#------------------------

# WHATSIZE.MAK make file

#------------------------

110

whatsize.exe : whatsize.obj

$(LINKER) $(GUIFLAGS) -OUT:whatsize.exe whatsize.obj $(GUILIBS)

whatsize.obj : whatsize.c

$(CC) $(CFLAGS) whatsize.c

WHATSIZE.C

/*-----------------------------------------

WHATSIZE.C -- What Size is the Window?

(c) Charles Petzold, 1996

-----------------------------------------*/

#include <windows.h> #include <stdio.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)

{

static char szAppName[] = "WhatSize";

HWND

hwnd;

MSG

msg;

WNDCLASSEX

wndclass;

wndclass.cbSize

= sizeof(wndclass);

wndclass.style

= CS_HREDRAW | CS_VREDRAW;

wndclass.lpfnWndProc

= WndProc;

wndclass.cbClsExtra

= 0;

wndclass.cbWndExtra

= 0;

wndclass.hInstance

= hInstance;

wndclass.hIcon

= LoadIcon(NULL, IDI_APPLICATION);

wndclass.hCursor

= LoadCursor(NULL, IDC_ARROW);

wndclass.hbrBackground

=(HBRUSH) GetStockObject(WHITE_BRUSH);

wndclass.lpszMenuName

= NULL;

wndclass.lpszClassName

= szAppName;

wndclass.hIconSm

= LoadIcon(NULL, IDI_APPLICATION);

RegisterClassEx(&wndclass);

hwnd = CreateWindow(szAppName, "What Size is the Window?", WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT, CW_USEDEFAULT,

CW_USEDEFAULT, CW_USEDEFAULT,

NULL, NULL, hInstance, NULL);

ShowWindow(hwnd, iCmdShow);

UpdateWindow(hwnd);

while(GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

return msg.wParam;

}

void Show(HWND hwnd, HDC hdc, int xText, int yText, int iMapMode, char *szMapMode)

{

char szBuffer [60]; RECT rect;

SaveDC(hdc);

111

SetMapMode(hdc, iMapMode);

GetClientRect(hwnd, &rect);

DPtoLP(hdc,(PPOINT) &rect, 2);

RestoreDC(hdc, -1);

TextOut(hdc, xText, yText, szBuffer,

sprintf(szBuffer, "%-20s %7d %7d %7d %7d", szMapMode, rect.left, rect.right, rect.top, rect.bottom));

}

LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)

{

 

 

 

 

 

static char

szHeading [] =

 

 

 

 

 

"Mapping Mode

Left

Right

Top

Bottom";

static char

szUndLine [] =

 

 

 

 

 

"------------

----

-----

---

------";

static int

cxChar, cyChar;

 

 

 

 

HDC

hdc;

 

 

 

 

PAINTSTRUCT

ps;

 

 

 

 

TEXTMETRIC

tm;

 

 

 

 

switch(iMsg)

{

case WM_CREATE:

hdc = GetDC(hwnd);

SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));

GetTextMetrics(hdc, &tm); cxChar = tm.tmAveCharWidth;

cyChar = tm.tmHeight + tm.tmExternalLeading;

ReleaseDC(hwnd, hdc); return 0;

case WM_PAINT:

hdc = BeginPaint(hwnd, &ps);

SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));

SetMapMode(hdc, MM_ANISOTROPIC);

SetWindowExtEx(hdc, 1, 1, NULL);

SetViewportExtEx(hdc, cxChar, cyChar, NULL);

TextOut(hdc, 1, 1, szHeading, sizeof szHeading - 1);

TextOut(hdc, 1, 2, szUndLine, sizeof szUndLine - 1);

Show(hwnd, hdc, 1, 3, MM_TEXT,

"TEXT(pixels)");

Show(hwnd, hdc, 1, 4, MM_LOMETRIC,

"LOMETRIC(.1 mm)");

Show(hwnd, hdc, 1, 5, MM_HIMETRIC,

"HIMETRIC(.01 mm)");

Show(hwnd, hdc, 1, 6, MM_LOENGLISH,

"LOENGLISH(.01 in)");

Show(hwnd, hdc, 1, 7, MM_HIENGLISH,

"HIENGLISH(.001 in)");

Show(hwnd, hdc, 1, 8, MM_TWIPS,

"TWIPS(1/1440 in)");

EndPaint(hwnd, &ps); return 0;

case WM_DESTROY: PostQuitMessage(0); return 0;

}

return DefWindowProc(hwnd, iMsg, wParam, lParam);

}

Рис. 4.19 Программа WHATSIZE

Для упрощения вывода информации с использованием функции TextOut программа WHATSIZE использует режим отображения MM_ANISOTROPIC с логическими координатами, установленными на базе размеров символа:

Соседние файлы в предмете Операционные системы