2012-06-06 8 views
19

z klasą (TObject) mam:Niestandardowe wiadomości w klasach bez okien - potrzebujesz domyślnego programu obsługi?

private 
    FHwnd : HWND; 
    procedure HandleMyMessage(var Message : TMessage); message TH_MYMESSAGE; 

gdzie TH_MYMESSAGE = WM_USER + 1

W konstruktorze klasy:

FHwnd := AllocateHWND(HandleMyMessage); 

Jedynym obiektem, który otrzymuje odniesienie do FHwnd jest prywatny zwyczaj TThread (utworzone w tej klasie) i jedyny komunikat, który publikuje to TH_MYMESSAGE. Rozumiem, że dyrektywa message w deklaracji proceduralnej ogranicza obsługę tylko do TH_MYMESSAGE.

To działało dobrze podczas testowania, ale po integracji z dużo większą aplikacją otrzymuję informację zwrotną, że HandleMyMessage wystrzeliwuje również dla innych wiadomości (z oczywistymi niepożądanymi wynikami).

Zostało to łatwo naprawione przez dodanie if Message.Msg <> TH_MYMESSAGE then Exit; w HandleMyMessage. Moje pytanie brzmi: dlaczego tak się dzieje?

Domyślam się, że AllocateHWND dokonał HandleMyMessage odpowiednika DefWndProc, mimo że ma dyrektywę message. Czy istnieje właściwy sposób wdrożenia tego, czego mi brakuje?

+4

Twoje przypuszczenie jest poprawna '' WndProc' HandleMyMessage' staje utworzonych non-wideo okno. więc otrzymuje wszystkie wiadomości; twoje rozwiązanie do filtrowania 'Message.Msg' również jest poprawne. 'modulator modu' message' używany przez Delphi do domyślnej obsługi wywołań 'TObject.Dispatch' (w klasach bez okien) – teran

+0

@teran Zakładając, że chciałbym mieć domyślny" WndProc "dla innych wiadomości, filtr" HandleMyMessage "poprawnie z dyrektywą 'message', jeśli zrobiłem' AllocateHWND' na jakiejś innej ogólnej procedurze? –

+0

@Ken Nie ma problemu z WM_USER tutaj. –

Odpowiedz

13

No tak, oczywiście. AllocateHWnd akceptuje TWndMethod jako procedurę okna utworzonego okna. Zamieszanie, jak sądzę, jest spowodowane tym, że kompilator akceptuje dyrektywę messsage. Nie należy umieszczać go:

private 
    FHwnd : HWND; 
    procedure HandleMyMessage(var Message : TMessage); 

.. 

procedure TMyClass.HandleMyMessage(var Message: TMessage); 
begin 
    case Message.Msg of 
    TH_MYMESSAGE: // 
    end; 
    Message.Result := DefWindowProc(FHWnd, Message.Msg, Message.WParam, Message.LParam); 
end; 


edit: (Odpowiedź na komentarz). Aby mieć komunikat obsługiwane na klasy, który stworzył okno użytkową można trasa wiadomość z okna AllocateHWnd tworzy się klasy:

private 
    FHwnd : HWND; 
    procedure HandleMyMessage(var Message : TMessage); 
    procedure THMyMessage(var Message: TMessage); message TH_MYMESSAGE; 

.. 

procedure TMyClass.HandleMyMessage(var Message: TMessage); 
begin 
    case Message.Msg of 
    TH_MYMESSAGE: Dispatch(Message); 
    end; 
    Message.Result := DefWindowProc(FHWnd, Message.Msg, Message.WParam, Message.LParam); 
end; 

procedure TMyClass.THMyMessage(var Message: TMessage); 
begin 
    // 
end; 
+1

Czy program AllocateHwnd tworzy okno, które odbiera programy? Dla czegoś takiego chciałbym szukać okna tylko wiadomości, HWND_MESSAGE. –

+1

To ma sens. Druga część pytania: czy w tej samej klasie można zdefiniować inną procedurę, która wykorzystywała dyrektywę "message" do kierowania określonych komunikatów z głównego programu obsługi? –

+1

@David - Oczywiście, ale korzystanie z AllocateHWnd jest o wiele łatwiejsze. Mój system jest pełen "TPUtilWindow w danym momencie. –

Powiązane problemy