Nie wiem co to za problem ;-))

0

No więc sprawa wygląda tak:

PostMessage(uchwyt_programu, WM_QUIT, 0, 0);
Sleep(5000);

Na mój zdrowy rozum najpierw powinien zostać zamknięty
program a potem odczekane 5 sekund :-)

Niestety taki kod realizowany jest tak że program
zostaje zamknięty po 5 sekundach :-(

Największy problem jest taki że po tym kodzie
następuje procedura zapisująca do tego programu
więc musi on zostać wyłączony najpierw.

Jak to rozwiązać i z czego to wynika ?

0

<font color="green">Na mój zdrowy rozum najpierw powinien zostać zamknięty
program a potem odczekane 5 sekund </span>

Jak chcesz wykonać jakąkolwiek procedury po zamknięciu programu? [glowa] ;p

0

Próbowałeś zamiast PostMessage użyć SendMessage ?

0

a mzoe zly uchwyt? bo ja juz nie wiem co zamykasz swoje czy inne?

0

Looknij do faq tam Adam opisał jak odinstalować aplikacje. Najpierw wysłał komunikat o zamknięciu a potem wykonał kilka procek. Sam byłem xdziwiony dlaczego program się wcześniej nie zamknął... :-)

0

a żeby nie było wątpliwości:

  • ten program (co podałem kod) jest bez formy i bez
    głównej pętli okna i w ogóle... po prostu program begin end;

  • uchwyt jest poprawny i się zamyka, ale nie wtedy kiedy bym chciał

[b][wyboldowane][/b] for Marooned :-)

<font size="18">- a chce zamknąć <font color="red">[b]inną[/b]</span> normalną aplikację i wykonać na jej
źródle kilka operacji</span>

0

PostMessage(uchwyt_programu, WM_QUIT, 0, 0);
Sleep(5000);

Na mój zdrowy rozum najpierw powinien zostać zamknięty
program a potem odczekane 5 sekund :-)

Popatrz, co robisz:
Wysyłasz komunikat WM_QUIT do siebie funkcją, która nie czeka, aż komunikat zostanie przetworzony.
Następnie uruchamiasz funkcję Sleep, która usypia Twój program.
Wysłany komunikat zostanie przetworzony dopiero po zakończeniu wszelkich instrukcji. Właśnie z tego powodu przy długich pętlach stosuje się metodę ProcessMessage.

Jednak jak zauważyłem, ProcessMessage obsługuje wszystkie komunikaty z wyjątkiem WM_QUIT. Spróbuj zrobić tak:

for i:=1 to 99999 do begin
x:=sqrt(sqrt(i*i)); //cokolwiek, co zajmie trochę czasu
Application.ProcessMessage;
end;

Dzięki ProcessMessage można w czasie obliczeń np. poruszać oknem (obsługa odpowiedzialnych za to komunikatów jest zapewniona), ale okna nie zamkniesz.

0

a jak zrobić Application.ProcessMessage; w programie bez Application ?

0

Piechnat, u mnie ten kod dziala bez zarzutu.
a klopot polega na tym, ze prawdopodobnie masz zly uchwyt do programu.
napisalem taki progs na Twoim kodzie:

program Project1;

uses
Windows, Messages;

var
H : THandle;
begin
H := FindWindow(nil, 'Windows commander 5.0');
PostMessage(h, WM_QUIT, 0, 0);
Sleep(5000);
MessageBox(0, 'Windows Commander zamknięty', 'Koniec', MB_OK);
end.

no i wtedy kod dzialal tak jak u Ciebie, czyli sam zamykal siebie po 5 sekundach, ale jak po "Windows Commander 5.0" dopisalem spacje:

program Project1;

uses
Windows, Messages;

var
H : THandle;
begin
H := FindWindow(nil, 'Windows commander 5.0 ');
PostMessage(h, WM_QUIT, 0, 0);
Sleep(5000);
MessageBox(0, 'Windows Commander zamknięty', 'Koniec', MB_OK);
end.

to wszystko bylo wporzadku, czyli zamknelo mi windowsa commandera i po 5 sekundach wyswietlilo messageboxa.
czyli pokombinuj z nazwa tego progsa, ktorego chcesz zamknac!!!

niby niewielka zmiana ale znaczenie ogromne

0

Albo lepiej szukaj nie po tytule okna tylko po klasie. Jeśli zamykany program jest twój to to nie problem, jeśli nie, to to też nie problem - wystarczy taki mały programik o nazwie "Hacker's Eye" (poszukaj na google, nie pamiętam skąd to wziąłem)

0

Witam

a klopot polega na tym, ze prawdopodobnie masz zly uchwyt do programu.

...zapewniam po raz drugi że nie dawałbym pytania bez uprzedniego sprawdzenia uchwytu

Dzięki za kod. Przetestowałem i rzeczywiście to działało no i pomogło mi
w odnalezieniu prawdziwego powodu błędnego działania:

var
H : Hwnd;
begin
H := FindWindow('TForm1', nil);
PostMessage(H, WM_QUIT, 0, 0);
//- A
Sleep(5000);
//- B
MessageBox(0,'ok','',0);
end.

zamknięcie następuje w miejscu A, ale:
mój błąd bo nie podałem wszystkich okoliczności, przepraszam...
a więc ten mały program
jest uruchamiany przez WinExec() z Aplikacji, która ma być właśnie przez
niego zamknięta. W takim wypadku zamknięcie zostaje zrealizowane w miejscu B.

Ktoś wie dlaczego ?

BTW:

no i wtedy kod dzialal tak jak u Ciebie, czyli sam zamykał siebie po 5 sekundach

w tym przypadku FindWindow() zwraca 0, no i rzeczywiście
PostMessage(0, WM_QUIT, 0, 0) powoduje zamknięcie samego siebie
ale dlaczego ? mógłbym to sobie wytłumaczyć tak że 0 reprezentuje
uchwyt do samego siebie, ale program bez WindowsProcedure (WndProc)
nie może odbierać komunikatów więc skąd to się bierze ?

Wracając do tego błędu, to uporałem się ;-)
Skorzystałem z ShellExecute() ;-)
ale mam pytanie dodatkowe:

Jak sprawdzić czy program jest uruchomiony czy też
nie i można do niego zapisywać, IsWindow() się nie
sprawdza bo po WM_QUIT nie ma już okna ale program
jest jeszcze przez chwilę używany przez system,
jak to sprawdzić ?
bo jedyne co mi przychodzi do głowy to robić AssignFile
i patrzeć czy się wysypie ale może jest jakiś bardziej
elegancki sposób ?

0

robić AssignFile i patrzeć czy się wysypie ale może jest jakiś bardziej elegancki sposób ?

Hmm, jeśli ten sposób działa (przecież sam pisałeś, że aplikacja jest już zamknięta), to obadaj funkcję CreateMutex. Powinno Ci przypasować. I jest to sposób bardzo elegancki :-).

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