Handle zmienia swoją wartość ale dlaczego?

Handle zmienia swoją wartość ale dlaczego?
RD
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 212
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

Kopiuj
    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:

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

Komunikat dociera i wykonywana jest poniższa procedura

Kopiuj
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:

Kopiuj
 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

Kopiuj
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?

flowCRANE
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Tuchów
  • Postów: 12269
0

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

KA
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Gorlice
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?

cerrato
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Poznań
  • Postów: 9019
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?

RD
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 212
0
Kopiuj
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++

Kopiuj
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.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.