Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник |
Коллекция курьезных вопросов из форумов
KOL и MCK |
KOL и MCK - Компактные программы на Delphi
Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / rsdn.org

 
Чтобы не потерять эту дискуссию, сделайте закладку « предыдущая ветвь | форум | следующая ветвь »

WM_LBUTTONDOWN


dmk ©   (28.03.17 06:30

Всем привет! Обрабатываю сообщение WM_LBUTTONDOWN. Транслирую его для дочернего класса без оконной процедуры. И естественно обработчик после того как послал 1 раз, воторой раз не приходит, пока не вызовешь Application.ProcessMessages.

А чем еще можно прокрутить очередь сообщений? Dispatch?
Или надо свой цикл выборки писать? Не хочется VCL :(


Игорь Шевченко ©   (28.03.17 10:16[1]

Каша какая-то.

Причем тут VCL, Application и прочее ?
У тебя нет исходников VCL и ты не можешь посмотреть, какие функции вызываются тем же методом ProcessMessages ?

Ты сообщение, кому пришедшее, обрабатываешь ?


dmk ©   (28.03.17 13:44[2]

Application - это VCL. Не хочу внедрять в EXE библиотеки VCL. У меня почти чистый WinApi.

Сообщение посылается из формы дочернему контролу созданному с помощью AllocateHWnd. Оконной процедуры у него нет, поэтому просто транслирую сообщение. Обычный SendMessage. Сообщения принимается нормально. WM_PAINT, WM_MOUSEMOVE транслируются без задержек. Но в случае с WM_LBUTTONDOWN происходит задержка около секунды. Если вставить Application.ProcessMessages в конец трансляции, то сообщения начинают поступать в дочерний контрол по кругу, как в оконной процедуре без задержек. Поэтому я и подумал, что возможно есть какой то способ делать трансляцию без задержек.


dmk ©   (28.03.17 13:47[3]

Пробовал свой TranslateMessage/DispatchMessage сделать, но это приводит к зацикливанию. В Application есть TranslateMessageA/TranslateMessageW и с Dispatch тоже самое. Может в этом дело. В общем пока не знаю что делать.


Игорь Шевченко ©   (28.03.17 14:10[4]

dmk ©   (28.03.17 13:44) [2]

Если не трудно, переведи свой пост на русский язык. Я до сих пор не понимаю, что ты имеешь в виду, а вытягивать из тебя информацию мне не надо, в конце концов проблемы у тебя.


dmk ©   (28.03.17 19:03[5]

Суть в трасляции. Она выполняется для WM_LBUTTONDOWN с задержкой.
Есть форма, в ней есть оконная процедура. Она транслирует дочернему контролу TWindow64 сообщения. TWindow64 их принимает и обрабатывает. Например, что-нибудь рисует. Видно ниже в процедуре OnMessage. Так вот в случае с WM_LBUTTONDOWN происходит задержка выборки сообщения из общей очереди. Пока не нажмешь еще раз мышкой - сообщение не транслируется, т.к. то ли считается не обработанным, то ли еще по какой-то причине.

procedure TImageForm.WndProc(var Message: TMessage);
var
 Msg: dword;

begin
 inherited;

 Msg := Message.Msg;

 case Msg of
   WM_MOUSEMOVE: TranslateMessage(Message);
   WM_LBUTTONDOWN: TranslateMessage(Message);
   WM_LBUTTONUP: TranslateMessage(Message);
   WM_RBUTTONDOWN: TranslateMessage(Message);
   WM_RBUTTONUP: TranslateMessage(Message);
   WM_PAINT: TranslateMessage(Message);
   WM_NCPAINT: TranslateMessage(Message);
 end;
end;

procedure TWindow64.OnMessage(var Message: TMessage);
begin
 case Message.Msg of
   WM_MOUSEMOVE: WMMouseMove(TWMMouse(Message));
   WM_LBUTTONDOWN: WMLButtonDown(TWMMouse(Message));
   WM_LBUTTONUP: WMLButtonUp(TWMMouse(Message));
   WM_PAINT: WMPaint(TWMPaint(Message));
   WM_NCPAINT: WMNCPaint(TWMNCPaint(Message));
 end;//case
end;


dmk ©   (28.03.17 19:13[6]

Пробую сделать DispatchMessageW(FMsg) после трансляции, опять EStackOverflow.
Может как то иначе транслировать сообщения надо?


Игорь Шевченко ©   (28.03.17 21:28[7]


> Суть в трасляции. Она выполняется для WM_LBUTTONDOWN с задержкой.


А зачем она вообще нужна ?

Как построен цикл выборки сообщений:

while GetMessage (Msg) do
begin
 TranslateMessage(Msg);
 DispatchMessage(Msg);
end;

Когда твое окно получает WM_MOUSExxx никакой дополнительной трансляции не требуется.


dmk ©   (28.03.17 21:41[8]

Проблема в том, что после нажатия сообщение не поступает мгновенно по кругу в трансляцию, а в VCL оно при зажатой кнопке работает нормально. Т.е. если держишь кнопку нажатой, то сообщение поступает постоянно. В этом и загвоздка. У меня из TForm посылается сообщение в TObject. Все сообщения нормально посылаются кроме клавиш мыши. После того как оно обработано нужно его снять из очереди сообщений, чтобы следующий WM_LBUTTONDOWN прошел, а этого не происходит. Получается между кликами по 0,5 секунды где-то. Вот и ищу проблему. GetAsyncState думаю пока выручит, а так надо свою выборку из очереди писать. Фактически свой мини-VCL.


Игорь Шевченко ©   (28.03.17 23:38[9]

dmk ©   (28.03.17 21:41) [8]

Ты б книги какие почитал, Рихтера с Петцольдом - такое ощущение, что путаница в элементарных вещах. Круги, трансляции, мини-VCL - зачем это все ?


dmk ©   (28.03.17 23:38[10]

По-моему проблема в TForm. Сообщение WM_LBUTTONDOWN принимается с задержкой именно в TForm. На WinApi такой задержки нет. Все очень шустро.


dmk ©   (29.03.17 00:24[11]

Игорь, у меня порядок с пониманием. Думал наскоком сделать  не вышло.
VCL с WinAPI мешать тяжело. Надо VCL знать изнутри, чего совсем не хочется.
Ибо мне все навороты VCL не нужны.


D7   (29.03.17 00:48[12]

С какой такой задержкой? Что значит снять? Обработали его и всё.
Сделайте что ли мини-проект, без основного кода вашего удивительного класса, а чтоб было видно проблему.


D7   (29.03.17 00:55[13]

> Получается между кликами по 0,5 секунды где-то.

Так может у вас не клик, а даблклик? :)


D7   (29.03.17 01:18[14]

> procedure TImageForm.WndProc(var Message: TMessage);
> ...


эм... Зачем многоступенчатый case-то? Как бы внутри WndProc можно просто:

TranslateMessage(Message);

без case, у вас в OnMessage уже есть такой же case, либо хотя бы так:

 case Msg of
   WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_RBUTTONDOWN, WM_RBUTTONUP, WM_PAINT, WM_NCPAINT:
     TranslateMessage(Message);


А вообще есть смысл вызывать эти всякие WMMouseMove(TWMMouse(Message)); и прочие в самом WndProc.


dmk ©   (29.03.17 01:19[15]

Нет у меня сделано вот так:

procedure TImageForm.WndProc(var Message: TMessage);
begin
 case Message.Msg of
   WM_MOUSEMOVE: MessageToChild(Message);
   WM_LBUTTONDOWN: MessageToChild(Message);
   WM_LBUTTONUP: MessageToChild(Message);
   WM_PAINT: MessageToChild(Message);
 end;

 inherited WndProc(Message);
end;

//Транслирует сообщения элементам класса TWindow64
procedure TImageForm.MessageToChild(var Msg: TMessage);
var
 i: integer;
 Wnd: HWND;
 Wnds: array[0..1] of HWND;

begin
 if FRulesEnabled and InState(VS_INITED) then
 begin
   Wnds[0] := FHScroll.Handle;
   Wnds[1] := FVScroll.Handle;

   Caption := IntToStr(Msg.Msg);

   for i := Low(Wnds) to High(Wnds) do
   begin
     Wnd := Wnds[i];
     SendMessage(Wnd, Msg.Msg, Msg.WParam, Msg.LParam);
   end;

   Msg.Result := S_OK;
 end;//if InState
end;


D7   (29.03.17 02:44[16]

Зачем вам вообще дочерние окна? Вы же хотите всё рисовать сами. Хороший вариант - нарисовать всё на буфере, иметь одно окно которое только и делает что выводит буфер и принимает управление.

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

S_OK ..?


dmk ©   (29.03.17 02:57[17]

>S_OK
Просто константа. Когда пишешь много именованная константа гораздо удобнее для восприятия чем простой ноль. Задекларирована в Windows.Messages.


dmk ©   (29.03.17 02:58[18]

А вообще я нашел проблему. WM_NCHITTEST меня спас.
Там и позиция и клики.


dmk ©   (29.03.17 02:59[19]

>S_OK ..?
Есть еще S_FALSE


D7   (29.03.17 16:54[20]

Я знаю, просто в MSDN написано конкретно и буквально "должна возвращать ноль" или "должна возвращать единицу", а не подобную константу. И разные сообщения после обработки должны возвращать не обязательно только ноль.
Тем более вроде ж не давалось гарантий что S_OK всегда и во всех версиях WindowsAPI будет равна нулю. Это как передавать в функцию SetWindowPos() параметр MK_MBUTTON вместо SWP_NOACTIVATE, махая руками мол - ну и чего, значения-то у них равны...


dmk ©   (29.03.17 18:36[21]

>во всех версиях WindowsAPI будет равна нулю
Константу можно перегрузить в зависимости от версии.


версия для печати

Написать ответ

Ваше имя (регистрация  E-mail 







Разрешается использование тегов форматирования текста:
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)


Наверх

  Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо