Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2008.04.13;
Скачать: [xml.tar.bz2];

Вниз

Удалить все сообщения контролу из очереди сообщений   Найти похожие ветки 

 
DevilDevil ©   (2007-08-13 15:03) [0]

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

Вообще можно вызывать деструктор по OnMouseUp... но это - неделовой подход. Есть ли способ удалить из очереди сообщений все сообщению, присланные окну. Вызов такой функции в OnClick ни к чему не приводит:

function KillMouseEvents(Handle : HWND) : integer;
begin
 Result := 0;

 while (PeekMessage(nil, Handle, WM_MOUSEFIRST, WM_MOUSELAST, PM_NOREMOVE)) inc(Result);

end;


заранее благодарен.


 
DevilDevil ©   (2007-08-13 15:05) [1]

Result, кстати всегда = 0.


 
Сергей М. ©   (2007-08-13 15:12) [2]


> Есть панель, на панели - кнопка.
> По нажатию на кнопку вызывается деструктор панели


Нельзя так делать, это уже сто раз обсуждалось в форуме.
Вместо непосредственного разрушения панели посылай (Postmessage) форме какое-либо предопределенное сообщение, по получении которого панель должна быть разрушена в коде-обработчике этого сообщения.


 
DevilDevil ©   (2007-08-13 15:18) [3]

> Сергей М. ©   (13.08.07 15:12) [2]

1) с чемп это связано?
2) как удалить сообщения в очереди?


 
DVM ©   (2007-08-13 15:31) [4]


> 1) с чемп это связано?

с тем, что не надо пилить сук на котором сидишь.


 
DevilDevil ©   (2007-08-13 15:36) [5]

> DVM ©   (13.08.07 15:31) [4]

А если посерьёзнее?

Я, к примеру, иногда из себя вызываю деструктор себя. Вроде ничего крименального в этом нет.


 
DVM ©   (2007-08-13 15:40) [6]


> Я, к примеру, иногда из себя вызываю деструктор себя.

Одно дело, когда ты вызваешь деструктор для самой кнопки при щелчке по ней и совсем другое дело, когда кнопка лежит на панели.


 
Сергей М. ©   (2007-08-13 15:43) [7]


> 1) с чемп это связано?


см. [4], [6]


> 2) как удалить сообщения в очереди?


Не нужно лезть в очередь сообщений без явной необходимости.
А уж если полез, то удаление осуществляется при флаге PM_REMOVE, а не PM_NOREMOVE


 
DevilDevil ©   (2007-08-13 15:52) [8]

ну в данном случае вся проблема в приходящем OnMouseUp после OnClick. Вы утрверждаете, что в общем случае необходимо посылать сообщение. Вот я и спрашиваю, какие проблемы возникают ещё.

Но имхо логичнее очищать всю очередь сообщений для определённого контрола... или лучше для целой иерархии контролов.

Ваш метод в общем случае более подвержен ошибкам. Например...
Есть несколько мест и условий, при которых следует удалить себя.

Допустим, послал я своё сообщение на удаление; оно не будет обработано, пока не обработаются сообщения, пришедшие раньше. В одном из обработчиков стандартных сообщений я определяю, что мне необходимо вызвать деструктор себя и вновь посылаю сообщение на удаление.

Настанет время обработки, я вызову у себя деструктор, а в очереди останутся сообщения на удаление. Когда они придут в следующий раз, возникнет та же самая ошибка.


 
DVM ©   (2007-08-13 15:54) [9]


> ну в данном случае вся проблема в приходящем OnMouseUp после
> OnClick. Вы утрверждаете, что в общем случае необходимо
> посылать сообщение. Вот я и спрашиваю, какие проблемы возникают
> ещё.

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


 
tesseract ©   (2007-08-13 15:58) [10]


>  я вызову у себя деструктор, а в очереди останутся сообщения
> на удаление. Когда они придут в следующий раз, возникнет
> та же самая ошибка.


Деструктор у объектов не вызываеться, вызываеться Free. Вызов деструктора в себе, это как в череп выстрелить. Ты по нажатию кнопки вызываешь сообщение - и в функции обработки этого сообщения уже вызываешь free;


 
Сергей М. ©   (2007-08-13 15:59) [11]


> В одном из обработчиков стандартных сообщений я определяю,
>  что мне необходимо вызвать деструктор себя и вновь посылаю
> сообщение на удаление


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


 
DevilDevil ©   (2007-08-13 16:00) [12]

хех,

procedure TControl.WMLButtonUp(var Message: TWMLButtonUp);
begin
 inherited;
 if csCaptureMouse in ControlStyle then MouseCapture := False;
 if csClicked in ControlState then
 begin
   Exclude(FControlState, csClicked);
   if PtInRect(ClientRect, SmallPointToPoint(Message.Pos)) then Click;
 end;
 DoMouseUp(Message, mbLeft);
end;


вот теперь понимаю, почему лучше сообщение... :)

> Сергей М. ©   (13.08.07 15:43) [7]

да... что то я просмотрел...
Но меня больше удивляло, что Result всегда был равен 0. Впрочем, теперь понятно, почему.

Всем спасибо.


 
DevilDevil ©   (2007-08-13 16:03) [13]

> tesseract ©   (13.08.07 15:58) [10]

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


 
MBo ©   (2007-08-13 16:23) [14]

http://delphimaster.net/view/1-1186483022/


 
Игорь Шевченко ©   (2007-08-14 09:55) [15]


> ничего не вижу плохого в том, чтобы вызвать деструктор экземпляра
> класса из этого же класса.


Плохого в этом ничего нету, Коран не запрещает.


> По нажатию на кнопку вызывается деструктор панели... а после
> этого несуществующей кнопке приходит OnMouseUp, в общем
> ошибка!


Сам видишь, что происходит, а после этого - "ничего плохого не вижу".

Меня удивляет стремление ряда людей придумать себе трудности и мужественно их преодолевать, зачем, спрашивается ?
Вот в фирме Борланд долго думали и придумали метод Release у формы, почему бы не посмотреть в первую очередь, как выверты сделаны другими, вместо того, чтобы веселым маршем шагать по граблям ?


 
Leonid Troyanovsky ©   (2007-08-14 10:04) [16]


> DevilDevil ©   (13.08.07 15:03)  

> Есть панель, на панели - кнопка.
> По нажатию на кнопку вызывается деструктор панели...


procedure TForm1.Action1Execute(Sender: TObject);
begin
 Panel1.Free;
 ShowMessage("1");
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 if Action1.Execute then
   ShowMessage("2");
end;


--
Regards, LVT.



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2008.04.13;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.179 c
15-1204184372
Kerk
2008-02-28 10:39
2008.04.13
Прекрасное далёко...


2-1205927025
Deled
2008-03-19 14:43
2008.04.13
Программный анализатор


2-1205762898
Михаил
2008-03-17 17:08
2008.04.13
Компонент для выбора толщины и вида линии


2-1206015131
WildBoolean
2008-03-20 15:12
2008.04.13
TListBox +OnDrawItem


2-1205758991
savyhinst
2008-03-17 16:03
2008.04.13
Повернуть картинку





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский