TN040:MFC/OLE 就地調整大小和縮放
注意
下列技術提示自其納入線上文件以來,未曾更新。 因此,有些程序和主題可能已過期或不正確。 如需最新資訊,建議您在線上文件索引中搜尋相關的主題。
這個提示會討論與就地編輯相關的問題,以及伺服器應該如何完成正確的縮放和就地調整大小。 對於就地啟用,是進一步採取 WYSIWYG 概念,即容器和伺服器會彼此互相合作,並以相同的方式特別說明 OLE 規格。
由於容器和支援就地啟用的伺服器之間的密切互動,因此從應該維護的使用者會有幾項期待:
版面的顯示 (在
COleServerItem::OnDraw
覆寫中繪製的中繼檔) 應該與其繪製以供編輯時一模一樣 (除了看不到編輯工具以外)。當容器縮放時,伺服器視窗應該也隨之縮放!
容器和伺服器應該使用相同的度量顯示供編輯的物件。 這表示在顯示裝置上轉譯時,根據每英吋的邏輯 圖元數目 使用對應模式,而不是每英吋的實體圖元。
注意
由於就地啟用只套用於內嵌的 (未連結的) 項目,所以縮放只套用於內嵌的物件。 您會在用於縮放的 COleServerDoc
和 COleServerItem
中看到 API。 這個二分法的原因是只有對連結和內嵌專案有效的函式( COleServerItem
這可讓您有一個通用的實作),而且只適用于内嵌物件的函式位於 COleServerDoc
類別中(從伺服器的觀點來看,它是 內嵌的檔 )。
大部分負載在伺服器實作上,該伺服器必須知道容器的縮放因數並適當地修改其編輯介面。 但是伺服器如何判斷容器所使用的縮放因數
MFC 支援縮放
目前的縮放因數可以透過呼叫 COleServerDoc::GetZoomFactor
來決定。 當文件不是就地啟用時呼叫此項,總是會產生 100% 縮放因數 (或 1:1 比例)。 當就地啟用作用中呼叫它,則可能傳回 100% 以外的值。
如需正確縮放的範例,請參閱 MFC OLE 範例 HIERSVR 。 HIERSVR 中的縮放伴隨的事實是其顯示文字,而文字一般並不會線性方式 (提示、印刷樣式慣例、設計寬度和高度都讓問題更複雜) 縮放。 不過,HIERSVR 是正確實作縮放的合理參考,MFC 教學課程 SCRIBBLE 也是如此(步驟 7)。
COleServerDoc::GetZoomFactor
是根據可從容器或從實作您的 COleServerItem
和 COleServerDoc
類別取得的幾個不同度量,來決定縮放因數。 簡言之,目前的縮放因數取決於下列公式:
Position Rectangle (PR) / Container Extent (CE)
POSITION RECTANGLE 取決於容器。 當呼叫 COleClientItem::OnGetItemPosition
時,以及當容器呼叫伺服器的 COleServerDoc::OnSetItemRects
時更新的話 (使用呼叫 COleClientItem::SetItemRects
),它會在就地啟用期間傳回到伺服器。
CONTAINER EXTENT 的計算稍微比較複雜。 如果容器已呼叫 COleServerItem::OnSetExtent
(使用呼叫 COleClientItem::SetExtent
),則 CONTAINER EXTENT 是轉換為像素 (以每邏輯英吋的像素數為基礎) 的這個值。 如果容器未呼叫 SetExtent (通常是如此),則 CONTAINER EXTENT 是從 COleServerItem::OnGetExtent
傳回的大小。 因此,如果容器尚未呼叫 SetExtent,則架構會假設容器是否呼叫該容器,其自然範圍為 100%(從 COleServerItem::GetExtent
傳回的值)。 以另一個方式陳述,架構會假設容器是 100% (不多也不少) 顯示項目。
要注意的是,雖然 COleServerItem::OnSetExtent
和 COleServerItem::OnGetExtent
具有類似的名稱,但是它們不操作相同屬性的項目。 呼叫 OnSetExtent
是為了讓伺服器知道物件有多少部分會顯示在容器 (不論縮放因數) 中,而容器會呼叫 OnGetExtent
決定物件的理想大小。
查看所牽涉的每個 API,您就可以更清楚了解:
COleServerItem::OnGetExtent
這個函式應項目的 HIMETRIC 單位傳回「原始大小」。 最好的方式將「原始大小」視為會定義其在列印時顯示的大小。 此處傳回的大小是特定項目內容的常數 (很像中繼檔,其為特定項目的常數)。 當縮放套用到項目時,這個大小不會變更。 當容器藉由呼叫 OnSetExtent
給予項目或多或少的空間時,它通常不會變更。 變更的範例可能是沒有「邊界」功能的簡單文字編輯器,自動換行是根據容器所傳送的最後一個範圍。 如果伺服器變更,伺服器可能要在系統登錄中設定 OLEMISC_RECOMPOSEONRESIZE 位元 (如需此選項的詳細資訊,請參閱 OLE SDK 文件)。
COleServerItem::OnSetExtent
當容器「或多或少」顯示物件時,會呼叫這個函式。 大多數容器根本不會呼叫這個方法。 預設實作會以「m_sizeExtent」儲存從容器接收的最後一個值,其如以上所述在運算 CONTAINER EXTENT 值時,會在 COleServerDoc::GetZoomFactor
中使用。
COleServerDoc::OnSetItemRects
只有在文件為就地啟用作用中時,呼叫這個函式。 當容器更新項目的位置或套用到項目的裁剪時,便會呼叫它。 如上所述,POSITION RECTANGLE 提供計算縮放因數的列舉程式。 伺服器可能要求呼叫 COleServerDoc::RequestPositionChange
來變更項目位置。 容器可以或可能不會透過呼叫 OnSetItemRects
來回應此要求(呼叫 COleServerItem::SetItemRects
)。
COleServerDoc::OnDraw
必須要了解的是透過 COleServerItem::OnDraw
的覆寫所建立的中繼檔,不論目前縮放因數為何,會產生完全相同的中繼檔。 容器會適當地縮放中繼檔。 這是檢視的 OnDraw
和伺服器項目的 OnDraw
之間的重要區別。 檢視會處理縮放,專案只會建立 可 縮放的中繼檔,並將其保留至容器,以執行適當的縮放。
如果您的文件是就地啟用的話,確保您的伺服器正常運作的最好方式是使用實作 COleServerDoc::GetZoomFactor
。
MFC 支援就地調整大小
MFC 會如 OLE 2 規格中所述完全實作就地調整介面大小。 類別支援 COleResizeBar
使用者介面、自訂訊息WM_SIZECHILD,以及中 COleIPFrameWnd
這個訊息的特殊處理。
您可能會想要實作以不同於架構所提供的方式處理此訊息。 如上所述,架構會將就地調整大小的結果留給容器來決定,而伺服器會回應縮放因數中的變更。 如果容器在處理其 COleClientItem::OnChangeItemPosition
(因為呼叫 COleServerDoc::RequestPositionChange
的緣故而呼叫) 期間透過設定 CONTAINER EXTENT 和 POSITION RECTANGLE 二者來反應的話,則就地調整大小會導致在編輯視窗中「或多或少」顯示項目。 如果容器在處理 COleClientItem::OnChangeItemPosition
期間只是透過設定 POSITION RECTANGLE 來反應的話,則縮放因數會變更,並且項目會「放大或縮小」顯示。
伺服器可以控制 (某種程度上) 在此交涉期間會發生什麼情況。 例如,當使用者在就地編輯項目期間調整視窗大小時,試算表可以選擇顯示更多或更少儲存格。 文字處理器可能會選擇變更「頁面邊界」,以便讓它們與視窗相同並將文字重新換行至新邊界。 當調整大小完成時,伺服器會變更原始範圍 (從 COleServerItem::OnGetExtent
傳回的大小) 以實作此項。 這會讓 POSITION RECTANGLE 和 CONTAINER EXTENT 以相同的數量進行變更,產生相同的縮放因數,但是檢視區域會較大或者較小。 此外,在 OnDraw
所產生的中繼檔中,會或多或少顯示文件。 在此情況下,當使用者調整項目大小,而不只是檢視區域時,文件本身會隨之變更。
您可以實作自訂調整大小,並仍然透過覆寫 類別 COleIPFrameWnd
中的WM_SIZECHILD訊息,來利用所提供的 COleResizeBar
使用者介面。 如需WM_SIZECHILD的詳細資訊,請參閱 技術附注 24 。