C++ VCL Mesaj gönderme ve yakalama.

Başlatan Klein, 23 Ağustos 2013, 21:38:06

Klein

TLabel sınıfından türetilmiş aşağıdaki gibi bir sınıfım var.
TTimer tipinde bir işaretçiye de referans veriyorum.   
Yapmak istediğim şey :
Referans verdiğim timer "OnTimer" mesajı ürettiğinde , bu Timer' e referans veren tüm MyLabel nesnelerim "UpdateCaption()" fonksiyonunu çağırsın.
Ama nasıl yapacağımı bilmiyorum.   

(Timer'in "OnTimer" olayını nesnemin "UpdateCaption()" fonksiyonunu çağıracak şekilde ayarlayabiliyorum. Ama bu durumda sadece o nesnenin fonksiyonu çağırılıyor. Benim aradığım şey ise,Timer'e referans veren tüm nesnelerin güncellenmesi.

Belki Timer'in bir metodu ezilip mesaj yayınlatılabilir. Ama hem hangi fonksiyonu nasıl ezeceğimi, hem de nasıl mesaj yayınlayacağımı bilmiyorum.
 
class PACKAGE TMyLabel : public TLabel
{
private:
	TTimer *FTimer;
	void __fastcall UpdateCaption(TObject *Sender);
protected:
public:
__published:
	__property TTimer *Trigger = { read = FTimer , write = FTimer};
};

Klein

Yok hocam öyle yapamam.  Çünkü komponent yazıyorum.
Komponenti forma koyup , Timer'e bağlayınca iş bitmeli.
İllaki timer olmak zorunda da değil.  Bir şekilde otomatik olarak güncellemem gerek.

Klein

Timer'in "OnTimer" olayını ele geçirip "WM_USER" mesajı broadcast ederak sorunu geçici olarak hallettim.
Timer kullanmak yerine yeni bir sınıf yazıp , thread kullanarak belirli zamanda broadcast mesajı yayınlamak sanırım daha şık bir çözüm olacak.
Broadcast mesajlar ile ilgili bir kaç sorum var.

1- Broadcast mesajların sorunları ve tehlikeleri nedir?
2- Broadcast mesaj yayını Tüm sistemde mi? geçerlidir? uygulamada mı?
3- Eğer tüm sistemde geçerli ise, başka bir uygulamanın yayınlayabileceği mesajla karışması nasıl engellenir?
4- Tüm sisteme değil sadece belirli bir sınıfa ( örn: sadece TLabel sınıfına) mesaj yayınlanabilir mi? nasıl?


muhittin_kaplan


Klein

#4
Yaşlanınca uyku ihtiyacı azalıyormuş  :)

Biraz araştırdım. 
0x4000 - 0x7FFF aralığındaki WM_USER mesajları tüm sistemde geçerli.  Bir kısmı çeşitli sınıflar için ayrılmış durumda.  Hangi mesajları kim kullanıyor bulamadım.
0x8000 - 0xBFFF aralığındaki WM_APP mesajları Sadece uygulamada kullanılıyor. Gönül rahatlığıyla kullanabilirsiniz demiş Microsoft. Umarım doğrudur.

2, 3 ve 4. soruların cevaplarını kısmen buldum.  1. soru halen güncel.

Bir sorum daha var.
Nesne yapılandırılırken bir değişkenine unique bir değer atmam gerekiyor. HWND gibi ama daha küçük bir sayı olmalı. Mesajın kimden geldiğini anlamak için, mesajı yayımlarken bu numarayla birlikte yayımlayacağım.

Mesaj yakalamak için şimdilik aşağıdaki filtre makrosunu kullanıyorum.
BEGIN_MESSAGE_MAP
		MESSAGE_HANDLER(WM_APP, TMessage, MsgUpdate)
	END_MESSAGE_MAP(TLabel);


Ama "WndProc()" kullanmak istiyorum. "WndProc()" ile istediğim mesajı yakalıyorum.
Ancak nesne kendisine gelen diğer mesajları almıyor.  Hatta tasarım kipi mesajlarını bile almıyor.  Tasatım kipinde nesnenin yeri bile değiştirilemiyor. Caption siliniyor vs.. vs.. Aynı şey Runtime kipinde de geçerli. Sanırım mesajlar benim WndProc() fonksiyonuma düştüğü için  diğer mesajlar  işlenemiyor.
Bazı örneklerde  Gelen mesaj beklenen mesaj değilse ,  "WndProc()" kendi içerisinden tekrar çağırılıyor.  Bunu denedim ama Stack taşıyor.
İlgilenmediğimiz mesajı nesneye geri göndermenin bir yolu  nedir?




yamak

Hocam merağımdan soruyorum uygulamanızı hangi ortamda geliştiriyorsunuz.Visual c++ mı?Çünkü bu bahsettiğiniz yöntemler bildiğimiz kadarıyla standart c++'da yok da.Çünkü daha önce buna benzer bi olayı yapmak istemiştim ama beceremeyip daha farklı bir yöntem ile sorunumu çözmüştüm.Hatta aşağıdaki linkte konu tartışılmıştı

https://www.picproje.org/index.php/topic,46770.0.html

Klein