ActiveX 1
Katedra Optoelektroniki i Systemów Elektronicznych
ActiveX 2
Oprogramowanie Systemów Elektronicznych
Zagadnienia: 1. 2. 3. 4. 5.
Temat wykładu
Kontrolki ActiveX
ActiveX 3
Technologia ActiveX DDE
OLE
COM ActiveX
VBX
OCX
OLE (Object Linking and Embedding) – osadzanie i łączenie obiektów. Technologia pozwalająca na umieszczanie jednego obiektu wewnątrz drugiego i prezentowania go w takiej formie, jak czyni to aplikacja macierzysta. COM (Component Object Model) – model programowania zorientowanego obiektowo, udostępniającego programiście technologię OLE. VBX (Visual Basic Controls) – kontrolki wizualne utworzone za pomocą Visual Basic (16-bitowe). OCX (OLE Control Extension) – kontrolki wizualne przeniesione na platformę 32bitową, wykorzystujące technologię OLE. ActiveX – promowana przez Microsoft technologia pozwalająca na stosowanie obiektów OLE wewnątrz innych dokumentów w sposób niezależny od systemu operacyjnego.
ActiveX 5
Technologia ActiveX
Jedną z kluczowych technologii występujących w obiektach ActiveX jest automatyzacja. Automatyzacja pozwala aplikacji, będącej serwerem ActiveX (ang. ActiveX server), na osadzanie się wewnątrz innej aplikacji stanowiącej kontener ActiveX (ang. ActiveX container), aktywowanie się i kontrolowanie należącej do niej części interfejsu użytkownika lub dokumentu. Kiedy użytkownik wykona niezbędne zmiany i przejdzie do innej części programu nie kontrolowanej przez aplikację osadzoną, ta samoczynnie kończy swoją pracę.
Kontrolki ActiveX
Technologia ActiveX Programowanie interfejsów Rejestrowanie kontrolek ActiveX Projektowanie kontrolki ActiveX w Visual Studio C++ Wykorzystanie kontrolek ActiveX
ActiveX 4
Technologia ActiveX
Interfejs – zbiór logicznie powiązanych właściwości, metod i zdarzeń obejmujących określoną funkcjonalność (wygląd obiektu, współdziałanie z otaczającą aplikacją, wywoływanie zdarzeń). Technologia COM określa, w jaki sposób aplikacje i pojedyncze komponenty mogą współpracować poprzez użycie interfejsów. Technologia ActiveX definiuje z kolei płaszczyznę zbudowaną na szczycie modelu COM, określając jakiego typu interfejsy powinny wspierać różne obiekty, a także jak różne obiekty powinny ze sobą współpracować.
ActiveX 6
Technologia ActiveX
Każdy obiekt ActiveX, który może mieć osadzone w sobie inne obiekty ActiveX, jest kontenerem ActiveX. Zatem jedna aplikacja może być równocześnie kontenerem oraz serwerem ActiveX. Serwer ActiveX 4 Kontener ActiveX 1 Kontener ActiveX 3
Serwer ActiveX 1
Serwer ActiveX 2 Serwer ActiveX 5 Kontener ActiveX 2 Serwer ActiveX 3
Przykłady: - Edycja równania MS Equation lub arkusza MS Excel w dokumencie MS Word. - Przeglądanie plików pdf w przeglądarce internetowej. - Wykorzystanie komponentów graficznych CVI w aplikacjach Visual C++
Kontrolka ActiveX jest szczególnym przykładem serwera ActiveX, który nie jest aplikacją i nie jest w stanie funkcjonować samodzielnie. Może być jednak osadzony w innej aplikacji, czyniąc ją automatycznie kontenerem ActiveX.
1.1
ActiveX 7
Technologia ActiveX
Każdy obiekt ActiveX posiada właściwości, które określają jego wygląd oraz sposób interakcji z otoczeniem (kontenerem). Podstawowe grupy właściwości: Ambient – zawierają informacje dotyczące parametrów kontenera związanych z jego wyglądem. Są one udostępniane kontrolce ActiveX w celu umożliwienia dopasowania jej wyglądu do wyglądu kontenera. Kontrolka nie może zmieniać wartości tych właściwości. Przykładowe właściwości należące do tej grupy to BackColor, ForeColor, Font, ScaleUnits (nazwa jednostki odległości używanej przez kontener). Control – właściwości ustawiane przez kontrolkę podczas jej osadzania w kontenerze. Zawierają podstawowe parametry związane z typem pracy i wyglądem, np. Enabled, Hwnd (uchwyt do okna kontrolki), Caption, Appearnace (FALSE dla kontrolki 2-D, TRUE dla kontrolki 3-D). Kontrolka utworzona w oparciu o bibliotekę MFC zawiera 9 podstawowych właściwości typu Control. Są to tzw. Stock Properties. Dodając funkcjonalność kontrolki ActiveX programista określa natomiast nowe właściwości, czyli tzw. Custom Properties. Extended - dodatkowe właściwości ustawiane przez kontener np. Visible, Parent.
ActiveX 9
Kontrolki ActiveX
Technologia ActiveX
Obiekt ActiveX posiada metody, które pozwalają na sterowanie jego pracą z poziomu kontenera. Metody te definiowane są przez programistę. W MFC oprócz tego definiowane są dwie metody tzw. Stock Methods: Refresh() („odświeżenie” wyglądu kontrolki) oraz DoClick() (symulacja naciśnięcia klawiszem myszy na kontrolkę). Obie metody są metodami klasy ColeControl. Obiekt ActiveX generuje zdarzenie (Event) w sytuacji, gdy odbierze określony komunikat kierowany do niej przez system lub gdy użytkownik wykona na obiekcie określoną operację. Zdarzenia generowane przez obiekt ActiveX są przekazywane do kontenera, którego zadaniem jest ich obsługa. Typowe zdarzenia związane są z komunikatami generowanymi przez urządzenia peryferyjne (klawiatura, mysz). W MFC są to Click, DblClick, KeyDown, KeyPress, MouseDown, MouseMove. Programista może oczywiście dodawać nowe zdarzenia, które są generowane przez kontrolkę w różnych sytuacjach, np. kontrola zakresu wartości liczbowych, współpraca z inną kontrolką lub aplikacją, monitorowanie zdarzeń interfejsu szeregowego.
ActiveX 10
Programowanie interfejsów
Interfejs IUnknown jest wymagany w każdym obiekcie ActiveX i służy do ustalenia jakie inne interfejsy są przez obiekt wspierane.
Zagadnienia: 1. 2. 3. 4. 5.
ActiveX 8
Technologia ActiveX Programowanie interfejsów Rejestrowanie kontrolek ActiveX Projektowanie kontrolki ActiveX w Visual Studio C++ Wykorzystanie kontrolek ActiveX
Interfejs IUnknown udostępnia trzy podstawowe metody: QueryInterface – zwrócenie tablicy wskaźników do wspieranych interfejsów. AddRef, Release – Zwiększenie/zmniejszenie licznika odwołań do interfejsu. Jeżeli licznik odwołań zmniejszy się do zera interfejs jest usuwany z pamięci. Metody stosowane w celach diagnostycznych. Ponadto obiekty AvtiveX powinny posiadać zdolność do samorejestrowania się.
ActiveX 11
Programowanie interfejsów
Rodzaje interfejsów: Kontener ActiveX • • • • • • • • •
• • • •
IOleInPlaceFrame IOleInPlaceUIWindow IOleInPlaceSite IOleClientSaite IAdviseSink IOleControlSite IDispatch (properties) IPropertyNotifySink IDispatch (events) Cztery obszary funkcjonalności: GUI Metody Zdarzenia Właściwości
Serwer (kontrolka) ActiveX • • • • • • • • • • • • • • •
IOleInPlaceActiveObject IOleInPlaceObject IOleObject IRunnableObject IDataObject IViewObject2 IOleCache2 IPersistStorage IPersistStreamInit ISpecifyPropertyPages IConnectionPointContainer IConnectionPoint IProvideClassInfo2 IDispatch (methods) IOleControl
ActiveX 12
Programowanie interfejsów
Wzajemne oddziaływanie między serwerem a kontenerem ActiveX odbywa się głównie przez trzy interfejsy IDispatch. Jeden z tych interfejsów należy do kontrolki, pozostałe do kontenera. Kontener ActiveX
Serwer (kontrolka) ActiveX
zdarzenia
właściwości
metody
1.2
ActiveX 13
Programowanie interfejsów
Podstawowym elementem umożliwiającym automatyzację jest interfejs IDispatch (dispinterface). Został utworzony, aby umożliwić nie obiektowym językom programowania (np. Visual Basic) odwoływanie się do obiektów COM. Interfejs IDispatch udostępnia cztery podstawowe metody: 1. GetTypeInfoCount – służy do sprawdzania, ile typów zostało zadeklarowanych w bibliotece typów danego obiektu COM; 2. GetTypeInfo – zwraca informacje, z których możemy dowiedzieć się, ile metod oferuje konkretny obiekt, jakie są ich nazwy i parametry ich wywołań; czasami zawiera opisy metod; 3. GetIDsOfNames – zwraca uchwyt (wskaźnik) do metody, której nazwa została przekazana jako parametr wywołania funkcji; 4. Invoke – powoduje wykonanie metody, odczyt lub zmianę wartości właściwości o identyfikatorze pobranym przez funkcję GetIDsOfNames.
ActiveX 15
Programowanie interfejsów
HRESULT Invoke( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult, EXCEPINFO FAR* pExcepInfo, unsigned int FAR* puArgErr); Parametry funkcji Invoke: DISPID dispIdMember - identyfikator (metody, właściwości) REFIID riid - IID_NULL LCID lcid identyfikator narodowościowy, wykorzystywany przez funkcję GetIDsOfNames WORD wFlags - przyczyna wywołania funkcji: DISPATCH_METHOD – wywołanie metody DISPATCH_PROPERTYGET – pobranie wartości właściwości DISPATCH_PROPERTYPUT – ustawienie wartości właściwości DISPATCH_PROPERTYPUTREF - ustawienie wartości właściwości poprzez zmienną referencyjną
ActiveX 17
Programowanie interfejsów
Przykładowe wartość zwracana przez funkcję Invoke: Return value S_OK DISP_E_BADPARAMCOUNT DISP_E_BADVARTYPE DISP_E_EXCEPTION
Meaning OK Niewłaściwa liczba parametrów Niewłaściwy typ parametru Wystąpił wyjątek
DISP_E_MEMBERNOTFOUND Właściwość nie istnieje, lub jest tylko do odczytu DISP_E_NONAMEDARGS Implementacja interfejsu IDispatch nie zezwala na stosowanie nazw parametrów DISP_E_PARAMNOTFOUND Nie znaleziono parametru
ActiveX 14
Programowanie interfejsów
Interfejs IDispatch zawiera wskaźnik do tablicy aktywnych metod, które mogą być uruchamiane wewnątrz kontrolki ActiveX lub osadzonej aplikacji. Każda metoda posiada identyfikator DISPID. Uruchomienie metody osadzonego obiektu odbywa się przez wywołanie funkcji Invoke z parametrem DISPID, identyfikującym metodę. Obiekt
Idispatch::Invoke(DISPID)
Klient
Tablica inentyfikatorów interfejsu IDispatch Invoke() switch case case case } }
ActiveX 16
{ (DISPID) { 1: MetodaX(); 2: MetodaY(); 3: MetodaZ();
Programowanie interfejsów
Parametry funkcji Invoke cd.: DISPPARAMS FAR* pDispParams -
wskaźnik do struktury DISPPARAMS, przez którą przekazywane są parametry VARIANT FAR* pVarResult - wskaźnik do obszaru pamięci gdzie ma zostać zapisany rezultat wykonania funkcji. Jeśli funkcja nic nie zwraca to NULL. Parametr jest ignorowany jeśli ustawiane są wartości właściwości. EXCEPINFO FAR* pExcepInfo Wskaźnik do struktury zawierającej informacje o błędzie. Może być NULL. unsigned int FAR* puArgErr – pierwszy element w tablicy parametrów funkcji dla którego wystąpił błąd. Parametr jest aktualizowany jeśli funkcja Invoke zwróci DISP_E_TYPEMISMATCH lub DISP_E_PARAMNOTFOUND.
ActiveX 18
Programowanie interfejsów
Parametry dla metody lub właściwości są przekazywane przez strukturę DISPPARAMS typedef struct FARSTRUCT tagDISPPARAMS{ VARIANTARG FAR* rgvarg; // tablica argumentów DISPID FAR* rgdispidNamedArgs; // Identyfikatory argumentów zdefiniowanych nazwami unsigned int cArgs; // Liczba argumentów unsigned int cNamedArgs; // Liczba argumentów zdefiniowanych nazwami } DISPPARAMS; Parametry w tablicy rgvarg są przekazywane w odwrotnej kolejności, tj. rgvarg[cArgs–1] – pierwszy parametr rgvarg[0] – ostatni parametr
1.3
ActiveX 19
Programowanie interfejsów
ActiveX 20
Programowanie interfejsów
Zmienna typu VARIANT: typedef struct FARSTRUCT tagVARIANT VARIANTARG; struct FARSTRUCT tagVARIANT{ VARTYPE vt; //typ parametru unsigned short wReserved1; unsigned short wReserved2; unsigned short wReserved3; union { short iVal; /* VT_I2 */ // wartość parametru // The rest of this union specifies numerous other types.
Zmienna typu VARTYPE: typedef unsigned short VARTYPE; enum VARENUM { VT_EMPTY = 0, VT_NULL = 1, VT_I4 = 3, VT_R4 = 4, VT_CY = 6, VT_DATE = 7, VT_DISPATCH = 9, VT_ERROR = 10, VT_VARIANT = 12, VT_UNKNOWN = 13,
}; } VARIANTARG;
VT_RESERVED = 0x8000 VT_BYREF = 0x4000 VT_ARRAY = 0x2000
ActiveX 21
Programowanie interfejsów
VT_I2 = 2, VT_R8 = 5, VT_BSTR = 8, VT_BOOL = 11, VT_UI1 = 17, ...
};
ActiveX 22
Programowanie interfejsów
Przykład wywołania metody Simple klasy CMyObject (bez parametrów):
Przykład wywołania metody Simple klasy CMyObject (bez parametrów) cd.:
HRESULT hresult; // rezultat wykonania funkcji IUnknown FAR* punk; // wskaźnik do interfejsu IUnknown IDispatch FAR* pdisp = (IDispatch FAR*)NULL; // wskaźnik do interfejsu IDispatch OLECHAR FAR* szMember = "Simple"; // nazwa metody DISPID dispid; // identyfikator metody DISPPARAMS dispparams = {NULL, NULL, 0, 0}; // struktura z parametrami dla metody Simple
// Pobranie wskaźnika do interfejsu IDispatch (pdisp) hresult = punk->QueryInterface(IID_IDispatch, (void FAR* FAR*)&pdisp); // Pobranie identyfikatora metody „Simple” (dispid) hresult = pdisp->GetIDsOfNames(IID_NULL, &szMember, 1, LOCALE_USER_DEFAULT, &dispid); // Wywołanie funkcji „Simple” hresult = pdisp->Invoke( dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, NULL, NULL, NULL);
//Osadzenie obiektu klasy CMyObject i pobranie wskaźnika do interfejsu IUnknown (punk) hresult = CoCreateInstance(CLSID_CMyObject,NULL, CLSCTX_SERVER, IID_Unknown, (void FAR* FAR*)&punk);
ActiveX 23
Programowanie interfejsów
Przykład pobrania wartości właściwości On: VARIANT FAR *pVarResult; // wskaźnik do zmiennej typu VARIANT, // przechowującej wartość // odczytanej właściwości. //... szMember = "On"; hresult = pdisp->GetIDsOfNames(IID_NULL, &szMember, 1, LOCALE_USER_DEFAULT, &dispid); hresult = pdisp->Invoke( dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparams, pVarResult, NULL, NULL);
ActiveX 24
Programowanie interfejsów
Przykład zmiany wartości właściwości On: // identyfikator reprezentujący zmianę wartości właściwości DISPID mydispid = DISPID_PROPERTYPUT dispparams.rgvarg[0].vt = VT_BOOL; // typ właściwości dispparams.rgvarg[0].bool = FALSE; // nowa wartość // Zmieniając wartość właściwości musimy podać argument // zdefiniowany nazwą reprezentujący przypisanie wartości // do właściwości. dispparams.rgdispidNamedArgs = &mydispid; dispparams.cArgs = 1; dispparams.cNamedArgs = 1; // zmiana właściwości hresult = pdisp->Invoke( dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
1.4
ActiveX 25
Kontrolki ActiveX Zagadnienia: 1. 2. 3. 4. 5.
ActiveX 27
Technologia ActiveX Programowanie interfejsów Rejestrowanie kontrolek ActiveX Projektowanie kontrolki ActiveX w Visual Studio C++ Wykorzystanie kontrolek ActiveX
Rejestrowanie kontrolek ActiveX
ActiveX 26
Jeśli kontrolka nie posiada programu instalacyjnego to należy ją zarejestrować programem regsvr32.exe, np. regsvr32.exe MyCtrl.ocx. Rejestracja kontrolki polega na zapisaniu w rejestrze Windows większości informacji dotyczących obiektu (np. lokalizacja kontrolki na dysku). Informacje te są wykorzystywane za każdym razem, kiedy aplikacja używa obiektu ActiveX. Program regsvr32.exe ponadto wywołuje funkcję DLLSelfRegister. Parametry programu regsvr32.exe: Regsvr32 [/u] [/s] [/n] [/i[:cmdline]] dllname /s - Silent; display no message boxes /u - Unregister server /i - Call DllInstall passing it an optional [cmdline]; when used with /u calls dll uninstall /n - do not call DllRegisterServer; this option must be used with /i
ActiveX 28
Każda kontrolka ma przypisany unikalny identyfikator (CLSID) class ID. Jest to liczba 128 bitowa zapisana heksalnie np. {03437DCB-1719-4119-B253-02B4939A2CF4}
Projektowanie kontrolki ActiveX
Utworzenie nowego projektu
Kontrolki ActiveX Zagadnienia: 1. 2. 3. 4. 5.
Zarejestrowane w systemie kontrolki ActiveX są wyszczególnione w gałęzi HKEY_LOCAL_MACHINE\SOFTWARE\CLASSES\CLSID
ActiveX 29
Rejestrowanie kontrolek ActiveX
ActiveX 30
Technologia ActiveX Programowanie interfejsów Rejestrowanie kontrolek ActiveX Projektowanie kontrolki ActiveX w Visual Studio C++ Wykorzystanie kontrolek ActiveX
Projektowanie kontrolki ActiveX
Utworzenie nowego projektu
Liczba kontrolek w projekcie Czy będzie wymagana licencja? Czy w kodzie mają być zamieszczane komentarze? Czy mają być wygenerowane szkieletowe pliki pomocy?
1.5
ActiveX 31
Projektowanie kontrolki ActiveX
Utworzenie nowego projektu
ActiveX 32
Projektowanie kontrolki ActiveX
Utworzenie nowego projektu Klasy wykorzystywane do budowania kontrolki: CSimpleSliderApp:COleControlModule:CWnd Klasa zawiera dwie metody wykorzystywane przy ładowaniu i usuwaniu kontrolki z pamięci InitInstance(); ExitInstance();
Czy kontrolka ma się uaktywniać gdy staje się widoczna? Czy kontrolka może być niewidoczna w czasie działania?
CSimpleSliderCtrl:COleControl:CWnd
Czy kontrolka ma być dostępna z poziomu innych projektów?
Klasa zapewnia podstawową funkcjonalność kontrolki. Zawiera metody i właściwości oraz pozwala na generowanie zdarzeń.
Czy kontrolka ma pełnić tylko funkcję pojemnika?
CSimpleSliderPropPage:COlePropertyPage:CWnd Klasa okna dialogowego właściwości kontrolki.
ActiveX 33
Projektowanie kontrolki ActiveX
Utworzenie nowego projektu
ActiveX 34
Projektowanie kontrolki ActiveX
Utworzenie nowego projektu
/////////////////////////////////////////////////////////////// // CSimpleSliderCtrl::OnDraw - Drawing function void CSimpleSliderCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) { // TODO: Replace the following code with // your own drawing code. pdc->FillRect(rcBounds, CBrush::FromHandle( (HBRUSH)GetStockObject(WHITE_BRUSH))); pdc->Ellipse(rcBounds); }
ActiveX 35
Projektowanie kontrolki ActiveX
Kontrolka SimpleSlider
ActiveX 36
Projektowanie kontrolki ActiveX
Kontrolka SimpleSlider
m_min
m_pos
m_max
Właściwości: m_min/m_max – minimalna/maksymalna wartość m_pos – położenie suwaka (m_min < m_pos < m_max) Metody: short GetPosition(); – pobranie aktualnej pozycji suwaka void SetPosition(short nNewValue); – ustawienie nowej pozycji suwaka void GetRange(short *min, short *max); – pobranie zakresu void SetRange(short min, short max); – ustawienie zakresu void OnMaxChanged(); – zmiana wartości maksymalnej void OnMinChanged(); – zmiana wartości maksymalnej
1.6
ActiveX 37
Projektowanie kontrolki ActiveX
Dodawanie właściwości class CSimpleSliderCtrl : public COleControl { DECLARE_DYNCREATE(CSimpleSliderCtrl) public: CSimpleSliderCtrl(); virtual void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid); virtual void DoPropExchange(CPropExchange* pPX); virtual void OnResetState(); protected: ~CSimpleSliderCtrl(); private: short m_width; // szerokość kontrolki short m_pos; // aktualne położenie suwaka short m_pos0; // poprzednie położenie suwaka };
ActiveX 39
Projektowanie kontrolki ActiveX
Dodawanie właściwości
ActiveX 38
Projektowanie kontrolki ActiveX
Dodawanie właściwości
ActiveX 40
Projektowanie kontrolki ActiveX
Dodawanie właściwości
Właściwość: m_pos - Nazwa zewnętrzna ”Position”
Właściwości: m_min, m_max
Metody: short GetPosition(); void SetPosition(short nNewValue);
Metody: void OnMinChanged(); void OnMaxChanged();
ActiveX 41
Projektowanie kontrolki ActiveX
Projektowanie kontrolki ActiveX
Dodawanie zdarzeń
Dodawanie metod
Metody: void GetRange(short *, short *);
ActiveX 42
void SetRange(short, short);
1.7
ActiveX 43
Dodawanie zdarzeń
ActiveX 45
ActiveX 46
// szerokość kontrolki m_width = rcBounds.right - rcBounds.left; // obliczenie położenia suwaka względem okienka kontrolki int centerPos = m_width * (m_pos-m_min) / (m_max-m_min);
Projektowanie kontrolki ActiveX
Edycja kodu źródłowego void CSimpleSliderCtrl::OnResetState() { // Resets defaults found in DoPropExchange COleControl::OnResetState(); m_min = 0; m_max = 100; m_pos = 50; } void CSimpleSliderCtrl::OnMinChanged() { if (CheckValues()) FireParamsModified(); InvalidateControl(); } void CSimpleSliderCtrl::OnMaxChanged() { if (CheckValues()) FireParamsModified(); InvalidateControl(); }
ActiveX 48
Projektowanie kontrolki ActiveX
Edycja kodu źródłowego void CSimpleSliderCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) { // rcBounds – wymiary okienka kontrolki // klasa CRect zawiera pola: left, top, right, bottom.
Projektowanie kontrolki ActiveX
Edycja kodu źródłowego // dodatkowa funkcja kontroli zakresu BOOL CSimpleSliderCtrl::CheckValues() { BOOL modified = FALSE; if (m_min >= m_max) { m_min = 0; m_max = 100; modified = TRUE; } if (m_pos < m_min) { m_pos = m_min; modified = TRUE; } if (m_pos > m_max) { m_pos = m_max; modified = TRUE; } return modified; }
Projektowanie kontrolki ActiveX
Edycja kodu źródłowego short CSimpleSliderCtrl::GetPosition() { return m_pos; } void CSimpleSliderCtrl::SetPosition(short nNewValue) { m_pos = nNewValue; if (CheckValues()) FireParamsModified(); InvalidateControl();//wymuszenie wykonania funkcji OnDraw } void CSimpleSliderCtrl::GetRange(short *min, short *max) { *min = m_min; *max = m_max; } void CSimpleSliderCtrl::SetRange(short min, short max) { m_min = min; m_max = max; if (CheckValues()) FireParamsModified(); }
ActiveX 47
ActiveX 44
Projektowanie kontrolki ActiveX
Projektowanie kontrolki ActiveX
Edycja kodu źródłowego // ... selBounds.right = centerPos; CBrush lSelBrush; lSelBrush.CreateSolidBrush(RGB(0, 64, 224)); pdc->SelectObject(&lSelBrush); pdc->FillRect(selBounds,&lSelBrush);
notSelBounds.left = centerPos; CBrush lNotSelBrush; lNotSelBrush.CreateSolidBrush(RGB(224, 224, 224)); pdc->SelectObject(&lNotSelBrush); pdc->FillRect(notSelBounds,&lNotSelBrush);
// Suwak stanowi dwa przylegające do siebie prostokąty CRect selBounds = rcBounds, notSelBounds = rcBounds; // ... }
1.8
ActiveX 49
ActiveX 50
Projektowanie kontrolki ActiveX
Projektowanie kontrolki ActiveX
Funkcje obsługi zdarzeń WM_MOUSEMOVE i WM_LBUTTONDOWN
Funkcje obsługi zdarzeń WM_MOUSEMOVE i WM_LBUTTONDOWN
WM_MOUSEMOVE void CSimpleSliderCtrl::OnMouseMove(UINT nFlags,CPoint point) { if ((nFlags & MK_LBUTTON) == MK_LBUTTON) { m_pos = m_min + (m_max - m_min) * point.x / m_width; CheckValues(); if (m_pos != m_pos0) { // wywołanie zdarzenia PosChanged FirePosChanged(m_pos); m_pos0 = m_pos; } InvalidateControl(); } COleControl::OnMouseMove(nFlags, point); }
WM_LBUTTONDOWN void CSimpleSliderCtrl::OnLButtonDown(UINT nFlags,CPoint point) { m_pos = m_min + (m_max - m_min) * point.x / m_width; FirePosChanged(m_pos); InvalidateControl();
ActiveX 51
Projektowanie kontrolki ActiveX
Edycja okna właściwości
ActiveX 53
Projektowanie kontrolki ActiveX
Funkcja obsługi okna właściwości void CSimpleSliderCtrl::DoPropExchange(CPropExchange* pPX) { ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor)); COleControl::DoPropExchange(pPX); PX_Short(pPX, _T("Position"), (short &)m_pos, 50); PX_Short(pPX, _T("Min"), (short &)m_min, 0); PX_Short(pPX, _T("Max"), (short &)m_max, 100); }
COleControl::OnLButtonDown(nFlags, point); }
ActiveX 52
Projektowanie kontrolki ActiveX
Edycja okna właściwości
ActiveX 54
Projektowanie kontrolki ActiveX
Testowanie kontrolki
BOOL PX_Short( CPropExchange* pPX, //wskaźnik do obiektu klasy CPropExchange LPCTSTR pszPropName, // nazwa modyfikowanej właściwości short& sValue, // zmienna przechowująca wartość // właściwości w klasie COlePropertyPage sDefault // domyślna wartość właściwości );
1.9
ActiveX 55
Projektowanie kontrolki ActiveX
ActiveX 56
Kontrolki ActiveX
Testowanie kontrolki
Zagadnienia: 1. 2. 3. 4. 5.
ActiveX 57
Przykładowa aplikacja
Przykładowa aplikacja z kontrolką SimpleSlider
ActiveX 59
Przykładowa aplikacja
Przykładowe metody klasy CSimpleSlider w projekcie short CSimpleSlider::GetMin() { short result; GetProperty(0x1, VT_I2, (void*)&result); return result; } void CSimpleSlider::SetMin(short propVal) { SetProperty(0x1, VT_I2, propVal); } short CSimpleSlider::GetPosition() { short result; GetProperty(0x3, VT_I2, (void*)&result); return result; } void CSimpleSlider::SetPosition(short propVal) { SetProperty(0x3, VT_I2, propVal); }
ActiveX 58
Technologia ActiveX Programowanie interfejsów Rejestrowanie kontrolek ActiveX Projektowanie kontrolki ActiveX w Visual Studio C++ Wykorzystanie kontrolek ActiveX
Przykładowa aplikacja
Klasa dodana do projektu po utworzeniu zmiennej m_slider class CSimpleSlider : public CWnd { public: CLSID const& GetClsid() { static CLSID const clsid = { 0x3437dcb, 0x1719, 0x4119, { 0xb2, 0x53, 0x2, 0xb4, 0x93, 0x9a, 0x2c, 0xf4 } }; return clsid; } // Attributes short GetMin(); short GetMax(); void SetMin(short); void SetMax(short); short GetPosition(); void SetPosition(short); // Operations void SetRange(short Min, short Max); void GetRange(short* Min, short* Max); };
ActiveX 60
Przykładowa aplikacja
Przykładowe metody klasy CSimpleSlider w projekcie ///////////////////////////////////////////////////////////////// // CSimpleSlider operations void CSimpleSlider::SetRange(short Min, short Max) { static BYTE parms[] = VTS_I2 VTS_I2; InvokeHelper(0x4, DISPATCH_METHOD, VT_EMPTY, NULL, parms, Min, Max); } void CSimpleSlider::GetRange(short* Min, short* Max) { static BYTE parms[] = VTS_PI2 VTS_PI2; InvokeHelper(0x5, DISPATCH_METHOD, VT_EMPTY, NULL, parms, Min, Max); }
1.10
ActiveX 61
Przykładowa aplikacja
Uzupełnienie kodu źródłowego aplikacji testSlider
ActiveX 62
Przykładowa aplikacja
Dodanie funkcji obsługi zdarzeń PosChanged i ParamsModified
void CTestSliderDlg::OnGet() { m_slider.GetRange(&m_min, &m_max); m_pos = m_slider.GetPosition(); UpdateData(FALSE); } void CTestSliderDlg::OnSet() { UpdateData(TRUE); m_slider.SetRange(m_min, m_max); m_slider.SetPosition(m_pos); }
ActiveX 63
Przykładowa aplikacja
Uzupełnienie kodu źródłowego funkcji obsługi zdarzeń kontrolki SimpleSlider
ActiveX 64
Przykładowa aplikacja
Dynamiczne dodawanie kontrolek ActiveX do aplikacji
void CTestSliderDlg::OnPosChangedSimpleslider(short newPos) { m_pos = newPos; UpdateData(FALSE); } void CTestSliderDlg::OnParamsModifiedSimpleslider() { m_pos = m_slider.GetPosition(); m_slider.GetRange(&m_min, &m_max); UpdateData(FALSE); }
ActiveX 65
Przykładowa aplikacja
Dynamiczne dodawanie kontrolek ActiveX do aplikacji class CTestSliderDlg : public CDialog { //... // m_slider2 - zmienna kontrolki tworzonej dynamicznie CSimpleSlider m_slider, m_slider2; /... }; void CTestSliderDlg::OnCreateActivex() { m_slider2.CreateControl(m_slider2.GetClsid(), NULL, WS_VISIBLE, CRect(20,200,320,260), this, 0); } void CTestSliderDlg::OnDestroyActivex() { m_slider2.DestroyWindow(); }
1.11