Помощь - Поиск - Пользователи - Календарь
Полная версия: Графический режим
Форум «Всё о Паскале» > Pascal, Object Pascal > 32 битные компиляторы
Bokul
Не знаю проблемы у меня или в модуле Wingraph или еще в чем-то, но не всегда получается отловить нажатие кнопки мыши, а после readkey графическое окно вообще перестает реагировать на другие события. sad.gif

Как я пытаюсь работать с мышой:
 
repeat
if PollMouseEvent(MEvent) then
begin
GetMouseEvent(MEvent);
MouseX:=MEvent.x; MouseY:=MEvent.y;
if (MouseX <> x0) or (MouseY <> y0) then
begin
x0:=MouseX; y0:=MouseY;
if (MEvent.action=MouseActionDown) or (keypressed) then
Arrow.StartNew
else
Arrow.ChangePosition(round(MouseX/step)*step,
round(MouseY/step)*step);
end;
Delay(1);
end;
until CloseGraphRequest;
CloseGraph;


Полный исходник: Нажмите для просмотра прикрепленного файла
При каждом нажатии любой кнопки мыши шарик, который постоянно бегает за курсором, должен оставаться на том месте, где была нажата клавиша, но это происходит далеко не всегда sad.gif .
Если проблемы в коде укажите, пожалуйста, ошибку, в противном случае - подскажите другие модуле с такими же функциями или другие способы работы с мышой в граф. режиме. Отдельно интересует такая возможность используя WinApi.
volvo
Погоди, а зачем PollMouseEvent? Насколько я помню, можно просто вот по такому шаблону:
uses WinCrt, WinMouse, Graph;
...
flag := false;
repeat
GetMouseState(x, y, State);

If (State and LButton) = LButton Then // чего-то там делать, было нажатие

If ( State and RButton ) = RButton Then // ну, а по правому клику - выход
flag := true;

until flag;
Bokul
Цитата
Погоди, а зачем PollMouseEvent?

Эта функция проверяет есть ли новые события, а GetMouseEvent уже читает их. Почему не использовать просто GetMouseEvent? Потому что она не отдаст управление программе пока сама не выполнится, т.е. пока не считает Event:

procedure GetMouseEvent(out MouseEvent:MouseEventType);
begin
while (nr_readmouse = nr_inputmouse) do Sleep(10);<---!!!!!
EnterCriticalSection(protect_mouse);
PollMouseEvent(MouseEvent);
IncMouseCyclic(nr_readmouse);
LeaveCriticalSection(protect_mouse);
end;



Цитата
Насколько я помню, можно просто вот по такому шаблону

Имена процедур действительны или ты просто привел для примера?
uses WinCrt, WinMouse, Graph;

Может wingraph?
Volvo, ты пробовал запускать мою прогу? Если да, то у тебя такие же проблемы как и у меня?
volvo
Во-первых, я ничего просто
Цитата
для примера
не привожу, и если я написал GetMouseState, значит, я имел в виду именно ее, а не GetMouseEvent... А во-вторых, WinGraph в стандартной поставке FPC не присутствует, а я не пользуюсь чьими-то дополнительными костылями... Именно Graph

Да, я запускал твою программу, и она у меня просто не всегда определяет нажатие кнопки мыши, а в логике работы я не разобрался, еще не совсем отошел от 3-х дневной температуры 39.5, как смогу - попробую написать точнее, что можно сделать...
Bokul
А можно поинтересоваться- почему стандартный модуль mouse не работает со стандартным модулем graph?
Цитата
еще не совсем отошел от 3-х дневной температуры 39.5

Давай выздоравливай!
volvo
Ну, модуль Graph я тоже не знаю, зачем поддерживается в FPC... Можно было и забыть уже про него - это ж только для совместимости с TP/BP, а так есть же GL/GLUT в стандартной поставке (согласись, то, что можно создать в GLUT обычному Графу и не снилось)... yes2.gif

А вообще-то я в FreePascal Community наткнулся на интересный способ работы с мышью - от некоего Sampsa Seppälä, который предлагал вот такое:

uses windows;
var
mpos: tpoint;

...
getcursorpos(mpos);
write(mpos.x, mpos.y); { mouse cordinates }
if getasynckeystate(1) < 0 then { mouse button pressed }
...

(не проверял, но выглядит вполне работоспособно)
Bokul
Цитата
(не проверял, но выглядит вполне работоспособно)

Работает! good.gif
Можно ссылочку на полное описание процедуры? 10.gif А где модуль windows описан?
Цитата
а так есть же GL/GLUT в стандартной поставке (согласись, то, что можно создать в GLUT обычному Графу и не снилось).

А как они называются? Ибо у себя (ни в папке units, ни в документации) найти их не могу.
volvo
blink.gif blink.gif У тебя в папке "FPC\units\i386-win32\opengl" нет файлов GL.*, GLU.*, GLUT.* ? Значит, "неправильный мед" (С) - качай правильный...

Ну, а описание модуля Windows - это как всегда: msdn.microsoft.com (там все те же функции из WinAPI, только в фри-паскальной обертке)

Цитата
Можно ссылочку на полное описание процедуры?
А более полного там и не было - все, что было - я привел... Вот здесь брал: Mouse unit not working..?
Bokul
Нет, мед - правильный, это у меня что-то неправильно.. smile.gif
Цитата
У тебя в папке "FPC\units\i386-win32\opengl" нет файлов GL.*, GLU.*, GLUT.*

А документация по нему отдельно идет или как?
volvo
yes2.gif Лучше всего - в виде "OpenGL Programming Guide (Addison-Wesley Publishing Company)
RedBook: Second Edition (The Official Guide to Learning OpenGL)" - довольно полное и понятное (по-английски, разумеется) описание основных функций с примерами использования...

По форуму пошерсти, по-моему тоже что-то на тему OpenGL проскальзывало...
SKVOZNJAK
Тема обработки событий уже жевалась, и не на одном форуме. http://www.freepascal.ru/forum/viewtopic.p...38ff0c577841999 SDL - в нём и видео и обработка событий. Сейчас забросил в каталог файл sdl.dll и заработало под виндовсом. Всё просто. Функцией SDL_PollEvent записываем в переменную события а потом вытаскиваем нужное. И клик мышкой и координаты курсора, всё сразу записано в одной переменной.
Bokul
SKVOZNJAK, можешь чуть подробнее объяснить? Почему ты мне даешь модуль с видеорежимом? Мне же просто графический надо.. какая разница между ними? Пробовал запустить твой код с последнего месседжа - не вышло: компиляция проходит успешно, но потом, во время выполнения, вылетает с 309 ошибкой.
SKVOZNJAK
Да, наверно никакой, так назвалось. И последний и предпоследний пример в 2.0.2 версии у меня запустились. Спешил, не было времени другую демку делать. Версий причин неполадок у меня 3:
1 Пример выводит на экран картинку BMP. Программа могла не найти в текущем каталоге графический файл указанного разрешения и имени файла.
2
screen := SDL_SetVideoMode(width, height, colordepth, (SDL_FULLSCREEN + SDL_SWSURFACE));
Последний параметр в функции, сумма констант, маска. Она определяет многое, можно убирать лишние и прибавлять дополнительные константы. Если убрать SDL_FULLSCREEN, окно будет не полноэкранным. SDL_SWSURFACE - тип используемой видеорежимом памяти, можно использовать другой, прибавить константы - двойная буферизация, опенгл. Но с последней константой у меня не работало. Попробуй использовать другой тип памяти.
3 У тебя железо тянет глубину цветности 32 бита? Можно и 16 и 8 поставить.

Пример с пояснениями, без картинок. Кодировка перепуталась, но в иде норм видно.

program demo;

uses
SDL, SDL_Video, SDL_Events, SDL_Mouse, crt;

const
width = 800;
height = 600;

{Ј«гЎЁ­  梥⭮бвЁ}
colordepth = 32;

var
screen: PSDL_Surface;
event: PSDL_Event;
done: Boolean;
XX,YY,q,w : word;


{Ґб«Ё Ј«гЎЁ­  梥⭮бвЁ 16 ЎЁв, ЁбЇ®«м§®ў вм вЁЇ word, 8 - byte}
Type
Pixel = cardinal ; { Must have colordepth bits }

Type {ЎгдҐа ў Є®в®а®¬ Ўг¤Ґ¬ аЁб®ў вм Ја дЁЄг}
{ This type mimics the pixel surface srtucture: 'height' sequential rows
of 'width' pixels each. }
TpixelBuf = Array [0..height-1, 0..width-1] of Pixel ;


var zzz: Pixel;


begin

SDL_Init(SDL_INIT_VIDEO);
event := new(PSDL_Event);

{Ё­ЁжЁ «Ё§ жЁп Ја д ०Ё¬ , ў ЇҐаҐ¬Ґ­­го screen § ЇЁблў овбп Ї а ¬Ґвал Ја д ®Є­  }
screen := SDL_SetVideoMode(width, height, colordepth, ({SDL_FULLSCREEN +} SDL_SWSURFACE));

if screen = nil then
begin
writeLn ('Couldn''t initialize video mode at ', width, 'x', height, 'x', colordepth, 'bpp');
halt(1);
end;

{Ё§ в Ў«Ёжл 梥⮢ нв®Ј® ўЁ¤Ґ®аҐ¦Ё¬  ўлЎЁа Ґ¬ ­г¦­л© § ЇЁблў п ҐЈ® Єа б­®Ґ,
§Ґ«с­®Ґ Ё бЁ­ҐҐ §­ зҐ­ЁҐ - ЎЁвҐ}
zzz:=SDL_MapRGB(screen^.format, 255,0,255);


{§ ЇЁблў Ґ¬ ў ЎгдҐа Ї® Є®®а¤Ё­ в ¬ е=400, г=200 дЁ®«Ґв®ўго в®зЄг}
Tpixelbuf(screen^.pixels^)[200,400] :=zzz;


{Ґб«Ё Ї®б«Ґ¤­ЁҐ 4 Ї а ¬Ґва  =0 - ®Ў­®ў«пҐвбп нЄа ­, в®Ј¤  в®зЄ  Ї®Ї ¤св ­  нЄа ­}
SDL_updateRect(screen, 0, 0, 0, 0);


Tpixelbuf(screen^.pixels^)[200,100] := SDL_MapRGB(screen^.format, 255,255,255);
Tpixelbuf(screen^.pixels^)[300,400] := SDL_MapRGB(screen^.format, 0,255,0);
delay(3000);
SDL_updateRect(screen, 0, 0, 0, 0);


done := FALSE;
while (done = FALSE) do
begin
if (SDL_PollEvent(event) > 0) then
begin
CASE event^.eventtype OF

{Їа®Ё§®и«® б®ЎлвЁҐ - ­ ¦ вЁҐ ­  Є« ўг}
SDL_KEYDOWN :begin
{зЁв Ґ¬ § ЇЁб ­­л© бЄ ­Є®¤ ­ ¦ в®© Є« ўл}
xx:= event^.Key.keysym.sym ;
w:=1;
done := TRUE;
end;
{Їа®Ё§®и«® б®ЎлвЁҐ - ­ ¦ вЁҐ ­  Є­®ЇЄг Єалбл}
SDL_MOUSEBUTTONDOWN : begin
{зЁв Ґ¬ § ЇЁб ­­лҐ Є®®а¤Ё­ вл Єгаб®а  ­  ¬®¬Ґ­в Є«ЁЄ }
xx:=event^.MOTION.x;
yy:=event^.MOTION.y;
q:=1;
done := TRUE;
end;
end;
end;
end;


{ў®§ўа йҐ­ЁҐ нЄа ­г ҐЈ® த­®Ј® а §аҐиҐ­Ёп}
SDL_freeSurface(screen);
SDL_Quit ;



if q=1 then writeln('x Ї®§ЁжЁп Єгаб®а  ', xx,', y Ї®§ЁжЁп Єгаб®а  ',yy);
if w=1 then writeln('Ўл«  ­ ¦ в  Є« ў , Ґс бЄ ­Є®¤ ',xx);

delay(5000);

writeln('rfrjq tynj dsvjhf;bdf.obq vfhfpv nsrfnm d dbylt vbrhjcrjgbxtcrbt cbvdjks');



end.

Ни одного гото не используется, почти подвиг smile.gif В принципе, поправить кодировочку и можно на хранение в фак, в рунете с примерами к SDL - совсем не густо.
Bokul
Цитата
3 У тебя железо тянет глубину цветности 32 бита?

Обижаешь. smile.gif

Нет, ты не угадал. А дело было так: наверное, Fpc не проверяет существование dll-ок на этапе компиляции и по-этому не сообщает о их отсутствии, что приводит к ошибки время выполнения.

Цитата
В принципе, поправить кодировочку и можно на хранение в фак, в рунете с примерами к SDL - совсем не густо.

А сам изменить кодировку не хочешь? rolleyes.gif

Большое спасибо за пример, все работает отлично. good.gif

P.S. первому варианту можно давать любую bmp-шку?
P.P.S. в документации (user.pdf - Run Time errors) не нашёл 309-ой. Откуда она взялась?
P.P.P.S может действительно начать делать Faq по FreePascal?
volvo
Цитата
P.P.S. в документации (user.pdf - Run Time errors) не нашёл 309-ой. Откуда она взялась?
Сообщение об ошибке - военная тайна? С твоих слов, например, непонятно, ошибка ли это FPC/SDL/Windows?
Bokul
Цитата
С твоих слов, например, непонятно, ошибка ли это FPC/SDL/Windows?

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

volvo, что думаешь насчет Faq?
volvo
Цитата(Bokul @ 4.01.2007 10:27)
Как выяснить какая?
rolleyes.gif

http://userpage.fu-berlin.de/~molski/fpsdl...pitel/kap1.html
(последний параграф)

Цитата(Bokul @ 4.01.2007 10:27)
что думаешь насчет Faq?

Что именно ты хочешь чтобы было в FAQ-е? Кое-какие вещи уже описывались, если есть что-то что интересует больше десятка людей (пока я не вижу особенного интереса к FPC, в основном те, кто приходит хотят программу на TP, потому что "именно на TP у него будут принимать", а делать просто так, чтобы было, не очень-то охота), и этого нельзя найти в доках - можно и написать...
Bokul
Цитата
(последний параграф)

lol.gif

Цитата
Кое-какие вещи уже описывались, если есть что-то что интересует больше десятка людей

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

Цитата
кто приходит хотят программу на TP, потому что "именно на TP у него будут принимать", а делать просто так, чтобы было, не очень-то охота

А те кто остаются встречаются с проблемой нехватки информации о FPC. Обычно на TP программируют люди, которым программирование ** не надо или которые еще не попробовали FPC, но достаточно хорошо знают TP. Так для последних и надо сделать.

Цитата
и этого нельзя найти в доках - можно и написать...

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

Цитата
Что именно ты хочешь чтобы было в FAQ-е?

Продолжить уже начатую тобой Altair-ом работу, создать отдельный раздел. Ну пока можно ограничиться составлением списка вопросов. Если хочешь можно создать тему, где все это обговорим?
volvo
Создавай smile.gif
SKVOZNJAK
Цитата(Bokul @ 4.01.2007 4:35) *


P.S. первому варианту можно давать любую bmp-шку?



Практически, хоть ХХХ smile.gif Я скачивал прикольные каринки, смотрел в паинте разрешение, сохранял как bmp и подставлял в исходник нужное разрешение и имя файла.
Ozzя
Цитата(Bokul @ 4.01.2007 20:28) *



А те кто остаются встречаются с проблемой нехватки информации о FPC. Обычно на TP программируют люди, которым программирование ** не надо или которые еще не попробовали FPC, но достаточно хорошо знают TP. Так для последних и надо сделать.



Не обязательно. Мне, например, для занятий нужен лицензионно чистый паскаль (ТП7 отпадает) с ИДЕ, как у тп7 (отпадают Дельфи (6ПЕ и Турбо), ТП5.5, Дев-Паскаль, Паскаль-АБС, ТМТ 3.9) и с поддержкой модуля Graph (WinGraph) (отпадает vp). И остается только fpc
Bokul
Цитата
И остается только fpc

Ozzя, а же о этом и писал..
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.