Zamykanie innego okna

0

HI,
zastanawiam się czy jest możliwe w łatwy sposób, aby zamknąć okno programu napisanego np. w delphi, gdzie te okno ma zablokowaną możliwość zamknięcia, coś w stylu CanClose := False; oraz jest to okno potomne, a nie główne.

Czy ktoś się bawił takim czymś?

Drugie pytanie takie for fun, jaki komunikat podesłać do kontrolki w innej aplikacji, aby uzyskała status Enabled := true, jesli była false.

pozdro!

0

WM_DESTROY

1
szwejks napisał(a):

zastanawiam się czy jest możliwe w łatwy sposób, aby zamknąć okno programu napisanego np. w delphi, gdzie te okno ma zablokowaną możliwość zamknięcia, coś w stylu CanClose := False; oraz jest to okno potomne, a nie główne.

Czy ktoś się bawił takim czymś?

Tak, jest to możłiwe. Czy sposób jest łatwy? To w sumie pojęcie względne. Na pewno przy ustawionym CanClose na False jedynie w sposób lekko "inwazyjny". I tak, bawiłem się przed chwilą. Najpierw może kwestia CanClose ustawionego na False. Otóż aby zamknąć taką formatkę, jeżeli się nie mylę - należy wstrzyknąć dllkę w proces takiej aplikacji. W aplikację 32 bitową można tego dokonać przy użyciu modułu afxcodehook.pas pisząc dllkę w dowolnym języku oraz injector, który ją wstrzyknie pod Delphi. Dllka musi "podczepić" się pod funkcję obsługi komunikatów formatki z CanClose := False, którą chcemy "ubić". Dlatego w ogóle potrzebna nam tak wstrzyknięta dllką, ponieważ będzie ona traktowana jako kod docelowej aplikacji, a jak wiadomo "podczepienie się" pod funkcję obsługi komunikatów obcej aplikacji jest inaczej niemożliwe. Następnie po otrzymaniu od jakiejś aplikacji funkcji niszczących okno - na przykład właśnie WM_DESTROY musi wykonać funkcję DestroyWindow na uchwycie tej formatki czyli pierwszym parametrze funkcji obsługi komunikatów, zwrócić zero i zakończyć obsługę komunikatów przez Exit nie osługując dalej domyślnej akcji dla komunikatu. Teraz kwestia okna bez CanClose ustawionego na False. Mając uchwyt okna uważam, że nie będzie znaczenia czy jest ono potomne czy głowne. Po prostu wysyłamy odpowiedni komunikat do tego celu pod ten uchwyt. Jeżeli okno nie ma niestandardowej obsługi takiego komunikatu i jego blokowania to według mnie powinno zareagować. Przy drugiej sytuacji nie potrzebujemy kombinowania z injekcją dllki.

Drugie pytanie takie for fun, jaki komunikat podesłać do kontrolki w innej aplikacji, aby uzyskała status Enabled := true, jesli była false.

Sprawdzić dostępnośc kontrolki lub okna przez funkcję IsWindowEnabled dokonaną na jej uchwycie. Najszybciej będzie wykonać funkcję EnableWindow na jej uchwycie z drugim parametrem jako not IsWindowEnabled(UchwytKontrolki). Tutaj również, jeżeli kontrolka nie ma przez programistę zmienionej standardowej funkcji obsługi komunikatów, tak aby zmienianie jej dostępności było blokowane - obejdzie się bez injectowania dllki. A i więcej informacji oczywiście do znalezienia poprzez google. Przede wszystkim czytać i szukać na MSDNie.

0

No i Olesio udało Ci się cos stworzyć konkretnego podczas tej zabawy i mogbys sie podzielic ze mna?

Napisalem sobie kodzik 4fun na te zamykanie okna jesli nie jest ono blokowane, ale jesli ma canclose:= false, to juz ciezej mi cos znalezc na ten temat.

0
szwejks napisał(a)

Drugie pytanie takie for fun, jaki komunikat podesłać do kontrolki w innej aplikacji, aby uzyskała status Enabled := true, jesli była false.

Przyda się funkcja EnableWindow - musisz mieć tylko uchwyt tej kontrolki;

EDIT: Skoro nie masz uchwytu i nie masz możliwości tego tak rozwiązać, to pozostaje injekcja kodu wspomniana przez kolegę wyżej;

0

a jak pobrać uchwyt kontrolki, ktora jest Disabled.
Mam program, ktory pokazuje uchwyty i klasy, ale tylko aktywnych kontrolek.

0
szwejks napisał(a):

No i Olesio udało Ci się cos stworzyć konkretnego podczas tej zabawy i mogbys sie podzielic ze mna?

Tak, mój sposób z injekcją dllki działa. Tylko po ubiciu okna aplikacja nadal działa, ponieważ nie ruszam ukytrgo okna o klasie TApplication, które posiadają wszystkie aplikacje VCL pisane w Delphi. I powyżej opisałem wszystko, co jest Tobie potrzebne. Gotowca nie podeśle, bo na prawdę uwierz mi, takimi gotowcami się tylko Was pytających na prawdę krzywdzi. Sam się o tym niedawno przekonałem. Podesłany gotowy kod, rodził mnóstwo kolejnych i często banalnych pytan, ponieważ osoba prowadzona za rączkę nie pomyslała, nie przeanalizowała sobie podesłanego nawet krotkiego kodu, tylko bezmyślnie go kompilowała i tyle. Napisz z czym masz konkretnie problem. Podałem wszystkie informacje jakich potrzeba do podjęcia próby samodzielnego poszukania materiałów. Na tym forum pewnie da się jakoś jeszcze znaleźć wątek gdzie podsyłam gotowy kod do injekcji dllki tym modułem, o którym wspomnialem i blokowania możliwości zamknięcia okna Windows Media Player przyciskiem "X" w okienku. Zasada jest podobna. Tylko, że tam podczepiam się pod okno o konkretnej klasie, a tutaj wystarczy w dllce wykonać EnumWindows i w funkcji enumerującej sprawdzać funkcją GetWindowThreadProcessId, które okna należą do procesu i pod nie podczepić się pod funkcję obsługi komunikatów (wiadomo, funkcja SetWindowLong na uchwyt z drufim parametrem GWL_WNDPROC). Tylko wiadomo. Albo podczepiasz się pod jedno konkretne okno albo robisz sobie na przykład typ rekordowy z polami jako uchwyt okna HWND i pointerem, który przechowa oryginalną funkcję obslugi komunikatów okna i dodajesz to do tablicy dynamicznej, której rozmiar zwiększasz przy wyszukiwaniu i znalezieniu kolejnego okna. Później można zrobić dodatkową funkcję, która sprawdza w pętli tę tablicę i zwraca eleement o podanym w parametre uchwycie okna. Takie kombinowanie jest konieczne jeżeli chcemy przejąc obsługę komunikatów funkcji więcej niż jednego okna, a wiadomo wywołana pod koniec obsługi funkcja CallWindowProc musi jako parametr przyjąc Poiner na właściwe okno, a każde okno czy kontrolka, szczegołnie różnego typu powinna mieć inną funkcję obsługi komunikatów aby nie powodować błędów i zawieszenie programu. I jeżeli będziesz miał KONKRETNY problem, to pytaj tutaj. Wszystko elegancko można znaleźć w google i doczytać na MSDnie, jak pisałem.

szwejks napisał(a):

a jak pobrać uchwyt kontrolki, ktora jest Disabled.
Mam program, ktory pokazuje uchwyty i klasy, ale tylko aktywnych kontrolek.

Zastosuj wspomiane funkcje EnumWindow, ewentualnie w obrębie samego okna EnumChildWindows i będziesz miał wszystkie uchwyty. Aktywność typowej kontrolki nie powinna wpłynąc na możłiwość pobrania jej uchwytu. Jeżeli ten program, którego używasz do pobierania uchwytów tego jednak nie potrafi, to według mnie jest po prostu źle napisany.

0

co do programu sprawdzjacego uchwyty to sprawdzilem 3 i zaden nie pokazywal uchwytow kontrolek disable, mowie tutaj oczywiscie o pokazywaniu przez najechanie myszka,
jeden program mial pobieranie wszystkich klasi uchwytow z ekranu i tam pojawil sie uchwyt do tych komponentow, wiec faktycznie trzeba je wyszukiwac w jakis sposob,
do tematu powroce.

0

Zwracam honor. Faktycznie, kiedy wykorzystujemy funkcję WindowFromPoint, a takową wykorzystują za pewne te programy. Mój własny w WinAPi również ją wykorzystuje. Przyciski (a za pewne i inne kontrolki), które nie są Enabled są dla tej funkcji jakby niewidoczne. Ale jak wspomniałem. Mamy EnumChildWindows, która z tym problemu nie ma. Możesz pobrać mój Downloader do Demotywatorów ze strony http://olesio.eu/downloaders i sprawdzić poniższy kod. Bez problemu w Memo między innymi pokaże się również wspis dotyczący przycisku Anuluj, który może być też i nieaktywny. Także według mnie trochę niepotrzebnie mnożysz sobie sam problemy, gdzie ich nie ma. Już dawno byś znalazł na necie potrzebne moduły i informacje, po czym zaprogramował, co Tobie potrzeba według moich podpowiedzi, jakie zamieściłem w poprzednich postach w tym wątku.

//...
function GetControlClassName(AHWnd : HWND) : string;
var
  AName : array[0..255] of Char;
begin
  Result := '';
  if (AHWnd > 0) and boolean(GetClassName(AHWnd, AName, SizeOf(AName))) then
  begin
    Result := AName;
  end;
end;

function GetTextLen(AHandle : HWND) : integer;
begin
  Result := SendMessage(AHandle, WM_GETTEXTLENGTH, 0, 0);
end;

function GetTextBuf(AHandle : HWND; Buffer : PChar; BufSize : integer) : integer;
begin
  Result := SendMessage(AHandle, WM_GETTEXT, BufSize, Longint(Buffer));
end;

function GetText(AHandle : HWND) : string;
var
  Len : integer;
begin
  Len := GetTextLen(AHandle);
  SetString(Result, PChar(nil), Len);
  if Len <> 0 then
  begin
    GetTextBuf(AHandle, Pointer(Result), Len + 1);
  end;
end;

function EnumFunc(AHWnd : HWND; ALParam : LParam) : boolean; stdcall;
begin
  Result := True;
  Form1.Memo1.Lines.Add(Format('Handle: %s Text: %s Class: %s',
    [IntToHex(AHWnd, 2), GetText(AHWnd), GetControlClassName(AHWnd)]));
end;

procedure TForm1.Button1Click(Sender : TObject);
begin
  Memo1.Clear;
  EnumChildWindows(FindWindow(nil, 'Demotywatory Downloader 2.6'), @EnumFunc, 0);
end;

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