Przystosowanie aplikacji 16-bitowych

Modyfikowanie aplikacji może być stosunkowo prostą sprawą lub całkiem skomplikowanym zadaniem. Ten drugi przypadek ma miejsce wtedy, gdy nie dysponujemy kodem źródłowym programu.

Modyfikowanie aplikacji może być stosunkowo prostą sprawą lub całkiem skomplikowanym zadaniem. Ten drugi przypadek ma miejsce wtedy, gdy nie dysponujemy kodem źródłowym programu.

Ci wszyscy, którzy bazują na aplikacjach przystosowanych do konkretnego środowiska pracy (Excel, Word, Project czy Access), mogą mieć pewne kłopoty z przechodzeniam na system Win95. Mimo starań Microsofta, aby przechodzenie ze środowiska pracy opartego na 16-bitowych aplikacjach systemu Windows 3.1 na środowisko 32-bitowe (Win95) odbywało się w miarę płynnie, próby komunikowania się z obu tymi środowiskami jednocześnie mogą prowadzić do poważnych kłopotów.

Występują one wtedy, gdy jedna z 32-bitowych aplikacji pakietu Office zawiera polecenie odnoszące się do środowiska 16-bitowego (i odwrotnie), które wywołuje bibliotekę DLL (Dynamic Link Library) lub korzysta z usług złącza programowego API (Application Programming Interface). 32-bitowy program Excel powinien wywoływać 32-bitową bibliotekę DLL (czy złącze Windows 95 API), podobnie jak 16-bitowy Excel 16-bitową biblotekę czy Windows 3.1 API.

Dotyczy to wszystkich aplikacji, ale nie znaczy wcale, że aplikacje takie należy usunąć. Trzeba je jednak zmodyfikować. Sposób przeprowadzenia zmian zależy od tego, czy użytkownik zamierza korzystać zarowno z 16-, jak i 32-bitowych programów oraz czy dysponuje kodem źródłowym wywołań DLL i API.

Modyfikowanie kodu

Istnieją trzy sposoby rozwiązywania problemu. Pierwszy i najłatwiejszy polega na zmodyfikowaniu kodu aplikacji i zamianie wszystkich odwołań do Windows 3.1 API i 16-bitowej biblioteki DDL na odwołania do Windows 95 API oraz 32-bitowej biblioteki. Należy oczywiście pamiętać, że po dokonaniu tych zmian, aplikacja taka nie może już pracować w środowisku 16-bitowej biblioteki i 16-bitowych procedur złącza API.

Cały zabieg polega na zamianie np. 16-bitowego wywołania API (GetVersion):

Declare GetFunction GetVersion Lib

"KERNEL" () As Long

na 32-bitowe wywołanie:

Declare GetFunction GetVersion Lib

"KERNEL32" () As Long

Chociaż wygląda to dość prosto, należy jednak zachować czujność. Po pierwsze, zdarzają się nieraz takie wywołania API, których parametry (wyrażenia w nawiasach) mogą zmieniać wersję 16-bitową na 32-bitową (lub odwrotnie). Przystępując do modyfikowania aplikacji proszę to wziąć pod uwagę.

Aby wiedzieć, które wywołania należy zmodyfikować, radzę zapoznać się z plikiem tekstowym WIN32API.TXT, który Microsoft umieścił na dysku CD-ROM "Developer Network Development Library" (lipiec 1995). Innym źródłem informacji może być Reference of Win95 Programmers. W obu tych plikach znajdziecie Państwo spis wywołań do 32-bitowych procedur API, który ułatwi zadanie modyfikowania aplikacji.

Kolejnym powodem kłopotów może być bardzo banalna sprawa: złącze Windows 95 API rozróżnia duże i małe litery. Dlatego Microsoft radzi stosować nazwy umowne (alias):

Declare Function GetVersion Lib

"KERNEL32"Alias"GetVersion" () As Long

Teraz kod przetworzy wywołanie GetVersion API niezależnie od tego, czy wstawimy litery duże czy małe (nawet wtedy, jeśli użyjemy w jednym podprogramie kilku metod).

Po zmodyfikowaniu 16-bitowych wywołań API można przystąpić do 16-bitowej biblioteki DLL. Zadanie to jest proste, ale mimo to najlepiej zlecić je programiście.

Jeśli ktoś nie ma jednak dostępu do kodu źródłowego, modyfikacja komplikuje się nieco. 32-bitowy Windows używa płaskiego modelu adresowania pamięci, który opiera się na zupełnie innych zasadach, niż te stosowane przez 16-bitowy Windows. Należy w tym przypadku uruchomić proces, który podda konwersji jeden system adresowania pamięci na drugi.

Trzeba więc w tym momencie przywołać do pracy proces "thunking". W Win95 jest to szczególnego rodzaju interfejs (czy raczej konwerter) umieszczony między tą częścią systemu, która obsługuje aplikacje 32-bitowe a tą obsługującą aplikacje 16-bitowe. Zadaniem tego procesu jest szybkie poddawanie konwersji argumentów procedury API (zamiana kodu 16-bitowego na 32-bitowy lub odwrotnie), tak aby mogły być one ukryte przed procedurą API pracującą na kodzie innej długości.

Trzeba więc utworzyć 32-bitową procedurę DLL, która jest konwertem umiejscowionym między 16-bitowymi a 32-bitowymi stosami pamięci. Pozwala to być pewnym, że dane są prawidłowo zapisywane i odczytywane z tych stosów. DLL typu "thunking" wymaga stosowania specjalnego kompilatora. Proszę pamiętać, że Windows 95 i Windows NT realizują zadania "thunking" w odmienny sposób.

I chociaż wygląda to na całkiem proste zadanie, to jednak w przypadku przetwarzania dużej liczby wskaźników pamięci można się łatwo pogubić. Dlatego lepiej jest to zadanie powierzyć wykwalifikowanemu programiście.

Rozwiązanie uniwersalne

Jeśli przedsiębiorstwo zamierza w dalszym ciągu eksploatować 16-bitowe (np. Excel 5) i 32-bitowe (np. Excel 95) aplikacje pakietu Office, konieczne jest wprowadzenie dalszych modyfikacji. Trzeba napisać podprogram, który sprawdza czy dana aplikacja zawiera odwołania 16- czy 32-bitowe.

Podprogram taki należy umieszczać na samym początku aplikacji użytkowej. Służy on do ustawiania globalnej zmiennej "Bitnees". W przypadku konieczności skorzystania z procedur API lub biblioteki DLL należy użyć tej zmiennej do wybrania 16-bitowego lub 32-bitowego wywołania.

Na przykład w module Visual Basic for Applications (for Excel lub Project) pracę należy zacząć od zadeklarowania zmiennej Public Bitness: Public Bitness As Integer.

Następnie deklarujemy odpowiednie wywołania, zarówno 16-, jak i 32-bitowe. Oto przykład z zastosowaniem zaprezentowanej już wcześniej opcji GetVersion:

Declare Function GetVersion 16 Lib

"KERNEL"Alias"GetVersion" () As Long

Declare Function GetVersion32 Lib

"KERNEL32"Alias"GetVersion" () Ad Long

A oto kod sprawdzający aplikację:

Function BitnessCheck ()

If InStr(Application.Operating System, "32") then Bitness=32

End Function

W te miejsca, w których znajdują się wywołania GetVersionAPI, należy wstawić instrukcję if-then-else. Pozwala to wybrać odpowiednie wywołanie do API:

Function GetVersion () As Long

If Bitness=32 then

GetVersion=GetVersion32()

Else

GetVersion=GetVersion16()

End if

End Function

Funkcja GetVersion sprawdza zmienną Bitness i wywołuje odpowiednie API. (W przypadku DLL muszą być dostępne obie wersje bibliotek: 16- i 32-bitowa. Jeśli tak nie jest, konieczne będzie - gdy wywołujemy 16-bitową bibliotekę DLL z 32-bitowego programu pakietu Office - posłużenie się omówionym wcześniej procesem "thunking").

Uwaga - kod sprawdzający zmienną Bitness różni się nieco dla programów Access i Word. Dla programu Access należy wpisać:

Function BitnessCheck ()

If SysCMD(7)>2 then Bitnees=32

End Function

A dla programu Word:

Function BitneesCheck ()

If Val (GetSystemInfo$(23))>6.3 or

Len(GetSystemInfo$(23))=0 then

Bitnees=32

End Function

To warto przeczytać

Więcej informacji na temat kompatybilności 16- i 32-bitowych aplikacji wchodzących w skład pakietu Office można znaleźć w opracowanym przez Microsoft poradniku "Porting Your 16-bit Office-Based Solution to 32-bit Office". Dodatkowe informacje na ten temat odszukać można też w The Office Resource Kit.

Nasuwa się tu nieodparcie pytanie: skoro wiadomo jak to wszystko zrobić, dlaczego Microsoft nie wprowadził tych rozwiązań do swoich produktów? Programy Access, Word, Project i Excel z pakietu Office 95 same wykonywałyby zadanie konwersji 16-bitowych wywołań API na 32-bitowe, a instrukcja if-then-else sprawdzałaby aktualną wersję kodu. Odpowiedź brzmi: wbrew pozorom, nie jest to takie proste.

Michel Risse (odpowiedzialny w firmie Microsoft za Access) twierdzi, "jeśli bardzo, ale to rzeczywiście bardzo chcesz się narazić programistom, spróbuj dobrać się do ich programów. Nigdy nie można być pewnym, dlaczego akurat w tym miejscu znajduje się odwołanie do złącza API czy do biblioteki DLL i jaki to ma wpływ na pracę całej aplikacji?" Ludzie dopisują do programów takie rzeczy, których obecności nie można by się nigdy spodziewać".

W celu komercyjnej reprodukcji treści Computerworld należy zakupić licencję. Skontaktuj się z naszym partnerem, YGS Group, pod adresem [email protected]

TOP 200