|
|
1.1 root 1: /*************************************************************************
2: **
3: ** OLE 2 Server Sample Code
4: **
5: ** svrinpl.c
6: **
7: ** This file contains all interfaces, methods and related support
8: ** functions for an In-Place Object (Server) application (aka. Visual
9: ** Editing). The in-place Object application includes the following
10: ** implementation objects:
11: **
12: ** ServerDoc Object
13: ** exposed interfaces:
14: ** IOleInPlaceObject
15: ** IOleInPlaceActiveObject
16: **
17: ** ServerApp Object
18: ** exposed interfaces:
19: ** IUnknown
20: **
21: ** (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved
22: **
23: *************************************************************************/
24:
25:
26: #include "outline.h"
27:
28: OLEDBGDATA
29:
30: extern LPOUTLINEAPP g_lpApp;
31:
32:
33: #if defined( INPLACE_SVR )
34:
35: /* OLE2NOTE: the object should compose a string that is used by
36: ** in-place containers to be used for the window titles. this string
37: ** is passed to the container application via
38: ** IOleInPlaceUIWindow::SetActiveObject. the string should have the
39: ** following form:
40: ** <application name> - <object short type name>
41: ** SDI containers can use the string directly to display in the
42: ** frame window title. the container would concatenate the string
43: ** " in <container doc name>".
44: ** an MDI container with the MDI child window maximized can do the
45: ** same as the SDI container. an MDI container with the MDI child
46: ** windows NOT maximized can look for the " - " in the string from
47: ** the object. the first part of the string (app name) would be put
48: ** as the frame window title; the second part would be composed with
49: ** " in <container doc name>" and used as the MDI child window
50: ** title.
51: */
52:
53: // REVIEW: should use string resource for messages
54: char g_szIPObjectTitle[] = APPNAME " - " SHORTUSERTYPENAME;
55:
56: extern RECT g_rectNull;
57:
58:
59:
60: /*************************************************************************
61: ** ServerDoc::IOleInPlaceObject interface implementation
62: *************************************************************************/
63:
64: // IOleInPlaceObject::QueryInterface method
65:
66: STDMETHODIMP SvrDoc_IPObj_QueryInterface(
67: LPOLEINPLACEOBJECT lpThis,
68: REFIID riid,
69: LPVOID FAR * lplpvObj
70: )
71: {
72: LPSERVERDOC lpServerDoc =
73: ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
74:
75: return OleDoc_QueryInterface((LPOLEDOC)lpServerDoc, riid, lplpvObj);
76: }
77:
78:
79: // IOleInPlaceObject::AddRef method
80:
81: STDMETHODIMP_(ULONG) SvrDoc_IPObj_AddRef(LPOLEINPLACEOBJECT lpThis)
82: {
83: LPSERVERDOC lpServerDoc =
84: ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
85:
86: OleDbgAddRefMethod(lpThis, "IOleInPlaceObject");
87:
88: return OleDoc_AddRef((LPOLEDOC)lpServerDoc);
89: }
90:
91:
92: // IOleInPlaceObject::Release method
93:
94: STDMETHODIMP_(ULONG) SvrDoc_IPObj_Release(LPOLEINPLACEOBJECT lpThis)
95: {
96: LPSERVERDOC lpServerDoc =
97: ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
98:
99: OleDbgReleaseMethod(lpThis, "IOleInPlaceObject");
100:
101: return OleDoc_Release((LPOLEDOC)lpServerDoc);
102: }
103:
104:
105: // IOleInPlaceObject::GetWindow method
106:
107: STDMETHODIMP SvrDoc_IPObj_GetWindow(
108: LPOLEINPLACEOBJECT lpThis,
109: HWND FAR* lphwnd
110: )
111: {
112: LPSERVERDOC lpServerDoc =
113: ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
114:
115: OLEDBG_BEGIN2("SvrDoc_IPObj_GetWindow\r\n")
116:
117: *lphwnd = ((LPOUTLINEDOC)lpServerDoc)->m_hWndDoc;
118:
119: OLEDBG_END2
120: return S_OK;
121: }
122:
123:
124: // IOleInPlaceObject::ContextSensitiveHelp method
125:
126: STDMETHODIMP SvrDoc_IPObj_ContextSensitiveHelp(
127: LPOLEINPLACEOBJECT lpThis,
128: BOOL fEnable
129: )
130: {
131: LPSERVERDOC lpServerDoc =
132: ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
133:
134: OLEDBG_BEGIN2("SvrDoc_IPObj_ContextSensitiveHelp\r\n")
135:
136: lpServerDoc->m_lpIPData->fInCSHelpMode = fEnable;
137:
138: OLEDBG_END2
139: return S_OK;
140: }
141:
142:
143: // IOleInPlaceObject::InPlaceDeactivate method
144:
145: STDMETHODIMP SvrDoc_IPObj_InPlaceDeactivate(LPOLEINPLACEOBJECT lpThis)
146: {
147: LPSERVERDOC lpServerDoc =
148: ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
149: HRESULT hrErr;
150:
151: OLEDBG_BEGIN2("SvrDoc_IPObj_InPlaceDeactivate\r\n")
152:
153: hrErr = ServerDoc_DoInPlaceDeactivate(lpServerDoc);
154:
155: OLEDBG_END2
156: return hrErr;
157: }
158:
159:
160: // IOleInPlaceObject::UIDeactivate method
161:
162: STDMETHODIMP SvrDoc_IPObj_UIDeactivate(LPOLEINPLACEOBJECT lpThis)
163: {
164: LPSERVERDOC lpServerDoc =
165: ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
166: LPSERVERAPP lpServerApp = (LPSERVERAPP)g_lpApp;
167: LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
168: LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData;
169: LPLINELIST lpLL = (LPLINELIST)&((LPOUTLINEDOC)lpServerDoc)->m_LineList;
170: HWND hWndApp = OutlineApp_GetWindow(g_lpApp);
171:
172: OLEDBG_BEGIN2("SvrDoc_IPObj_UIDeactivate\r\n");
173:
174: if (!lpServerDoc->m_fUIActive) {
175: OLEDBG_END2
176: return NOERROR;
177: }
178:
179: lpServerDoc->m_fUIActive = FALSE;
180:
181: // Clip the hatch window to the size of pos rect so, that the object
182: // adornments and hatch border will not be visible.
183: ServerDoc_ResizeInPlaceWindow(lpServerDoc,
184: (LPRECT)&(lpServerDoc->m_lpIPData->rcPosRect),
185: (LPRECT)&(lpServerDoc->m_lpIPData->rcPosRect)
186: );
187:
188: if (lpIPData->lpDoc)
189: lpIPData->lpDoc->lpVtbl->SetActiveObject(lpIPData->lpDoc, NULL, NULL);
190:
191: if (lpIPData->lpFrame) {
192: lpIPData->lpFrame->lpVtbl->SetActiveObject(
193: lpIPData->lpFrame,
194: NULL,
195: NULL
196: );
197: }
198:
199: #if defined( USE_FRAMETOOLS )
200: /* OLE2NOTE: we must hide our frame tools here but NOT call
201: ** IOleInPlaceFrame::SetBorderSpace(NULL) or SetMenu(NULL).
202: ** we must hide our tools BEFORE calling
203: ** IOleInPlaceSite::OnUIDeactivate. the container will put
204: ** his menus and tools back when OnUIDeactivate is called.
205: */
206: ServerDoc_RemoveFrameLevelTools(lpServerDoc);
207: #endif
208:
209: OLEDBG_BEGIN2("IOleInPlaceSite::OnUIDeactivate called\r\n");
210: lpIPData->lpSite->lpVtbl->OnUIDeactivate(lpIPData->lpSite, FALSE);
211: OLEDBG_END2
212:
213: /* Reset to use our normal app's accelerator table */
214: g_lpApp->m_hAccel = g_lpApp->m_hAccelApp;
215: g_lpApp->m_hWndAccelTarget = hWndApp;
216:
217: OLEDBG_END2
218:
219: #if !defined( SVR_INSIDEOUT )
220: /* OLE2NOTE: an "outside-in" style in-place server would hide its
221: ** window here. an "inside-out" style server leaves its window
222: ** visible when it is UIDeactivated. it would only hide its
223: ** window when InPlaceDeactivated. this app is an "inside-out"
224: ** style server. it is recommended for most server to support
225: ** inside-out behavior if possible.
226: */
227: ServerDoc_DoInPlaceHide(lpServerDoc);
228: #endif // INSIEDOUT
229:
230: return NOERROR;
231: }
232:
233:
234: // IOleInPlaceObject::SetObjectRects method
235:
236: STDMETHODIMP SvrDoc_IPObj_SetObjectRects(
237: LPOLEINPLACEOBJECT lpThis,
238: LPCRECT lprcPosRect,
239: LPCRECT lprcClipRect
240: )
241: {
242: LPSERVERDOC lpServerDoc =
243: ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
244: LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData;
245: LPLINELIST lpLL = OutlineDoc_GetLineList((LPOUTLINEDOC)lpServerDoc);
246:
247: OLEDBG_BEGIN2("SvrDoc_IPObj_SetObjectRects\r\n")
248:
249: OleDbgOutRect3("SvrDoc_IPObj_SetObjectRects (PosRect)",
250: (LPRECT)lprcPosRect);
251: OleDbgOutRect3("SvrDoc_IPObj_SetObjectRects (ClipRect)",
252: (LPRECT)lprcClipRect);
253:
254: // save the current PosRect and ClipRect
255: lpIPData->rcPosRect = *lprcPosRect;
256: lpIPData->rcClipRect = *lprcClipRect;
257:
258: if (! lpServerDoc->m_fUIActive) // hatch and adornaments must not be drawn
259: lprcClipRect = lprcPosRect;
260:
261: ServerDoc_ResizeInPlaceWindow(
262: lpServerDoc, (LPRECT)lprcPosRect, (LPRECT)lprcClipRect);
263:
264:
265: /* reset the horizontal extent of the listbox. this makes
266: ** the listbox realize that a scroll bar is not needed.
267: */
268: SendMessage(
269: lpLL->m_hWndListBox,
270: LB_SETHORIZONTALEXTENT,
271: (int) 0,
272: 0L
273: );
274: SendMessage(
275: lpLL->m_hWndListBox,
276: LB_SETHORIZONTALEXTENT,
277: (int) (lpIPData->rcPosRect.right - lpIPData->rcPosRect.left),
278: 0L
279: );
280:
281: OLEDBG_END2
282: return NOERROR;
283: }
284:
285:
286: // IOleInPlaceObject::ReactivateAndUndo method
287:
288: STDMETHODIMP SvrDoc_IPObj_ReactivateAndUndo(LPOLEINPLACEOBJECT lpThis)
289: {
290: OLEDBG_BEGIN2("SvrDoc_IPObj_ReactivateAndUndo\r\n")
291:
292: // We do not support support UNDO.
293:
294: /* REVIEW: for debugging purposes it would be useful to give a
295: ** message box indicating that this method has been called.
296: */
297:
298: OLEDBG_END2
299: return NOERROR;
300: }
301:
302:
303: /*************************************************************************
304: ** ServerDoc::IOleInPlaceActiveObject interface implementation
305: *************************************************************************/
306:
307: // IOleInPlaceActiveObject::QueryInterface method
308:
309: STDMETHODIMP SvrDoc_IPActiveObj_QueryInterface(
310: LPOLEINPLACEACTIVEOBJECT lpThis,
311: REFIID riid,
312: LPVOID FAR * lplpvObj
313: )
314: {
315: SCODE sc = E_NOINTERFACE;
316: LPSERVERDOC lpServerDoc =
317: ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
318:
319: /* The container should not be able to access the other interfaces
320: ** of our object by doing QI on this interface.
321: */
322:
323: *lplpvObj = NULL;
324: if (IsEqualIID(riid, &IID_IUnknown) ||
325: IsEqualIID(riid, &IID_IOleWindow) ||
326: IsEqualIID(riid, &IID_IOleInPlaceActiveObject)) {
327: OleDbgOut4("OleDoc_QueryInterface: IOleInPlaceActiveObject* RETURNED\r\n");
328:
329: *lplpvObj = lpThis;
330: OleDoc_AddRef((LPOLEDOC)lpServerDoc);
331: sc = NOERROR;
332: }
333:
334: OleDbgQueryInterfaceMethod(*lplpvObj);
335:
336: return ResultFromScode(sc);
337: }
338:
339:
340: // IOleInPlaceActiveObject::AddRef method
341:
342: STDMETHODIMP_(ULONG) SvrDoc_IPActiveObj_AddRef(
343: LPOLEINPLACEACTIVEOBJECT lpThis
344: )
345: {
346: LPSERVERDOC lpServerDoc =
347: ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
348:
349: OleDbgAddRefMethod(lpThis, "IOleInPlaceActiveObject");
350:
351: return OleDoc_AddRef((LPOLEDOC)lpServerDoc);
352: }
353:
354:
355: // IOleInPlaceActiveObject::Release method
356:
357: STDMETHODIMP_(ULONG) SvrDoc_IPActiveObj_Release(
358: LPOLEINPLACEACTIVEOBJECT lpThis
359: )
360: {
361: LPSERVERDOC lpServerDoc =
362: ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
363:
364: OleDbgReleaseMethod(lpThis, "IOleInPlaceActiveObject");
365:
366: return OleDoc_Release((LPOLEDOC)lpServerDoc);
367: }
368:
369:
370: // IOleInPlaceActiveObject::GetWindow method
371:
372: STDMETHODIMP SvrDoc_IPActiveObj_GetWindow(
373: LPOLEINPLACEACTIVEOBJECT lpThis,
374: HWND FAR* lphwnd
375: )
376: {
377: LPSERVERDOC lpServerDoc =
378: ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
379:
380: OLEDBG_BEGIN2("SvrDoc_IPActiveObj_GetWindow\r\n")
381:
382: *lphwnd = ((LPOUTLINEDOC)lpServerDoc)->m_hWndDoc;
383:
384: OLEDBG_END2
385: return NOERROR;
386: }
387:
388:
389: // IOleInPlaceActiveObject::ContextSensitiveHelp method
390:
391: STDMETHODIMP SvrDoc_IPActiveObj_ContextSensitiveHelp(
392: LPOLEINPLACEACTIVEOBJECT lpThis,
393: BOOL fEnable
394: )
395: {
396: LPSERVERDOC lpServerDoc =
397: ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
398:
399: OLEDBG_BEGIN2("SvrDoc_IPActiveObj_ContextSensitiveHelp\r\n")
400:
401: lpServerDoc->m_lpIPData->fInCSHelpMode = fEnable;
402:
403: OLEDBG_END2
404: return NOERROR;
405: }
406:
407:
408: // IOleInPlaceActiveObject::TranslateAccelerator method
409:
410: STDMETHODIMP SvrDoc_IPActiveObj_TranslateAccelerator(
411: LPOLEINPLACEACTIVEOBJECT lpThis,
412: LPMSG lpmsg
413: )
414: {
415: // This will never be called because this server is implemented as an EXE
416: return NOERROR;
417: }
418:
419:
420: // IOleInPlaceActiveObject::OnFrameWindowActivate method
421:
422: STDMETHODIMP SvrDoc_IPActiveObj_OnFrameWindowActivate(
423: LPOLEINPLACEACTIVEOBJECT lpThis,
424: BOOL fActivate
425: )
426: {
427: LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)
428: ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
429: HWND hWndDoc = OutlineDoc_GetWindow(lpOutlineDoc);
430:
431: OleDbgOut2("SvrDoc_IPActiveObj_OnFrameWindowActivate\r\n");
432:
433: /* OLE2NOTE: this is a notification of the container application's
434: ** WM_ACTIVATEAPP status. some applications may find this
435: ** important. we need to update the enable/disable status of our
436: ** tool bar buttons.
437: */
438:
439: // OLE2NOTE: We can't call OutlineDoc_UpdateFrameToolButtons
440: // right away which
441: // would generate some OLE calls and eventually
442: // WM_ACTIVATEAPP and a loop was formed. Therefore, we
443: // should delay the frame tool initialization until
444: // WM_ACTIVATEAPP is finished by posting a message
445: // to ourselves.
446:
447: /* Update enable/disable state of buttons in toolbar */
448: if (fActivate)
449: PostMessage(hWndDoc, WM_U_INITFRAMETOOLS, 0, 0L);
450:
451: return NOERROR;
452: }
453:
454:
455: // IOleInPlaceActiveObject::OnDocWindowActivate method
456:
457: STDMETHODIMP SvrDoc_IPActiveObj_OnDocWindowActivate(
458: LPOLEINPLACEACTIVEOBJECT lpThis,
459: BOOL fActivate
460: )
461: {
462: LPSERVERDOC lpServerDoc =
463: ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
464: LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData;
465:
466: OLEDBG_BEGIN2("SvrDoc_IPActiveObj_OnDocWindowActivate\r\n")
467:
468: if (fActivate) {
469: ServerDoc_AddFrameLevelUI(lpServerDoc);
470: }
471: else {
472: #if defined( USE_FRAMETOOLS )
473: /* OLE2NOTE: we must NOT call IOleInPlaceFrame::SetBorderSpace(NULL)
474: ** or SetMenu(NULL) here. we should simply hide our tools.
475: */
476: ServerDoc_RemoveFrameLevelTools(lpServerDoc);
477: #endif
478: }
479:
480: OLEDBG_END2
481: return NOERROR;
482: }
483:
484:
485: // IOleInPlaceActiveObject::ResizeBorder method
486:
487: STDMETHODIMP SvrDoc_IPActiveObj_ResizeBorder(
488: LPOLEINPLACEACTIVEOBJECT lpThis,
489: LPCRECT lprectBorder,
490: LPOLEINPLACEUIWINDOW lpIPUiWnd,
491: BOOL fFrameWindow
492: )
493: {
494: LPSERVERDOC lpServerDoc =
495: ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
496: LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
497:
498: OLEDBG_BEGIN2("SvrDoc_IPActiveObj_ResizeBorder\r\n")
499:
500:
501: #if defined( USE_FRAMETOOLS )
502:
503: if (fFrameWindow) {
504: FrameTools_NegotiateForSpaceAndShow(
505: lpOutlineDoc->m_lpFrameTools,
506: (LPRECT)lprectBorder,
507: (LPOLEINPLACEFRAME)lpIPUiWnd
508: );
509: }
510:
511: #endif
512:
513: OLEDBG_END2
514: return NOERROR;
515: }
516:
517:
518: // IOleInPlaceActiveObject::EnableModeless method
519:
520: STDMETHODIMP SvrDoc_IPActiveObj_EnableModeless(
521: LPOLEINPLACEACTIVEOBJECT lpThis,
522: BOOL fEnable
523: )
524: {
525: LPSERVERDOC lpServerDoc =
526: ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
527:
528: OleDbgOut2("SvrDoc_IPActiveObj_EnableModeless\r\n");
529:
530: return NOERROR;
531: }
532:
533:
534: /*************************************************************************
535: ** Support Functions
536: *************************************************************************/
537:
538:
539: HRESULT ServerDoc_DoInPlaceActivate(
540: LPSERVERDOC lpServerDoc,
541: LONG lVerb,
542: LPMSG lpmsg,
543: LPOLECLIENTSITE lpActiveSite
544: )
545: {
546: LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
547: LPSERVERAPP lpServerApp = (LPSERVERAPP)g_lpApp;
548: LPOLEAPP lpOleApp = (LPOLEAPP)g_lpApp;
549: SCODE sc = E_FAIL;
550: RECT rcPos;
551: RECT rcClip;
552: LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData;
553: LPOUTLINEDOC lpOutlineDoc=(LPOUTLINEDOC)lpServerDoc;
554: HWND hWndDoc = lpOutlineDoc->m_hWndDoc;
555: HWND hWndHatch = lpServerDoc->m_hWndHatch;
556: HRESULT hrErr;
557: LPLINELIST lpLL=(LPLINELIST)&lpOutlineDoc->m_LineList;
558: LPOLEINPLACESITE lpIPSite = NULL;
559:
560: /* OLE2NOTE: lpActiveSite should be used only for InPlace PLAYing.
561: ** This app does not do inplace PLAYing, so it never uses
562: ** lpActiveSite.
563: */
564:
565: /* InPlace activation can only be done if the ClientSite is non-NULL. */
566: if (! lpServerDoc->m_lpOleClientSite)
567: return NOERROR;
568:
569: if (! lpServerDoc->m_fInPlaceActive) {
570:
571: // if the object is in open mode then we do not want to do inplace
572: // activation.
573: if (IsWindowVisible(lpOutlineDoc->m_hWndDoc))
574: return NOERROR;
575:
576: lpIPSite = (LPOLEINPLACESITE)OleStdQueryInterface(
577: (LPUNKNOWN)lpServerDoc->m_lpOleClientSite,
578: &IID_IOleInPlaceSite
579: );
580:
581: if (! lpIPSite)
582: goto errActivate;
583:
584: if (lpIPSite->lpVtbl->CanInPlaceActivate(lpIPSite) != NOERROR)
585: goto errActivate;
586:
587: lpServerDoc->m_fInPlaceActive = TRUE;
588: if (lpIPSite->lpVtbl->OnInPlaceActivate(lpIPSite) != NOERROR)
589: goto errActivate;
590:
591: if (! ServerDoc_AllocInPlaceData(lpServerDoc)) {
592: sc = E_OUTOFMEMORY;
593: lpIPSite->lpVtbl->OnInPlaceDeactivate(lpIPSite);
594: goto errActivate;
595: }
596:
597: (lpIPData = lpServerDoc->m_lpIPData)->lpSite = lpIPSite;
598: goto InPlaceActive;
599:
600: errActivate:
601: lpServerDoc->m_fInPlaceActive = FALSE;
602: if (lpIPSite)
603: OleStdRelease((LPUNKNOWN)lpIPSite);
604: return ResultFromScode(sc);
605: }
606:
607:
608: InPlaceActive:
609:
610: if (! lpServerDoc->m_fInPlaceVisible) {
611: lpServerDoc->m_fInPlaceVisible = TRUE;
612:
613: OLEDBG_BEGIN2("IOleInPlaceSite::GetWindow called\r\n");
614: hrErr = lpIPData->lpSite->lpVtbl->GetWindow(
615: lpIPData->lpSite,
616: &lpServerDoc->m_hWndParent
617: );
618: OLEDBG_END2
619: if (hrErr != NOERROR) {
620: sc = GetScode(hrErr);
621: goto errRtn;
622: }
623:
624: if (! lpServerDoc->m_hWndParent)
625: goto errRtn;
626:
627: /* OLE2NOTE: The server should fill in the "cb" field so that the
628: ** container can tell what size structure the server is
629: ** expecting. this enables this structure to be easily extended
630: ** in future releases of OLE. the container should check this
631: ** field so that it doesn't try to use fields that do not exist
632: ** since the server may be using an old structure definition.
633: */
634: _fmemset(
635: (LPOLEINPLACEFRAMEINFO)&lpIPData->frameInfo,
636: 0,
637: sizeof(OLEINPLACEFRAMEINFO)
638: );
639: lpIPData->frameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
640:
641: OLEDBG_BEGIN2("IOleInPlaceSite::GetWindowContext called\r\n");
642: hrErr = lpIPData->lpSite->lpVtbl->GetWindowContext(lpIPData->lpSite,
643: (LPOLEINPLACEFRAME FAR*) &lpIPData->lpFrame,
644: (LPOLEINPLACEUIWINDOW FAR*)&lpIPData->lpDoc,
645: (LPRECT)&rcPos,
646: (LPRECT)&rcClip,
647: (LPOLEINPLACEFRAMEINFO)&lpIPData->frameInfo);
648: OLEDBG_END2
649:
650: if (hrErr != NOERROR) {
651: sc = GetScode(hrErr);
652: goto errRtn;
653: }
654:
655: lpServerApp->m_lpIPData = lpIPData;
656: ShowWindow(hWndDoc, SW_HIDE); // make sure we are hidden
657:
658: /* OLE2NOTE: reparent in-place server document's window to the
659: ** special in-place hatch border window. set the in-place site's
660: ** window as the parent of the hatch window. position the
661: ** in-place and hatch border windows using the PosRect and
662: ** ClipRect.
663: ** it is important to properly parent and position the in-place
664: ** server window BEFORE calling IOleInPlaceFrame::SetMenu and
665: ** SetBorderSpace.
666: */
667: ShowWindow(lpServerDoc->m_hWndHatch, SW_SHOW);
668: // make sure App busy/blocked dialogs are parented to our
669: // new hWndFrame
670: OleStdMsgFilter_SetParentWindow(
671: lpOleApp->m_lpMsgFilter,lpIPData->frameInfo.hwndFrame);
672: SetParent(lpServerDoc->m_hWndHatch, lpServerDoc->m_hWndParent);
673: SetParent(hWndDoc, lpServerDoc->m_hWndHatch);
674:
675: OleDbgOutRect3("IOleInPlaceSite::GetWindowContext (PosRect)",
676: (LPRECT)&rcPos);
677: OleDbgOutRect3("IOleInPlaceSite::GetWindowContext (ClipRect)",
678: (LPRECT)&rcClip);
679:
680: // save the current PosRect and ClipRect
681: lpIPData->rcPosRect = rcPos;
682: lpIPData->rcClipRect = rcClip;
683:
684: /* OLE2NOTE: build the shared menu for the in-place container and
685: ** the server.
686: */
687: if (ServerDoc_AssembleMenus (lpServerDoc) != NOERROR)
688: goto errRtn;
689:
690: #if defined( SVR_INSIDEOUT )
691: if (lVerb == OLEIVERB_INPLACEACTIVATE) {
692: // Clip the hatch window to the size of pos rect so, that
693: // hatch and object adornments will not be visible.
694: ServerDoc_ResizeInPlaceWindow(lpServerDoc,
695: (LPRECT)&(lpServerDoc->m_lpIPData->rcPosRect),
696: (LPRECT)&(lpServerDoc->m_lpIPData->rcPosRect)
697: );
698: }
699: #endif // SVR_INSIDEOUT
700: }
701:
702: #if defined( SVR_INSIDEOUT )
703: // OLE2NOTE: if verb is OLEIVERB_INPLACEACTIVATE we do NOT want to
704: // show our UI
705: if (lVerb == OLEIVERB_INPLACEACTIVATE) {
706: return NOERROR;
707: }
708: #endif // SVR_INSIDEOUT
709:
710: if (! lpServerDoc->m_fUIActive) {
711: lpServerDoc->m_fUIActive = TRUE;
712: OLEDBG_BEGIN2("IOleInPlaceSite::OnUIActivate called\r\n");
713: hrErr = lpIPData->lpSite->lpVtbl->OnUIActivate(lpIPData->lpSite);
714: OLEDBG_END2
715: if (hrErr != NOERROR) {
716: lpServerDoc->m_fUIActive = FALSE;
717: goto errRtn;
718: }
719:
720: SetFocus(hWndDoc);
721:
722: // Show the object adornments and hacth border around them.
723: ServerDoc_ResizeInPlaceWindow(lpServerDoc,
724: (LPRECT)&lpIPData->rcPosRect,
725: (LPRECT)&lpIPData->rcClipRect
726: );
727:
728: /* OLE2NOTE: IOleInPlaceFrame::SetActiveObject must be called BEFORE
729: ** IOleInPlaceFrame::SetMenu.
730: */
731: lpIPData->lpFrame->lpVtbl->SetActiveObject(
732: lpIPData->lpFrame,
733: (LPOLEINPLACEACTIVEOBJECT) &lpServerDoc->m_OleInPlaceActiveObject,
734: (LPSTR)g_szIPObjectTitle
735: );
736:
737: if (lpIPData->lpDoc) {
738: lpIPData->lpDoc->lpVtbl->SetActiveObject(
739: lpIPData->lpDoc,
740: (LPOLEINPLACEACTIVEOBJECT)&lpServerDoc->m_OleInPlaceActiveObject,
741: (LPSTR)g_szIPObjectTitle
742: );
743: }
744:
745: /* OLE2NOTE: install the menu and frame-level tools on the in-place
746: ** frame.
747: */
748: ServerDoc_AddFrameLevelUI(lpServerDoc);
749: }
750:
751: return NOERROR;
752:
753: errRtn:
754: ServerDoc_DoInPlaceDeactivate(lpServerDoc);
755: return ResultFromScode(sc);
756: }
757:
758:
759:
760: HRESULT ServerDoc_DoInPlaceDeactivate(LPSERVERDOC lpServerDoc)
761: {
762: LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData;
763: LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
764:
765: if (!lpServerDoc->m_fInPlaceActive)
766: return S_OK;
767:
768: lpServerDoc->m_fInPlaceActive = FALSE;
769:
770: SvrDoc_IPObj_UIDeactivate(
771: (LPOLEINPLACEOBJECT)&lpServerDoc->m_OleInPlaceObject);
772:
773: #if defined( SVR_INSIDEOUT )
774: /* OLE2NOTE: an inside-out style in-place server will
775: ** NOT hide its window in UIDeactive (an outside-in
776: ** style object will hide its window in
777: ** UIDeactivate). thus we need to explicitly hide
778: ** our window now.
779: */
780: ServerDoc_DoInPlaceHide(lpServerDoc);
781: #endif // INSIEDOUT
782:
783: OLEDBG_BEGIN2("IOleInPlaceSite::OnInPlaceDeactivate called\r\n");
784: lpIPData->lpSite->lpVtbl->OnInPlaceDeactivate(lpIPData->lpSite);
785: OLEDBG_END2
786:
787: OleStdRelease((LPUNKNOWN)lpIPData->lpSite);
788: lpIPData->lpSite = NULL;
789:
790: ServerDoc_FreeInPlaceData(lpServerDoc);
791:
792: return NOERROR;
793: }
794:
795:
796: HRESULT ServerDoc_DoInPlaceHide(LPSERVERDOC lpServerDoc)
797: {
798: LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData;
799: LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
800: LPOLEAPP lpOleApp = (LPOLEAPP)g_lpApp;
801: HWND hWndApp = OutlineApp_GetWindow(g_lpApp);
802:
803: if (! lpServerDoc->m_fInPlaceVisible)
804: return NOERROR;
805:
806: // Set the parent back to server app's window
807: OleDoc_HideWindow((LPOLEDOC)lpServerDoc, FALSE /* fShutdown */);
808:
809: lpServerDoc->m_fInPlaceVisible = FALSE;
810:
811: lpServerDoc->m_hWndParent = hWndApp;
812: SetParent(
813: lpOutlineDoc->m_hWndDoc,
814: lpServerDoc->m_hWndParent
815: );
816:
817: // make sure App busy/blocked dialogs are parented to our own hWndApp
818: OleStdMsgFilter_SetParentWindow(lpOleApp->m_lpMsgFilter, hWndApp);
819:
820: // Hide the in-place hatch border window.
821: ShowWindow(lpServerDoc->m_hWndHatch, SW_HIDE);
822:
823: ServerDoc_DisassembleMenus(lpServerDoc);
824:
825: /* we no longer need the IOleInPlaceFrame* or the doc's
826: ** IOleInPlaceWindow* interface pointers.
827: */
828: if (lpIPData->lpDoc) {
829: OleStdRelease((LPUNKNOWN)lpIPData->lpDoc);
830: lpIPData->lpDoc = NULL;
831: }
832:
833: if (lpIPData->lpFrame) {
834: OleStdRelease((LPUNKNOWN)lpIPData->lpFrame);
835: lpIPData->lpFrame = NULL;
836: }
837:
838: ((LPSERVERAPP)g_lpApp)->m_lpIPData = NULL;
839:
840: return NOERROR;
841: }
842:
843:
844: BOOL ServerDoc_AllocInPlaceData(LPSERVERDOC lpServerDoc)
845: {
846: LPINPLACEDATA lpIPData;
847:
848: if (!(lpIPData = (LPINPLACEDATA) New(sizeof(INPLACEDATA))))
849: return FALSE;
850:
851: lpIPData->lpFrame = NULL;
852: lpIPData->lpDoc = NULL;
853: lpIPData->lpSite = NULL;
854: lpIPData->fInCSHelpMode = FALSE;
855: lpIPData->hOlemenu = NULL;
856: lpIPData->hMenuShared = NULL;
857:
858: lpServerDoc->m_lpIPData = lpIPData;
859: return TRUE;
860: }
861:
862:
863: void ServerDoc_FreeInPlaceData(LPSERVERDOC lpServerDoc)
864: {
865: Delete(lpServerDoc->m_lpIPData);
866: lpServerDoc->m_lpIPData = NULL;
867: }
868:
869:
870: HRESULT ServerDoc_AssembleMenus(LPSERVERDOC lpServerDoc)
871: {
872: HMENU hMenuShared;
873: LONG FAR* lpWidths;
874: UINT uPosition;
875: UINT uPositionStart;
876: LPSERVERAPP lpServerApp = (LPSERVERAPP) g_lpApp;
877: LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData;
878: HRESULT hresult;
879: BOOL fNoError = TRUE;
880:
881: lpWidths = lpIPData->menuGroupWidths.width;
882: hMenuShared = CreateMenu();
883:
884: if (hMenuShared &&
885: (hresult = lpIPData->lpFrame->lpVtbl->InsertMenus(
886: lpIPData->lpFrame, hMenuShared,
887: &lpIPData->menuGroupWidths)) == NOERROR) {
888:
889: /* Insert EDIT group menus */
890:
891: uPosition = (UINT)lpWidths[0]; /* # of menus in the FILE group */
892: uPositionStart = uPosition;
893:
894: fNoError &= InsertMenu(
895: hMenuShared,
896: (UINT)uPosition,
897: (UINT)(MF_BYPOSITION | MF_POPUP),
898: (UINT)lpServerApp->m_hMenuEdit,
899: (LPCSTR)"&Edit"
900: );
901: uPosition++;
902:
903: lpWidths[1] = uPosition - uPositionStart;
904:
905: /* Insert OBJECT group menus */
906:
907: uPosition += (UINT)lpWidths[2];
908: uPositionStart = uPosition;
909:
910: fNoError &= InsertMenu(
911: hMenuShared,
912: (UINT)uPosition,
913: (UINT)(MF_BYPOSITION | MF_POPUP),
914: (UINT)lpServerApp->m_hMenuLine,
915: (LPCSTR)"&Line"
916: );
917: uPosition++;
918:
919: fNoError &= InsertMenu(
920: hMenuShared,
921: (UINT)uPosition,
922: (UINT)(MF_BYPOSITION | MF_POPUP),
923: (UINT)lpServerApp->m_hMenuName,
924: (LPCSTR)"&Name"
925: );
926: uPosition++;
927:
928: fNoError &= InsertMenu(
929: hMenuShared,
930: (UINT)uPosition,
931: (UINT)(MF_BYPOSITION | MF_POPUP),
932: (UINT)lpServerApp->m_hMenuOptions,
933: (LPCSTR)"&Options"
934: );
935: uPosition++;
936:
937: fNoError &= InsertMenu(
938: hMenuShared,
939: (UINT)uPosition,
940: (UINT)(MF_BYPOSITION | MF_POPUP),
941: (UINT)lpServerApp->m_hMenuDebug,
942: (LPCSTR)"DbgI&Svr"
943: );
944: uPosition++;
945:
946: lpWidths[3] = uPosition - uPositionStart;
947:
948: /* Insert HELP group menus */
949:
950: uPosition += (UINT) lpWidths[4]; /* # of menus in WINDOW group */
951: uPositionStart = uPosition;
952:
953: fNoError &= InsertMenu(
954: hMenuShared,
955: (UINT)uPosition,
956: (UINT)(MF_BYPOSITION | MF_POPUP),
957: (UINT)lpServerApp->m_hMenuHelp,
958: (LPCSTR)"&Help"
959: );
960: uPosition++;
961:
962: lpWidths[5] = uPosition - uPositionStart;
963:
964: OleDbgAssert(fNoError == TRUE);
965:
966: } else {
967: /* In-place container does not allow us to add menus to the
968: ** frame.
969: ** OLE2NOTE: even when the in-place container does NOT allow
970: ** the building of a merged menu bar, it is CRITICAL that
971: ** the in-place server still call OleCreateMenuDescriptor
972: ** passing NULL for hMenuShared.
973: */
974: if (hMenuShared) {
975: DestroyMenu(hMenuShared);
976: hMenuShared = NULL;
977: }
978: }
979:
980: lpIPData->hMenuShared = hMenuShared;
981:
982: if (!(lpIPData->hOlemenu = OleCreateMenuDescriptor(hMenuShared,
983: &lpIPData->menuGroupWidths)))
984: return ResultFromScode(E_OUTOFMEMORY);
985:
986: return NOERROR;
987: }
988:
989:
990: void ServerDoc_DisassembleMenus(LPSERVERDOC lpServerDoc)
991: {
992: UINT uCount;
993: UINT uGroup;
994: UINT uDeleteAt;
995: LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData;
996: LONG FAR* lpWidths = lpIPData->menuGroupWidths.width;
997: BOOL fNoError = TRUE;
998:
999: /* OLE2NOTE: even when hMenuShared is NULL (ie. the server has no
1000: ** Menu), there is still an hOleMenu created that must be destroyed.
1001: */
1002: if (lpIPData->hOlemenu) {
1003: OleDestroyMenuDescriptor (lpIPData->hOlemenu);
1004: lpIPData->hOlemenu = NULL;
1005: }
1006:
1007: if (! lpIPData->hMenuShared)
1008: return; // no menus to be destroyed
1009:
1010: /* Remove server group menus. */
1011: uDeleteAt = 0;
1012: for (uGroup = 0; uGroup < 6; uGroup++) {
1013: uDeleteAt += (UINT)lpWidths[uGroup++];
1014: for (uCount = 0; uCount < (UINT)lpWidths[uGroup]; uCount++)
1015: fNoError &= RemoveMenu(lpIPData->hMenuShared, uDeleteAt,
1016: MF_BYPOSITION);
1017: }
1018:
1019: /* Remove container group menus */
1020: fNoError &= (lpIPData->lpFrame->lpVtbl->RemoveMenus(
1021: lpIPData->lpFrame,
1022: lpIPData->hMenuShared) == NOERROR);
1023:
1024: OleDbgAssert(fNoError == TRUE);
1025:
1026: DestroyMenu(lpIPData->hMenuShared);
1027: lpIPData->hMenuShared = NULL;
1028: }
1029:
1030:
1031: /* ServerDoc_UpdateInPlaceWindowOnExtentChange
1032: ** -------------------------------------------
1033: ** The size of the in-place window needs to be changed.
1034: ** calculate the size required in Client coordinates (taking into
1035: ** account the current scale factor imposed by the in-place
1036: ** container) and ask our in-place container to allow us to resize.
1037: ** our container must call us back via
1038: ** IOleInPlaceObject::SetObjectRects for the actual sizing to take
1039: ** place.
1040: **
1041: ** OLE2NOTE: the rectangle that we ask for from our in-place
1042: ** container is always the rectangle required for the object display
1043: ** itself (in our case the size of the LineList contents). it does
1044: ** NOT include the space we require for object frame adornments.
1045: */
1046: void ServerDoc_UpdateInPlaceWindowOnExtentChange(LPSERVERDOC lpServerDoc)
1047: {
1048: SIZEL sizelHim;
1049: SIZEL sizelPix;
1050: RECT rcPosRect;
1051: LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
1052: LPLINELIST lpLL=(LPLINELIST)&lpOutlineDoc->m_LineList;
1053: HWND hWndLL = lpLL->m_hWndListBox;
1054: LPSCALEFACTOR lpscale = (LPSCALEFACTOR)&lpOutlineDoc->m_scale;
1055:
1056: if (!lpServerDoc->m_fInPlaceActive)
1057: return;
1058:
1059: OleDoc_GetExtent((LPOLEDOC)lpServerDoc, (LPSIZEL)&sizelHim);
1060:
1061: // apply current scale factor
1062: sizelHim.cx = sizelHim.cx * lpscale->dwSxN / lpscale->dwSxD;
1063: sizelHim.cy = sizelHim.cy * lpscale->dwSxN / lpscale->dwSxD;
1064: XformSizeInHimetricToPixels(NULL, (LPSIZEL)&sizelHim, (LPSIZEL)&sizelPix);
1065:
1066: GetWindowRect(hWndLL, (LPRECT)&rcPosRect);
1067: ScreenToClient(lpServerDoc->m_hWndParent, (POINT FAR *)&rcPosRect);
1068:
1069: rcPosRect.right = rcPosRect.left + (int) sizelPix.cx;
1070: rcPosRect.bottom = rcPosRect.top + (int) sizelPix.cy;
1071:
1072: OleDbgOutRect3("ServerDoc_UpdateInPlaceWindowOnExtentChange: (PosRect)",
1073: (LPRECT)&rcPosRect);
1074:
1075: OLEDBG_BEGIN2("IOleInPlaceSite::OnPosRectChange called\r\n");
1076: lpServerDoc->m_lpIPData->lpSite->lpVtbl->OnPosRectChange(
1077: lpServerDoc->m_lpIPData->lpSite,
1078: (LPRECT) &rcPosRect
1079: );
1080: OLEDBG_END2
1081: }
1082:
1083:
1084: /* ServerDoc_CalcInPlaceWindowPos
1085: * ------------------------------
1086: *
1087: * Move (and re-scale) the ServerDoc to the specified rectangle.
1088: *
1089: * Parameters:
1090: * lprcListBox - rect in client coordinate in which the listbox will fit
1091: * lprcDoc - corresponding size of the Doc in client coordinate
1092: *
1093: */
1094: void ServerDoc_CalcInPlaceWindowPos(
1095: LPSERVERDOC lpServerDoc,
1096: LPRECT lprcListBox,
1097: LPRECT lprcDoc,
1098: LPSCALEFACTOR lpscale
1099: )
1100: {
1101: SIZEL sizelHim;
1102: SIZEL sizelPix;
1103: LPLINELIST lpLL;
1104: LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
1105: LPHEADING lphead;
1106:
1107: if (!lpServerDoc || !lprcListBox || !lprcDoc)
1108: return;
1109:
1110: lphead = (LPHEADING)&lpOutlineDoc->m_heading;
1111:
1112: lpLL = OutlineDoc_GetLineList(lpOutlineDoc);
1113: OleDoc_GetExtent((LPOLEDOC)lpServerDoc, (LPSIZEL)&sizelHim);
1114: XformSizeInHimetricToPixels(NULL, &sizelHim, &sizelPix);
1115:
1116: if (sizelHim.cx == 0) {
1117: lpscale->dwSxN = 1;
1118: lpscale->dwSxD = 1;
1119: } else {
1120: lpscale->dwSxN = lprcListBox->right - lprcListBox->left;
1121: lpscale->dwSxD = sizelPix.cx;
1122: }
1123:
1124: if (sizelHim.cy == 0) {
1125: lpscale->dwSyN = 1;
1126: lpscale->dwSyD = 1;
1127: } else {
1128: lpscale->dwSyN = lprcListBox->bottom - lprcListBox->top;
1129: lpscale->dwSyD = sizelPix.cy;
1130: }
1131:
1132: lprcDoc->left = lprcListBox->left - Heading_RH_GetWidth(lphead,lpscale);
1133: lprcDoc->right = lprcListBox->right;
1134: lprcDoc->top = lprcListBox->top - Heading_CH_GetHeight(lphead,lpscale);
1135: lprcDoc->bottom = lprcListBox->bottom;
1136: }
1137:
1138:
1139: /* ServerDoc_ResizeInPlaceWindow
1140: ** -----------------------------
1141: ** Actually resize the in-place ServerDoc windows according to the
1142: ** PosRect and ClipRect allowed by our in-place container.
1143: **
1144: ** OLE2NOTE: the PosRect rectangle that our in-place container tells
1145: ** us is always the rectangle required for the object display
1146: ** itself (in our case the size of the LineList contents). it does
1147: ** NOT include the space we require for object frame adornments.
1148: */
1149: void ServerDoc_ResizeInPlaceWindow(
1150: LPSERVERDOC lpServerDoc,
1151: LPCRECT lprcPosRect,
1152: LPCRECT lprcClipRect
1153: )
1154: {
1155: LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
1156: LPLINELIST lpLL = (LPLINELIST)&lpOutlineDoc->m_LineList;
1157: SCALEFACTOR scale;
1158: RECT rcDoc;
1159: POINT ptOffset;
1160:
1161: /* OLE2NOTE: calculate the space needed for our object frame
1162: ** adornments. our in-place container tells us the size that our
1163: ** object should take in window client coordinates
1164: ** (lprcPosRect). the rectangle cooresponds to the size that our
1165: ** LineList ListBox should be. our Doc window must the correct
1166: ** amount larger to accomodate our row/column headings.
1167: ** then move all windows into position.
1168: */
1169: ServerDoc_CalcInPlaceWindowPos(
1170: lpServerDoc,
1171: (LPRECT)lprcPosRect,
1172: (LPRECT)&rcDoc,
1173: (LPSCALEFACTOR)&scale
1174: );
1175:
1176: /* OLE2NOTE: we need to honor the lprcClipRect specified by our
1177: ** in-place container. we must NOT draw outside of the ClipRect.
1178: ** in order to achieve this, we will size the hatch window to be
1179: ** exactly the size that should be visible (rcVisRect). the
1180: ** rcVisRect is defined as the intersection of the full size of
1181: ** the in-place server window and the lprcClipRect.
1182: ** the ClipRect could infact clip the HatchRect on the
1183: ** right/bottom and/or on the top/left. if it is clipped on the
1184: ** right/bottom then it is sufficient to simply resize the hatch
1185: ** window. but if the HatchRect is clipped on the top/left then
1186: ** we must "move" the ServerDoc window (child of HatchWindow) by
1187: ** the delta that was clipped. the window origin of the
1188: ** ServerDoc window will then have negative coordinates relative
1189: ** to its parent HatchWindow.
1190: */
1191: SetHatchWindowSize(
1192: lpServerDoc->m_hWndHatch,
1193: (LPRECT)&rcDoc,
1194: (LPRECT)lprcClipRect,
1195: (LPPOINT)&ptOffset
1196: );
1197:
1198: // shift Doc window to account for hatch frame being drawn
1199: OffsetRect((LPRECT)&rcDoc, ptOffset.x, ptOffset.y);
1200:
1201: // move/size/set scale factor of ServerDoc window.
1202: OutlineDoc_SetScaleFactor(
1203: lpOutlineDoc, (LPSCALEFACTOR)&scale, (LPRECT)&rcDoc);
1204: }
1205:
1206:
1207:
1208: /* ServerDoc_GetTopInPlaceFrame
1209: ** ----------------------------
1210: ** returns NON-AddRef'ed pointer to Top In-Place Frame interface
1211: */
1212: LPOLEINPLACEFRAME ServerDoc_GetTopInPlaceFrame(LPSERVERDOC lpServerDoc)
1213: {
1214: if (lpServerDoc->m_lpIPData)
1215: return lpServerDoc->m_lpIPData->lpFrame;
1216: else
1217: return NULL;
1218: }
1219:
1220: void ServerDoc_GetSharedMenuHandles(
1221: LPSERVERDOC lpServerDoc,
1222: HMENU FAR* lphSharedMenu,
1223: HOLEMENU FAR* lphOleMenu
1224: )
1225: {
1226: if (lpServerDoc->m_lpIPData) {
1227: *lphSharedMenu = lpServerDoc->m_lpIPData->hMenuShared;
1228: *lphOleMenu = lpServerDoc->m_lpIPData->hOlemenu;
1229: } else {
1230: *lphSharedMenu = NULL;
1231: *lphOleMenu = NULL;
1232: }
1233: }
1234:
1235:
1236: void ServerDoc_AddFrameLevelUI(LPSERVERDOC lpServerDoc)
1237: {
1238: LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
1239: LPSERVERAPP lpServerApp = (LPSERVERAPP)g_lpApp;
1240: LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
1241: LPOLEINPLACEFRAME lpTopIPFrame=ServerDoc_GetTopInPlaceFrame(lpServerDoc);
1242: HMENU hSharedMenu; // combined obj/cntr menu
1243: HOLEMENU hOleMenu; // returned by OleCreateMenuDesc.
1244:
1245: ServerDoc_GetSharedMenuHandles(
1246: lpServerDoc,
1247: &hSharedMenu,
1248: &hOleMenu
1249: );
1250:
1251: lpTopIPFrame->lpVtbl->SetMenu(
1252: lpTopIPFrame,
1253: hSharedMenu,
1254: hOleMenu,
1255: lpOutlineDoc->m_hWndDoc
1256: );
1257:
1258: lpOutlineApp->m_hAccel = lpServerApp->m_hAccelIPSvr;
1259: lpOutlineApp->m_hWndAccelTarget = lpOutlineDoc->m_hWndDoc;
1260:
1261: #if defined( USE_FRAMETOOLS )
1262: ServerDoc_AddFrameLevelTools(lpServerDoc);
1263:
1264: // update toolbar button enable states
1265: OutlineDoc_UpdateFrameToolButtons(lpOutlineDoc);
1266: #endif
1267: }
1268:
1269:
1270: void ServerDoc_AddFrameLevelTools(LPSERVERDOC lpServerDoc)
1271: {
1272: LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
1273: LPSERVERAPP lpServerApp = (LPSERVERAPP)g_lpApp;
1274: LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
1275: LPOLEINPLACEFRAME lpTopIPFrame=ServerDoc_GetTopInPlaceFrame(lpServerDoc);
1276:
1277: #if defined( USE_FRAMETOOLS )
1278: HWND hWndFrame;
1279:
1280: FrameTools_Enable(lpOutlineDoc->m_lpFrameTools, TRUE);
1281:
1282: // if not in-place UI active, add our tools to our own frame.
1283: if (! lpServerDoc->m_fUIActive) {
1284: OutlineDoc_AddFrameLevelTools(lpOutlineDoc);
1285: return;
1286: }
1287:
1288: if ((hWndFrame = OutlineApp_GetFrameWindow(lpOutlineApp)) == NULL) {
1289: /* we could NOT get a valid frame window, so POP our tools up. */
1290:
1291: /* OLE2NOTE: since we are poping up our tools, we MUST inform
1292: ** the top in-place frame window that we need NO tool space
1293: ** BUT that it should NOT put its own tools up. if we were
1294: ** to pass NULL instead of (0,0,0,0), then the container
1295: ** would have the option to leave its own tools up.
1296: */
1297: lpTopIPFrame->lpVtbl->SetBorderSpace(
1298: lpTopIPFrame,
1299: (LPCBORDERWIDTHS)&g_rectNull
1300: );
1301: FrameTools_PopupTools(lpOutlineDoc->m_lpFrameTools);
1302: } else {
1303:
1304: /* OLE2NOTE: we need to negotiate for space and attach our frame
1305: ** level tools to the top-level in-place container's frame window.
1306: */
1307: FrameTools_AttachToFrame(lpOutlineDoc->m_lpFrameTools, hWndFrame);
1308:
1309: FrameTools_NegotiateForSpaceAndShow(
1310: lpOutlineDoc->m_lpFrameTools,
1311: NULL,
1312: lpTopIPFrame
1313: );
1314: }
1315:
1316: #else // ! USE_FRAMETOOLS
1317: /* OLE2NOTE: if you do NOT use frame tools, you MUST inform the top
1318: ** in-place frame window so that it can put back its own tools.
1319: */
1320: lpTopIPFrame->lpVtbl->SetBorderSpace(lpIPData->lpFrame, NULL);
1321: #endif // ! USE_FRAMETOOLS
1322: }
1323:
1324:
1325: #if defined( USE_FRAMETOOLS )
1326:
1327: void ServerDoc_RemoveFrameLevelTools(LPSERVERDOC lpServerDoc)
1328: {
1329: LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
1330: OleDbgAssert(lpOutlineDoc->m_lpFrameTools != NULL);
1331:
1332: FrameTools_Enable(lpOutlineDoc->m_lpFrameTools, FALSE);
1333: }
1334: #endif // USE_FRAMETOOLS
1335:
1336:
1337:
1338: void ServerDoc_UIActivate (LPSERVERDOC lpServerDoc)
1339: {
1340: if (lpServerDoc->m_fInPlaceActive && !lpServerDoc->m_fUIActive) {
1341: ServerDoc_DoInPlaceActivate(lpServerDoc,
1342: OLEIVERB_UIACTIVATE,
1343: NULL /*lpmsg*/,
1344: lpServerDoc->m_lpOleClientSite
1345: );
1346: OutlineDoc_ShowWindow((LPOUTLINEDOC)lpServerDoc);
1347: }
1348: }
1349:
1350:
1351:
1352: #endif // INPLACE_SVR
1353:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.