Udostępnij za pośrednictwem


TN040: MFC/OLE — zmienianie rozmiaru i powiększanie w miejscu

Uwaga

Następująca uwaga techniczna nie została zaktualizowana, ponieważ została po raz pierwszy uwzględniona w dokumentacji online. W związku z tym niektóre procedury i tematy mogą być nieaktualne lub nieprawidłowe. Aby uzyskać najnowsze informacje, zaleca się wyszukanie interesującego tematu w indeksie dokumentacji online.

W tej notatce omówiono problemy związane z edycją w miejscu oraz sposób, w jaki serwer powinien osiągnąć poprawne powiększanie i zmianę rozmiaru w miejscu. W przypadku aktywacji w miejscu koncepcja WYSIWYG jest podejmowana o krok dalej w tym, że kontenery i serwery współpracują ze sobą, a w szczególności interpretować specyfikację OLE w taki sam sposób.

Ze względu na ścisłą interakcję między kontenerem a serwerem obsługującym aktywację w miejscu istnieje wiele oczekiwań od użytkownika końcowego, które należy zachować:

  • Wyświetlanie prezentacji (metaplik narysowany w COleServerItem::OnDraw przesłonięciu) powinno wyglądać dokładnie tak samo, jak w przypadku rysowania do edycji (z wyjątkiem tego, że narzędzia do edycji nie są widoczne).

  • Po powiększeniu kontenera okno serwera również powinno być!

  • Zarówno kontener, jak i serwer powinny wyświetlać obiekty do edycji przy użyciu tych samych metryk. Oznacza to użycie trybu mapowania na podstawie liczby pikseli logicznych na cal — a nie pikseli fizycznych na cal podczas renderowania na urządzeniu wyświetlania.

Uwaga

Ponieważ aktywacja w miejscu dotyczy tylko elementów osadzonych (nie połączonych), powiększanie dotyczy tylko obiektów osadzonych. Zobaczysz interfejsy API w obu COleServerDoc i COleServerItem , które są używane do powiększania. Przyczyną tej dichotomii jest to, że w klasie znajdują się tylko funkcje prawidłowe zarówno dla elementów połączonych, jak i osadzonych (pozwala to na wspólną implementację) oraz funkcje, które są prawidłowe tylko dla obiektów osadzonych COleServerItem , znajdują się w COleServerDoc klasie (z perspektywy serwera jest to dokument osadzony).

Większość obciążeń jest umieszczana na implementatorze serwera, ponieważ serwer musi być świadomy współczynnika powiększenia kontenera i odpowiednio zmodyfikować jego interfejs edycji. Jednak jak serwer określa współczynnik powiększenia używany przez kontener

Obsługa powiększania MFC

Bieżący współczynnik powiększenia można określić przez wywołanie metody COleServerDoc::GetZoomFactor. Wywołanie tej funkcji, gdy dokument nie jest aktywny w miejscu, zawsze spowoduje 100% współczynnika powiększenia (lub współczynnik 1:1). Wywoływanie go, gdy aktywne miejsce może zwrócić coś innego niż 100%.

Aby uzyskać przykład poprawnego powiększania, zobacz przykład HIERSVR MFC OLE. Powiększanie HIERSVR jest skomplikowane przez fakt, że wyświetla tekst i tekst, ogólnie rzecz biorąc, nie skaluje się w sposób liniowy (wskazówki, konwencje typograficzne, szerokość projektu i wysokości wszystkie komplikują sprawę). Mimo to HIERSVR jest rozsądnym odwołaniem do poprawnego implementowania powiększania, a więc jest to samouczek MFC SCRIBBLE (krok 7).

COleServerDoc::GetZoomFactor określa współczynnik powiększenia na podstawie wielu różnych metryk dostępnych z kontenera lub z implementacji COleServerItem klas i COleServerDoc . Krótko mówiąc, bieżący współczynnik powiększenia jest określany przez następującą formułę:

Position Rectangle (PR) / Container Extent (CE)

PROSTOKĄT POZYCJI jest określany przez kontener. Jest zwracany do serwera podczas aktywacji w miejscu, gdy COleClientItem::OnGetItemPosition jest wywoływany i jest aktualizowany, gdy kontener wywołuje serwer COleServerDoc::OnSetItemRects (z wywołaniem metody ).COleClientItem::SetItemRects

Zakres KONTENERa jest nieco bardziej złożony do obliczenia. Jeśli kontener został wywołany COleServerItem::OnSetExtent (z wywołaniem metody COleClientItem::SetExtent), wartość CONTAINER EXTENT jest konwertowana na piksele na podstawie liczby pikseli na cal logiczny. Jeśli kontener nie ma nazwy SetExtent (zwykle jest to przypadek), wówczas rozmiar kontenera jest rozmiarem zwróconym z COleServerItem::OnGetExtent. W związku z tym, jeśli kontener nie nazwał SetExtent, struktura zakłada, że jeśli kontener zostałby nazwany z 100% naturalnego zakresu (wartość zwrócona z COleServerItem::GetExtent). W inny sposób struktura zakłada, że kontener wyświetla 100% (nie więcej, nie mniej) elementu.

Należy pamiętać, że chociaż COleServerItem::OnSetExtent i COleServerItem::OnGetExtent mają podobne nazwy, nie manipulują tym samym atrybutem elementu. OnSetExtent Polecenie jest wywoływane w celu określenia, ile obiektu jest widoczne w kontenerze (niezależnie od współczynnika powiększenia) i OnGetExtent jest wywoływane przez kontener w celu określenia idealnego rozmiaru obiektu.

Patrząc na poszczególne zaangażowane interfejsy API, możesz uzyskać jaśniejszy obraz:

COleServerItem::OnGetExtent

Ta funkcja powinna zwrócić "rozmiar naturalny" w jednostkach HIMETRIC elementu. Najlepszym sposobem myślenia o "rozmiarze naturalnym" jest zdefiniowanie go jako rozmiaru, który może pojawić się podczas drukowania. Zwracany tutaj rozmiar jest stały dla określonej zawartości elementu (podobnie jak metaplik, który jest stałą dla określonego elementu). Ten rozmiar nie zmienia się podczas powiększania elementu. Zwykle nie zmienia się, gdy kontener daje elementowi więcej lub mniej miejsca przez wywołanie metody OnSetExtent. Przykładem zmiany może być funkcja prostego edytora tekstów bez możliwości "marginesu", która opakowała tekst w oparciu o ostatni zakres wysłany przez kontener. Jeśli serwer ulegnie zmianie, serwer powinien prawdopodobnie ustawić OLEMISC_RECOMPOSEONRESIZE bit w rejestrze systemowym (zobacz dokumentację zestawu OLE SDK, aby uzyskać więcej informacji na temat tej opcji).

COleServerItem::OnSetExtent

Ta funkcja jest wywoływana, gdy kontener wyświetla "mniej lub więcej" obiektu. Większość kontenerów w ogóle tego nie wywoła. Domyślna implementacja przechowuje ostatnią wartość odebraną z kontenera w lokalizacji "m_sizeExtent", która jest używana podczas COleServerDoc::GetZoomFactor obliczania wartości CONTAINER EXTENT opisanej powyżej.

COleServerDoc::OnSetItemRects

Ta funkcja jest wywoływana tylko wtedy, gdy dokument jest aktywny. Jest on wywoływany, gdy kontener aktualizuje pozycję elementu lub wycinki zastosowane do elementu. PROSTOKĄT POZYCJI, jak opisano powyżej, zawiera licznik dla obliczenia współczynnika powiększenia. Serwer może zażądać zmiany pozycji elementu przez wywołanie metody COleServerDoc::RequestPositionChange. Kontener może lub nie odpowiada na to żądanie przez wywołanie OnSetItemRects metody COleServerItem::SetItemRects.

COleServerDoc::OnDraw

Należy pamiętać, że metaplik utworzony przez zastąpienie COleServerItem::OnDraw tworzy dokładnie ten sam metaplik, niezależnie od bieżącego współczynnika powiększenia. Kontener będzie skalować metaplik zgodnie z potrzebami. Jest to ważne rozróżnienie między widokami OnDraw a elementem OnDrawserwera . Widok obsługuje powiększanie, element tworzy powiększy metaplik i pozostawia go do kontenera w celu odpowiedniego powiększenia.

Najlepszym sposobem zapewnienia prawidłowego zachowania serwera jest użycie implementacji COleServerDoc::GetZoomFactor , jeśli dokument jest aktywny w miejscu.

Obsługa zmiany rozmiaru w miejscu MFC

MFC w pełni implementuje interfejs zmiany rozmiaru w miejscu zgodnie z opisem w specyfikacji OLE 2. Interfejs użytkownika jest obsługiwany przez klasę COleResizeBar , niestandardowy komunikat WM_SIZECHILD i specjalną obsługę tego komunikatu w programie COleIPFrameWnd.

Możesz zaimplementować inną obsługę tego komunikatu niż to, co jest dostarczane przez platformę. Jak opisano powyżej, struktura pozostawia wyniki zmiany rozmiaru w miejscu do kontenera — serwer reaguje na zmianę współczynnika powiększenia. Jeśli kontener reaguje, ustawiając zarówno zakres KONTENERa, jak i POZYCJĘ PROSTOKĄT PODCZAS przetwarzania elementu COleClientItem::OnChangeItemPosition (wywoływanego w wyniku wywołania metody COleServerDoc::RequestPositionChange), zmiana rozmiaru w miejscu spowoduje wyświetlenie "więcej lub mniej" elementu w oknie edycji. Jeśli kontener reaguje, ustawiając tylko ustawienie POZYCJI PROSTOKĄT PODCZAS przetwarzania COleClientItem::OnChangeItemPosition, współczynnik powiększenia zmieni się, a element zostanie wyświetlony "powiększony lub wychodzący".

Serwer może kontrolować (do pewnego stopnia) co się dzieje podczas tych negocjacji. Na przykład arkusz kalkulacyjny może wybrać wyświetlanie większej lub mniejszej liczby komórek, gdy użytkownik zmienia rozmiar okna podczas edytowania elementu w miejscu. Edytor wyrazów może zdecydować się na zmianę "marginesów strony", aby były takie same jak w oknie i ponownie opakowywać tekst do nowego marginesu. Serwery implementują to przez zmianę naturalnego zakresu (rozmiar zwrócony z COleServerItem::OnGetExtent) po zakończeniu zmiany rozmiaru. Spowoduje to zmianę zarówno POZYCJI PROSTOKĄTA, jak i ZAKRESU KONTENERA o taką samą ilość, co powoduje taki sam współczynnik powiększenia, ale większy lub mniejszy obszar wyświetlania. Ponadto więcej lub mniej dokumentu będzie widoczne w metapliku generowanym przez OnDrawelement . W takim przypadku sam dokument zmienia się, gdy użytkownik zmienia rozmiar elementu zamiast tylko obszaru wyświetlania.

Możesz zaimplementować niestandardową zmianę rozmiaru i nadal korzystać z interfejsu użytkownika udostępnianego przez COleResizeBar zastąpienie komunikatu WM_SIZECHILD w COleIPFrameWnd klasie. Aby uzyskać więcej informacji na temat specyfiki WM_SIZECHILD, zobacz Uwaga techniczna 24.

Zobacz też

Uwagi techniczne według numerów
Uwagi techniczne według kategorii