IPB
ЛогинПароль:

> ВНИМАНИЕ!

Прежде чем задать вопрос, смотрите FAQ.
Рекомендуем загрузить DRKB.

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

 
 Ответить  Открыть новую тему 
> WinAPI для простой графики
сообщение
Сообщение #1


Новичок
*

Группа: Пользователи
Сообщений: 16
Пол: Женский

Репутация: -  0  +


Как практически с помощью функций WinAPI нарисовать мячик, который бы двигался горизонтально в прямоугольнике вправо-влево, "отскакивая" от боковых стенок, "пинг-понг" - ? smile.gif

Сообщение отредактировано: KljaGGsa -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гость






Что именно вызывает затруднения? Рисуем шарик с помощью Ellipse, сам прямоугольник - Rectangle. Написать программу, которая будет проверять, не выходит ли шарик за пределы прямоугольника, и если выходит - изменить направление движения - не должно составить большой проблемы.

Начинай, если что непонятно - говори, что именно.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Новичок
*

Группа: Пользователи
Сообщений: 16
Пол: Женский

Репутация: -  0  +


В обычном пейнтбоксе и канвасе это действительно несложно, а вот как применить API сколько литературы не читаю, и бумажной и электронной, найти не могу . . . (((


Сообщение отредактировано: KljaGGsa -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






Так тебе совсем WinAPI-шное приложение надо, без VCL? Ну, тогда так, к примеру:
program Project1;

uses
Windows, Messages;

const
WM_SETUP = 500;

WinName = 'MainWClass';
R = 5;

var
myTimer: THandle;
delta: integer;
Rec: TRect;
posX, posY: integer;

function MainWndProc(Window: HWnd; AMessage: UINT; WParam: WPARAM; LParam: LPARAM): INT_PTR; stdcall;
var
myDC: HDC;
ps: PAINTSTRUCT;
begin
case AMessage of
WM_CREATE: // Создание окна
begin
myTimer := SetTimer(Window, 0, 1, nil);
Result := 0; Exit;
end;
WM_SETUP: // "Установка" начальных значений
begin
myDC := GetDC(Window);
GetClientRect(Window, Rec);
posX := 0; posY := (Rec.Bottom - Rec.Top) div 2; delta := 5;
ReleaseDC(Window, myDC);
Result := 0; Exit;
end;
WM_SIZE: // Изменение размеров окна
begin
PostMessage(Window, WM_SETUP, 0, 0); // Просто вызываем "установку"
Result := 0; Exit;
end;
WM_PAINT:
begin
myDC := BeginPaint(Window, ps);
PostMessage(Window, WM_SETUP, 0, 0); // Тоже "установка"
EndPaint(Window, ps);
Result := 0; Exit;
end;
WM_TIMER: // Событие таймера
begin
myDC := GetDC(Window);
// стираем старое изображение шарика
SelectObject(myDC, GetStockObject(WHITE_PEN));
Ellipse(myDC, posX - R, posY - R, posX + R, posY + R);

if ((delta > 0) and (posX + delta + R > (Rec.Right - Rec.Left)))
or
((delta < 0) and (posX - delta - R < 0))
then delta := -delta;
posX := posX + delta;

// и рисуем в новых координатах новое
SelectObject(myDC, GetStockObject(BLACK_PEN));
Ellipse(myDC, posX - R, posY - R, posX + R, posY + R);
ReleaseDC(Window, myDC);
Result := 0; Exit;
end;
WM_DESTROY: // Уничтожение окна
begin
KillTimer(Window, myTimer);
PostQuitMessage(0);
Result := 0; Exit;
end;
else
Result := DefWindowProc(Window, AMessage, WParam, LParam);
end;
end;

function InitApplication: Boolean;
var
wcx: TWndClass;
begin
wcx.style := CS_HREDRAW or CS_VREDRAW;
wcx.lpfnWndProc := @MainWndProc;
wcx.cbClsExtra := 0;
wcx.cbWndExtra := 0;
wcx.hInstance := hInstance;
wcx.hIcon := LoadIcon(0, IDI_APPLICATION);
wcx.hCursor := LoadCursor(0, IDC_ARROW);
wcx.hbrBackground := COLOR_WINDOW;
wcx.lpszMenuName := nil;
wcx.lpszClassName := PChar(WinName);

Result := RegisterClass(wcx) <> 0;
end;

function InitInstance: HWND;
begin
Result := CreateWindow(
PChar(WinName),
'Ping-pong',
WS_OVERLAPPEDWINDOW,
Integer(CW_USEDEFAULT),
Integer(CW_USEDEFAULT),
Integer(CW_USEDEFAULT),
Integer(CW_USEDEFAULT),
0, 0, hInstance, nil);
end;

var
hwndMain: HWND;
AMessage: msg;
begin
if (not InitApplication) then begin
MessageBox(0, 'Ошибка регистрации окна', nil, mb_Ok)
end
else begin
hwndMain := InitInstance;
if (hwndMain = 0) then begin
MessageBox(0, 'Ошибка создания окна', nil, mb_Ok)
end
else begin
ShowWindow(hwndMain, CmdShow);
UpdateWindow(hwndMain);
while (GetMessage(AMessage, 0, 0, 0)) do begin
TranslateMessage(AMessage);
DispatchMessage(AMessage);
end;
end;
end;

end.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Профи
****

Группа: Пользователи
Сообщений: 865
Пол: Мужской
Реальное имя: Вячеслав

Репутация: -  20  +


Это же не простой проект. Куда надо это скопировать?

Сообщение отредактировано: Client -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гость






Цитата
Это же не простой проект. Куда надо это скопировать?
blink.gif Это не простой, это простейший проект. Надо создать новое консольное приложение, и заменить код, предлагаемый Дельфями на код, приведенный выше.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Профи
****

Группа: Пользователи
Сообщений: 865
Пол: Мужской
Реальное имя: Вячеслав

Репутация: -  20  +


Цитата
Это не простой, это простейший проект
В смысле что там нету формы куда ложить кнопки, едиты....


Эскизы прикрепленных изображений
Прикрепленное изображение
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Гость






Это WinAPI. Какие кнопки? Какие эдиты? VCL не используется.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Новичок
*

Группа: Пользователи
Сообщений: 16
Пол: Женский

Репутация: -  0  +


а я в полном шоке от этого кода, совершенно растерялась и вчера даже в эфир не вышла . . . Где взять справочный и учебный материал, который мог бы хоть поверхностно объяснить откуда здесь ноги растут??? blink.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Гость






Цитата
Где взять справочный и учебный материал, который мог бы хоть поверхностно объяснить откуда здесь ноги растут???
Ну, начнем с самого начала. Ты знаешь, как Windows-приложение взаимодействует с ОСью? Про механизм сообщений слышала?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Новичок
*

Группа: Пользователи
Сообщений: 16
Пол: Женский

Репутация: -  0  +


Нет, мне пока что это совсем незнакомо. Знаю только в первом приближении интерфейс оболочки Delphi7, основные свойства самых расхожих компонентов и простейшие алгоритмы их взаимодействия. Вот фрагмент вашего кода сразу бросился в глаза и удивил - какие-то сплошные сообщения, а не язык программирования: smile.gif

while (GetMessage(AMessage, 0, 0, 0)) do begin
TranslateMessage(AMessage);
DispatchMessage(AMessage);

 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Новичок
*

Группа: Пользователи
Сообщений: 16
Пол: Женский

Репутация: -  0  +


Хм, но что-то цель не получилось достичь. Прямое обращение к функциям операционки по идее должно дать быструю и эффективную (плавную) работу, а шарик на экране движется явно не лучше, чем если бы я его нарисовала эллипсом в канвасе и закрашивала бы каждый раз при единичном перемещении. Дискретность и дрыганье - те же самые...
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Гость






Цитата
сразу бросился в глаза и удивил - какие-то сплошные сообщения, а не язык программирования:
Вот именно это и есть основной цикл обработки сообщений. Перевожу на русский:
пока (есть_сообщения_для_окна)
транслировать_сообщение;
переслать_сообщение_оконной_функции;
А уже внутри оконной функции (та самая MainWndProc) анализируем, собственно, какое сообщение было получено, и что надо делать в связи с его получением.

P.S. А вот тут была? http://www.firststeps.ru/mfc/winapi/r.php?51 Там хоть и С рассматривается, но принцип работы Win-приложения прояснится...

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

Добавлено через 14 мин.
Цитата
шарик на экране движется явно не лучше, чем если бы я его нарисовала эллипсом в канвасе и закрашивала бы каждый раз при единичном перемещении.
Кстати, вопрос на засыпку: с чего ты взяла, что на WinAPI должно быть ЛУЧШЕ? То же самое рисование на канвасе, то же самое перемещение (только не единичное, а 5-ти единичное, что может послужить причиной "дерганья", нет DoubleBuffered, что тоже не улучшает визуализацию). Ты меня извини, конечно, но писать здесь полный код, работающий идеально, я считаю нецелесообразным. По нескольким причинам. Главная из которых - если тебя ЭТО уже вводит в ступор, то я представляю, куда тебя введет более сложный код.

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

Удачи.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Профи
****

Группа: Пользователи
Сообщений: 865
Пол: Мужской
Реальное имя: Вячеслав

Репутация: -  20  +


По той ссылке код для Си а примерах, а те функции и на Delphi работают? И только для консольного приложения или для VCL тоже?

Сообщение отредактировано: Client -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Новичок
*

Группа: Пользователи
Сообщений: 16
Пол: Женский

Репутация: -  0  +


Владимир, прямое обращение к функциям ОС меня заинтересовало потому что Вы здесь на форуме утверждали, что это принципиальная экономия тактов и загрузки процессора, а следовательно и увеличение быстродействия программы. Использовать WinAPI правильнее, чем пытаться оптимизировать алгоритмы в графических VCL. Теперь буду пытаться разобраться, на каком этапе возникает дискретность анимации. В моем варианте мячик пинг-понга движется с видимыми хотя и незначительными рывками примерно одинаково что в канвасе пейнтбокса, что в нарисованном Вами консольном поле. Процессор Core Duo Pro с соответствующей тактовой частотой, на который грех жаловаться, другие программы отключены, резидентно висит только самый необходимый минимум. И очень огорчаюсь, если Вас чем-то ненароком обидела .. blink.gif

Сообщение отредактировано: KljaGGsa -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Дерганье и правда присутствует, даже не дёрганье, а перемещение мячика как бы маленькими рывками. Это хорошо заметно, если поставить интервал таймера равным 500, например. Но для учебных целей этого более чем достаточно, по моему:) На WinAPI вроде бы программы ещё маленькие получаются...


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 2.05.2024 7:12
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name