Konfiguracja sprzętu i oprogramowania

Błąd Nie można utworzyć obiektu przez kontener activex. Tworzenie kontenerów formantów ActiveX

Aleksander Kostariew
Programista działu technologii R-Style Software Lab.

Tworzenie formantów ActiveX jest szeroko omawiane w literaturze specjalistycznej. Jednak znacznie rzadziej omawia techniki pisania kontenerów ActiveX, głównie tylko w ramach ich interakcji z obiektami ActiveX. Jeszcze mniej publikacji poświęconych jest procedurom tworzenia kontenerów obsługujących własny interfejs programistyczny (API), który umożliwia pracę z nimi oraz zawartymi w nich obiektami z innych aplikacji czy języków skryptowych. Przykładami takich kontenerów są takie produkty programowe jak Microsoft Visual Basic, Borland Delphi itp.

Niemniej jednak szeregu zadań nie da się rozwiązać w oparciu o istniejące kontenery – wymaga to specjalistycznych kontenerów kontroli. Jednym z takich wyzwań jest stworzenie rozszerzalnej aplikacji, która pozwala zautomatyzować typowe operacje, których nie można było przewidzieć podczas tworzenia. Automatyzacja wymaga, aby aplikacja udostępniała swoje obiekty na zewnątrz i była zintegrowana z narzędziem do tworzenia rozszerzeń. Budynek interfejs użytkownika opiera się w większości przypadków na wstawianiu różnych kontrolek do formularza - kontenera obiektów ActiveX. Tak więc stworzenie narzędzie wymaga utworzenia kontenera ActiveX.

Zastanowimy się nad niektórymi problemami, które pojawiają się przy wprowadzaniu architektury komponentowej do kompleksu narzędziowego, a także metodami ich rozwiązywania. Może to zainteresować zarówno deweloperów kontenerów kontrolnych, jak i deweloperów samych obiektów ActiveX, ponieważ w tym artykule przedstawiono cel i zastosowanie różnych metod standardowych interfejsów kontrolnych po stronie kontenera.

Proponowane rozwiązania opierają się na doświadczeniach rozwoju kompleksu narzędzi RS-Forms - nowość Produkt oprogramowania Laboratorium oprogramowania w stylu R. RS-Forms zawiera narzędzie programistyczne GUI użytkownik włączony Platforma Windows, środowisko wykonawcze programów tworzonych w językach RSL*, C i C++, a także system debugowania programów RSL.

*Obiekt RSL - język programowania wysoki poziom, stworzony przez R-Style Software Lab. Zobacz http://www.softlab.ru/products/rsl/, aby uzyskać szczegółowe informacje. - Notatka. wyd.

W ramach projektu zaimplementowano pierwszą wersję kreatora formularzy (rys. 1), która umożliwia tworzenie formularzy, osadzanie w nich zarówno standardowych kontrolek, jak i dowolnych obiektów ActiveX, zapisywanie gotowych formularzy w magazynie na trwałym nośniku medium i załaduj je z niego. Za pomocą projektanta możesz przeglądać właściwości, metody i zdarzenia dowolnego elementu kontrolnego osadzonego w formularzu, zmieniać wartości właściwości.

Projektant bazuje na kontenerze (formularzu) kontrolki ActiveX, który udostępnia opisaną powyżej funkcjonalność. Ponadto formularz obsługuje różne opcje ustawienia jego prezentacji, w tym procentowe wiązanie elementów osadzonych z obramowaniami, sterowanie kolejnością ich obchodzenia za pomocą klawiatury, ich widoczności, kroju i rozmiaru czcionki, koloru tła, tekstu itp.

Oprócz opracowania graficznego interfejsu użytkownika projektant posiada mechanizm automatycznego generowania kodu w C++ i RSL. Należy pamiętać, że wszystkie operacje wykonywane na formularzu w projektancie są również dostępne w trybie runtime z kodu programu.

Ryż. 1. Projektant formularzy.

Stworzony w projektanta formy graficzne może być używany w dowolnej aplikacji C/C++, a także w dowolnym języku skryptowym, takim jak Visual Basic lub RSL. Podczas korzystania z formularzy w aplikacjach C++ opracowanych za pomocą biblioteki MFC projektant może być używany jako edytor zasobów okna dialogowego.

Omówmy teraz koncepcję budowania kontenera oraz zasady pracy z kontrolkami ActiveX.

Podstawowe funkcje kontenera

Każdy kontener kontrolek powinien posiadać funkcjonalność pozwalającą na tworzenie obiektów ActiveX, zapewnianie ich poprawnego działania, usuwanie ich z pamięć o dostępie swobodnym, a także przechowywać przedmioty w magazynie obiektowym na trwałym nośniku pamięci i ładować je z niego*. Kontener zawiera szereg komponentów (rys. 2), które zapewniają standardową (zgodną z technologią Microsoft ActiveX) funkcjonalność niezbędną do prawidłowego działania kontrolek.

*Ogólne zagadnienia budowania kontenerów i serwerów obiektów COM są omówione w książce D. Chappel „ActiveX and OLE Technologies” - M.: „Russian Edition”, 1997.

Kontener przechowuje kolekcję (na przykład listę) obiektów połączeń z kontrolkami ActiveX, jeden obiekt połączenia na kontrolkę. Ponadto programowalny kontener musi zapewniać standardowy mechanizm manipulacji elementami tej kolekcji.

Za poprawną interakcję odpowiedniego elementu z kontenerem odpowiada obiekt strony kontrolnej. Każdy obiekt połączenia zawiera podobiekt, który rozszerza kontrolkę o zestaw właściwości, metod i zdarzeń specyficznych dla kontenera. Taki podobiekt nazywa się rozszerzoną kontrolą. Przykładem właściwości rozszerzonych jest nazwa (Name), lokalizacja w kontenerze (Width, Left) i tak dalej. Podane zestawy są właściwościami kontenera, a nie jakiejkolwiek indywidualnej kontrolki, chociaż tak to wygląda dla użytkownika systemu. Istnieje kilka opcji implementacji rozszerzonej kontroli. Na przykład może to być podobiekt obiektu komunikacyjnego (patrz rysunek 2) lub rzeczywisty obiekt COM, który agreguje pierwotne sterowanie. Każda z opcji ma swoje zalety i wady. W tym artykule rozważamy tylko pierwszą metodę.

Każda rozszerzona kontrolka zawiera jako podobiekt obiekt ujścia zdarzeń z skojarzonej z nim kontrolki (rysunek 2). Jego zadania obejmują podstawową identyfikację odebranych zdarzeń (czy wymagane jest niestandardowe przetwarzanie zdarzeń, czy nie) oraz, jeśli to konieczne, przekazywanie ich do obiektu właściciela (kontrola rozszerzona), który zapewnia kierowanie zdarzeń wzdłuż hierarchii obiektów kontenera.

Skrypt tworzenia sterowania

Wstrzykiwanie kontrolki do kontenera składa się z trzech faz: tworzenia obiektu ActiveX, inicjowania go i aktywowania.

Kontrolki są tworzone w przestrzeni adresowej kontenera za pomocą standardowe funkcje COM jak CoCreateInstance. Odpowiedni globalnie unikalny identyfikator CLSID jest przekazywany do funkcji jako identyfikator kontrolki. Należy zauważyć, że kontener musi obsługiwać różne opcje identyfikacji obiektów COM w systemie – np. identyfikator programu ProgID, unikalny identyfikator klasy w postaci ciągu itp.

Głównym celem fazy inicjalizacji jest przekazanie do kontrolki wskaźnika do interfejsu IOleClientSite obiektu połączenia poprzez funkcję IOleObject::SetClientSite i wywołanie funkcji IPersistStreamInit::InitNew lub IPersistStreamInit::Load (w zależności od tego, czy obiekt jest ładowane z magazynu lub nie). Przekazywanie obiektu wskaźnika do interfejsu IOleClientSite może nastąpić przed załadowaniem/inicjalizacją lub po; o momencie transmisji decyduje obecność atrybutu OLEMISC_SETCLIENTSITEFIRST (IOleObject::GetMiscStatus). Jest to o tyle istotne, że przekazywanie wskaźnika określa, w jakim momencie kontrolka otrzyma z kontenera wartości właściwości otoczenia. Jeśli ta funkcja zostanie zignorowana, dalsze działanie obiektu ActiveX może być nieprawidłowe.

Następnie w ramach rozważanej fazy należy przeprowadzić inicjalizację właściwości rozszerzonej kontrolki, która uzupełnia tworzony obiekt ActiveX. Na przykład trzeba poprawnie ustawić nazwę obiektu (zainicjować właściwość Name, która zapewnia identyfikację kontrolek w kontenerze). Każda kontrolka osadzona w programowalnym kontenerze musi obsługiwać tę właściwość, ale nadal jest właściwością kontenera. Często obiektom domyślnie przypisywana jest skrócona nazwa klasy, do której należą (nazwa ta jest zwracana przez metodę IOleObject::GetUserType dla parametru USERCLASSTYPE_SHORT), z dodanym indeksem liczbowym, aby zapewnić, że nazwy kontrolek w pojemniki są wyjątkowe. Jeśli otrzymasz określone imię nie powiedzie się, lub jeśli nie spełnia logiki kontenera, można nadać predefiniowaną nazwę z odpowiednim indeksem.

Aktywacja kontrolki implikuje pewną sekwencję działań. Pierwszym krokiem jest ustanowienie łącza zwrotnego obiektu ActiveX do obiektu łącza w kontenerze (witrynie kontrolnej). W tym celu wywoływana jest metoda IOleObject::Advise, do której przekazywany jest wskaźnik do standardowy interfejs Obiekt połączenia IAdviseSink. Następnie należy poprawnie zażądać interfejsu z rodziny IViewObject (zgodnie ze specyfikacją obiekt ActiveX może obsługiwać interfejsy IViewObject, IViewObject2, IViewObjectEx, które są w hierarchii dziedziczenia) i ustalić informację zwrotną dla niego, wywołując IViewObject:: Metoda SetAdvise przekazująca wskaźnik do IAdviseSink. Dodatkowo należy podać kontrolce nazwę jej kontenera (realizuje się to poprzez wywołanie metody IOleObject::SetHostName), zażądać i zapisać wszystkie interfejsy wymagane do poprawnej pracy z obiektem ActiveX (przynajmniej IOleInPlaceObject i IOleControl). Ostatnią rzeczą, jaką należy zrobić, aby wizualnie renderować kontrolkę, jest wywołanie funkcji IOleObject::DoVerb* z parametrem OLEIVERB_INPLACEACTIVATE.

*W implementacji ATL określona funkcja odpowiada między innymi za tworzenie okna dla normalnych (okienkowych) kontrolek.

Skrypt usuwania kontroli

Aby usunąć z pamięci kontrolkę osadzoną w kontenerze, należy wykluczyć z kolekcji obiekt skojarzenia z odpowiadającą mu kontrolką, a następnie wykonać kolejno dwie operacje: break sprzężenie zwrotne i uwolnienie zapisanych wskaźników do interfejsów obiektu ActiveX.

Aby zerwać linki zwrotne, należy najpierw poinformować usuwany element o konieczności zwolnienia (poprzez wywołanie metody IUnknown::Release) trzymanych przez niego wskaźników do interfejsu IAdviseSink obiektu linku. W tym celu wywoływane są metody IViewObject::SetAdvise (przekazujące NULL jako argument) oraz IOleObject::Unadvise, do którego należy podać identyfikator relacji zapisany podczas fazy aktywacji. Następnie należy aktywować procedurę deinicjalizacji obiektu ActiveX (poprzez wywołanie funkcji IOleObject::Close). Następnym krokiem jest poinformowanie kontrolki o zwolnieniu wskaźnika interfejsu IOleClientSite przez wywołanie IOleObject::SetClientSite z parametrem NULL.

Faza uwalniania zapisanych wskaźników do interfejsów sterujących polega na wywoływaniu na nich kolejno metody Release. Jak tylko ostatni wskaźnik zostanie zwolniony, obiekt (zgodnie z technologią COM) zostanie usunięty z pamięci RAM.

Zapisz i załaduj skrypt

Zapisanie obiektu kontenera do pamięci, niezależnie od rodzaju tego ostatniego, polega na zapisaniu właściwości kontenera (takich jak właściwości środowiska) oraz kolekcji osadzonych kontrolek, czyli identyfikatorów i właściwości (w tym rozszerzonych) każdego obiektu należący do kolekcji. Identyfikator kontrolki może być globalnie unikalnym identyfikatorem klasy CLSID. Umożliwi to etapowi inicjalizacji utworzenie wymaganego obiektu ActiveX i załadowanie go danymi zawartymi w sklepie po określonym identyfikatorze. Aby zapisać właściwości kontrolki, na przykład w strumieniu, wywoływana jest metoda Save standardowego interfejsu obiektu ActiveX IPersistStreamInit. Aby załadować, wywoływana jest metoda Load tego samego interfejsu.

Ta procedura składowania zapewnia, że ​​obiekt kontenera zostanie później odtworzony z pamięci. Opisana metoda działa dobrze pod warunkiem, że od momentu zapisania do momentu załadowania nie nastąpiły żadne zmiany wersji ani usunięcie jakichkolwiek kontrolek z systemu. Takie sytuacje często pojawiają się podczas migracji magazynu danych z jednego komputera na inny, na którym nie zainstalowano ani nie zarejestrowano zapisanych formantów ActiveX. W takim przypadku wczytanie obiektu kontenera z magazynu albo doprowadzi do krytycznego zakończenia programu, albo spowoduje błąd podczas ładowania całego kontenera jako całości. Aby zapobiec błędom, konieczne jest wyraźne ustalenie granicy między danymi różnych kontroli, zapisując do pamięci po identyfikatorze obiektu rozmiar przechowywanych przez nią informacji. Dzięki temu faza ładowania będzie mogła dokładnie ustawić się na początku danych każdego obiektu ActiveX, a także pominąć kontrolki, które nie są zarejestrowane w systemie, ale ładują obiekt kontenera jako całość.

Interfejsy gromadzenia obiektów ActiveX

Zgodnie ze standardem kontener kontrolny musi zapewniać interakcję pomiędzy osadzonymi w nim obiektami ActiveX. Aby to zrobić, musisz obsługiwać interfejs IOleContainer, który pozwala wyliczyć wszystkie wstawione do niego kontrolki. Jeśli istnieje rozszerzona kontrolka, wyliczenie musi przechodzić przez jego interfejsy IUnknown, a nie interfejsy obiektu bazowego.

Aby zapewnić dostęp do kolekcji klientom automatyzacji, użyj standardowego interfejsu zbierania obiektów. Standardowa kolekcja obejmuje metody Add, Remove, Clear, Item oraz właściwości _NewEnum i Count, które zapewniają kompleksową iterację elementów. Na przykład konstrukcja język wizualny Basic dla każdego używa właściwości _NewEnum do wyliczania elementów i konstrukcji w następnym wiąże się z użyciem właściwości Count i metody Item. W Object RSL podczas uzyskiwania dostępu używana jest właściwość _NewEnum metoda standardowa CreateEnum obiekt ActiveX. Ilustruje to na przykład program RSL, który drukuje nazwy plików otwieranych w aplikacji przy użyciu określonej metody. Microsoft Excel(jego tekst podano poniżej).

importuj rslx; ob = ActiveX("Excel.Aplikacja", null, prawda); pl = ob.Skoroszyty.CreateEnum; while (en.next) println(pl.item.Name) end;

Powyższe scenariusze umożliwiają tworzenie funkcji dodawania kontrolki do kontenera i usuwania go z niego. W większości przypadków funkcja add tworzy obiekt łącza z kontrolką (która przechowuje wszystkie wskaźniki do interfejsów obiektu ActiveX, których potrzebuje do działania) i wywołuje na nim podobną funkcję. Ten z kolei realizuje opisany powyżej scenariusz implementacji (być może bez fazy aktywacji). Jeśli utworzenie obiektu ActiveX w pamięci RAM powiodło się, funkcja kontenera dodaje do kolekcji odpowiedni obiekt łącza. Często ze względu na ich podobieństwo procedury osadzania i ładowania kontrolki ze sklepu są łączone.

* * *

Omówiliśmy tutaj główne kwestie związane z budowaniem kontenerów kontrolnych: wstrzykiwanie, wyświetlanie wizualne, zapisywanie i ładowanie obiektu ActiveX, a także jego poprawne usuwanie z pamięci RAM. Jednak w procesie tworzenia graficznego środowiska pracy musieliśmy zaimplementować kilka kontenerów, które różniłyby się od siebie dostarczonymi interfejsami automatyzacji, podzbiorami obiektów ActiveX, które można wstrzykiwać, zestawami właściwości, metod i zdarzeń rozszerzonych kontrolek, i tak dalej. W tym celu zaproponowano model, który pozwala na tworzenie różnych elementów kontenera i dobrze integruje się z biblioteką ATL. Niezależność od konkretnych interfejsów uzyskuje się poprzez zastosowanie klas szablonowych, których parametrami są te interfejsy.

*Na przykład formant Tab jest kontenerem stron właściwości, które są kontenerami ogólnego przeznaczenia.

Model ten pozwala na szybkie tworzenie podstawowych wariantów różnych obiektów ActiveX, które mają wpisaną „logikę kontenera”. Dodatkowo zaimplementowana infrastruktura pozwala na tworzenie kontenerów, które nie są kontrolkami. Taki pojemnik można ustawić jako Okna Windows do dowolnej części tworzonej aplikacji, a następnie, wysyłając odpowiednie komunikaty, zaimplementuj w niej różne kontrolki.

Rezultatem jest dość elastyczna architektura do budowania kontenerów, dzięki której można stworzyć kreatora (Wizard), który rozszerza funkcjonalnośćŚrodowiska Microsoft studio wizualne do mechanizmu generowania szkieletu kontenera.


Ręczna edycja rejestru systemu Windows w celu usunięcia nieprawidłowych kluczy Błąd 800A01AD nie jest zalecany, chyba że jesteś profesjonalistą w zakresie obsługi komputera. Błędy popełnione podczas edycji rejestru mogą spowodować, że komputer stanie się bezużyteczny i spowodować nieodwracalne uszkodzenia system operacyjny. W rzeczywistości nawet pojedynczy przecinek w niewłaściwym miejscu może uniemożliwić uruchomienie komputera!

Z uwagi na to ryzyko stanowczo zalecamy korzystanie z zaufanego narzędzia do czyszczenia rejestru, takiego jak WinThruster [Pobierz] (stworzonego przez firmę Microsoft Gold Certified Partner), które umożliwia skanowanie i naprawianie wszelkich błędów 800A01AD. Korzystając z narzędzia [Download] Registry Cleaner, możesz zautomatyzować proces wyszukiwania uszkodzonych wpisów rejestru, brakujących odniesień do plików (takich jak ten, który powoduje błąd %%error_name%%) i uszkodzonych łączy w rejestrze. Przed każdym skanowaniem automatycznie tworzony kopia zapasowa, który pozwala cofnąć wszelkie zmiany jednym kliknięciem i chroni przed możliwym uszkodzeniem komputera. Najlepsze jest to, że naprawienie błędów rejestru [Pobierz] może drastycznie poprawić szybkość i wydajność systemu.


Ostrzeżenie: Jeśli nie jesteś zaawansowanym użytkownikiem komputera, NIE zalecamy ręcznej edycji rejestru systemu Windows. Nieprawidłowe korzystanie z Edytora rejestru może prowadzić do poważnych problemów i wymagać ponowna instalacja systemu Windows. Nie gwarantujemy rozwiązania problemów wynikających z niewłaściwego korzystania z Edytora rejestru. Korzystasz z Edytora rejestru na własne ryzyko.

Przed ręcznym przywróceniem Rejestr systemu Windows, musisz utworzyć kopię zapasową, eksportując część rejestru związaną z błędem 800A01AD (na przykład ActiveX):

  1. Kliknij przycisk Na początek.
  2. Wchodzić " Komenda" v pasek wyszukiwania... NIE NACISKAJ JESZCZE WCHODZIĆ!
  3. Trzymanie klawiszy CTRL+Shift na klawiaturze naciśnij WCHODZIĆ.
  4. Wyświetlone zostanie okno dialogowe dostępu.
  5. Kliknij tak.
  6. Czarna ramka otwiera się z migającym kursorem.
  7. Wchodzić " regedit" i naciśnij WCHODZIĆ.
  8. W Edytorze rejestru wybierz klucz związany z plikiem Error 800A01AD (np. ActiveX), dla którego chcesz utworzyć kopię zapasową.
  9. W menu Plik wybierać Eksport.
  10. Katalogowany Zapisz do wybierz folder, w którym chcesz zapisać kopię zapasową klucza ActiveX.
  11. W terenie Nazwa pliku wprowadź nazwę pliku kopii zapasowej, np. „ActiveX Backup”.
  12. Upewnij się, że pole Zakres eksportu wybrana wartość Wybrany oddział.
  13. Kliknij Zapisać.
  14. Plik zostanie zapisany z rozszerzeniem .reg.
  15. Utworzono kopię zapasową wpisu rejestru związanego z formantami ActiveX.

Kolejne kroki ręcznego edytowania rejestru nie zostaną omówione w tym artykule, ponieważ mogą uszkodzić system. Jeśli chcesz uzyskać więcej informacji na temat ręcznej edycji rejestru, skorzystaj z poniższych łączy.

Systemy i były dostępne wszystkie powiązane . Ten błąd ma następujące przyczyny i rozwiązania:

    Klasa nie jest zarejestrowana. Na przykład nie ma wzmianki o klasie w rejestrze systemu lub klasę wymienia się, ale wskazuje plik niewłaściwego typu lub plik, którego nie można znaleźć. Jeśli to możliwe, uruchom aplikację obiektu. Jeśli informacje w rejestrze są nieprawidłowe lub nieaktualne, aplikacja sprawdzi rejestr i poprawi informacje. Jeśli uruchomienie aplikacji nie rozwiąże problemu, uruchom ponownie instalator aplikacji;

    Nie mogę użyć DLL Wymagany przez obiekt, ponieważ nie został znaleziony lub został uszkodzony. Upewnij się, że wszystkie powiązane biblioteki DLL są dostępne. Na przykład obiekt dostępu do danych (DAO) wymaga obsługi bibliotek DLL, które różnią się w zależności od platformy. Jeśli to jest przyczyną błędu, musisz ponownie uruchomić instalator dla tego elementu;

    Obiekt jest dostępny na komputerze, ale jest licencjonowany i nie może sprawdzić, czy licencja wymagana do utworzenia wystąpienia obiektu jest dostępna.

    Niektóre obiekty można utworzyć dopiero po znalezieniu przez komponent klucz licencyjny A potwierdzający, że ten obiekt jest zarejestrowany do tworzenia instancji w dniu ten komputer. Jeśli w prawidłowo ustawionym lub prawidłowym kluczu znajduje się odniesienie do obiektu, jest dostarczane automatycznie.

    Jeśli próba utworzenia instancji jest wynikiem wywołania funkcji Utwórz obiekt lub Pobierz obiekt, obiekt musi znaleźć klucz. W takim przypadku może przeszukiwać rejestr systemu lub wyszukiwać plik specjalny, który tworzy podczas instalacji (na przykład z rozszerzeniem .LIC). Jeśli nie można znaleźć klucza, nie można utworzyć wystąpienia obiektu. Jeśli użytkownik końcowy błędnie skonfigurował aplikację obiektu, zostanie trwale usunięty żądany plik lub zmienił rejestr systemowy, obiekt nie będzie mógł znaleźć swojego klucza. Jeśli nie można znaleźć klucza, nie można utworzyć wystąpienia obiektu. W takim przypadku tworzenie instancji może działać w systemie programisty, ale nie w systemie użytkownika. Użytkownik musi ponownie zainstalować licencjonowany element;

    Próbujesz użyć funkcji pobierania obiektu Pobierz obiekt aby uzyskać odniesienie do klasy utworzonej za pomocą za pomocą wizualizacji podstawowy. Pobierz obiekt nie można użyć do uzyskania odwołania do klasy utworzonej za pomocą Visual Basic;

    Dostęp do obiektu jest jawnie zabroniony. Na przykład próbujesz uzyskać dostęp do obiektu danych, który jest aktualnie używany i zablokowany, aby zapobiec zakleszczeniu. W takim przypadku możesz uzyskać dostęp do obiektu w innym czasie.

Za zdobycie Dodatkowe informacje wybierz element, o który masz pytanie i naciśnij F1 (Windows) lub HELP (Macintosh).

Podobał Ci się artykuł? Podziel się z przyjaciółmi!
Czy ten artykuł był pomocny?
tak
Nie
Dziekuję za odpowiedź!
Coś poszło nie tak i Twój głos nie został policzony.
Dziękuję Ci. Twoja wiadomość została wysłana
Znalazłeś błąd w tekście?
Wybierz, kliknij Ctrl+Enter a my to naprawimy!