Zapewnianie aktywacji niepowiązanej z oknami
Kod tworzenia okna (czyli wszystko, co dzieje się po wywołaniu CreateWindow
) jest kosztowne do wykonania. Kontrolka, która obsługuje okno na ekranie, musi zarządzać komunikatami dla okna. W związku z tym kontrolki bez okien są szybsze niż kontrolki z oknami.
Dodatkową zaletą kontrolek bez okien jest to, że w przeciwieństwie do kontrolek okien bez okien kontrolki obsługują przezroczyste obszary malowania i nierektangularnego ekranu. Typowym przykładem przezroczystej kontrolki jest kontrolka tekstu z przezroczystym tłem. Kontrolki malują tekst, ale nie tło, więc niezależnie od tego, co znajduje się pod tekstem. Nowsze formularze często korzystają z nierektangularnych kontrolek, takich jak strzałki i przyciski okrągłe.
Często kontrolka nie potrzebuje własnego okna, a zamiast tego może korzystać z usług okien kontenera, pod warunkiem że kontener został zapisany do obsługi obiektów bez okien. Kontrolki bez okien są zgodne z poprzednimi wersjami ze starszymi kontenerami. W starszych kontenerach, które nie są zapisywane w celu obsługi kontrolek bez okien, kontrolki bez okien tworzą okno, gdy jest aktywne.
Ponieważ kontrolki bez okien nie mają własnych okien, kontener (który ma okno) jest odpowiedzialny za dostarczanie usług, które w przeciwnym razie zostałyby udostępnione przez własne okno kontrolki. Jeśli na przykład kontrolka musi wykonywać zapytania dotyczące fokusu klawiatury, przechwytywać mysz lub uzyskiwać kontekst urządzenia, te operacje są zarządzane przez kontener. Kontener kieruje komunikaty wejściowe użytkownika wysyłane do okna do odpowiedniej kontrolki bez okien przy użyciu interfejsu IOleInPlaceObjectWindowless
. (Zobacz Zestaw ActiveX SDK zawiera opis tego interfejsu). COleControl
funkcje członkowskie wywołują te usługi z kontenera.
Aby kontrolka korzystała z aktywacji bez okien, dołącz flagę windowlessActivate w zestawie flag zwróconych przez COleControl::GetControlFlags. Przykład:
DWORD CMyAxOptCtrl::GetControlFlags()
{
DWORD dwFlags = COleControl::GetControlFlags();
// The control can activate without creating a window.
dwFlags |= windowlessActivate;
return dwFlags;
}
Kod dołączania tej flagi jest generowany automatycznie, jeśli wybierzesz opcję Aktywacji bez okna na stronie Kontrola Ustawienia Kreatora kontrolek ActiveX MFC.
Po włączeniu aktywacji bez okien kontener deleguje komunikaty wejściowe do interfejsu kontrolki IOleInPlaceObjectWindowless
. COleControl
Implementacja tego interfejsu wysyła komunikaty za pośrednictwem mapy komunikatów kontrolki po odpowiednim dostosowaniu współrzędnych myszy. Komunikaty takie jak zwykłe komunikaty okna można przetwarzać, dodając odpowiednie wpisy do mapy komunikatów. W programach obsługi tych komunikatów należy unikać używania zmiennej składowej m_hWnd (lub dowolnej funkcji składowej korzystającej z niej) bez wcześniejszego sprawdzenia, czy jej wartość nie ma wartości NULL.
COleControl
Udostępnia funkcje członkowskie, które wywołują przechwytywanie myszy, fokus klawiatury, przewijanie i inne usługi okien z kontenera, w tym:
W kontrolkach bez okien należy zawsze używać COleControl
funkcji składowych zamiast odpowiednich CWnd
funkcji składowych lub powiązanych funkcji interfejsu API Win32.
Kontrolka bez okna może być elementem docelowym operacji przeciągania i upuszczania OLE. Zwykle wymagałoby to zarejestrowania okna kontrolki jako miejsca docelowego upuszczania. Ponieważ kontrolka nie ma własnego okna, kontener używa własnego okna jako miejsca docelowego upuszczania. Kontrolka zapewnia implementację interfejsu IDropTarget
, do którego kontener może delegować wywołania w odpowiednim czasie. Aby uwidocznić ten interfejs w kontenerze, przesłoń wartość COleControl::GetWindowlessDropTarget. Na przykład:
IDropTarget* CMyAxOptCtrl::GetWindowlessDropTarget()
{
m_DropTarget.m_xDropTarget.AddRef();
return &m_DropTarget.m_xDropTarget;
}