Для демонстрации обработки сообщения WM_LBUTTONDOWN , поступающего при нажатии левой кнопки мыши, разработаем программу, выводящую на экран компьютера кустарник, состоящий из отдельных кустов. При каждом нажатии левой кнопки мыши она будет выводить куст, корень которого находится в позиции, указанной курсором мыши. Листья кустарника будем изображать зеленым цветом, с помощью функции Ellipse(). Поскольку внутренние точки эллипса окрашиваются цветом кисти, то необходимо определить кисть. Для этого вызовем функции
Hgreenbrush = CreateSolidBrush (RGB(0,255,0));
hbrush = SelectObject (hdc,hgreenbrush);
возвращающие значения, определенные с помощью
HBRUSH hgreenbrush,hbrush;
где hdc – контекст устройства.
Цвет шаблона восстанавливается с помощью вызова функции
SelectObject(hdc,hbrush);
Разработаем рекурсивную подпрограмму, выводящую на экран куст, состоящий из ствола, веток и листьев (рис. 2.9). Из конца каждой ветки (и из конца ствола) выходят две ветки, углы между которыми и длины которых вычисляются случайным образом (рис. 2.10). Рекурсивная функция будет иметь следующий прототип:
void tree (HDC dc, float x, float y, float l, float phi);
где dc – контекст устройства, (х,у) – координаты начала ветки, l – длина ветки, phi – угол между веткой и осью абсцисс.
Рис. 2.9. Куст

Рис. 2.10. Ветка
Эта функция выводит отрезок длины l, соединяющий точки (x,y) и (x+lcos, y+lsin
), а потом вызывает себя два раза, передавая параметры таким образом, что при первом вызове рисуется ветка длины rn(l)*0.8, под углом
+rn(
/50), а при втором — длины rn(l)*0.8 под углом
-rn(
/50). Здесь rn(x) – функция, значениями которой являются случайные числа t, равномерно распределённые в интервале
. Когда длина ветки не превышает одного пиксела, то выводится лист ( круг радиуса 5).
Программа
#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
LRESULT CALLBACK WindowFunc(HWND,UINT,WPARAM,LPARAM);
char szwinname[] = "MyWindow";
int maxX,maxY;
int i=0;
POINT pnts[4];
HDC memdc;
HBITMAP hbit;
int WINAPI WinMain(HINSTANCE hthisinst, HINSTANCE hprevinst,
LPSTR lpszargs, int nwinmode)
{
HWND hwnd;
MSG msg;
WNDCLASS wcl;
HACCEL haccel;
wcl.hInstance = hthisinst;
wcl.lpszClassName = szwinname;
wcl.lpfnWndProc= WindowFunc;
wcl.style = 0;
wcl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wcl.hCursor = LoadCursor(NULL,IDC_ARROW);
wcl.lpszMenuName = NULL;
wcl.cbClsExtra = 0;
wcl.cbWndExtra = 0;
wcl.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
if(!RegisterClass(&wcl)) return 0;
hwnd = CreateWindow(szwinname, "Tree",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 600, 600,
HWND_DESKTOP, NULL, hthisinst, NULL);
haccel=LoadAccelerators(hthisinst,NULL);
ShowWindow(hwnd,nwinmode);
UpdateWindow(hwnd);
SetTimer(hwnd,1,30,NULL);
while(GetMessage(&msg,NULL,0,0))
{
if(!TranslateAccelerator(hwnd,haccel,&msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
KillTimer(hwnd,1);
return msg.wParam;
}
// генерация случайного числа из отрезка (0.5x, x)
float rn(float x)
{
return x*(500.+rand()%500)/1000;
}
// рекурсивная функция вывода дерева
void tree(HDC dc,float x, float y, float l, float phi)
{
if(l<=1) Ellipse(dc,x-5,y-5,x+5,y+5);// вывод листа
else
{
MoveToEx(dc,x,y,NULL);
LineTo(dc,x+l*cos(phi), y+l*sin(phi));// вывод ветки
tree(dc,x+l*cos(phi), y+l*sin(phi),rn(l)*0.8, phi+rn(3.14/5));
tree(dc,x+l*cos(phi), y+l*sin(phi),rn(l)*0.9, phi-rn(3.14/5));
}
}
LRESULT CALLBACK WindowFunc(HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
static HDC hdc;
double phi;
double r=100;
static HBRUSH hbrush;
static HBRUSH hgreenbrush;
switch(message)
{
case WM_CREATE:
maxX= 600;
maxY= 600;
hdc = GetDC (hwnd);
hgreenbrush = CreateSolidBrush(RGB(0,255,0));
hbrush = (HBRUSH)SelectObject(hdc, hgreenbrush);
break;
case WM_LBUTTONDOWN:
randomize();
tree(hdc,LOWORD(lParam) ,HIWORD(lParam),
(0.+maxY)/5, -3.14/2);
break;
case WM_DESTROY:
SelectObject(hdc, hbrush);
ReleaseDC(hwnd,hdc);
DeleteObject(hgreenbrush);
DeleteObject(hbrush);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,message,wParam,lParam);
}
return 0;
}
Результаты работы программы приведены на рис. 2.11.
Рис. 2.11. Кустарник