Handle zmienia swoją wartość ale dlaczego?

0

Ten tydzień to same niespodzianki wczoraj natknąłem się na ciekawą rzecz, niestety mój poziom wiedzy nie potrafi tego rozwiązać :)

Podczas startu tworzone są dwie formy

    Application.CreateForm(TMainForm, MainForm);  //Główna
    Application.CreateForm(TTasks, Tasks);  //Visible = False

Teraz na formie głównej jest przycisk który uruchamia wątek a ten wysyła komunikat:

var
   hwnd: THandle;
begin
   hwnd := SendMessage(FindWindow('TTasks', 'Tasks'), WM_AddTask, NativeUInt(Self), 0));
end;

Komunikat dociera i wykonywana jest poniższa procedura

procedure TTasks.AddTask(var Msg: TMessage); WM_USER + 1;
var
  T: TFrame;
begin
  T := TFrame.Create(nil);
  T.ObjectOwner := TObject(NativeUInt(Msg.WParam));
  T.Parent := Self;      // Tutaj następuje zmiana Handle z oczywistych względów
  Msg.Result := T.Handle;  //Tutaj zwracana jest "niby" prawidłowa wartość handle
end;

Teraz wracamy ponownie do wątku gdzie ten po wykonaniu określonych zadania wysyła no taki komunikat do wcześniej stworzonej ramki:

 PostMessage(hwnd, WM_SetTaskMarquee, 0, 0);

I tu pojawia się problem. Jeżeli poczekam ok 20 sekund po włączeniu aplikacji kod zazwyczaj działa ale od razu po włączeniu już nie. Na ramce dałem timer1 z kodem

label1.caption := inttotstr(self.handle); 

I wartości THandle czasami są równe a czasami nie, mało tego raz handle ma jedną wartość a po chwili się zmienia. Próbowałem wywoływać procedure HandleNeeded ale to nic nie daje.

Pytanie brzmi: Jak uzyskać prawidłowy uchwyt nie wyświetlając formy?

0

Jesteś pewny, że FindWindow znajduje ten drugi, ukryty formularz?

0

Okno widoczne czy nie ma zawsze od utworzenia do jego zniszczenia ten sam uchwyt. Takie okno powinna znaleźć funkcja FindWindow wywołana z poprawnymi parametrami i pytanie czy na pewno to jedyne okno w całym systemie spełniające podane w parametrach kryteria?

1

Nie rozumiem jednej rzeczy - skoro oba okienka są tworzone przez Ciebie i działają w ramach jednej aplikacji, to po co bawisz się w znajdywanie uchwytu do okna przez FindWindow, zamiast po prostu odczytać tą wartość bezpośrednio z TForm1?

0
SendMessage(FindWindow('TTasks', 'Tasks'), WM_AddTask, NativeUInt(Self), 0));

To zawsze znajduje poprawne okno. Problem leży w kodzie poniżej, Wystarczy tylko raz wywołać ( gdziekolwiek nawet w onCreate MainForm) visible := true i visible := false aby T.Handle miało prawidłową wartość. Poszukałem i wujek google podpowiada że wizualne okienka otrzymują stałe handle podczas pierwszego wywołania Show/Visible - to znalazłem gdzieś na forum C++

procedure TTasks.AddTask(var Msg: TMessage); WM_AddTask;
var
  T: TFrame;
begin
  Self.Visible := true;
  Self.Visible := false;
  T := TFrame.Create(nil); 
  T.ObjectOwner := TObject(NativeUInt(Msg.WParam));
  T.Parent := Self;      // Tutaj następuje zmiana Handle z oczywistych względów
  Msg.Result := T.Handle;  //Teraz wartość jest zawsze prawidłowa
end;

Jednak to mi nie rozwiązuje problemu ponieważ okienko mignie. A nie chciałbym robić prowizorki i wyświetlać tego okienka poza obszarem pulpitu po to aby wykonać raz visible := true;

cerrato napisał(a):

Nie rozumiem jednej rzeczy - skoro oba okienka są tworzone przez Ciebie i działają w ramach jednej aplikacji, to po co bawisz się w znajdywanie uchwytu do okna przez FindWindow, zamiast po prostu odczytać tą wartość bezpośrednio z TForm1?

To jest tylko przykład mojego problemu w bardziej złożonej aplikacji. Tak samo bezsensu jest tworzenie pustej ramki :) To jest tylko dla przykładu :)

kAzek napisał(a):

Okno widoczne czy nie ma zawsze od utworzenia do jego zniszczenia ten sam uchwyt. Takie okno powinna znaleźć funkcja FindWindow wywołana z poprawnymi parametrami i pytanie czy na pewno to jedyne okno w całym systemie spełniające podane w parametrach kryteria?

Tak FindWindow znajduje okno poprawnie ale AddTask różne wątki mogę wywołać kilka razy i dla każdego wątku przypisuje jedno TFrame / TFrameTask w którym nie określam nazwy dlatego FindWindow znajdzie mi np 5 okienek typu TFrame i musiałbym wprowadzić jakąś zmienną żeby określać które jest czyje. Wydaje mi się że handle idealnie to rozwiązuje.

1 użytkowników online, w tym zalogowanych: 0, gości: 1