// Done by TheTutor -- 6/30/01 (Updated Last: 9/29/02)
// Перевод © 2004 Евгений Казеко
// www.gamecoder.kazeko.com
// evgeniy@kazeko.com
/* Сейчас мы будем рисовать с использованием HPEN --
HPEN это ничто иное, как указатель на "перо".
Очень важно знать, что мы можем рисовать с использованием HPEN
*/
#include <windows.h>
#define WIN_WIDTH 320
#define WIN_HEIGHT 240
// Глобальные переменные ---
HDC hdc; // Это будет глобальный контекст устройства (для рисования)
// Стандартная callback функция
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprev, PSTR cmdline, int ishow)
{
char class_name[] = "GameTutorials";
HWND hwnd;
MSG msg;
WNDCLASSEX wndclassex = {0};
// Заполняем нужные нам поля
wndclassex.cbSize = sizeof(WNDCLASSEX);
wndclassex.style = CS_HREDRAW | CS_VREDRAW;
wndclassex.lpfnWndProc = WinProc;
wndclassex.hInstance = hinstance;
wndclassex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclassex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclassex.lpszClassName = class_name;
RegisterClassEx(&wndclassex); // Регистрируем окно
hwnd = CreateWindowEx(NULL, // Нет дополнительных атрибутов окна
class_name,
"Drawing with HPENs",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, // Окно будет размещаться с координатой x по умолчанию
CW_USEDEFAULT, // Окно будет размещаться с координатой y по умолчанию
WIN_WIDTH,
WIN_HEIGHT,
NULL,
NULL,
hinstance,
NULL);
// Проверка на ошибку
if(!hwnd)
return EXIT_FAILURE; // Случилось что-то плохое
hdc = GetDC(hwnd); // Получаем контекст устройства окна
// Проверка на ошибку
if(!hdc)
return EXIT_FAILURE; // Не можем получить hdc окна
ShowWindow(hwnd, ishow);
UpdateWindow(hwnd);
while(1)
{
// Получить сообщения, если они есть
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
// Здесь можно проводить сложные расчеты
}
}
// Освободить глобальный HDC
ReleaseDC(hwnd,hdc);
return msg.wParam;
}
// Оконная процедура
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
HPEN hpen; // Это наше "перо" hpen, которым мы будем рисовать
HPEN old_pen; // Будет использоваться для сохранения "старого пера"
// Нам нужно сохранить его, чтобы мы могли освободить память
// после рисования
PAINTSTRUCT ps;
// В зависимости от сообщения выполняем различные действия
switch(message)
{
// Это сообщение посылается каждый раз при нажатии клавиши
case WM_KEYDOWN:
switch(wparam) // wparam сохраняет виртуальный код нажатой клавиши
{
case VK_F1: // Если нажата клавиша 'F1'
// Создаем сплошное (solid) перо "шириной 5 логических блоков"
// и цветом Red=75, Green=175, Blue=255
hpen = CreatePen(PS_SOLID,5,RGB(75,175,255));
old_pen = (HPEN)SelectObject(hdc,hpen);
/* Эта функция делает то, что вы и ожидаете, она рисует эллипс,
используя текущий HPEN в качестве границы эллипса.
hdc это контекст устройства, где нужно рисовать.
30,30 (x,y) это верхний левый угол прямоугольника,
в который вписывается эллипс.
130,130 (x,y) это нижний правый угол.
*/
Ellipse(hdc,30,30,130,130);
// Мы нарисовали то, что хотели - освободим память
SelectObject(hdc,old_pen); // Сперва выберем "обратно" старое перо
DeleteObject(hpen); // А затем удалим перо, которое создали
break;
case VK_F2: // Если нажата клавиша 'F2'
// Создаем пунктирное перо "шириной 1 логический блок" --
// PS_DASH работает только с перьями шириной 1 или меньше
hpen = CreatePen(PS_DASH,1,RGB(175,75,2));
old_pen = (HPEN)SelectObject(hdc,hpen);
Ellipse(hdc,70,50,90,115);
// Освобождаем память
SelectObject(hdc,old_pen);
DeleteObject(hpen);
break;
case VK_F3: // Если нажата клавиша 'F3'
// Создаем пунктирное перо "шириной 1 логический блок"
// PS_DOT работает только с перьями шириной 1 или меньше
hpen = CreatePen(PS_DOT,1,RGB(255,15,20));
old_pen = (HPEN)SelectObject(hdc,hpen);
Ellipse(hdc,120,120,180,180);
// Освобождаем память
SelectObject(hdc,old_pen);
DeleteObject(hpen);
break;
}
return 0;
case WM_PAINT:
BeginPaint(hwnd,&ps);
EndPaint(hwnd,&ps);
return 0;
case WM_DESTROY:
case WM_CLOSE:
PostQuitMessage(0);
return 0;
} // конец switch(message)
return DefWindowProc(hwnd, message, wparam, lparam);
}
/* Еще немного о перьях...
Есть два других стиля пера, которые оба требуют ширину 1 логический блок.
Вот они:
PS_DASHDOT - Пунктир из точек и черточек
PS_DASHDOTDOT - Пунктир из черточек и двух точек
*/
/*
| TheTutor
| thetutor@gametutorials.com
| © 2000-2002 GameTutorials
*/
// Перевод © 2004 Евгений Казеко
// www.gamecoder.kazeko.com
// evgeniy@kazeko.com
|