Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.04.13;
Скачать: CL | DM;

Вниз

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

 
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 вся ветка

Текущий архив: 2008.04.13;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.019 c
2-1205343170
MegaPiha
2008-03-12 20:32
2008.04.13
Как создать "живой" SQL запрос?


15-1204254610
Slider007
2008-02-29 06:10
2008.04.13
С днем рождения ! 29 февраля 2008 пятница


15-1203938605
Nogard
2008-02-25 14:23
2008.04.13
ZIP архивы


2-1205773174
SpellCaster
2008-03-17 19:59
2008.04.13
Условное компилирование модулей


2-1205652597
Федор
2008-03-16 10:29
2008.04.13
Помогите, пожалуйста, оптимизировать заполнение ComboBox-ов