Centrum skryptów - Systemy operacyjne

Jak sprawić, by aplikacja HTA pamietała swoją poprzednią pozycję na ekranie?

Udostępnij na: Facebook

Skrypciarze odpowiadają na Wasze pytania

Witamy w rubryce TechNet, w której Skrypciarze z firmy Microsoft odpowiadają na częste pytania dotyczące używania skryptów w administracji systemu. Jeśli macie jakieś pytania z tej dziedziny, zachęcamy do wysłania e-maila na adres: scripter@microsoft.com. Nie możemy zagwarantować odpowiedzi na każde otrzymane pytanie, ale staramy się jak możemy.

Jak sprawić, by aplikacja HTA pamietała swoją poprzednią pozycję na ekranie?

Cześć, Skrypciarze! Jak sprawić, aby aplikacja HTA pamiętała swoją poprzednią pozycję na ekranie? Niektórzy użytkownicy są bardzo wyczuleni na punkcie miejsca aplikacji HTA na ekranie i chcą, aby podczas kolejnego uruchomienia aplikacji znajdowała się dokładnie w tym samym miejscu.

-- DF

Cześć, DF. Wiecie już, mówiłem o tym nie raz, że ostatnie tygodnie były dla mnie bardzo ciężkie. Zresztą nie tylko dla mnie, dla wszystkich Skrypciarzy. Pozwólcie jednak, że jeżeli mam się nad czymś lub nad kimś użalać, to wolę nad sobą. To mi wychodzi najlepiej. Myślałem sobie, że teraz trochę odpocznę, ale nic z tego. Czeka mnie mnóstwo pracy.

Jakiej pracy, zapytacie. Domowej. Ale nie takiej pracy domowej, która polega na tym, że idąc do domu zabieramy ze sobą materiały i pracujemy w domu nad czymś, nad czym powinniśmy pracować w pracy. Nie, to byłoby zbyt piękne. Otóż czeka mnie ciężka fizyczna praca w domu. Począwszy od dzisiaj. Wiosenne malowanie mieszkania. Możecie sobie wyobrazić coś gorszego? Nie sądzę. W każdym razie ja wprost nie mogę znieść myśli, że przez najbliższy tydzień będę mieszkał wśród mebli owiniętych folią i zamiast wieczorami po pracy odpoczywać oglądając telewizję, będę musiał udzielać się podczas malowania. Całe szczęście, że dużo pracuję. (Nie wierzę, że to powiedziałem, ale to chyba jedyny mój ratunek). Dzisiaj jest etap pierwszy: mycie ścian i gruntowanie. Tego nie lubię najbardziej. Zanim jednak wrócę do domu, żeby się tym zająć, muszę odpowiedzieć na pytanie DF dotyczące skryptu, który sprawi, że aplikacja HTA zapamięta swoją poprzednią pozycję na ekranie. Zatem do dzieła. Ech, szkoda, że odpowiedź na to pytanie nie zajmie mi całego wieczoru.

Oto skrypt, dzięki któremu nie ma mnie jeszcze w domu:

<SCRIPT Language="VBScript">

    Dim intLeft

    Dim intTop



    Sub Window_onLoad

        window.offscreenBuffering = True



        Const ForReading = 1

        Set objFSO = CreateObject("Scripting.FileSystemObject")

        Set objFile = objFSO.OpenTextFile("HTA.ini", ForReading)

        strContents = objFile.ReadAll

        objFile.Close



        arrContents = Split(strContents, ",")

        window.moveTo arrContents(0), arrContents(1)

    End Sub



    Sub Window_onBeforeUnLoad

        intLeft = window.screenLeft

        intTop = window.screenTop



        Const ForWriting = 2

        Set objFSO = CreateObject("Scripting.FileSystemObject")

        Set objFile = objFSO.OpenTextFile("HTA.ini", ForWriting)

        objFile.WriteLine intLeft & "," & intTop

        objFile.Close

    End Sub

</SCRIPT>



<BODY>

</BODY>

Jak widzimy, aplikacja HTA jest całkiem prosta; wręcz nie ma w niej nic (zamiast tworzyć aplikację HTA od zera, skopiowałem po prostu listę rzeczy, które udało mi się zrobić w domu w ciągu ostatnich kilku lat. To chyba nie był taki dobry pomysł, jak mi się wydawało). Mamy za to dwie podprocedury: podprocedurę Window_onLoad, która uruchamia się automatycznie po każdym uruchomieniu lub odświeżeniu aplikacji HTA, oraz podprocedurę Window_onBeforeUnload, która uruchamia się automatycznie tuż przed zamknięciem aplikacji HTA. Do czego potrzebne nam są te dwie automatycznie się uruchamiające podprocedury? Właśnie chciałem o tym opowiedzieć.

Zacznijmy od podprocedury Window_onLoad. Jak widzimy, na początku mamy poniższy wiersz kodu:

window.offscreenBuffering = True

Za pomocą tego wiersza ustawiamy wartość właściwości offscreenBuffering jako True.

Jasne, sami mogliście na to wpaść. No dobrze; w takim wypadku tak naprawdę informujemy aplikację HTA, że chcemy przeciągnąć okno (i wszystkie elementy znajdujące się w tym oknie) poza ekran; nie chcemy widzieć aplikacji HTA na ekranie, dopóki nie będzie na to gotowa. Dlaczego? No cóż, domyślnie, aplikacja HTA będzie się ładować za każdym razem w tym samym miejscu; dopiero po załadowaniu, kiedy jest już widoczna, będzie się przemieszczać do miejsca swojej ostatniej lokalizacji (Zaraz wyjaśnię o co mi chodzi). Jeżeli będziemy obserwować to na ekranie, zobaczymy ładującą się aplikację HTA, która następnie „przeskakuje” do nowej lokalizacji. Jeżeli aplikacja HTA będzie się ładować poza ekranem, nie zobaczymy przeskoku. Pojawi się natomiast, gdy już będzie gotowa, we wskazanym miejscu.

Zobaczycie, że to naprawdę ma sens po przeczytaniu całego dzisiejszego artykułu.

Właśnie: mam nadzieję, że zobaczycie.

Uwaga. Słuszna uwaga: powinienem także wspomnieć, że zdefiniowałem dwie zmienne, intLeft oraz intTop. Są to zmienne globalne; czyli takie, które są dostępne dla każdej podprocedury w aplikacji HTA. Skąd wiadomo, że są to zmienne globalne? To proste: nie zostały zdefiniowane w podprocedurze. Istnieją natomiast jako kod wewnątrz tagu <SCRIPT>.

Co dokładnie dzieje się poza ekranem? Cóż, na początek definiujemy stałą o nazwie ForReading i ustawiamy jej wartość jako 1. Zastosujemy tę stałą podczas otwierania pliku .INI do odczytu.

Uwaga. Kolejna słuszna uwaga: tak, do rozwiązania tego problemu używamy pliku .INI. Podczas każdego uruchomienia naszej aplikacji HTA odczyta ona swoje początkowe współrzędne z pliku .INI; podczas każdego zamykania zapisze bieżące współrzędne do tego samego pliku .INI. W ten sposób HTA będzie uruchamiać się dokładnie w tej samej pozycji na ekranie, w której zakończyła działanie.

Po zdefiniowaniu stałej tworzymy wystąpienie obiektu Scripting.FileSystemObject, a następnie użyjemy metody OpenTextFile do otwarcia pliku HTA.ini do odczytu (zakładamy, że plik .INI znajduje się w tym samym folderze, co aplikacja HTA):

Set objFile = objFSO.OpenTextFile("HTA.ini", ForReading)

Plik .INI składa się z jednego wiersza, który wygląda mniej więcej tak:

0,0

Do czego służy wartość 0,0? Cóż, pierwsze 0 reprezentuje lewą krawędź okna aplikacji HTA; innymi słowy chcemy, żeby aplikacja HTA uruchomiła się przyklejona do lewej strony ekranu (wcięta 0 pikseli od lewej). Drugie 0 reprezentuje górną krawędź okna aplikacji HTA; oznacza to, że chcemy, aby aplikacja HTA uruchomiła się w odległości 0 pikseli od góry ekranu. Co otrzymamy? Domyślnie, aplikacja HTA będzie się uruchamiać w górnym, lewym rogu ekranu. Jednak nie zawsze będzie musiała uruchomić się w lokalizacji 0,0, sami się o tym zaraz przekonacie.

W celu ustawienia tych współrzędnych używamy metody ReadAll do odczytania zawartości pliku .INI, zachowując ten jeden wiersz w zmiennej o nazwie strContents:

strContents = objFile.ReadAll

Po zamknięciu pliku używamy funkcji Split w celu rozdzielenia zawartości, używając przecinka jako delimitera. W ten sposób otrzymamy tablicę o nazwie arrContents zawierającą następujące dwa elementy:

  • 0
  • 0

Teraz przechodzimy do zabawniejszej części: używamy metody moveTo w celu przeniesienia okna aplikacji HTA do lokalizacji określonej za pomocą współrzędnych, używając wartości pierwszego elementu w tablicy (numer indeksu 0) jako wartości reprezentującej lewą stronę okna oraz wartości drugiego elementu z tablicy (numer indeksu 1) jako wartości reprezentującej górną krawędź okna.

window.moveTo arrContents(0), arrContents(1)

Mówiłem, że to będzie zabawne, prawda?

Rozwiązaliśmy już połowę problemu: podczas każdego uruchamiania aplikacja HTA odczyta plik .INI, zanalizuje jego zawartość i umieści okno według wartości zapisanych w pliku. To dobrze. Jak już mówiłem, to rozwiązuje połowę problemu. Co się stanie, jeżeli przesuniemy okno aplikacji HTA? W takim wypadku lewa i górna współrzędna zostaną zmienione i okno nie będzie już umieszczane w pozycji 0,0. To z kolei oznacza, że musimy zaktualizować plik .INI. Jak to zrobić? No i, co równie ważne, kiedy?

Zacznijmy od kwestii kiedy plik .INI powinien zostać zaktualizowany. Najlepszy moment na takie posunięcie jest tuż przed zamknięciem aplikacji HTA; czyli tuż przed uruchomieniem zdarzenia Window_onUnload. Oczywiście moglibyśmy aktualizować plik .INI po każdym przesunięciu okna, ale nie ma takiej potrzeby. Może ono zostać przesunięte jeszcze raz. I jeszcze raz i jeszcze raz; za każdym razem musielibyśmy aktualizować plik .INI. Żeby tego uniknąć czekamy do zamknięcia okna. W ten sposób zapisujemy współrzędne ostatniej znanej pozycji aplikacji HTA w pliku .INI.

Oczywiście tylko o to nam chodzi.

Aby zapisać te współrzędne, najpierw pobieramy wartości właściwości screenLeft oraz screenTop i zachowujemy je w dwóch zmiennych globalnych:

intLeft = window.screenLeft

intTop = window.screenTop

Następnie definiujemy stałą o nazwie ForWriting i ustawiamy jej wartość jako 2; ta stała umożliwia nam zapisywanie informacji w pliku HTA.ini. Teraz tworzymy nowe wystąpienie obiektu Scripting.FileSystemObject i otwieramy plik HTA.ini do zapisu:

Set objFile = objFSO.OpenTextFile("HTA.ini", ForWriting)

Teraz zostało nam tylko jedno: zastąpienie istniejącej zawartości pliku naszą lewą współrzędną, przecinkiem oraz górną współrzędną. Użyjemy w tym celu poniższego wiersza kodu:

objFile.WriteLine intLeft & "," & intTop

Następnie zamykamy plik i czekamy na ponowne uruchomienie aplikacji HTA. Kiedy tak się stanie, okno pojawi się dokładnie w tym samym miejscu, w którym znajdowało się kiedy zamykaliśmy aplikację HTA.

Czy to zadziała? Jest tylko jeden sposób, żeby się przekonać: spróbujcie i zobaczcie, co się stanie.

Ja tymczasem zbieram się pomału, nie mogę ciągle opóźniać powrotu do domu. Ktoś mógłby zacząć podejrzewać, że chcę się wymigać od tego malowania.

 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne