|
|
//**********************************************************************
// File name: IOO.CPP
//
// Implementation file for the COleObject Class
//
// Functions:
//
// See ioo.h for a list of member functions.
//
// Copyright (c) 1993 Microsoft Corporation. All rights reserved.
//**********************************************************************
#include "pre.h"
#include "obj.h"
#include "ioo.h"
#include "app.h"
#include "doc.h"
#define VERB_OPEN 1
//**********************************************************************
//
// COleObject::QueryInterface
//
// Purpose:
// Used for interface negotiation
//
// Parameters:
//
// REFIID riid - Interface being queried for.
//
// LPVOID FAR *ppvObj - Out pointer for the interface.
//
// Return Value:
//
// S_OK - Success
// E_NOINTERFACE - Failure
//
// Function Calls:
// Function Location
//
// CSimpSvrObj::QueryInterface OBJ.CPP
//
//
//********************************************************************
STDMETHODIMP COleObject::QueryInterface ( REFIID riid, LPVOID FAR* ppvObj) { TestDebugOut(TEXT("In COleObject::QueryInterface\r\n")); return m_lpObj->QueryInterface(riid, ppvObj); }
//**********************************************************************
//
// COleObject::AddRef
//
// Purpose:
//
// Increments the reference count on CSimpSvrObj. Since COleObject
// is a nested class of CSimpSvrObj, we don't need an extra reference
// count for COleObject. We can safely use the reference count of
// CSimpSvrObj.
//
// Parameters:
//
// None
//
// Return Value:
//
// The new reference count on the CSimpSvrObj
//
// Function Calls:
// Function Location
//
// OuputDebugString Windows API
// CSimpSvrObj::AddRef OBJ.CPP
//
//
//********************************************************************
STDMETHODIMP_(ULONG) COleObject::AddRef () { TestDebugOut(TEXT("In COleObject::AddRef\r\n")); return m_lpObj->AddRef(); }
//**********************************************************************
//
// COleObject::Release
//
// Purpose:
//
// Decrements the reference count on CSimpSvrObj. Since COleObject
// is a nested class of CSimpSvrObj, we don't need an extra reference
// count for COleObject. We can safely use the reference count of
// CSimpSvrObj.
//
// Parameters:
//
// None
//
// Return Value:
//
// The new reference count of CSimpSvrObj
//
// Function Calls:
// Function Location
//
// TestDebugOut Windows API
// CSimpSvrObj::Release OBJ.CPP
//
//
//********************************************************************
STDMETHODIMP_(ULONG) COleObject::Release () { TestDebugOut(TEXT("In COleObject::Release\r\n")); return m_lpObj->Release(); }
//**********************************************************************
//
// COleObject::SetClientSite
//
// Purpose:
//
// Called to notify the object of it's client site.
//
// Parameters:
//
// LPOLECLIENTSITE pClientSite - ptr to new client site
//
// Return Value:
//
// S_OK
//
// Function Calls:
// Function Location
//
// TestDebugOut Windows API
// IOleClientSite::Release Container
// IOleClientSite::AddRef Container
//
//
//********************************************************************
STDMETHODIMP COleObject::SetClientSite ( LPOLECLIENTSITE pClientSite) { TestDebugOut(TEXT("In COleObject::SetClientSite\r\n"));
// if we already have a client site, release it.
if (m_lpObj->m_lpOleClientSite) { m_lpObj->m_lpOleClientSite->Release(); m_lpObj->m_lpOleClientSite = NULL; }
// store copy of the client site.
m_lpObj->m_lpOleClientSite = pClientSite;
// AddRef it so it doesn't go away.
if (m_lpObj->m_lpOleClientSite) m_lpObj->m_lpOleClientSite->AddRef();
return ResultFromScode(S_OK); }
//**********************************************************************
//
// COleObject::Advise
//
// Purpose:
//
// Called to set up an advise on the OLE object.
//
// Parameters:
//
// LPADVISESINK pAdvSink - ptr to the Advise Sink for notification
//
// DWORD FAR* pdwConnection - place to return the connection ID.
//
// Return Value:
//
// Passed back from IOleAdviseHolder::Advise.
//
// Function Calls:
// Function Location
//
// TestDebugOut Windows API
// CreateOleAdviseHolder OLE API
// IOleAdviseHolder::Advise OLE
//
//
//********************************************************************
STDMETHODIMP COleObject::Advise ( LPADVISESINK pAdvSink, DWORD FAR* pdwConnection) { TestDebugOut(TEXT("In COleObject::Advise\r\n"));
// if we haven't made an OleAdviseHolder yet, make one.
if (!m_lpObj->m_lpOleAdviseHolder) { HRESULT hRes; if ((hRes=CreateOleAdviseHolder(&m_lpObj->m_lpOleAdviseHolder))!=S_OK) { TestDebugOut(TEXT("CreateOleAdviseHolder fails\n")); return(hRes); } }
// pass this call onto the OleAdviseHolder.
return m_lpObj->m_lpOleAdviseHolder->Advise(pAdvSink, pdwConnection); }
//**********************************************************************
//
// COleObject::SetHostNames
//
// Purpose:
//
// Called to pass strings for Window titles.
//
// Parameters:
//
// LPCOLESTR szContainerApp - ptr to string describing Container App
//
// LPCOLESTR szContainerObj - ptr to string describing Object
//
// Return Value:
//
// S_OK
//
// Function Calls:
// Function Location
//
// TestDebugOut Windows API
//
// Comments:
//
// This routine is called so that the server application can
// set the window title appropriately.
//
//********************************************************************
STDMETHODIMP COleObject::SetHostNames ( LPCOLESTR szContainerApp, LPCOLESTR szContainerObj) { TestDebugOut(TEXT("In COleObject::SetHostNames\r\n"));
return ResultFromScode( S_OK); }
//**********************************************************************
//
// COleObject::DoVerb
//
// Purpose:
//
// Called by the container application to invoke a verb.
//
// Parameters:
//
// LONG iVerb - The value of the verb to be
// invoked.
//
// LPMSG lpmsg - The message that caused the
// verb to be invoked.
//
// LPOLECLIENTSITE pActiveSite - Ptr to the active client site.
//
// LONG lindex - Used in extended layout
//
// HWND hwndParent - This should be the window handle of
// the window in which we are contained.
// This value could be used to "fake"
// inplace activation in a manner similar
// to Video for Windows in OLE 1.0.
//
// LPCRECT lprcPosRect - The rectangle that contains the object
// within hwndParent. Also used to
// "fake" inplace activation.
//
// Return Value:
//
// OLE_E_NOTINPLACEACTIVE - Returned if attempted to undo while not
// inplace active.
// S_OK
//
// Function Calls:
// Function Location
//
// TestDebugOut Windows API
// ShowWindow Windows API
// CSimpSvrObj::DoInPlaceActivate OBJ.CPP
// CSimpSvrObj::DoInPlaceHide OBJ.CPP
// COleObject::OpenEdit IOO.CPP
// CSimpSvrDoc::GethDocWnd DOC.H
// COleInPlaceObj::InPlaceDeactivate IOIPO.CPP
//
// Comments:
//
// Be sure to look at TECHNOTES.WRI included with the OLE
// SDK for a description of handling the inplace verbs
// properly.
//
//********************************************************************
STDMETHODIMP COleObject::DoVerb ( LONG iVerb, LPMSG lpmsg, LPOLECLIENTSITE pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect) { TestDebugOut(TEXT("In COleObject::DoVerb\r\n"));
switch (iVerb) { case OLEIVERB_SHOW: case OLEIVERB_PRIMARY: if (m_fOpen) SetFocus(m_lpObj->m_lpDoc->GethAppWnd()); else if (m_lpObj->DoInPlaceActivate(iVerb) == FALSE) OpenEdit(pActiveSite); break;
case OLEIVERB_UIACTIVATE: if (m_fOpen) return ResultFromScode (E_FAIL);
// inplace activate
if (!m_lpObj->DoInPlaceActivate(iVerb)) return ResultFromScode (E_FAIL); break;
case OLEIVERB_DISCARDUNDOSTATE: // don't have to worry about this situation as we don't
// support an undo state.
if (!m_lpObj->m_fInPlaceActive) return ResultFromScode(OLE_E_NOT_INPLACEACTIVE); break;
case OLEIVERB_HIDE: // if inplace active, do an "inplace" hide, otherwise
// just hide the app window.
if (m_lpObj->m_fInPlaceActive) { // clear inplace flag
m_lpObj->m_fInPlaceActive = FALSE;
// deactivate the UI
m_lpObj->DeactivateUI(); m_lpObj->DoInPlaceHide(); } else m_lpObj->m_lpDoc->GetApp()->HideAppWnd(); break;
case OLEIVERB_OPEN: case VERB_OPEN: // if inplace active, deactivate
if (m_lpObj->m_fInPlaceActive) m_lpObj->m_OleInPlaceObject.InPlaceDeactivate();
// open into another window.
OpenEdit(pActiveSite); break;
default: if (iVerb < 0) return ResultFromScode(E_FAIL); }
return ResultFromScode( S_OK); }
//**********************************************************************
//
// COleObject::GetExtent
//
// Purpose:
//
// Returns the extent of the object.
//
// Parameters:
//
// DWORD dwDrawAspect - The aspect in which to get the size.
//
// LPSIZEL lpsizel - Out ptr to return the size.
//
// Return Value:
// S_OK if the aspect is DVASPECT_CONTENT
// E_FAIL otherwise
//
// Function Calls:
// Function Location
//
// TestDebugOut Windows API
// XformWidthInPixelsToHimetric OLE2UI
// XformHeightInPixelsToHimetric OLE2UI
//
//
//********************************************************************
STDMETHODIMP COleObject::GetExtent ( DWORD dwDrawAspect, LPSIZEL lpsizel) { TestDebugOut(TEXT("In COleObject::GetExtent\r\n"));
SCODE sc = E_FAIL;
// Only DVASPECT_CONTENT is supported....
if (dwDrawAspect == DVASPECT_CONTENT) { sc = S_OK;
// return the correct size in HIMETRIC...
lpsizel->cx = XformWidthInPixelsToHimetric(NULL, m_lpObj->m_size.x); lpsizel->cy = XformHeightInPixelsToHimetric(NULL, m_lpObj->m_size.y); }
return ResultFromScode( sc ); }
//**********************************************************************
//
// COleObject::Update
//
// Purpose:
//
// Called to get the most up to date data
//
// Parameters:
//
// None
//
// Return Value:
//
// S_OK
//
// Function Calls:
// Function Location
//
// TestDebugOut Windows API
// IDataAdviseHolder::SendOnDataChange OLE
//
//
//********************************************************************
STDMETHODIMP COleObject::Update() { TestDebugOut(TEXT("In COleObject::Update\r\n"));
// force an update
m_lpObj->SendOnDataChange();
return ResultFromScode( S_OK ); }
//**********************************************************************
//
// COleObject::Close
//
// Purpose:
//
// Called when the OLE object needs to be closed
//
// Parameters:
//
// DWORD dwSaveOption - Flags to instruct the server how to prompt
// the user.
//
// Return Value:
//
// S_OK
//
// Function Calls:
// Function Location
//
// TestDebugOut Windows API
// CSimpSvrDoc::Close DOC.CPP
//
//
//********************************************************************
STDMETHODIMP COleObject::Close ( DWORD dwSaveOption) { TestDebugOut(TEXT("In COleObject::Close\r\n"));
// delegate to the document object.
m_lpObj->m_lpDoc->Close();
return ResultFromScode( S_OK ); }
//**********************************************************************
//
// COleObject::Unadvise
//
// Purpose:
//
// Breaks down an OLE advise that has been set up on this object.
//
// Parameters:
//
// DWORD dwConnection - Connection that needs to be broken down
//
// Return Value:
//
// Passed back from IOleAdviseHolder::Unadvise
//
// Function Calls:
// Function Location
//
// TestDebugOut Windows API
// IOleAdviseHolder::Unadvise OLE
//
//
//********************************************************************
STDMETHODIMP COleObject::Unadvise ( DWORD dwConnection) { TestDebugOut(TEXT("In COleObject::Unadvise\r\n"));
// pass on to OleAdviseHolder.
return m_lpObj->m_lpOleAdviseHolder->Unadvise(dwConnection); }
//**********************************************************************
//
// COleObject::EnumVerbs
//
// Purpose:
//
// Enumerates the verbs associated with this object.
//
// Parameters:
//
// LPENUMOLEVERB FAR* ppenumOleVerb - Out ptr in which to return
// the enumerator
//
// Return Value:
//
// OLE_S_USEREG - Instructs OLE to use the verbs found in the
// REG DB for this server.
//
// Function Calls:
// Function Location
//
// TestDebugOut Windows API
//
// Comments:
//
// In a .DLL, an application cannot return OLE_S_USEREG. This is
// due to the fact that the default object handler is not being
// used, and the container is really making direct function calls
// into the server .DLL.
//
//********************************************************************
STDMETHODIMP COleObject::EnumVerbs ( LPENUMOLEVERB FAR* ppenumOleVerb) { TestDebugOut(TEXT("In COleObject::EnumVerbs\r\n"));
return ResultFromScode( OLE_S_USEREG ); }
//**********************************************************************
//
// COleObject::GetClientSite
//
// Purpose:
//
// Called to get the current client site of the object.
//
// Parameters:
//
// LPOLECLIENTSITE FAR* ppClientSite - Out ptr in which to return the
// client site.
//
// Return Value:
//
// S_OK
//
// Function Calls:
// Function Location
//
// TestDebugOut Windows API
//
//
//********************************************************************
STDMETHODIMP COleObject::GetClientSite ( LPOLECLIENTSITE FAR* ppClientSite) { TestDebugOut(TEXT("In COleObject::GetClientSite\r\n")); *ppClientSite = m_lpObj->m_lpOleClientSite; return ResultFromScode( S_OK ); }
//**********************************************************************
//
// COleObject::SetMoniker
//
// Purpose:
//
// Used to set the objects moniker
//
// Parameters:
//
// DWORD dwWhichMoniker - Type of moniker being set
//
// LPMONIKER pmk - Pointer to the moniker
//
// Return Value:
// S_OK
// E_FAIL if the Moniker cannot be set
//
// Function Calls:
// Function Location
//
// TestDebugOut Windows API
//
//
//********************************************************************
STDMETHODIMP COleObject::SetMoniker ( DWORD dwWhichMoniker, LPMONIKER pmk) { TestDebugOut(TEXT("In COleObject::SetMoniker\r\n"));
LPMONIKER lpmk; HRESULT hRes;
if (! m_lpObj->GetOleClientSite()) return ResultFromScode (E_FAIL);
if (m_lpObj->GetOleClientSite()->GetMoniker (OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_OBJFULL, &lpmk) != NOERROR) return ResultFromScode (E_FAIL);
if (m_lpObj->GetOleAdviseHolder()) { if ((hRes=m_lpObj->GetOleAdviseHolder()->SendOnRename(lpmk))!=S_OK) TestDebugOut(TEXT("SendOnRename fails\n")); }
LPRUNNINGOBJECTTABLE lpRot;
if (GetRunningObjectTable(0, &lpRot) == NOERROR) { if (m_lpObj->m_dwRegister) lpRot->Revoke(m_lpObj->m_dwRegister);
if ( ((hRes=lpRot->Register(0, m_lpObj, lpmk, &m_lpObj->m_dwRegister))!=S_OK) || (hRes!=ResultFromScode(MK_S_MONIKERALREADYREGISTERED))) TestDebugOut(TEXT("Running Object Table Register fails\n"));
lpRot->Release(); }
return ResultFromScode( S_OK ); }
//**********************************************************************
//
// COleObject::GetMoniker
//
// Purpose:
// returns a moniker from the client site
//
// Parameters:
//
// DWORD dwAssign - Assignment for the moniker
//
// DWORD dwWhichMoniker - Which moniker to return
//
// LPMONIKER FAR* ppmk - An out ptr to return the moniker
//
// Return Value:
//
//
// Function Calls:
// Function Location
//
// TestDebugOut Windows API
//
//
//********************************************************************
STDMETHODIMP COleObject::GetMoniker ( DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER FAR* ppmk) { TestDebugOut(TEXT("In COleObject::GetMoniker\r\n")); // need to NULL the out parameter
*ppmk = NULL;
return m_lpObj->GetOleClientSite()->GetMoniker(OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_OBJFULL, ppmk); }
//**********************************************************************
//
// COleObject::InitFromData
//
// Purpose:
//
// Initialize the object from the passed pDataObject.
//
// Parameters:
//
// LPDATAOBJECT pDataObject - Pointer to data transfer object
// to be used in the initialization
//
// BOOL fCreation - TRUE if the object is currently being
// created.
//
// DWORD dwReserved - Reserved
//
// Return Value:
//
// S_FALSE
//
// Function Calls:
// Function Location
//
// TestDebugOut Windows API
//
// Comments:
//
// We don't support this functionality, so we will always return
// error.
//
//********************************************************************
STDMETHODIMP COleObject::InitFromData ( LPDATAOBJECT pDataObject, BOOL fCreation, DWORD dwReserved) { TestDebugOut(TEXT("In COleObject::InitFromData\r\n"));
return ResultFromScode( S_FALSE ); }
//**********************************************************************
//
// COleObject::GetClipboardData
//
// Purpose:
//
// Returns an IDataObject that is the same as doing an OleSetClipboard
//
// Parameters:
//
// DWORD dwReserved - Reserved
//
// LPDATAOBJECT FAR* ppDataObject - Out ptr for the Data Object.
//
// Return Value:
//
// OLE_E_NOTSUPPORTED
//
// Function Calls:
// Function Location
//
// TestDebugOut Windows API
//
// Comments:
//
// Support of this method is optional.
//
//********************************************************************
STDMETHODIMP COleObject::GetClipboardData ( DWORD dwReserved, LPDATAOBJECT FAR* ppDataObject) { TestDebugOut(TEXT("In COleObject::GetClipboardData\r\n")); // NULL the out ptr
*ppDataObject = NULL; return ResultFromScode( E_NOTIMPL ); }
//**********************************************************************
//
// COleObject::IsUpToDate
//
// Purpose:
//
// Determines if an object is up to date
//
// Parameters:
//
// None
//
// Return Value:
//
// S_OK
//
// Function Calls:
// Function Location
//
// TestDebugOut Windows API
//
// Comments:
//
// Our embedded object is always up to date. This function is
// particularly useful in linking situations.
//
//********************************************************************
STDMETHODIMP COleObject::IsUpToDate() { TestDebugOut(TEXT("In COleObject::IsUpToDate\r\n")); return ResultFromScode( S_OK ); }
//**********************************************************************
//
// COleObject::GetUserClassID
//
// Purpose:
//
// Returns the applications CLSID
//
// Parameters:
//
// CLSID FAR* pClsid - Out ptr to return the CLSID
//
// Return Value:
//
// S_OK
//
// Function Calls:
// Function Location
//
// TestDebugOut Windows API
// CPersistStorage::GetClassID IPS.CPP
//
// Comments:
//
// This function is just delegated to IPS::GetClassID.
//
//********************************************************************
STDMETHODIMP COleObject::GetUserClassID ( CLSID FAR* pClsid) { TestDebugOut(TEXT("In COleObject::GetUserClassID\r\n"));
return ( m_lpObj->m_PersistStorage.GetClassID(pClsid) ); }
//**********************************************************************
//
// COleObject::GetUserType
//
// Purpose:
//
// Used to get a user presentable id for this object
//
// Parameters:
//
// DWORD dwFormOfType - The ID requested
//
// LPOLESTR FAR* pszUserType - Out ptr to return the string
//
// Return Value:
//
// OLE_S_USEREG - Use the reg db to get these entries.
//
// Function Calls:
// Function Location
//
// TestDebugOut Windows API
//
// Comment:
// In this implementation, we delegate to the default handler's
// implementation using the registration database to provide
// the requested info.
//
//********************************************************************
STDMETHODIMP COleObject::GetUserType ( DWORD dwFormOfType, LPOLESTR FAR* pszUserType) { TestDebugOut(TEXT("In COleObject::GetUserType\r\n"));
return ResultFromScode( OLE_S_USEREG ); }
//**********************************************************************
//
// COleObject::SetExtent
//
// Purpose:
//
// Called to set the extent of the object.
//
// Parameters:
//
// DWORD dwDrawAspect - Aspect to have its size set
//
// LPSIZEL lpsizel - New size of the object.
//
// Return Value:
//
// E_NOTIMPL - This function is not curently implemented.
//
// Function Calls:
// Function Location
//
// TestDebugOut Windows API
//
// Comments:
//
// See TECHNOTES.WRI include with the OLE SDK for proper
// implementation of this function.
//
//
//********************************************************************
STDMETHODIMP COleObject::SetExtent ( DWORD dwDrawAspect, LPSIZEL lpsizel) { TestDebugOut(TEXT("In COleObject::SetExtent\r\n")); return ResultFromScode( E_NOTIMPL); }
//**********************************************************************
//
// COleObject::EnumAdvise
//
// Purpose:
//
// Returns an enumerate which enumerates the outstanding advises
// associated with this OLE object.
//
// Parameters:
//
// LPENUMSTATDATA FAR* ppenumAdvise - Out ptr in which to return
// the enumerator.
//
// Return Value:
//
// Passed on from IOleAdviseHolder::EnumAdvise.
//
// Function Calls:
// Function Location
//
// TestDebugOut Windows API
// IOleAdviseHolder::EnumAdvise OLE
//
//
//********************************************************************
STDMETHODIMP COleObject::EnumAdvise ( LPENUMSTATDATA FAR* ppenumAdvise) { TestDebugOut(TEXT("In COleObject::EnumAdvise\r\n")); // need to NULL the out parameter
*ppenumAdvise = NULL;
// pass on to the OLE Advise holder.
return m_lpObj->m_lpOleAdviseHolder->EnumAdvise(ppenumAdvise); }
//**********************************************************************
//
// COleObject::GetMiscStatus
//
// Purpose:
//
// Return status information about the object
//
// Parameters:
//
// DWORD dwAspect - Aspect interested in.
//
// DWORD FAR* pdwStatus - Out ptr in which to return the bits.
//
// Return Value:
//
// OLE_S_USEREG - Use the reg db to get these entries.
//
// Function Calls:
// Function Location
//
// TestDebugOut Windows API
//
// Comment:
// In this implementation, we delegate to the default handler's
// implementation using the registration database to provide
// the requested info.
//
//
//********************************************************************
STDMETHODIMP COleObject::GetMiscStatus ( DWORD dwAspect, DWORD FAR* pdwStatus) { TestDebugOut(TEXT("In COleObject::GetMiscStatus\r\n")); // need to NULL the out parameter
*pdwStatus = NULL; return ResultFromScode( OLE_S_USEREG ); }
//**********************************************************************
//
// COleObject::SetColorScheme
//
// Purpose:
//
// Used to set the palette for the object to use.
//
// Parameters:
//
// LPLOGPALETTE lpLogpal - Pointer to the LOGPALETTE to be used.
//
// Return Value:
//
// S_OK
//
// Function Calls:
// Function Location
//
// TestDebugOut Windows API
//
// Comments:
//
// This server ignores this method.
//
//********************************************************************
STDMETHODIMP COleObject::SetColorScheme ( LPLOGPALETTE lpLogpal) { TestDebugOut(TEXT("In COleObject::SetColorScheme\r\n")); return ResultFromScode( S_OK ); }
//**********************************************************************
//
// COleObject::OpenEdit
//
// Purpose:
//
// Used to Open the object into a seperate window.
//
// Parameters:
//
// LPOLECLIENTSITE pActiveSite - Pointer to the Active clientsite.
//
// Return Value:
//
// None.
//
// Function Calls:
// Function Location
//
// IOleClientSite::OnShowWindow Container
// ShowWindow Windows API
// UpdateWindow Windows API
// TestDebugOut Windows API
// CSimpSvrDoc::GethAppWnd DOC.H
// CSimpSvrDoc::GethHatchWnd DOC.H
//
//
//********************************************************************
void COleObject::OpenEdit(LPOLECLIENTSITE pActiveSite) { if (m_lpObj->GetOleClientSite()) m_lpObj->GetOleClientSite()->ShowObject();
m_fOpen = TRUE;
// tell the site we are opening so the object can be hatched out.
if (m_lpObj->GetOleClientSite()) m_lpObj->GetOleClientSite()->OnShowWindow(TRUE);
m_lpObj->m_lpDoc->ShowDocWnd();
m_lpObj->m_lpDoc->HideHatchWnd();
// Show app window.
m_lpObj->m_lpDoc->GetApp()->ShowAppWnd();
SetFocus(m_lpObj->m_lpDoc->GethAppWnd()); }
|