home *** CD-ROM | disk | FTP | other *** search
- // This is a part of the Microsoft Foundation Classes C++ library.
- // Copyright (C) 1992-1998 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Microsoft Foundation Classes Reference and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Microsoft Foundation Classes product.
-
- #include "stdafx.h"
- #include "occimpl.h"
- #include "msdadc.h"
-
- #ifdef AFX_OCC_SEG
- #pragma code_seg(AFX_OCC_SEG)
- #endif
-
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- #define new DEBUG_NEW
-
- #define S_QUICKACTIVATED S_FALSE
-
- #include "initguid.h"
- #define DBINITCONSTANTS
- #define INITGUID
-
- DEFINE_GUID(IID_IDataSourceListener,0x7C0FFAB2L,0xCD84,0x11D0,0x94,0x9A,0x00,0xA0,0xC9,0x11,0x10,0xED);
- DEFINE_GUID(IID_IDataSource,0x7c0ffab3L, 0xcd84, 0x11d0, 0x94, 0x9a, 0x00, 0xa0, 0xc9, 0x11, 0x10, 0xed);
-
- /////////////////////////////////////////////////////////////////////////////
- // COleControlSite
-
- BEGIN_INTERFACE_MAP(COleControlSite, CCmdTarget)
- INTERFACE_PART(COleControlSite, IID_IOleClientSite, OleClientSite)
- INTERFACE_PART(COleControlSite, IID_IOleInPlaceSite, OleIPSite)
- INTERFACE_PART(COleControlSite, IID_IOleControlSite, OleControlSite)
- INTERFACE_PART(COleControlSite, IID_IDispatch, AmbientProps)
- INTERFACE_PART(COleControlSite, IID_IBoundObjectSite, BoundObjectSite)
- INTERFACE_PART(COleControlSite, IID_INotifyDBEvents, NotifyDBEvents)
- INTERFACE_PART(COleControlSite, IID_IRowsetNotify, RowsetNotify)
- END_INTERFACE_MAP()
-
- COleControlSite::COleControlSite(COleControlContainer* pCtrlCont) :
- m_pCtrlCont(pCtrlCont),
- m_pWndCtrl(NULL),
- m_nID((UINT)-1),
- m_pObject(NULL),
- m_pInPlaceObject(NULL),
- m_pActiveObject(NULL),
- m_dwEventSink(0),
- m_dwPropNotifySink(0),
- m_dwMiscStatus(0),
- m_dwNotifyDBEvents(0),
- m_pDataSourceControl(NULL),
- m_pDSCSite(NULL),
- m_defdispid(0),
- m_dwType(0),
- m_pBindings(NULL),
- m_bIgnoreNotify(FALSE),
- m_bIsDirty(FALSE)
- {
- memset(&m_varResult, 0, sizeof(VARIANT));
- m_varResult.vt = VT_EMPTY;
- }
-
- COleControlSite::~COleControlSite()
- {
- delete m_pDataSourceControl;
-
- DetachWindow();
-
- DisconnectSink(m_iidEvents, m_dwEventSink);
- DisconnectSink(IID_IPropertyNotifySink, m_dwPropNotifySink);
- DisconnectSink(IID_INotifyDBEvents, m_dwNotifyDBEvents);
-
- if (m_pInPlaceObject != NULL)
- {
- m_pInPlaceObject->InPlaceDeactivate();
- m_pInPlaceObject->Release();
- m_pInPlaceObject = NULL;
- }
-
- if (m_pActiveObject != NULL)
- {
- m_pActiveObject->Release();
- m_pActiveObject = NULL;
- }
-
- if (m_pObject != NULL)
- {
- m_pObject->SetClientSite(NULL);
- m_pObject->Close(OLECLOSE_NOSAVE);
- m_pObject->Release();
- m_pObject = NULL;
- }
-
- ::VariantClear(&m_varResult);
-
- BindProperty(DISPID_UNKNOWN, NULL); // gets rid of complex bindings
-
- if (m_defdispid != 0 && m_pDSCSite != NULL &&
- m_pDSCSite->m_pDataSourceControl != NULL)
- {
- // get rid of simple bindings
- m_pDSCSite->m_pDataSourceControl->BindProp(this, FALSE);
- }
- }
-
- BOOL COleControlSite::SetExtent()
- {
- CSize size(m_rect.Size());
- CClientDC dc(NULL);
- dc.DPtoHIMETRIC(&size);
-
- HRESULT hr;
-
- if (SUCCEEDED(hr = m_pObject->SetExtent(DVASPECT_CONTENT, (SIZEL*)&size)))
- {
- if (SUCCEEDED(m_pObject->GetExtent(DVASPECT_CONTENT, (SIZEL*)&size)))
- {
- dc.HIMETRICtoDP(&size);
- m_rect.right = m_rect.left + size.cx;
- m_rect.bottom = m_rect.top + size.cy;
- }
- }
-
- return SUCCEEDED(hr);
- }
-
- HRESULT COleControlSite::CreateControl(CWnd* pWndCtrl, REFCLSID clsid,
- LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, UINT nID,
- CFile* pPersist, BOOL bStorage, BSTR bstrLicKey)
- {
- CRect rect2( rect );
- CPoint pt;
- CSize size;
-
- pt = rect2.TopLeft();
- size = rect2.Size();
-
- return( CreateControl( pWndCtrl, clsid, lpszWindowName, dwStyle, &pt, &size,
- nID, pPersist, bStorage, bstrLicKey ) );
- }
-
- HRESULT COleControlSite::CreateControl(CWnd* pWndCtrl, REFCLSID clsid,
- LPCTSTR lpszWindowName, DWORD dwStyle, const POINT* ppt, const SIZE* psize,
- UINT nID, CFile* pPersist, BOOL bStorage, BSTR bstrLicKey)
- {
- HRESULT hr = E_FAIL;
- m_hWnd = NULL;
- CSize size;
-
- // Connect the OLE Control with its proxy CWnd object
- if (pWndCtrl != NULL)
- {
- ASSERT(pWndCtrl->m_pCtrlSite == NULL);
- m_pWndCtrl = pWndCtrl;
- pWndCtrl->m_pCtrlSite = this;
- }
-
- // Initialize OLE, if necessary
- _AFX_THREAD_STATE* pState = AfxGetThreadState();
- if (!pState->m_bNeedTerm && !AfxOleInit())
- return hr;
-
- if (SUCCEEDED(hr = CreateOrLoad(clsid, pPersist, bStorage, bstrLicKey)))
- {
- ASSERT(m_pObject != NULL);
- m_nID = nID;
-
- if (psize == NULL)
- {
- // If psize is NULL, ask the object how big it wants to be.
- CClientDC dc(NULL);
-
- m_pObject->GetExtent(DVASPECT_CONTENT, &size);
- dc.HIMETRICtoDP(&size);
- m_rect = CRect(*ppt, size);
- }
- else
- {
- m_rect = CRect(*ppt, *psize);
- }
-
- m_dwStyleMask = WS_GROUP | WS_TABSTOP;
-
- if (m_dwMiscStatus & OLEMISC_ACTSLIKEBUTTON)
- m_dwStyleMask |= BS_DEFPUSHBUTTON;
-
- if (m_dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME)
- dwStyle &= ~WS_VISIBLE;
-
- m_dwStyle = dwStyle & m_dwStyleMask;
-
- // If control wasn't quick-activated, then connect sinks now.
- if (hr != S_QUICKACTIVATED)
- {
- m_dwEventSink = ConnectSink(m_iidEvents, &m_xEventSink);
- m_dwPropNotifySink = ConnectSink(IID_IPropertyNotifySink,
- &m_xPropertyNotifySink);
- }
- m_dwNotifyDBEvents = ConnectSink(IID_INotifyDBEvents, &m_xNotifyDBEvents);
-
- // Now that the object has been created, attempt to
- // in-place activate it.
-
- SetExtent();
-
- if (SUCCEEDED(hr = m_pObject->QueryInterface(IID_IOleInPlaceObject,
- (LPVOID*)&m_pInPlaceObject)))
- {
- if (dwStyle & WS_VISIBLE)
- {
- // control is visible: just activate it
- hr = DoVerb(OLEIVERB_INPLACEACTIVATE);
- }
- else
- {
- // control is not visible: activate off-screen, hide, then move
- m_rect.OffsetRect(-32000, -32000);
- if (SUCCEEDED(hr = DoVerb(OLEIVERB_INPLACEACTIVATE)) &&
- SUCCEEDED(hr = DoVerb(OLEIVERB_HIDE)))
- {
- m_rect.OffsetRect(32000, 32000);
- hr = m_pInPlaceObject->SetObjectRects(m_rect, m_rect);
- }
- }
- }
- else
- {
- TRACE1("IOleInPlaceObject not supported on OLE control (dialog ID %d).\n", nID);
- TRACE1(">>> Result code: 0x%08lx\n", hr);
- }
-
- if (SUCCEEDED(hr))
- GetControlInfo();
-
- // if QueryInterface or activation failed, cleanup everything
- if (FAILED(hr))
- {
- if (m_pInPlaceObject != NULL)
- {
- m_pInPlaceObject->Release();
- m_pInPlaceObject = NULL;
- }
- DisconnectSink(m_iidEvents, m_dwEventSink);
- DisconnectSink(IID_IPropertyNotifySink, m_dwPropNotifySink);
- DisconnectSink(IID_INotifyDBEvents, m_dwNotifyDBEvents);
- m_dwEventSink = 0;
- m_dwPropNotifySink = 0;
- m_dwNotifyDBEvents = 0;
- m_pObject->Release();
- m_pObject = NULL;
- }
- }
-
- if (SUCCEEDED(hr))
- {
- AttachWindow();
-
- ASSERT(m_hWnd != NULL);
-
- // Initialize the control's Caption or Text property, if any
- if (lpszWindowName != NULL)
- SetWindowText(lpszWindowName);
-
- // Initialize styles
- ModifyStyle(0, m_dwStyle | (dwStyle & (WS_DISABLED|WS_BORDER)), 0);
- }
-
- return hr;
- }
-
- BOOL COleControlSite::DestroyControl()
- {
- ASSERT(m_hWnd != NULL); // was control ever successfully created?
- m_pCtrlCont->m_siteMap.RemoveKey(m_hWnd);
-
- //VBBUG: VB controls will crash if IOleObject::Close is called on them
- // when they have focus (and unfortunately, deactivating them does not
- // always move the focus). To work around this problem, we always hide
- // the control before closing it.
- ShowWindow(SW_HIDE);
-
- // Now it is safe to close the control.
- delete this;
-
- return TRUE;
- }
-
- AFX_STATIC HRESULT AFXAPI _AfxCoCreateInstanceLic(REFCLSID clsid, LPUNKNOWN pUnkOuter,
- DWORD dwClsCtx, REFIID iid, LPVOID* ppv, BSTR bstrLicKey)
- {
- HRESULT hr;
-
- if (bstrLicKey == NULL)
- {
- LPCLASSFACTORY pClassFactory = NULL;
-
- if (SUCCEEDED(hr = CoGetClassObject(clsid, dwClsCtx, NULL,
- IID_IClassFactory, (void**)&pClassFactory)))
- {
- ASSERT(pClassFactory != NULL);
- hr = pClassFactory->CreateInstance(pUnkOuter, iid, ppv);
- pClassFactory->Release();
- }
- }
- else
- {
- LPCLASSFACTORY2 pClassFactory = NULL;
-
- if (SUCCEEDED(hr = CoGetClassObject(clsid, dwClsCtx, NULL,
- IID_IClassFactory2, (void**)&pClassFactory)))
- {
- ASSERT(pClassFactory != NULL);
- hr = pClassFactory->CreateInstanceLic(pUnkOuter, NULL, iid,
- bstrLicKey, ppv);
- pClassFactory->Release();
- }
- }
-
- return hr;
- }
-
- AFX_STATIC_DATA const struct { DISPID dwDispID; DWORD dwFlag; } _afxAmbients[] =
- {
- { DISPID_AMBIENT_USERMODE, QACONTAINER_USERMODE },
- { DISPID_AMBIENT_UIDEAD, QACONTAINER_UIDEAD },
- { DISPID_AMBIENT_SHOWGRABHANDLES, QACONTAINER_SHOWGRABHANDLES },
- { DISPID_AMBIENT_SHOWHATCHING, QACONTAINER_SHOWHATCHING },
- { DISPID_AMBIENT_DISPLAYASDEFAULT, QACONTAINER_DISPLAYASDEFAULT },
- { DISPID_AMBIENT_AUTOCLIP, QACONTAINER_AUTOCLIP },
- { DISPID_AMBIENT_MESSAGEREFLECT, QACONTAINER_MESSAGEREFLECT },
- { DISPID_AMBIENT_SUPPORTSMNEMONICS, QACONTAINER_SUPPORTSMNEMONICS },
- };
-
- BOOL COleControlSite::QuickActivate()
- {
- BOOL bQuickActivated = FALSE;
- IQuickActivate* pQuick = NULL;
- if (SUCCEEDED(m_pObject->QueryInterface(IID_IQuickActivate,
- reinterpret_cast<void**>(&pQuick))))
- {
- ASSERT(pQuick != NULL);
-
- // Initialize QACONTAINER structure.
- QACONTAINER qaContainer;
- qaContainer.cbSize = sizeof(QACONTAINER);
- qaContainer.pClientSite = &m_xOleClientSite;
- qaContainer.pAdviseSink = NULL;
- qaContainer.pPropertyNotifySink = &m_xPropertyNotifySink;
- qaContainer.pUnkEventSink = &m_xEventSink;
- qaContainer.pUndoMgr = NULL;
- qaContainer.hpal = NULL;
- qaContainer.pBindHost = NULL;
-
- // Fill ambient property values in QACONTAINER.
- COleVariant var;
- CWnd* pWndContain = m_pCtrlCont->m_pWnd;
-
- qaContainer.dwAmbientFlags = 0;
- for (int i = 0; i < _countof(_afxAmbients); i++)
- {
- pWndContain->OnAmbientProperty(this, _afxAmbients[i].dwDispID, &var);
- if (V_BOOL(&var))
- qaContainer.dwAmbientFlags |= _afxAmbients[i].dwFlag;
- }
-
- pWndContain->OnAmbientProperty(this, DISPID_AMBIENT_FORECOLOR, &var);
- qaContainer.colorFore = V_I4(&var);
- pWndContain->OnAmbientProperty(this, DISPID_AMBIENT_BACKCOLOR, &var);
- qaContainer.colorBack = V_I4(&var);
- pWndContain->OnAmbientProperty(this, DISPID_AMBIENT_APPEARANCE, &var);
- qaContainer.dwAppearance = V_I2(&var);
- pWndContain->OnAmbientProperty(this, DISPID_AMBIENT_LOCALEID, &var);
- qaContainer.lcid = V_I4(&var);
- pWndContain->OnAmbientProperty(this, DISPID_AMBIENT_FONT, &var);
- if (FAILED(V_DISPATCH(&var)->QueryInterface(IID_IFont,
- reinterpret_cast<void**>(&qaContainer.pFont))))
- {
- qaContainer.pFont = NULL;
- }
-
- // Initialize QACONTROL structure.
- QACONTROL qaControl;
- qaControl.cbSize = sizeof(QACONTROL);
-
- // Do the quick activation.
- if (SUCCEEDED(pQuick->QuickActivate(&qaContainer, &qaControl)))
- {
- // Extract return values from QACONTROL structure.
- m_dwMiscStatus = qaControl.dwMiscStatus;
- m_dwEventSink = qaControl.dwEventCookie;
- m_dwPropNotifySink = qaControl.dwPropNotifyCookie;
- bQuickActivated = TRUE;
- }
- pQuick->Release();
-
- if (qaContainer.pFont != NULL)
- qaContainer.pFont->Release();
- }
-
- return bQuickActivated;
- }
-
- HRESULT COleControlSite::CreateOrLoad(REFCLSID clsid, CFile* pFile,
- BOOL bStorage, BSTR bstrLicKey)
- {
- ASSERT(m_pObject == NULL);
-
- #ifdef _DEBUG
- OLECHAR wszClsid[40];
- StringFromGUID2(clsid, wszClsid, 40);
- #endif //_DEBUG
-
- HRESULT hr;
- if (FAILED(hr = _AfxCoCreateInstanceLic(clsid, NULL,
- CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, IID_IOleObject,
- (void**)&m_pObject, bstrLicKey)))
- {
- TRACE1("CoCreateInstance of OLE control %ls failed.\n", wszClsid);
- TRACE1(">>> Result code: 0x%08lx\n", hr);
- TRACE0(">>> Is the control is properly registered?\n");
- return hr;
- }
-
- LPPERSISTSTREAMINIT pPersStm = NULL;
- LPPERSISTSTORAGE pPersStg = NULL;
- LPPERSISTMEMORY pPersMem = NULL;
-
- GetEventIID(&m_iidEvents);
- // Try to quick-activate first
- BOOL bQuickActivated = QuickActivate();
-
- if (!bQuickActivated)
- {
- m_pObject->GetMiscStatus(DVASPECT_CONTENT, &m_dwMiscStatus);
-
- // set client site first, if appropriate
- if (m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)
- {
- if (FAILED(hr = m_pObject->SetClientSite(&m_xOleClientSite)))
- {
- TRACE1("SetClientSite on OLE control %ls failed.\n", wszClsid);
- TRACE1(">>> Result code: 0x%08lx\n", hr);
- goto CreateOrLoadFailed;
- }
- }
- }
-
- ASSERT(!bStorage || pFile != NULL);
-
- // initialize via IPersistMemory (direct buffering)
- if (pFile != NULL && !bStorage &&
- SUCCEEDED(m_pObject->QueryInterface(IID_IPersistMemory, (void**)&pPersMem)) &&
- pFile->GetBufferPtr(CFile::bufferCheck) != 0)
- {
- ASSERT(pPersMem != NULL);
-
- // file supports direct buffering, get its buffer pointer and size
- LPVOID pvBuffer = NULL;
- LPVOID pvEnd;
- ULONG cbBuffer = pFile->GetBufferPtr(
- CFile::bufferRead, (UINT)-1, &pvBuffer, &pvEnd);
- ASSERT(((LPBYTE)pvEnd - (LPBYTE)pvBuffer) == (int)cbBuffer);
-
- // and then load it directly
- hr = pPersMem->Load(pvBuffer, cbBuffer);
- pPersMem->Release();
- pPersMem = NULL;
- if (FAILED(hr))
- goto CreateOrLoadFailed;
- }
- // initialize via IPersistStreamInit
- else if (!bStorage && SUCCEEDED(m_pObject->QueryInterface(
- IID_IPersistStreamInit, (void**)&pPersStm)))
- {
- ASSERT(pPersStm != NULL);
-
- if (pFile == NULL)
- {
- // just call InitNew
- hr = pPersStm->InitNew();
- }
- else
- {
- // open an IStream on the data and pass it to Load
- CArchive ar(pFile, CArchive::load);
- CArchiveStream stm(&ar);
- hr = pPersStm->Load(&stm);
- }
- pPersStm->Release();
-
- if (FAILED(hr))
- {
- TRACE1("InitNew or Load on OLE control %ls failed.\n", wszClsid);
- TRACE1(">>> Result code: 0x%08lx\n", hr);
- goto CreateOrLoadFailed;
- }
- }
- // initialize via IPersistStorage
- else if (SUCCEEDED(m_pObject->QueryInterface(
- IID_IPersistStorage, (void**)&pPersStg)))
- {
- ASSERT(pPersStg != NULL);
-
- if (pFile == NULL)
- {
- // create a scratch IStorage and pass it to InitNew
- LPLOCKBYTES pLockBytes = NULL;
- if (SUCCEEDED(hr = CreateILockBytesOnHGlobal(NULL, TRUE,
- &pLockBytes)))
- {
- ASSERT(pLockBytes != NULL);
- LPSTORAGE pStorage = NULL;
- if (SUCCEEDED(hr = StgCreateDocfileOnILockBytes(pLockBytes,
- STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0,
- &pStorage)))
- {
- ASSERT(pStorage != NULL);
- hr = pPersStg->InitNew(pStorage);
- pStorage->Release();
- }
- pLockBytes->Release();
- }
- }
- else if (bStorage)
- {
- // copy data to an HGLOBAL, so we can build an IStorage on it
- UINT cb = pFile->GetLength();
- HGLOBAL hGlobal;
- BYTE* pbData;
-
- if (((hGlobal = GlobalAlloc(GMEM_FIXED, cb)) != NULL) &&
- ((pbData = (BYTE*)GlobalLock(hGlobal)) != NULL))
- {
- pFile->Read(pbData, cb);
- GlobalUnlock(hGlobal);
- }
- else
- {
- hr = E_OUTOFMEMORY;
- hGlobal = NULL;
- }
-
- // open an IStorage on the data and pass it to Load
- LPLOCKBYTES pLockBytes = NULL;
- if ((hGlobal != NULL) &&
- SUCCEEDED(hr = CreateILockBytesOnHGlobal(hGlobal, TRUE,
- &pLockBytes)))
- {
- ASSERT(pLockBytes != NULL);
- LPSTORAGE pStorage = NULL;
- if (SUCCEEDED(hr = StgOpenStorageOnILockBytes(pLockBytes, NULL,
- STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &pStorage)))
- {
- ASSERT(pStorage != NULL);
- hr = pPersStg->Load(pStorage);
- pStorage->Release();
- }
- pLockBytes->Release();
- }
- }
- else
- {
- hr = E_UNEXPECTED;
- }
- pPersStg->Release();
-
- if (FAILED(hr))
- {
- TRACE1("InitNew or Load on OLE control %ls failed.\n", wszClsid);
- TRACE1(">>> Result code: 0x%08lx\n", hr);
- goto CreateOrLoadFailed;
- }
- }
- else
- {
- TRACE1("Persistence not supported on OLE control %ls.\n", wszClsid);
- TRACE1(">>> Result code: 0x%08lx\n", hr);
- goto CreateOrLoadFailed;
- }
-
- if (!bQuickActivated)
- {
- // set client site last, if appropriate
- if (!(m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))
- {
- if (FAILED(hr = m_pObject->SetClientSite(&m_xOleClientSite)))
- {
- TRACE1("SetClientSite on OLE control %ls failed.\n", wszClsid);
- TRACE1(">>> Result code: 0x%08lx\n", hr);
- goto CreateOrLoadFailed;
- }
- }
- }
-
- CreateOrLoadFailed:
- if (FAILED(hr) && (m_pObject != NULL))
- {
- m_pObject->Close(OLECLOSE_NOSAVE);
- m_pObject->Release();
- m_pObject = NULL;
- }
-
- if (pPersMem != NULL)
- pPersMem->Release();
-
- if (bQuickActivated && SUCCEEDED(hr))
- hr = S_QUICKACTIVATED;
-
- return hr;
- }
-
- UINT COleControlSite::GetID()
- {
- return m_nID;
- }
-
- HRESULT COleControlSite::DoVerb(LONG nVerb, LPMSG lpMsg)
- {
- return m_pObject->DoVerb(nVerb, lpMsg, &m_xOleClientSite, 0,
- m_pCtrlCont->m_pWnd->m_hWnd, m_rect);
- }
-
- BOOL COleControlSite::IsDefaultButton()
- {
- return ((m_dwMiscStatus & OLEMISC_ACTSLIKEBUTTON) &&
- (m_dwStyle & BS_DEFPUSHBUTTON));
- }
-
- DWORD COleControlSite::GetDefBtnCode()
- {
- if (m_dwMiscStatus & OLEMISC_ACTSLIKEBUTTON)
- return (m_dwStyle & BS_DEFPUSHBUTTON) ?
- DLGC_DEFPUSHBUTTON :
- DLGC_UNDEFPUSHBUTTON;
- else
- return 0;
- }
-
- void COleControlSite::SetDefaultButton(BOOL bDefault)
- {
- if (!(m_dwMiscStatus & OLEMISC_ACTSLIKEBUTTON))
- return;
-
- if (((m_dwStyle & BS_DEFPUSHBUTTON) != 0) == bDefault)
- return;
-
- m_dwStyle ^= BS_DEFPUSHBUTTON;
-
- // Notify control that its "defaultness" has changed.
- LPOLECONTROL pOleCtl = NULL;
- if (SUCCEEDED(m_pObject->QueryInterface(IID_IOleControl,
- (LPVOID*)&pOleCtl)))
- {
- ASSERT(pOleCtl != NULL);
- pOleCtl->OnAmbientPropertyChange(DISPID_AMBIENT_DISPLAYASDEFAULT);
- pOleCtl->Release();
- }
- }
-
- DWORD COleControlSite::ConnectSink(REFIID iid, LPUNKNOWN punkSink)
- {
- ASSERT(m_pObject != NULL);
-
- LPCONNECTIONPOINTCONTAINER pConnPtCont;
-
- if ((m_pObject != NULL) &&
- SUCCEEDED(m_pObject->QueryInterface(IID_IConnectionPointContainer,
- (LPVOID*)&pConnPtCont)))
- {
- ASSERT(pConnPtCont != NULL);
- LPCONNECTIONPOINT pConnPt = NULL;
- DWORD dwCookie = 0;
-
- if (SUCCEEDED(pConnPtCont->FindConnectionPoint(iid, &pConnPt)))
- {
- ASSERT(pConnPt != NULL);
- pConnPt->Advise(punkSink, &dwCookie);
- pConnPt->Release();
- }
-
- pConnPtCont->Release();
- return dwCookie;
- }
-
- return 0;
- }
-
- void COleControlSite::DisconnectSink(REFIID iid, DWORD dwCookie)
- {
- if (dwCookie == 0 || m_pObject == NULL)
- return;
-
- LPCONNECTIONPOINTCONTAINER pConnPtCont;
-
- if (SUCCEEDED(m_pObject->QueryInterface(IID_IConnectionPointContainer,
- (LPVOID*)&pConnPtCont)))
- {
- ASSERT(pConnPtCont != NULL);
- LPCONNECTIONPOINT pConnPt = NULL;
-
- if (SUCCEEDED(pConnPtCont->FindConnectionPoint(iid, &pConnPt)))
- {
- ASSERT(pConnPt != NULL);
- pConnPt->Unadvise(dwCookie);
- pConnPt->Release();
- }
-
- pConnPtCont->Release();
- }
- }
-
- #define IMPLTYPE_MASK \
- (IMPLTYPEFLAG_FDEFAULT | IMPLTYPEFLAG_FSOURCE | IMPLTYPEFLAG_FRESTRICTED)
-
- #define IMPLTYPE_DEFAULTSOURCE \
- (IMPLTYPEFLAG_FDEFAULT | IMPLTYPEFLAG_FSOURCE)
-
- BOOL COleControlSite::GetEventIID(IID* piid)
- {
- *piid = GUID_NULL;
-
- ASSERT(m_pObject != NULL);
-
- // Use IProvideClassInfo2, if control supports it.
- LPPROVIDECLASSINFO2 pPCI2 = NULL;
-
- if (SUCCEEDED(m_pObject->QueryInterface(IID_IProvideClassInfo2,
- (LPVOID*)&pPCI2)))
- {
- ASSERT(pPCI2 != NULL);
-
- if (SUCCEEDED(pPCI2->GetGUID(GUIDKIND_DEFAULT_SOURCE_DISP_IID, piid)))
- ASSERT(!IsEqualIID(*piid, GUID_NULL));
- else
- ASSERT(IsEqualIID(*piid, GUID_NULL));
-
- pPCI2->Release();
- }
-
- // Fall back on IProvideClassInfo, if IProvideClassInfo2 not supported.
- LPPROVIDECLASSINFO pPCI = NULL;
-
- if (IsEqualIID(*piid, GUID_NULL) &&
- SUCCEEDED(m_pObject->QueryInterface(IID_IProvideClassInfo,
- (LPVOID*)&pPCI)))
- {
- ASSERT(pPCI != NULL);
-
- LPTYPEINFO pClassInfo = NULL;
-
- if (SUCCEEDED(pPCI->GetClassInfo(&pClassInfo)))
- {
- ASSERT(pClassInfo != NULL);
-
- LPTYPEATTR pClassAttr;
- if (SUCCEEDED(pClassInfo->GetTypeAttr(&pClassAttr)))
- {
- ASSERT(pClassAttr != NULL);
- ASSERT(pClassAttr->typekind == TKIND_COCLASS);
-
- // Search for typeinfo of the default events interface.
-
- int nFlags;
- HREFTYPE hRefType;
-
- for (unsigned int i = 0; i < pClassAttr->cImplTypes; i++)
- {
- if (SUCCEEDED(pClassInfo->GetImplTypeFlags(i, &nFlags)) &&
- ((nFlags & IMPLTYPE_MASK) == IMPLTYPE_DEFAULTSOURCE))
- {
- // Found it. Now look at its attributes to get IID.
-
- LPTYPEINFO pEventInfo = NULL;
-
- if (SUCCEEDED(pClassInfo->GetRefTypeOfImplType(i,
- &hRefType)) &&
- SUCCEEDED(pClassInfo->GetRefTypeInfo(hRefType,
- &pEventInfo)))
- {
- ASSERT(pEventInfo != NULL);
-
- LPTYPEATTR pEventAttr;
-
- if (SUCCEEDED(pEventInfo->GetTypeAttr(&pEventAttr)))
- {
- ASSERT(pEventAttr != NULL);
- *piid = pEventAttr->guid;
- pEventInfo->ReleaseTypeAttr(pEventAttr);
- }
-
- pEventInfo->Release();
- }
-
- break;
- }
- }
-
- pClassInfo->ReleaseTypeAttr(pClassAttr);
- }
-
- pClassInfo->Release();
- }
-
- pPCI->Release();
- }
-
- return (!IsEqualIID(*piid, GUID_NULL));
- }
-
- void COleControlSite::GetControlInfo()
- {
- memset(&m_ctlInfo, 0, sizeof(CONTROLINFO));
- m_ctlInfo.cb = sizeof(CONTROLINFO);
- LPOLECONTROL pOleCtl = NULL;
-
- if (SUCCEEDED(m_pObject->QueryInterface(IID_IOleControl,
- (LPVOID*)&pOleCtl)))
- {
- ASSERT(pOleCtl != NULL);
- pOleCtl->GetControlInfo(&m_ctlInfo);
- pOleCtl->Release();
- }
- }
-
- BOOL COleControlSite::IsMatchingMnemonic(LPMSG lpMsg)
- {
- // return IsAccelerator(m_ctlInfo.hAccel, m_ctlInfo.cAccel, lpMsg, NULL);
-
- if ((m_ctlInfo.cAccel == 0) || (m_ctlInfo.hAccel == NULL))
- return FALSE;
-
- ACCEL* pAccel = new ACCEL[m_ctlInfo.cAccel];
- int cAccel = CopyAcceleratorTable(m_ctlInfo.hAccel, pAccel, m_ctlInfo.cAccel);
- ASSERT(cAccel == m_ctlInfo.cAccel);
-
- BOOL bMatch = FALSE;
- for (int i = 0; i < cAccel; i++)
- {
- BOOL fVirt = (lpMsg->message == WM_SYSCHAR ? FALT : 0);
- WORD key = LOWORD(lpMsg->wParam);
- if (((pAccel[i].fVirt & ~FNOINVERT) == fVirt) &&
- (pAccel[i].key == key))
- {
- bMatch = TRUE;
- break;
- }
- }
-
- delete [] pAccel;
- return bMatch;
- }
-
- void COleControlSite::SendMnemonic(LPMSG lpMsg)
- {
- if (!(m_dwMiscStatus & OLEMISC_NOUIACTIVATE))
- SetFocus();
-
- LPOLECONTROL pOleCtl = NULL;
-
- if (SUCCEEDED(m_pObject->QueryInterface(IID_IOleControl,
- (LPVOID*)&pOleCtl)))
- {
- ASSERT(pOleCtl != NULL);
- pOleCtl->OnMnemonic(lpMsg);
- pOleCtl->Release();
- }
- }
-
- void COleControlSite::FreezeEvents(BOOL bFreeze)
- {
- LPOLECONTROL pOleCtl = NULL;
- if (SUCCEEDED(m_pObject->QueryInterface(IID_IOleControl,
- (LPVOID*)&pOleCtl)))
- {
- ASSERT(pOleCtl != NULL);
- pOleCtl->FreezeEvents(bFreeze);
- pOleCtl->Release();
- }
- }
-
- void COleControlSite::AttachWindow()
- {
- HWND hWnd = NULL;
- if (SUCCEEDED(m_pInPlaceObject->GetWindow(&hWnd)))
- {
- ASSERT(hWnd != NULL);
- if (m_hWnd != hWnd)
- {
- m_hWnd = hWnd;
-
- if (m_pWndCtrl != NULL)
- {
- ASSERT(m_pWndCtrl->m_hWnd == NULL); // Window already attached?
- m_pWndCtrl->Attach(m_hWnd);
-
- ASSERT(m_pWndCtrl->m_pCtrlSite == NULL ||
- m_pWndCtrl->m_pCtrlSite == this);
- m_pWndCtrl->m_pCtrlSite = this;
- }
- }
- }
- }
-
- void COleControlSite::DetachWindow()
- {
- m_hWnd = NULL;
-
- if (m_pWndCtrl != NULL)
- {
- if (m_pWndCtrl->m_hWnd != NULL)
- {
- WNDPROC* lplpfn = m_pWndCtrl->GetSuperWndProcAddr();
- ASSERT(lplpfn != NULL);
- if (::IsWindow(m_pWndCtrl->m_hWnd) && *lplpfn != NULL)
- m_pWndCtrl->UnsubclassWindow();
-
- m_pWndCtrl->Detach();
- }
-
- m_pWndCtrl->m_pCtrlSite = NULL;
- }
- }
-
- BOOL COleControlSite::OnEvent(AFX_EVENT* pEvent)
- {
- // If this control has a proxy CWnd, look for a matching ON_*_REFLECT
- // entry for this event in its event map.
- if ((m_pWndCtrl != NULL) &&
- m_pWndCtrl->OnCmdMsg(m_nID, CN_EVENT, pEvent, NULL))
- {
- return TRUE;
- }
-
- // Proxy CWnd isn't interested, so pass the event along to the container.
- return m_pCtrlCont->m_pWnd->OnCmdMsg(m_nID, CN_EVENT, pEvent, NULL);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // invoke helpers
-
- void COleControlSite::InvokeHelperV(DISPID dwDispID, WORD wFlags,
- VARTYPE vtRet, void* pvRet, const BYTE* pbParamInfo, va_list argList)
- {
- if (m_dispDriver.m_lpDispatch == NULL)
- {
- // no dispatch pointer yet; find it now
- LPDISPATCH pDispatch;
-
- if ((m_pObject != NULL) &&
- SUCCEEDED(m_pObject->QueryInterface(IID_IDispatch,
- (LPVOID*)&pDispatch)))
- {
- ASSERT(pDispatch != NULL);
- m_dispDriver.AttachDispatch(pDispatch);
- }
- }
-
- if (m_dispDriver.m_lpDispatch == NULL)
- {
- // couldn't find dispatch pointer
- TRACE0("Warning: control has no IDispatch interface.");
- return;
- }
-
- // delegate call to m_dispDriver
- m_dispDriver.InvokeHelperV(dwDispID, wFlags, vtRet, pvRet, pbParamInfo,
- argList);
- }
-
- void COleControlSite::SetPropertyV(DISPID dwDispID, VARTYPE vtProp, va_list argList)
- {
- BYTE rgbParams[2];
- if (vtProp & VT_BYREF)
- {
- vtProp &= ~VT_BYREF;
- vtProp |= VT_MFCBYREF;
- }
-
- #if !defined(_UNICODE) && !defined(OLE2ANSI)
- if (vtProp == VT_BSTR)
- vtProp = VT_BSTRA;
- #endif
-
- WORD wFlags;
- if (vtProp & VT_MFCFORCEPUTREF)
- {
- wFlags = DISPATCH_PROPERTYPUTREF;
- vtProp &= ~VT_MFCFORCEPUTREF;
- }
- else
- {
- if (vtProp == VT_DISPATCH)
- wFlags = DISPATCH_PROPERTYPUTREF;
- else
- wFlags = DISPATCH_PROPERTYPUT;
- }
-
- rgbParams[0] = (BYTE)vtProp;
- rgbParams[1] = 0;
- InvokeHelperV(dwDispID, wFlags, VT_EMPTY, NULL, rgbParams, argList);
- }
-
- void AFX_CDECL COleControlSite::InvokeHelper(DISPID dwDispID, WORD wFlags, VARTYPE vtRet,
- void* pvRet, const BYTE* pbParamInfo, ...)
- {
- va_list argList;
- va_start(argList, pbParamInfo);
- InvokeHelperV(dwDispID, wFlags, vtRet, pvRet, pbParamInfo, argList);
- va_end(argList);
- }
-
- void COleControlSite::GetProperty(DISPID dwDispID, VARTYPE vtProp,
- void* pvProp) const
- {
- const_cast<COleControlSite*>(this)->InvokeHelper(dwDispID,
- DISPATCH_PROPERTYGET, vtProp, pvProp, NULL);
- }
-
- void AFX_CDECL COleControlSite::SetProperty(DISPID dwDispID, VARTYPE vtProp, ...)
- {
- va_list argList; // really only one arg, but...
- va_start(argList, vtProp);
- SetPropertyV(dwDispID, vtProp, argList);
- va_end(argList);
- }
-
- BOOL AFX_CDECL COleControlSite::SafeSetProperty(DISPID dwDispID, VARTYPE vtProp, ...)
- {
- va_list argList; // really only one arg, but...
- va_start(argList, vtProp);
-
- BOOL bSuccess;
-
- TRY
- {
- SetPropertyV(dwDispID, vtProp, argList);
- bSuccess = TRUE;
- }
- CATCH_ALL(e)
- {
- DELETE_EXCEPTION(e);
- bSuccess = FALSE;
- }
- END_CATCH_ALL
-
- va_end(argList);
- return bSuccess;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // special cases for CWnd functions
-
- DWORD COleControlSite::GetStyle() const
- {
- DWORD dwStyle = m_dwStyle |
- (::GetWindowLong(m_hWnd, GWL_STYLE) & WS_VISIBLE);
-
- TRY
- {
- BOOL bEnabled = TRUE;
- GetProperty(DISPID_ENABLED, VT_BOOL, &bEnabled);
- if (!bEnabled)
- dwStyle |= WS_DISABLED;
- }
- END_TRY
-
- TRY
- {
- short sBorderStyle = 0;
- GetProperty(DISPID_BORDERSTYLE, VT_I2, &sBorderStyle);
- if (sBorderStyle == 1)
- dwStyle |= WS_BORDER;
- }
- END_TRY
-
- return dwStyle;
- }
-
- DWORD COleControlSite::GetExStyle() const
- {
- DWORD dwExStyle = ::GetWindowLong(m_hWnd, GWL_EXSTYLE);
-
- TRY
- {
- short sAppearance = 0;
- GetProperty(DISPID_APPEARANCE, VT_I2, &sAppearance);
- if (sAppearance == 1)
- dwExStyle |= WS_EX_CLIENTEDGE;
- }
- END_TRY
-
- return dwExStyle;
- }
-
- BOOL COleControlSite::ModifyStyle(DWORD dwRemove, DWORD dwAdd, UINT nFlags)
- {
- m_dwStyle = ((m_dwStyle & ~dwRemove) | dwAdd) & m_dwStyleMask;
-
- // Enabled property
- if ((dwRemove & WS_DISABLED) || (dwAdd & WS_DISABLED))
- {
- if (SafeSetProperty(DISPID_ENABLED, VT_BOOL, (~dwAdd & WS_DISABLED)))
- {
- dwRemove &= ~WS_DISABLED;
- dwAdd &= ~WS_DISABLED;
- }
- }
-
- // BorderStyle property
- if ((dwRemove & WS_BORDER) || (dwAdd & WS_BORDER))
- {
- if (SafeSetProperty(DISPID_BORDERSTYLE, VT_I2, (dwAdd & WS_BORDER)))
- {
- dwRemove &= ~WS_BORDER;
- dwAdd &= ~WS_BORDER;
- }
- }
-
- return CWnd::ModifyStyle(m_hWnd, dwRemove, dwAdd, nFlags);
- }
-
- BOOL COleControlSite::ModifyStyleEx(DWORD dwRemove, DWORD dwAdd, UINT nFlags)
- {
- // BorderStyle property
- if ((dwRemove & WS_EX_CLIENTEDGE) || (dwAdd & WS_EX_CLIENTEDGE))
- {
- if (SafeSetProperty(DISPID_APPEARANCE, VT_I2, (dwAdd & WS_EX_CLIENTEDGE)))
- {
- dwRemove &= ~WS_EX_CLIENTEDGE;
- dwAdd &= ~WS_EX_CLIENTEDGE;
- }
- }
-
- return CWnd::ModifyStyleEx(m_hWnd, dwRemove, dwAdd, nFlags);
- }
-
- void COleControlSite::SetWindowText(LPCTSTR lpszString)
- {
- ASSERT(::IsWindow(m_hWnd));
-
- if (!SafeSetProperty(DISPID_CAPTION, VT_BSTR, lpszString))
- SafeSetProperty(DISPID_TEXT, VT_BSTR, lpszString);
- }
-
- void COleControlSite::GetWindowText(CString& str) const
- {
- ASSERT(::IsWindow(m_hWnd));
-
- TRY
- {
- GetProperty(DISPID_CAPTION, VT_BSTR, &str);
- }
- CATCH_ALL(e)
- {
- DELETE_EXCEPTION(e);
-
- TRY
- {
- GetProperty(DISPID_TEXT, VT_BSTR, &str);
- }
- END_TRY
- }
- END_CATCH_ALL
- }
-
- int COleControlSite::GetWindowText(LPTSTR lpszString, int nMaxCount) const
- {
- ASSERT(nMaxCount > 0);
- CString str;
- GetWindowText(str);
- lstrcpyn(lpszString, str, nMaxCount);
- return lstrlen(lpszString);
- }
-
- int COleControlSite::GetWindowTextLength() const
- {
- CString str;
- GetWindowText(str);
- return str.GetLength();
- }
-
- int COleControlSite::GetDlgCtrlID() const
- {
- return (int)m_nID;
- }
-
- int COleControlSite::SetDlgCtrlID(int nID)
- {
- int nPrevID = (int)m_nID;
- m_nID = (UINT)nID;
- return nPrevID;
- }
-
- void COleControlSite::MoveWindow(int x, int y, int nWidth, int nHeight, BOOL)
- {
- ASSERT(m_pInPlaceObject != NULL);
- ASSERT(m_pObject != NULL);
-
- CRect rectOld(m_rect);
- m_rect.SetRect(x, y, x + nWidth, y + nHeight);
- if (SetExtent())
- {
- m_rect.SetRect(x, y, x + m_rect.Width(), y + m_rect.Height());
- m_pInPlaceObject->SetObjectRects(m_rect, m_rect);
- }
- else
- {
- m_rect = rectOld;
- }
- }
-
- BOOL COleControlSite::SetWindowPos(const CWnd* pWndInsertAfter, int x, int y, int cx,
- int cy, UINT nFlags)
- {
- if (nFlags & SWP_HIDEWINDOW)
- ShowWindow(SW_HIDE);
-
- if ((nFlags & (SWP_NOMOVE|SWP_NOSIZE)) != (SWP_NOMOVE|SWP_NOSIZE))
- {
- int xNew;
- int yNew;
- if (nFlags & SWP_NOMOVE)
- {
- xNew = m_rect.left;
- yNew = m_rect.top;
- }
- else
- {
- xNew = x;
- yNew = y;
- }
-
- int cxNew;
- int cyNew;
- if (nFlags & SWP_NOSIZE)
- {
- cxNew = m_rect.Width();
- cyNew = m_rect.Height();
- }
- else
- {
- cxNew = cx;
- cyNew = cy;
- }
-
- MoveWindow(xNew, yNew, cxNew, cyNew, !(nFlags & SWP_NOREDRAW));
- }
-
- if (nFlags & SWP_SHOWWINDOW)
- ShowWindow(SW_SHOW);
-
- // we've handled hide, move, size, and show; let Windows do the rest
- nFlags &= ~(SWP_HIDEWINDOW|SWP_SHOWWINDOW);
- nFlags |= (SWP_NOMOVE|SWP_NOSIZE);
- return ::SetWindowPos(m_hWnd, pWndInsertAfter->GetSafeHwnd(),
- x, y, cx, cy, nFlags);
- }
-
- BOOL COleControlSite::ShowWindow(int nCmdShow)
- {
- BOOL bReturn = ::IsWindowVisible(m_hWnd);
- int iVerb = 0;
- switch (nCmdShow)
- {
- case SW_SHOW:
- case SW_SHOWNORMAL:
- case SW_SHOWNOACTIVATE:
- iVerb = OLEIVERB_SHOW;
- break;
-
- case SW_HIDE:
- iVerb = OLEIVERB_HIDE;
- break;
- }
-
- if (iVerb != 0)
- DoVerb(iVerb);
-
- return bReturn;
- }
-
- BOOL COleControlSite::IsWindowEnabled() const
- {
- BOOL bEnabled = TRUE;
- TRY
- GetProperty(DISPID_ENABLED, VT_BOOL, &bEnabled);
- END_TRY
-
- return bEnabled;
- }
-
- BOOL COleControlSite::EnableWindow(BOOL bEnable)
- {
- BOOL bResult;
- TRY
- {
- GetProperty(DISPID_ENABLED, VT_BOOL, &bResult);
- SetProperty(DISPID_ENABLED, VT_BOOL, bEnable);
- }
- CATCH_ALL(e)
- {
- DELETE_EXCEPTION(e);
- bResult = TRUE;
- }
- END_CATCH_ALL
-
- return !bResult; // return TRUE if previously disabled
- }
-
- CWnd* COleControlSite::SetFocus()
- {
- if (m_dwMiscStatus & OLEMISC_NOUIACTIVATE)
- return CWnd::FromHandle(::SetFocus(m_hWnd));
-
- CWnd* pWndPrev = CWnd::GetFocus();
- DoVerb(OLEIVERB_UIACTIVATE);
- return pWndPrev;
- }
-
- void COleControlSite::EnableDSC()
- {
- if (m_pDataSourceControl == NULL)
- {
- m_pDataSourceControl = new CDataSourceControl(this);
- m_pDataSourceControl->Initialize();
- }
- }
-
- void COleControlSite::BindDefaultProperty(DISPID dwDispID, VARTYPE vtProp, LPCTSTR szFieldName, CWnd* pDSCWnd)
- {
- // Remove any previous binding
- if (m_pDSCSite != NULL)
- {
- m_pDSCSite->m_pDataSourceControl->BindProp(this, FALSE);
- m_pDSCSite->m_pDataSourceControl->BindColumns();
- m_pDSCSite = NULL;
- }
-
- if (pDSCWnd != NULL)
- {
- ASSERT(pDSCWnd->m_pCtrlSite); // must be an OLE control
- pDSCWnd->m_pCtrlSite->EnableDSC();
- m_pDSCSite = pDSCWnd->m_pCtrlSite;
- m_defdispid = dwDispID;
- m_dwType = vtProp;
- m_strDataField = szFieldName;
- m_pDSCSite->m_pDataSourceControl->BindProp(this, TRUE);
- if (m_pDSCSite != NULL)
- m_pDSCSite->m_pDataSourceControl->BindColumns();
- }
- }
-
- void COleControlSite::BindProperty(DISPID dwDispId, CWnd* pWndDSC)
- {
- ASSERT(pWndDSC == NULL || pWndDSC->m_pCtrlSite);
- if (pWndDSC != NULL && dwDispId != DISPID_UNKNOWN)
- {
- m_pBindings = new CDataBoundProperty(m_pBindings, dwDispId, 0);
- m_pBindings->m_pDSCSite = pWndDSC->m_pCtrlSite;
- m_pBindings->m_pClientSite = this;
- m_pBindings->m_pDSCSite->EnableDSC();
- m_pBindings->m_pDSCSite->m_pDataSourceControl->BindProp(m_pBindings, TRUE);
- }
- else
- {
- // Try and locate the particular property to unbind
- // if dwDispId == DISPID_UNKNOWN && pWndDSC == NULL it unbinds all properties
- // if dwDispId == DISPID_UNKNOWN && pWndDSC != NULL it unbinds properties for that DSC
- CDataBoundProperty *pCurrent = m_pBindings;
- CDataBoundProperty* pPrev = NULL;
- while (pCurrent != NULL)
- {
- CDataBoundProperty* pNext = pCurrent->GetNext();
- if (dwDispId == DISPID_UNKNOWN || pCurrent->m_dispid == dwDispId)
- {
- if (pWndDSC == NULL || pWndDSC->m_pCtrlSite == pCurrent->m_pDSCSite)
- {
- if (pPrev != NULL)
- pPrev->m_pNext = pNext;
- else
- m_pBindings = pNext;
- if (pCurrent->m_pDSCSite != NULL && pCurrent->m_pDSCSite->m_pDataSourceControl != NULL)
- pCurrent->m_pDSCSite->m_pDataSourceControl->BindProp(pCurrent, FALSE);
- delete pCurrent;
- }
- }
- if (pPrev != NULL)
- pPrev = pPrev->GetNext();
- pCurrent = pNext;
- }
- }
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // COleControlSite::XOleClientSite
-
- STDMETHODIMP_(ULONG) COleControlSite::XOleClientSite::AddRef()
- {
- METHOD_PROLOGUE_EX_(COleControlSite, OleClientSite)
- return (ULONG)pThis->InternalAddRef();
- }
-
- STDMETHODIMP_(ULONG) COleControlSite::XOleClientSite::Release()
- {
- METHOD_PROLOGUE_EX_(COleControlSite, OleClientSite)
- return (ULONG)pThis->InternalRelease();
- }
-
- STDMETHODIMP COleControlSite::XOleClientSite::QueryInterface(
- REFIID iid, LPVOID* ppvObj)
- {
- METHOD_PROLOGUE_EX_(COleControlSite, OleClientSite)
- return (HRESULT)pThis->InternalQueryInterface(&iid, ppvObj);
- }
-
- STDMETHODIMP COleControlSite::XOleClientSite::SaveObject()
- {
- return E_NOTIMPL;
- }
-
- STDMETHODIMP COleControlSite::XOleClientSite::GetMoniker(DWORD, DWORD,
- LPMONIKER*)
- {
- return E_NOTIMPL;
- }
-
- STDMETHODIMP COleControlSite::XOleClientSite::GetContainer(
- LPOLECONTAINER* ppContainer)
- {
- METHOD_PROLOGUE_EX_(COleControlSite, OleClientSite)
- return (HRESULT)pThis->m_pCtrlCont->InternalQueryInterface(
- &IID_IOleContainer, (LPVOID*)ppContainer);
- }
-
- STDMETHODIMP COleControlSite::XOleClientSite::ShowObject()
- {
- METHOD_PROLOGUE_EX(COleControlSite, OleClientSite)
- pThis->AttachWindow();
- return S_OK;
- }
-
- STDMETHODIMP COleControlSite::XOleClientSite::OnShowWindow(BOOL)
- {
- return S_OK;
- }
-
- STDMETHODIMP COleControlSite::XOleClientSite::RequestNewObjectLayout()
- {
- return E_NOTIMPL;
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // COleControlSite::XOleIPSite
-
- STDMETHODIMP_(ULONG) COleControlSite::XOleIPSite::AddRef()
- {
- METHOD_PROLOGUE_EX_(COleControlSite, OleIPSite)
- return (ULONG)pThis->InternalAddRef();
- }
-
- STDMETHODIMP_(ULONG) COleControlSite::XOleIPSite::Release()
- {
- METHOD_PROLOGUE_EX_(COleControlSite, OleIPSite)
- return (ULONG)pThis->InternalRelease();
- }
-
- STDMETHODIMP COleControlSite::XOleIPSite::QueryInterface(
- REFIID iid, LPVOID* ppvObj)
- {
- METHOD_PROLOGUE_EX_(COleControlSite, OleIPSite)
- return (HRESULT)pThis->InternalQueryInterface(&iid, ppvObj);
- }
-
- STDMETHODIMP COleControlSite::XOleIPSite::GetWindow(HWND* phWnd)
- {
- METHOD_PROLOGUE_EX_(COleControlSite, OleIPSite)
- *phWnd = pThis->m_pCtrlCont->m_pWnd->GetSafeHwnd();
- return *phWnd != NULL ? S_OK : E_FAIL;
- }
-
- STDMETHODIMP COleControlSite::XOleIPSite::ContextSensitiveHelp(BOOL)
- {
- return E_NOTIMPL;
- }
-
- STDMETHODIMP COleControlSite::XOleIPSite::CanInPlaceActivate()
- {
- return S_OK;
- }
-
- STDMETHODIMP COleControlSite::XOleIPSite::OnInPlaceActivate()
- {
- return S_OK;
- }
-
- STDMETHODIMP COleControlSite::XOleIPSite::OnUIActivate()
- {
- METHOD_PROLOGUE_EX_(COleControlSite, OleIPSite)
- pThis->m_pCtrlCont->OnUIActivate(pThis);
- return S_OK;
- }
-
- STDMETHODIMP COleControlSite::XOleIPSite::GetWindowContext(
- LPOLEINPLACEFRAME* ppFrame, LPOLEINPLACEUIWINDOW* ppDoc, LPRECT prectPos,
- LPRECT prectClip, LPOLEINPLACEFRAMEINFO pFrameInfo)
- {
- METHOD_PROLOGUE_EX(COleControlSite, OleIPSite)
- ASSERT_VALID(pThis->m_pCtrlCont);
- ASSERT_VALID(pThis->m_pCtrlCont->m_pWnd);
-
- ASSERT(AfxIsValidAddress(ppFrame, sizeof(LPOLEINPLACEFRAME)));
- ASSERT((ppDoc == NULL) ||
- AfxIsValidAddress(ppDoc, sizeof(LPOLEINPLACEUIWINDOW)));
- ASSERT(AfxIsValidAddress(prectPos, sizeof(RECT)));
- ASSERT(AfxIsValidAddress(prectClip, sizeof(RECT)));
- ASSERT(AfxIsValidAddress(pFrameInfo, pFrameInfo->cb));
-
- //WINBUG: This is a temporary patch for IE3 beta. When IE3 is fixed, this
- // assert can be re-enabled. Otherwise it fires everytime you browse via
- // the CWebBrowser control.
- //
- // ASSERT(pFrameInfo->cb >= offsetof(OLEINPLACEFRAMEINFO, cAccelEntries) +
- // sizeof(int));
-
- // There is no separate doc window
- if (ppDoc != NULL)
- *ppDoc = NULL;
-
- // Set pointer to frame
- if (FAILED(pThis->m_pCtrlCont->InternalQueryInterface(
- &IID_IOleInPlaceFrame, (LPVOID*)ppFrame)))
- return E_FAIL;
-
- // Fill in position and clip rectangles
- CWnd* pWndContainer = pThis->m_pCtrlCont->m_pWnd;
- CopyRect(prectPos, pThis->m_rect);
- pWndContainer->GetClientRect(prectClip);
-
- // Fill in frame info
- pFrameInfo->fMDIApp = FALSE;
- pFrameInfo->hwndFrame = pWndContainer->GetSafeHwnd();
- pFrameInfo->haccel = NULL;
- pFrameInfo->cAccelEntries = 0;
-
- return S_OK;
- }
-
- STDMETHODIMP COleControlSite::XOleIPSite::Scroll(SIZE)
- {
- return S_FALSE;
- }
-
- STDMETHODIMP COleControlSite::XOleIPSite::OnUIDeactivate(BOOL)
- {
- METHOD_PROLOGUE_EX_(COleControlSite, OleIPSite)
- pThis->m_pCtrlCont->OnUIDeactivate(pThis);
- return S_OK;
- }
-
- STDMETHODIMP COleControlSite::XOleIPSite::OnInPlaceDeactivate()
- {
- METHOD_PROLOGUE_EX(COleControlSite, OleIPSite)
- pThis->DetachWindow();
- return S_OK;
- }
-
- STDMETHODIMP COleControlSite::XOleIPSite::DiscardUndoState()
- {
- return S_OK;
- }
-
- STDMETHODIMP COleControlSite::XOleIPSite::DeactivateAndUndo()
- {
- METHOD_PROLOGUE_EX_(COleControlSite, OleIPSite)
- pThis->m_pInPlaceObject->UIDeactivate();
- return S_OK;
- }
-
- STDMETHODIMP COleControlSite::XOleIPSite::OnPosRectChange(LPCRECT lprcPosRect)
- {
- METHOD_PROLOGUE_EX_(COleControlSite, OleIPSite)
- CRect rectClip;
- pThis->m_pCtrlCont->m_pWnd->GetClientRect(rectClip);
- pThis->m_rect = lprcPosRect;
- return pThis->m_pInPlaceObject->SetObjectRects(pThis->m_rect, rectClip);
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // COleControlSite::XOleControlSite
-
- STDMETHODIMP_(ULONG) COleControlSite::XOleControlSite::AddRef()
- {
- METHOD_PROLOGUE_EX_(COleControlSite, OleControlSite)
- return (ULONG)pThis->InternalAddRef();
- }
-
- STDMETHODIMP_(ULONG) COleControlSite::XOleControlSite::Release()
- {
- METHOD_PROLOGUE_EX_(COleControlSite, OleControlSite)
- return (ULONG)pThis->InternalRelease();
- }
-
- STDMETHODIMP COleControlSite::XOleControlSite::QueryInterface(
- REFIID iid, LPVOID* ppvObj)
- {
- METHOD_PROLOGUE_EX_(COleControlSite, OleControlSite)
- return (HRESULT)pThis->InternalQueryInterface(&iid, ppvObj);
- }
-
- STDMETHODIMP COleControlSite::XOleControlSite::OnControlInfoChanged()
- {
- METHOD_PROLOGUE_EX_(COleControlSite, OleControlSite)
- pThis->GetControlInfo();
- return NOERROR;
- }
-
- STDMETHODIMP COleControlSite::XOleControlSite::LockInPlaceActive(BOOL)
- {
- return E_NOTIMPL;
- }
-
- STDMETHODIMP COleControlSite::XOleControlSite::GetExtendedControl(
- LPDISPATCH*)
- {
- return E_NOTIMPL;
- }
-
- STDMETHODIMP COleControlSite::XOleControlSite::TransformCoords(
- POINTL* pptHimetric, POINTF* pptContainer, DWORD dwFlags)
- {
- METHOD_PROLOGUE_EX_(COleControlSite, OleControlSite)
- HRESULT hr = NOERROR;
-
- HDC hDC = ::GetDC(pThis->m_hWnd);
- ::SetMapMode(hDC, MM_HIMETRIC);
- POINT rgptConvert[2];
- rgptConvert[0].x = 0;
- rgptConvert[0].y = 0;
-
- if (dwFlags & XFORMCOORDS_HIMETRICTOCONTAINER)
- {
- rgptConvert[1].x = pptHimetric->x;
- rgptConvert[1].y = pptHimetric->y;
- ::LPtoDP(hDC, rgptConvert, 2);
- if (dwFlags & XFORMCOORDS_SIZE)
- {
- pptContainer->x = (float)(rgptConvert[1].x - rgptConvert[0].x);
- pptContainer->y = (float)(rgptConvert[0].y - rgptConvert[1].y);
- }
- else if (dwFlags & XFORMCOORDS_POSITION)
- {
- pptContainer->x = (float)rgptConvert[1].x;
- pptContainer->y = (float)rgptConvert[1].y;
- }
- else
- {
- hr = E_INVALIDARG;
- }
- }
- else if (dwFlags & XFORMCOORDS_CONTAINERTOHIMETRIC)
- {
- rgptConvert[1].x = (int)(pptContainer->x);
- rgptConvert[1].y = (int)(pptContainer->y);
- ::DPtoLP(hDC, rgptConvert, 2);
- if (dwFlags & XFORMCOORDS_SIZE)
- {
- pptHimetric->x = rgptConvert[1].x - rgptConvert[0].x;
- pptHimetric->y = rgptConvert[0].y - rgptConvert[1].y;
- }
- else if (dwFlags & XFORMCOORDS_POSITION)
- {
- pptHimetric->x = rgptConvert[1].x;
- pptHimetric->y = rgptConvert[1].y;
- }
- else
- {
- hr = E_INVALIDARG;
- }
- }
- else
- {
- hr = E_INVALIDARG;
- }
-
- ::ReleaseDC(pThis->m_hWnd, hDC);
-
- return hr;
- }
-
- STDMETHODIMP COleControlSite::XOleControlSite::TranslateAccelerator(
- LPMSG, DWORD)
- {
- return E_NOTIMPL;
- }
-
- STDMETHODIMP COleControlSite::XOleControlSite::OnFocus(BOOL)
- {
- return S_OK;
- }
-
- STDMETHODIMP COleControlSite::XOleControlSite::ShowPropertyFrame()
- {
- return E_NOTIMPL;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // COleControlSite::XAmbientProps
-
- STDMETHODIMP_(ULONG) COleControlSite::XAmbientProps::AddRef()
- {
- METHOD_PROLOGUE_EX_(COleControlSite, AmbientProps)
- return (ULONG)pThis->InternalAddRef();
- }
-
- STDMETHODIMP_(ULONG) COleControlSite::XAmbientProps::Release()
- {
- METHOD_PROLOGUE_EX_(COleControlSite, AmbientProps)
- return (ULONG)pThis->InternalRelease();
- }
-
- STDMETHODIMP COleControlSite::XAmbientProps::QueryInterface(
- REFIID iid, LPVOID* ppvObj)
- {
- METHOD_PROLOGUE_EX_(COleControlSite, AmbientProps)
- return (HRESULT)pThis->InternalQueryInterface(&iid, ppvObj);
- }
-
- STDMETHODIMP COleControlSite::XAmbientProps::GetTypeInfoCount(
- unsigned int*)
- {
- return E_NOTIMPL;
- }
-
- STDMETHODIMP COleControlSite::XAmbientProps::GetTypeInfo(
- unsigned int, LCID, ITypeInfo**)
- {
- return E_NOTIMPL;
- }
-
- STDMETHODIMP COleControlSite::XAmbientProps::GetIDsOfNames(
- REFIID, LPOLESTR*, unsigned int, LCID, DISPID*)
- {
- return E_NOTIMPL;
- }
-
- STDMETHODIMP COleControlSite::XAmbientProps::Invoke(
- DISPID dispid, REFIID, LCID, unsigned short wFlags,
- DISPPARAMS* pDispParams, VARIANT* pvarResult,
- EXCEPINFO*, unsigned int*)
- {
- UNUSED(wFlags);
- UNUSED(pDispParams);
-
- METHOD_PROLOGUE_EX(COleControlSite, AmbientProps)
- ASSERT(wFlags & DISPATCH_PROPERTYGET);
- ASSERT(pDispParams->cArgs == 0);
-
- ASSERT(pThis->m_pCtrlCont != NULL);
- ASSERT(pThis->m_pCtrlCont->m_pWnd != NULL);
-
- return pThis->m_pCtrlCont->m_pWnd->OnAmbientProperty(pThis, dispid, pvarResult) ?
- S_OK : DISP_E_MEMBERNOTFOUND;
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // COleControlSite::XPropertyNotifySink
-
- STDMETHODIMP COleControlSite::XPropertyNotifySink::QueryInterface(
- REFIID iid, LPVOID* ppvObj)
- {
- METHOD_PROLOGUE_EX_(COleControlSite, PropertyNotifySink)
-
- if (IsEqualIID(iid, IID_IUnknown) ||
- IsEqualIID(iid, IID_IPropertyNotifySink))
- {
- *ppvObj = this;
- AddRef();
- return S_OK;
- }
- else
- {
- return E_NOINTERFACE;
- }
- }
-
- STDMETHODIMP_(ULONG) COleControlSite::XPropertyNotifySink::AddRef()
- {
- return 1;
- }
-
- STDMETHODIMP_(ULONG) COleControlSite::XPropertyNotifySink::Release()
- {
- return 0;
- }
-
- STDMETHODIMP COleControlSite::XPropertyNotifySink::OnChanged(
- DISPID dispid)
- {
- METHOD_PROLOGUE_EX(COleControlSite, PropertyNotifySink)
-
- // If we are currently updating the control ignore notifications
- if (pThis->m_bIgnoreNotify)
- return S_OK;
-
- // Give user chance to override
- if (!pThis->m_pDataSourceControl)
- {
- AFX_EVENT event(AFX_EVENT::propChanged, dispid);
- pThis->OnEvent(&event);
- if (event.m_hResult != S_OK)
- return event.m_hResult;
- }
-
- if (pThis->m_defdispid == dispid)
- {
- ::VariantClear(&pThis->m_varResult);
-
- HRESULT hRes;
- LPDISPATCH pDispatch = NULL;
- hRes = pThis->m_pObject->QueryInterface(IID_IDispatch, (LPVOID *) &pDispatch);
- if (FAILED(hRes))
- return S_OK;
-
- EXCEPINFO excepinfo;
- memset(&excepinfo, 0, sizeof(EXCEPINFO));
- UINT uArgErr;
- DISPPARAMS dispparamsGetProp;
- memset (&dispparamsGetProp, 0, sizeof(DISPPARAMS));
- hRes = pDispatch->Invoke(dispid, IID_NULL, 0, INVOKE_PROPERTYGET, &dispparamsGetProp,
- &pThis->m_varResult, &excepinfo, &uArgErr); //Get bound control property
-
- if (excepinfo.bstrSource)
- SysFreeString(excepinfo.bstrSource);
- if (excepinfo.bstrDescription)
- SysFreeString(excepinfo.bstrDescription);
- if (excepinfo.bstrHelpFile)
- SysFreeString(excepinfo.bstrHelpFile);
-
- pDispatch->Release();
-
- if (FAILED(hRes))
- return S_OK;
-
- pThis->m_bIsDirty = TRUE;
- }
-
- return S_OK;
- }
-
- STDMETHODIMP COleControlSite::XPropertyNotifySink::OnRequestEdit(
- DISPID dispid)
- {
- METHOD_PROLOGUE_EX(COleControlSite, PropertyNotifySink)
-
- // If we are currently updating the control ignore notifications
- if (pThis->m_bIgnoreNotify)
- return S_OK;
-
- // If not bound fire regular MFC event
- if (!pThis->m_pDataSourceControl)
- {
- AFX_EVENT event(AFX_EVENT::propRequest, dispid);
- pThis->OnEvent(&event);
- if (event.m_hResult != S_OK)
- return event.m_hResult;
- }
-
- // Currently we only support Optimistic binding ala VB4
- // In this model, requests always succeed
- return S_OK;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // COleControlSite::XEventSink
-
- STDMETHODIMP_(ULONG) COleControlSite::XEventSink::AddRef()
- {
- return 1;
- }
-
- STDMETHODIMP_(ULONG) COleControlSite::XEventSink::Release()
- {
- return 0;
- }
-
- STDMETHODIMP COleControlSite::XEventSink::QueryInterface(
- REFIID iid, LPVOID* ppvObj)
- {
- METHOD_PROLOGUE_EX_(COleControlSite, EventSink)
-
- if (IsEqualIID(iid, IID_IUnknown) ||
- IsEqualIID(iid, IID_IDispatch) ||
- IsEqualIID(iid, pThis->m_iidEvents))
- {
- *ppvObj = this;
- AddRef();
- return S_OK;
- }
- else
- {
- return E_NOINTERFACE;
- }
- }
-
- STDMETHODIMP COleControlSite::XEventSink::GetTypeInfoCount(
- unsigned int*)
- {
- return E_NOTIMPL;
- }
-
- STDMETHODIMP COleControlSite::XEventSink::GetTypeInfo(
- unsigned int, LCID, ITypeInfo**)
- {
- return E_NOTIMPL;
- }
-
- STDMETHODIMP COleControlSite::XEventSink::GetIDsOfNames(
- REFIID, LPOLESTR*, unsigned int, LCID, DISPID*)
- {
- return E_NOTIMPL;
- }
-
- STDMETHODIMP COleControlSite::XEventSink::Invoke(
- DISPID dispid, REFIID, LCID, unsigned short wFlags,
- DISPPARAMS* pDispParams, VARIANT* pvarResult,
- EXCEPINFO* pExcepInfo, unsigned int* puArgError)
- {
- UNUSED(wFlags);
-
- METHOD_PROLOGUE_EX(COleControlSite, EventSink)
- ASSERT(pThis->m_pCtrlCont != NULL);
- ASSERT(pThis->m_pCtrlCont->m_pWnd != NULL);
- ASSERT(wFlags == DISPATCH_METHOD);
-
- AFX_EVENT event(AFX_EVENT::event, dispid, pDispParams, pExcepInfo,
- puArgError);
-
- pThis->OnEvent(&event);
-
- if (pvarResult != NULL)
- ::VariantClear(pvarResult);
-
- return event.m_hResult;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CDataSourceControl
-
-
- CDataSourceControl::CDataSourceControl(COleControlSite *pClientSite) :
- m_pClientSite(pClientSite),
- m_pCursorMove(NULL),
- m_pCursorUpdateARow(NULL),
- m_pMetaRowData(NULL),
- m_pVarData(NULL),
- m_nColumns(0),
- m_nBindings(0),
- m_pColumnBindings(NULL),
- m_pValues(NULL),
- m_bUpdateInProgress(FALSE),
- m_pDataSource(NULL),
- m_pRowPosition(NULL),
- m_pRowset(NULL),
- m_pDynamicAccessor(NULL),
- m_dwRowsetNotify(0)
- {
- ASSERT(pClientSite);
- }
-
- CDataSourceControl::~CDataSourceControl()
- {
- // cancel ole/db notifications
- if (m_dwRowsetNotify != 0 && m_pRowset != NULL)
- {
- LPCONNECTIONPOINTCONTAINER pConnPtCont;
-
- if (SUCCEEDED(m_pRowset->m_spRowset->QueryInterface(IID_IConnectionPointContainer,
- (LPVOID*)&pConnPtCont)))
- {
- ASSERT(pConnPtCont != NULL);
- LPCONNECTIONPOINT pConnPt = NULL;
-
- if (SUCCEEDED(pConnPtCont->FindConnectionPoint(IID_IRowsetNotify, &pConnPt)))
- {
- ASSERT(pConnPt != NULL);
- pConnPt->Unadvise(m_dwRowsetNotify);
- pConnPt->Release();
- }
-
- pConnPtCont->Release();
- }
- }
-
- // Now go through all cursor bound properties
- while (!m_CursorBoundProps.IsEmpty())
- {
- CDataBoundProperty* pProp = (CDataBoundProperty*) m_CursorBoundProps.GetHead();
- pProp->m_pClientSite->BindProperty(pProp->m_dispid, NULL);
- pProp->m_pClientSite->m_pDSCSite = NULL;
- }
- m_CursorBoundProps.RemoveAll();
-
- if (m_pValues)
- {
- for (int i=0; i<m_nBindings; i++)
- ::VariantClear(&m_pValues[i]);
- if (m_nBindings)
- {
- delete[] m_pColumnBindings;
- delete[] m_pValues;
- }
- }
-
- if (m_pCursorMove)
- m_pCursorMove->Release();
-
- if (m_pCursorUpdateARow)
- m_pCursorUpdateARow->Release();
-
- if (m_pMetaRowData)
- {
- for (int nCol=0; nCol<m_nColumns; nCol++)
- {
- POSITION pos = m_pMetaRowData[nCol].m_pClientList->GetHeadPosition();
- while (pos)
- {
- COleControlSite* pSite = (COleControlSite *)
- m_pMetaRowData[nCol].m_pClientList->GetNext(pos);
- pSite->m_pDSCSite = NULL;
- }
- m_pMetaRowData[nCol].m_pClientList->RemoveAll();
- delete m_pMetaRowData[nCol].m_pClientList;
- }
- ::CoTaskMemFree(m_pMetaRowData);
- }
- if (m_pVarData)
- ::CoTaskMemFree(m_pVarData);
-
- if(m_pDynamicAccessor != NULL)
- {
- m_pDynamicAccessor->ReleaseAccessors(m_pRowset->m_spRowset);
- m_pDynamicAccessor->Close();
- }
- delete m_pDynamicAccessor;
- delete m_pRowset;
- if (m_pRowPosition != NULL)
- m_pRowPosition->Release();
- if (m_pDataSource != NULL)
- m_pDataSource->Release();
- }
-
- interface IVBDSC : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE CancelUnload(BOOL __RPC_FAR* pfCancel) = 0;
- virtual HRESULT STDMETHODCALLTYPE Error(DWORD dwErr, BOOL __RPC_FAR* pfShowError) = 0;
- virtual HRESULT STDMETHODCALLTYPE CreateCursor(ICursor __RPC_FAR* __RPC_FAR* ppCursor) = 0;
- };
-
- const IID IID_IVBDSC = {0x1ab42240,0x8c70,0x11ce,{0x94,0x21,0x0,0xaa,0x0,0x62,0xbe,0x57}};
- const IID CLSID_DataAdapter = {0x3A08E130L,0x8F65,0x11D0,{0x94,0x84,0x00,0xA0,0xC9,0x11,0x10,0xED}};
-
- HRESULT CDataSourceControl::Initialize()
- {
- // The following is a work around for RDC behaviour when on an invisible dlg
- // When the dlg is invisible it cannot display the ODBC connect dialog
- // So check if visible, if not make it so and move it to the center
- // of the screen with null size. Then do the connect dialog
- // Finally put it all back like it was.
- CWnd* pParent = m_pClientSite->m_pWndCtrl->GetTopLevelParent();
- BOOL bHidden = !pParent->IsWindowVisible();
- CRect rcParent;
- if (bHidden)
- {
- CRect rcDesktop;
- CWnd::GetDesktopWindow()->GetWindowRect(&rcDesktop);
- pParent->GetWindowRect(&rcParent);
- pParent->MoveWindow((rcDesktop.right - rcDesktop.left)/2, (rcDesktop.bottom - rcDesktop.top)/2, 0, 0, FALSE);
- pParent->ShowWindow(SW_SHOWNORMAL);
- }
- IVBDSC* pDSC;
- HRESULT hRes;
-
- hRes = m_pClientSite->m_pObject->QueryInterface(IID_IDataSource, (void**)&m_pDataSource);
- if (SUCCEEDED(hRes))
- {
- hRes = m_pDataSource->GetDataMember(NULL, &IID_IRowPosition, (IUnknown**)&m_pRowPosition);
- if (m_pRowPosition == NULL)
- hRes = E_POINTER;
-
- if (FAILED(hRes))
- {
- if (bHidden)
- {
- pParent->MoveWindow(rcParent.left, rcParent.top, rcParent.right - rcParent.left, rcParent.bottom - rcParent.top, FALSE);
- pParent->ShowWindow(SW_HIDE);
- }
- return hRes;
- }
- }
- else
- {
- hRes = m_pClientSite->m_pObject->QueryInterface(IID_IVBDSC, (void**)&pDSC);
- if (FAILED(hRes))
- return hRes;
- ICursor* pCursor;
- pDSC->CreateCursor(&pCursor);
- pDSC->Release();
- if (!pCursor)
- return E_FAIL;
-
- hRes = pCursor->QueryInterface(IID_ICursorMove,
- (LPVOID *)&m_pCursorMove);
-
- pCursor->Release();
-
- if (FAILED(hRes))
- return hRes;
-
- hRes = m_pCursorMove->QueryInterface(IID_ICursorUpdateARow,
- (LPVOID *)&m_pCursorUpdateARow);
- }
-
- hRes = GetMetaData();
-
- if (bHidden)
- {
- pParent->MoveWindow(rcParent.left, rcParent.top, rcParent.right - rcParent.left, rcParent.bottom - rcParent.top, FALSE);
- pParent->ShowWindow(SW_HIDE);
- }
-
- return hRes;
- }
-
- IUnknown* CDataSourceControl::GetCursor()
- {
- ASSERT(m_pClientSite != NULL);
-
- if (m_pDataSource != NULL)
- {
- if(m_pRowset != NULL)
- return m_pDataSource;
- return NULL;
- }
-
- ICursor* pCursor;
- if (!m_pCursorMove)
- {
- IVBDSC* pDSC;
- HRESULT hRes;
- hRes = m_pClientSite->m_pObject->QueryInterface(IID_IVBDSC, (void**)&pDSC);
- if (FAILED(hRes))
- return NULL;
- pDSC->CreateCursor(&pCursor);
- pDSC->Release();
- if (!pCursor)
- return NULL;
- return pCursor;
- }
- if (SUCCEEDED(m_pCursorMove->QueryInterface(IID_ICursor, (LPVOID *) &pCursor)))
- return pCursor;
-
- ASSERT(FALSE); // DSC Cursor Not Found
- return NULL;
- }
-
- HRESULT CDataSourceControl::GetMetaData()
- {
- HRESULT hRes;
- METAROWTYPE* pOldMetaData = m_pMetaRowData;
- int nOldColumns = m_nColumns;
-
- if (m_pDataSource != NULL)
- {
- IRowset* pRowset;
-
- hRes = m_pRowPosition->GetRowset(IID_IRowset, reinterpret_cast<IUnknown**>(&pRowset));
- if (FAILED(hRes))
- return hRes;
-
- {
- LPCONNECTIONPOINTCONTAINER pConnPtCont;
-
- if (SUCCEEDED(pRowset->QueryInterface(IID_IConnectionPointContainer,
- (LPVOID*)&pConnPtCont)))
- {
- ASSERT(pConnPtCont != NULL);
- LPCONNECTIONPOINT pConnPt = NULL;
-
- if (SUCCEEDED(pConnPtCont->FindConnectionPoint(IID_IRowsetNotify, &pConnPt)))
- {
- ASSERT(pConnPt != NULL);
- pConnPt->Advise(&m_pClientSite->m_xRowsetNotify, &m_dwRowsetNotify);
- pConnPt->Release();
- }
-
- pConnPtCont->Release();
- }
- }
-
- m_pRowset = new CRowset(pRowset);
- pRowset->Release();
- m_pRowset->SetupOptionalRowsetInterfaces();
- m_pDynamicAccessor = new CDynamicAccessor;
- m_pDynamicAccessor->BindColumns(m_pRowset->m_spRowset);
- m_pRowset->SetAccessor(m_pDynamicAccessor);
- m_nColumns = m_pDynamicAccessor->GetColumnCount();
- m_pMetaRowData = (METAROWTYPE*)::CoTaskMemAlloc(sizeof(METAROWTYPE) * m_nColumns);
- ASSERT(m_pMetaRowData);
- memset(m_pMetaRowData, 0, sizeof(METAROWTYPE) * m_nColumns);
- m_pRowset->MoveFirst();
- m_pRowset->ReleaseRows();
- }
- else
- {
- ULONG nRows;
- ICursor* pCursor = (LPCURSOR)m_pCursorMove;
- ICursor* pColumnCursor;
-
- if (pCursor == NULL)
- return S_OK;
-
- hRes = pCursor->GetColumnsCursor(IID_ICursor, (IUnknown **) &pColumnCursor, &nRows);
- if (FAILED(hRes))
- return hRes;
-
- DBCOLUMNBINDING MetaColumns[2];
- CopyColumnID(&MetaColumns[0].columnID, &COLUMN_COLUMNID);
- MetaColumns[0].obData = offsetof(METAROWTYPE, idColumnID);
- MetaColumns[0].cbMaxLen = DB_NOMAXLENGTH;
- MetaColumns[0].obInfo = offsetof(METAROWTYPE, dwColumnID);
- MetaColumns[0].obVarDataLen = DB_NOVALUE;
- MetaColumns[0].dwBinding = DBBINDING_DEFAULT;
- MetaColumns[0].dwDataType = DBTYPE_COLUMNID;
-
- CopyColumnID(&MetaColumns[1].columnID, &COLUMN_NAME);
- MetaColumns[1].obData = offsetof(METAROWTYPE, lpstrName);
- MetaColumns[1].cbMaxLen = DB_NOMAXLENGTH;
- MetaColumns[1].obInfo = offsetof(METAROWTYPE, dwName);
- MetaColumns[1].obVarDataLen = DB_NOVALUE;
- MetaColumns[1].dwBinding = DBBINDING_DEFAULT;
- MetaColumns[1].dwDataType = VT_LPSTR;
-
- hRes = pColumnCursor->SetBindings(2, MetaColumns, sizeof(METAROWTYPE),
- DBCOLUMNBINDOPTS_REPLACE);
- if (FAILED(hRes))
- {
- pColumnCursor->Release();
- return hRes;
- }
-
- DBFETCHROWS FetchRows;
- FetchRows.cRowsRequested = nRows;
- FetchRows.dwFlags = DBROWFETCH_CALLEEALLOCATES;
- FetchRows.pData = NULL;
- FetchRows.pVarData = NULL;
- FetchRows.cbVarData = 0;
-
- LARGE_INTEGER dlZero;
- LISet32(dlZero, 0);
- hRes = pColumnCursor->GetNextRows(dlZero, &FetchRows);
- if (FAILED(hRes))
- {
- pColumnCursor->Release();
- return hRes;
- }
-
- m_pMetaRowData = (METAROWTYPE *)FetchRows.pData;
- ASSERT(m_pMetaRowData);
- nRows = FetchRows.cRowsReturned; // in case it changed
- m_pVarData = FetchRows.pVarData;
-
- m_nColumns = nRows;
-
- pColumnCursor->Release();
- }
-
- for (int nCol=0; nCol<m_nColumns; nCol++)
- m_pMetaRowData[nCol].m_pClientList = new CPtrList;
-
- // re-establish all bound property sites and then delete old meta-data
- if (pOldMetaData != NULL)
- {
- for (int nCol=0; nCol<nOldColumns; nCol++)
- {
- POSITION pos = pOldMetaData[nCol].m_pClientList->GetHeadPosition();
- while (pos)
- {
- COleControlSite* pSite = (COleControlSite *)
- m_pMetaRowData[nCol].m_pClientList->GetNext(pos);
- BindProp(pSite, TRUE);
- }
- pOldMetaData[nCol].m_pClientList->RemoveAll();
- delete pOldMetaData[nCol].m_pClientList;
- }
- ::CoTaskMemFree(pOldMetaData);
- }
-
- return hRes;
- }
-
- BOOL CDataSourceControl::CopyColumnID(
- DBCOLUMNID* pcidDst, DBCOLUMNID const *pcidSrc)
- {
- pcidDst->dwKind = pcidSrc->dwKind;
-
- switch (pcidSrc->dwKind)
- {
- case DBCOLKIND_GUID_NUMBER:
- pcidDst->guid = pcidSrc->guid;
- pcidDst->lNumber = pcidSrc->lNumber;
- break;
- case DBCOLKIND_GUID_NAME:
- pcidDst->guid = pcidSrc->guid;
- // fall through
- case DBCOLKIND_NAME:
- pcidDst->lpdbsz = (LPDBSTR) ::CoTaskMemAlloc(sizeof(DBCHAR) * (ldbstrlen(pcidSrc->lpdbsz) + 1));
- if (!pcidDst->lpdbsz)
- return FALSE;
- ldbstrcpy(pcidDst->lpdbsz, pcidSrc->lpdbsz);
- break;
- }
- return TRUE;
- }
-
- // Make a bound control/bound property a consumer to a particular column in this DSC
- void CDataSourceControl::BindProp(COleControlSite* pClientSite, BOOL bBind)
- {
- ASSERT(pClientSite);
-
- if (bBind)
- {
- BindProp(pClientSite, FALSE);
- ASSERT(pClientSite->m_pDSCSite == m_pClientSite);
- if (m_pDataSource != NULL)
- {
- for (int nCol=0; nCol<m_nColumns; nCol++)
- {
- if (pClientSite->m_strDataField == m_pDynamicAccessor->GetColumnName(nCol + 1))
- {
- m_pMetaRowData[nCol].m_pClientList->AddTail(pClientSite);
- return;
- }
- }
- }
- else
- {
- for (int nCol=0; nCol<m_nColumns; nCol++)
- {
- if (m_pMetaRowData[nCol].lpstrName == NULL)
- continue;
- if (pClientSite->m_strDataField == m_pMetaRowData[nCol].lpstrName)
- {
- m_pMetaRowData[nCol].m_pClientList->AddTail(pClientSite);
- return;
- }
- }
- }
- pClientSite->m_pDSCSite = NULL;
- return;
- }
- UpdateCursor();
- // UnBind
- for (int nCol=0; nCol<m_nColumns; nCol++)
- {
- POSITION pos = m_pMetaRowData[nCol].m_pClientList->GetHeadPosition();
- POSITION prev;
- while (pos)
- {
- prev = pos;
- COleControlSite* pSite = (COleControlSite *)
- m_pMetaRowData[nCol].m_pClientList->GetNext(pos);
- if (pSite == pClientSite)
- {
- m_pMetaRowData[nCol].m_pClientList->RemoveAt(prev);
- return;
- }
- }
- }
- }
-
- // Make a cursor bound control property a client to this control
- void CDataSourceControl::BindProp(CDataBoundProperty* pProperty, BOOL bBind)
- {
- ASSERT(pProperty);
-
- if (bBind)
- {
- BindProp(pProperty, FALSE);
- m_CursorBoundProps.AddTail(pProperty);
- }
- else
- {
- UpdateCursor();
- POSITION pos = m_CursorBoundProps.Find(pProperty);
- if (pos != NULL)
- m_CursorBoundProps.RemoveAt(pos);
- }
- }
-
- void CDataSourceControl::BindColumns()
- {
- if (m_pDataSource != NULL)
- {
- // this is done automatically by CDynamicAccessor
- GetBoundClientRow();
- UpdateControls();
- return;
- }
- if (m_pValues)
- {
- for (int i=0; i<m_nBindings; i++)
- ::VariantClear(&m_pValues[i]);
- if (m_nBindings > 0)
- {
- delete[] m_pValues;
- delete[] m_pColumnBindings;
- }
- m_pValues = NULL;
- }
- m_nBindings = 0;
- for (int nCol=0; nCol<m_nColumns; nCol++)
- {
- m_nBindings += m_pMetaRowData[nCol].m_pClientList->GetCount();
- }
- if (m_nBindings > 0)
- m_pColumnBindings = new DBCOLUMNBINDING[m_nBindings];
- int nItem = 0;
- for (nCol=0; nCol<m_nColumns; nCol++)
- {
- POSITION pos = m_pMetaRowData[nCol].m_pClientList->GetHeadPosition();
- while (pos)
- {
- COleControlSite* pSite = (COleControlSite *)
- m_pMetaRowData[nCol].m_pClientList->GetNext(pos);
- CopyColumnID(&m_pColumnBindings[nItem].columnID, &m_pMetaRowData[nCol].idColumnID);
- m_pColumnBindings[nItem].obData = sizeof(VARIANT) * nItem;
- m_pColumnBindings[nItem].cbMaxLen = DB_NOMAXLENGTH;
- m_pColumnBindings[nItem].obInfo = DB_NOVALUE;
- m_pColumnBindings[nItem].obVarDataLen = DB_NOVALUE;
- m_pColumnBindings[nItem].dwBinding = DBBINDING_VARIANT;
- m_pColumnBindings[nItem].dwDataType = pSite->m_dwType;
- nItem++;
- }
- }
- m_pCursorMove->SetBindings(m_nBindings, m_pColumnBindings,
- sizeof(VARIANT) * m_nBindings, DBCOLUMNBINDOPTS_REPLACE);
-
- if (m_nBindings)
- m_pValues = new VARIANT[m_nBindings];
-
- for (int i=0; i<m_nBindings; i++)
- {
- memset(&m_pValues[i], 0, sizeof(VARIANT));
- m_pValues[i].vt = VT_EMPTY;
- }
-
- GetBoundClientRow();
- UpdateControls();
- }
-
- HRESULT CDataSourceControl::GetBoundClientRow()
- {
- DBFETCHROWS FetchRows;
-
- if (m_pDataSource != NULL)
- {
- if(m_pRowset == NULL)
- return S_OK;
-
- if(m_pRowset->m_hRow == NULL)
- return S_OK;
-
- return m_pRowset->GetData();
- }
-
- if (m_nBindings == 0)
- return S_OK;
-
- FetchRows.pData = m_pValues;
- FetchRows.pVarData = NULL;
- FetchRows.cbVarData = NULL;
- FetchRows.cRowsRequested = 1;
- FetchRows.dwFlags = 0;
-
- LARGE_INTEGER dl = { 0, 0};
-
- return m_pCursorMove->Move(1, (LPVOID)&DBBMK_CURRENT, dl, &FetchRows);
- }
-
- COleVariant CDataSourceControl::ToVariant(int nCol)
- {
- ASSERT(m_pDataSource != NULL);
- ASSERT(m_pDynamicAccessor != NULL);
- COleVariant vt;
- DBSTATUS dbStatus;
- DBTYPE dbType;
-
- m_pDynamicAccessor->GetStatus(nCol, &dbStatus);
- if(dbStatus == DBSTATUS_S_ISNULL)
- return vt; // just return a blank variant
-
- if(!m_pDynamicAccessor->GetColumnType(nCol, &dbType))
- return vt;
- switch (dbType)
- {
- case DBTYPE_VARIANT:
- vt = COleVariant((LPCVARIANT)m_pDynamicAccessor->GetValue(nCol));
- break;
- case DBTYPE_STR:
- vt = COleVariant(CString((LPCSTR)m_pDynamicAccessor->GetValue(nCol)), VT_BSTR);
- break;
- case DBTYPE_WSTR:
- case DBTYPE_BSTR:
- vt = COleVariant(CString((LPCWSTR)m_pDynamicAccessor->GetValue(nCol)), VT_BSTR);
- break;
- case DBTYPE_I1:
- case DBTYPE_UI1:
- vt = COleVariant(*((BYTE*)m_pDynamicAccessor->GetValue(nCol)));
- break;
- case DBTYPE_I2:
- case DBTYPE_UI2:
- vt = COleVariant(*((short*)m_pDynamicAccessor->GetValue(nCol)));
- break;
- case DBTYPE_I4:
- case DBTYPE_UI4:
- vt = COleVariant(*((long*)m_pDynamicAccessor->GetValue(nCol)));
- break;
- case DBTYPE_R4:
- vt = COleVariant(*((float*)m_pDynamicAccessor->GetValue(nCol)));
- break;
- case DBTYPE_R8:
- vt = COleVariant(*((double*)m_pDynamicAccessor->GetValue(nCol)));
- break;
- case DBTYPE_BOOL:
- vt = COleVariant((short)*(BOOL*)m_pDynamicAccessor->GetValue(nCol), VT_BOOL);
- break;
- case DBTYPE_DATE:
- {
- COleDateTime dt(*((DATE*)m_pDynamicAccessor->GetValue(nCol)));
- vt = COleVariant(dt);
- }
- break;
- case DBTYPE_CY:
- {
- COleCurrency cy(*((CURRENCY*)m_pDynamicAccessor->GetValue(nCol)));
- vt = COleVariant(cy);
- }
- break;
- case DBTYPE_NUMERIC:
- {
- DB_NUMERIC num;
-
- if(m_pDynamicAccessor->GetValue(nCol, &num))
- {
- double dbl;
-
- dbl = (double)*((__int64*)num.val);
- while(num.scale-- > 0)
- dbl /= 10;
- if(num.sign == 0)
- dbl = -dbl;
- vt = COleVariant(dbl);
- }
- }
- break;
- case DBTYPE_DBDATE:
- {
- DBDATE dbDate;
-
- if(m_pDynamicAccessor->GetValue(nCol, &dbDate))
- {
- COleDateTime dt;
-
- dt.SetDate(dbDate.year, dbDate.month, dbDate.day);
- vt = COleVariant(dt);
- }
- }
- break;
- case DBTYPE_DBTIME:
- {
- DBTIME dbTime;
-
- if(m_pDynamicAccessor->GetValue(nCol, &dbTime))
- {
- COleDateTime dt;
-
- dt.SetTime(dbTime.hour, dbTime.minute, dbTime.second);
- vt = COleVariant(dt);
- }
- }
- break;
- case DBTYPE_DBTIMESTAMP:
- {
- DBTIMESTAMP dbTimeStamp;
-
- if(m_pDynamicAccessor->GetValue(nCol, &dbTimeStamp))
- {
- vt = COleVariant(COleDateTime(dbTimeStamp.year, dbTimeStamp.month, dbTimeStamp.day,
- dbTimeStamp.hour, dbTimeStamp.minute, dbTimeStamp.second));
- }
- }
- break;
- case DBTYPE_NULL:
- case DBTYPE_EMPTY:
- break;
- default:
- TRACE2("Unsupported DBTYPE (%d) in column %d\n", dbType, nCol);
- break;
- }
- return vt;
- }
-
- HRESULT CDataSourceControl::UpdateControls()
- {
- m_bUpdateInProgress = TRUE;
- int nItem = 0;
- for (int nCol=0; nCol<m_nColumns; nCol++)
- {
- POSITION pos = m_pMetaRowData[nCol].m_pClientList->GetHeadPosition();
- while (pos)
- {
- COleControlSite* pSite = (COleControlSite *)
- m_pMetaRowData[nCol].m_pClientList->GetNext(pos);
-
- DISPPARAMS dispparamsSetProp;
- DISPID dispidNamed = DISPID_PROPERTYPUT;
- EXCEPINFO excepinfo;
- memset(&excepinfo, 0, sizeof(EXCEPINFO));
- UINT uArgErr;
- COleVariant vt;
- if (m_pDataSource != NULL)
- {
- vt = ToVariant(nCol + 1);
- dispparamsSetProp.rgvarg = &vt;
- }
- else
- {
- dispparamsSetProp.rgvarg = &m_pValues[nItem];
- }
- dispparamsSetProp.rgdispidNamedArgs = &dispidNamed;
- dispparamsSetProp.cArgs = 1;
- dispparamsSetProp.cNamedArgs = 1;
- HRESULT hRes;
- LPDISPATCH pDispatch;
- pSite->m_bIgnoreNotify = TRUE;
- if (pSite->m_pObject == NULL)
- continue;
- hRes = pSite->m_pObject->QueryInterface(IID_IDispatch, (LPVOID *) &pDispatch);
- if (FAILED(hRes))
- continue;
- hRes = pDispatch->Invoke(pSite->m_defdispid, IID_NULL, 0, INVOKE_PROPERTYPUT, &dispparamsSetProp,
- NULL, &excepinfo, &uArgErr); //Set the bound control property
- pDispatch->Release();
- pSite->m_bIgnoreNotify = FALSE;
-
- if (excepinfo.bstrSource)
- SysFreeString(excepinfo.bstrSource);
- if (excepinfo.bstrDescription)
- SysFreeString(excepinfo.bstrDescription);
- if (excepinfo.bstrHelpFile)
- SysFreeString(excepinfo.bstrHelpFile);
-
- vt.Clear();
- nItem++;
- }
- }
- m_bUpdateInProgress = FALSE;
- return S_OK;
- }
-
- HRESULT CDataSourceControl::UpdateCursor()
- {
- HRESULT hRes;
- int nVariant = 0;
- int nDirtyField = 0;
-
- if (m_pDataSource != NULL)
- {
- if(m_pDynamicAccessor == NULL)
- return S_OK;
- // First go through all simple bound properties
- for (int nCol=1; nCol<=m_nColumns; nCol++)
- {
- POSITION pos = m_pMetaRowData[nCol - 1].m_pClientList->GetHeadPosition();
- while (pos)
- {
- COleControlSite* pSite = (COleControlSite *)
- m_pMetaRowData[nCol - 1].m_pClientList->GetNext(pos);
- DBTYPE dbType;
-
- if (pSite->m_bIsDirty)
- {
- pSite->m_bIsDirty = FALSE;
-
- nDirtyField++;
- if (nDirtyField == 1)
- {
- // UpdateinProgress semaphore - unexpected state
- ASSERT(!m_bUpdateInProgress);
- m_bUpdateInProgress = TRUE;
- }
-
- COleVariant var(pSite->m_varResult);
- CManualAccessor accessor;
-
- // Create accessor for output column
- accessor.CreateAccessor(1, m_pDynamicAccessor->GetValue(nCol), m_pDynamicAccessor->m_pColumnInfo[nCol].ulColumnSize);
- accessor.AddBindEntry(m_pDynamicAccessor->m_pColumnInfo[nCol].iOrdinal,
- m_pDynamicAccessor->m_pColumnInfo[nCol].wType,
- m_pDynamicAccessor->m_pColumnInfo[nCol].ulColumnSize,
- m_pDynamicAccessor->GetValue(nCol));
- accessor.BindColumns(m_pRowset->m_spRowset);
-
- VERIFY(m_pDynamicAccessor->GetColumnType(nCol, &dbType));
- switch(dbType)
- {
- case DBTYPE_I2:
- var.ChangeType(VT_I2);
- m_pDynamicAccessor->SetValue(nCol, var.iVal);
- break;
- case DBTYPE_I4:
- var.ChangeType(VT_I4);
- m_pDynamicAccessor->SetValue(nCol, var.lVal);
- break;
- case DBTYPE_R4:
- var.ChangeType(VT_R4);
- m_pDynamicAccessor->SetValue(nCol, var.fltVal);
- break;
- case DBTYPE_R8:
- var.ChangeType(VT_R8);
- m_pDynamicAccessor->SetValue(nCol, var.dblVal);
- break;
- case DBTYPE_CY:
- var.ChangeType(VT_CY);
- *(CY*)m_pDynamicAccessor->GetValue(nCol) = var.cyVal;
- break;
- case DBTYPE_DATE:
- var.ChangeType(VT_DATE);
- m_pDynamicAccessor->SetValue(nCol, var.date);
- break;
- case DBTYPE_BSTR:
- case DBTYPE_WSTR:
- var.ChangeType(VT_BSTR);
- wcsncpy((wchar_t*)m_pDynamicAccessor->GetValue(nCol), var.bstrVal, m_pDynamicAccessor->m_pColumnInfo[nCol].ulColumnSize);
- break;
- case DBTYPE_BOOL:
- var.ChangeType(VT_BOOL);
- m_pDynamicAccessor->SetValue(nCol, var.boolVal);
- break;
- case DBTYPE_DECIMAL:
- var.ChangeType(VT_DECIMAL);
- m_pDynamicAccessor->SetValue(nCol, var.decVal);
- break;
- case DBTYPE_UI1:
- var.ChangeType(VT_UI1);
- m_pDynamicAccessor->SetValue(nCol, var.bVal);
- break;
- case DBTYPE_I1:
- var.ChangeType(VT_I1);
- m_pDynamicAccessor->SetValue(nCol, (signed char)var.cVal);
- break;
- case DBTYPE_UI2:
- var.ChangeType(VT_UI2);
- m_pDynamicAccessor->SetValue(nCol, var.uiVal);
- break;
- case DBTYPE_UI4:
- var.ChangeType(VT_UI4);
- m_pDynamicAccessor->SetValue(nCol, var.ulVal);
- break;
- case DBTYPE_STR:
- var.ChangeType(VT_BSTR);
- WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, (char*)m_pDynamicAccessor->GetValue(nCol),
- m_pDynamicAccessor->m_pColumnInfo[nCol].ulColumnSize, NULL, NULL);
- break;
- case DBTYPE_DBTIMESTAMP:
- DBTIMESTAMP ts;
- SYSTEMTIME sysTime;
- var.ChangeType(VT_DATE);
- memset(&ts, 0, sizeof(DBTIMESTAMP));
- VariantTimeToSystemTime(var.date, &sysTime);
- ts.year = sysTime.wYear;
- ts.month = sysTime.wMonth;
- ts.day = sysTime.wDay;
- ts.hour = sysTime.wHour;
- ts.minute = sysTime.wMinute;
- ts.second = sysTime.wSecond;
- ts.fraction = sysTime.wMilliseconds / 1000000;
- m_pDynamicAccessor->SetValue(nCol, ts);
- break;
- default:
- TRACE2("Unsupported DBTYPE (%d) in column %d\n", dbType, nCol);
- break;
- }
-
- m_pRowset->SetAccessor(&accessor);
- m_pRowset->SetData();
- m_pRowset->SetAccessor(m_pDynamicAccessor);
-
- ::VariantClear(&pSite->m_varResult);
- }
- nVariant++;
- }
- }
- if (nDirtyField > 0)
- {
- m_bUpdateInProgress = FALSE;
- }
- return S_OK;
- }
- // Do we have an updateable cursor?
- if (m_pCursorUpdateARow == NULL)
- {
- // If not attempt to get one
- hRes = m_pCursorMove->QueryInterface(IID_ICursorUpdateARow,
- (LPVOID *)&m_pCursorUpdateARow);
-
- if (FAILED(hRes))
- return S_OK; // no update cursor, so forget updating
- }
-
- // First go through all simple bound properties
- for (int nCol=0; nCol<m_nColumns; nCol++)
- {
- POSITION pos = m_pMetaRowData[nCol].m_pClientList->GetHeadPosition();
- while (pos)
- {
- COleControlSite* pSite = (COleControlSite *)
- m_pMetaRowData[nCol].m_pClientList->GetNext(pos);
-
- if (pSite->m_bIsDirty)
- {
- pSite->m_bIsDirty = FALSE;
-
- nDirtyField++;
- if (nDirtyField == 1)
- {
- DWORD dwEdit;
- hRes = m_pCursorUpdateARow->GetEditMode(&dwEdit);
- if (FAILED(hRes))
- return hRes;
- if (dwEdit == DBEDITMODE_NONE)
- {
- hRes = m_pCursorUpdateARow->BeginUpdate(DBROWACTION_UPDATE);
- if (FAILED(hRes))
- return hRes;
- }
- // UpdateinProgress semaphore - unexpected state
- ASSERT(!m_bUpdateInProgress);
- m_bUpdateInProgress = TRUE;
- }
- DBBINDPARAMS bpBindParams;
- DWORD dwIndicator = sizeof(VARIANT);
- COleVariant vt;
- switch (V_VT(&pSite->m_varResult))
- {
- case VT_EMPTY:
- case VT_NULL:
- case VT_ERROR:
- dwIndicator = DB_NULL;
- vt = pSite->m_varResult;
- break;
- case VT_BSTR:
- if(*pSite->m_varResult.bstrVal == 0)
- {
- dwIndicator = DB_NULL;
- break;
- }
- default:
- vt = pSite->m_varResult;
- break;
- }
- bpBindParams.cbMaxLen = 0L;
- bpBindParams.dwBinding = DBBINDING_VARIANT;
- bpBindParams.dwDataType = m_pColumnBindings[nVariant].dwDataType;
- bpBindParams.cbVarDataLen = 0L;
- bpBindParams.dwInfo = dwIndicator;
- bpBindParams.pData = &vt;
-
- hRes = m_pCursorUpdateARow->SetColumn(&m_pColumnBindings[nVariant].columnID, &bpBindParams);
-
- ::VariantClear(&pSite->m_varResult);
- }
- nVariant++;
- }
- }
- // Now go through all cursor bound properties
- POSITION pos = m_CursorBoundProps.GetHeadPosition();
- while (pos != NULL)
- {
- CDataBoundProperty* pProp = (CDataBoundProperty*) m_CursorBoundProps.GetNext(pos);
- if (pProp->m_pClientSite->m_pObject == NULL)
- continue;
- IBoundObject *pBO;
- if (SUCCEEDED(pProp->m_pClientSite->m_pObject->QueryInterface(IID_IBoundObject,
- (LPVOID *) &pBO)))
- {
- if (pBO->IsDirty(pProp->m_dispid) == S_OK)
- {
- nDirtyField++;
- if (nDirtyField == 1)
- {
- DWORD dwEdit;
- hRes = m_pCursorUpdateARow->GetEditMode(&dwEdit);
- if (FAILED(hRes))
- return hRes;
- if (dwEdit == DBEDITMODE_NONE)
- {
- hRes = m_pCursorUpdateARow->BeginUpdate(DBROWACTION_UPDATE);
- if (FAILED(hRes))
- return hRes;
- }
- // UpdateinProgress semaphore - unexpected state
- ASSERT(!m_bUpdateInProgress);
- m_bUpdateInProgress = TRUE;
- }
- }
- pBO->Release();
- }
- }
-
- if (nDirtyField > 0)
- {
- hRes = m_pCursorUpdateARow->Update(0,0,0);
- m_bUpdateInProgress = FALSE;
- if (FAILED(hRes))
- {
- // Update failed w/dirty controls
- ASSERT(hRes!= S_OK);
- UpdateControls();
- return hRes;
- }
- }
-
- return S_OK;
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // CDataBoundProperty Handles Databound Controls
-
- CDataBoundProperty::CDataBoundProperty(CDataBoundProperty* pLast, DISPID dispid, WORD ctlid) :
- m_dispid(dispid),
- m_ctlid(ctlid),
- m_pClientSite(NULL),
- m_pDSCSite(NULL),
- m_bIsDirty(FALSE),
- m_pNext(pLast)
- {
- }
-
- void CDataBoundProperty::SetClientSite(COleControlSite *pClientSite)
- {
- m_pClientSite = pClientSite;
- }
-
-
- // (Re)bind a cursor bound property to a DSC
- void CDataBoundProperty::SetDSCSite(COleControlSite *pDSCSite)
- {
- if (m_pDSCSite == pDSCSite)
- return;
- m_pDSCSite = pDSCSite;
- Notify();
- }
-
- CDataBoundProperty* CDataBoundProperty::GetNext()
- {
- return m_pNext;
- }
-
- void CDataBoundProperty::RemoveSource()
- {
- m_pDSCSite = NULL;
- Notify();
- }
-
- void CDataBoundProperty::Notify()
- {
- if (m_dispid != DISPID_DATASOURCE)
- {
- IBoundObject *pBO;
- if (m_pClientSite != NULL)
- {
- if (SUCCEEDED(m_pClientSite->m_pObject->QueryInterface(IID_IBoundObject,
- (LPVOID *) &pBO)))
- {
- pBO->OnSourceChanged(m_dispid, m_pDSCSite != NULL, &m_bOwnXferOut);
- pBO->Release();
- }
- else
- {
- IUnknown* pUnk = GetCursor();
- if (pUnk != NULL)
- {
- VARTYPE vt = VT_UNKNOWN;
- if (m_pDSCSite->m_pDataSourceControl != NULL)
- vt |= VT_MFCFORCEPUTREF;
- m_pClientSite->SetProperty(m_dispid, vt, pUnk);
- }
- }
- }
- }
- }
-
- IUnknown* CDataBoundProperty::GetCursor()
- {
- if(m_pDSCSite == NULL)
- return NULL;
-
- m_pDSCSite->EnableDSC();
-
- ASSERT(m_pDSCSite->m_pDataSourceControl);
-
- m_pDSCSite->m_pDataSourceControl->BindProp(this);
-
- return m_pDSCSite->m_pDataSourceControl->GetCursor();
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // COleControlSite::XBoundObjectSite
-
- HRESULT COleControlSite::GetCursor(
- DISPID dispid, LPUNKNOWN* ppcursorOut, LPVOID *ppcidOut)
- {
- if (ppcidOut != NULL)
- *ppcidOut = NULL;
-
- CDataBoundProperty* pBinding = m_pBindings;
- while (pBinding != NULL)
- {
- if (pBinding->m_dispid == dispid)
- {
- *ppcursorOut = pBinding->GetCursor();
- return S_OK;
- }
- pBinding = pBinding->GetNext();
- }
- return S_OK;
- }
-
- STDMETHODIMP_(ULONG) COleControlSite::XBoundObjectSite::AddRef()
- {
- METHOD_PROLOGUE_EX(COleControlSite, BoundObjectSite)
- return (ULONG)pThis->ExternalAddRef();
- }
-
- STDMETHODIMP_(ULONG) COleControlSite::XBoundObjectSite::Release()
- {
- METHOD_PROLOGUE_EX(COleControlSite, BoundObjectSite)
- return (ULONG)pThis->ExternalRelease();
- }
-
- STDMETHODIMP COleControlSite::XBoundObjectSite::QueryInterface(
- REFIID iid, LPVOID far * ppvObj)
- {
- METHOD_PROLOGUE_EX(COleControlSite, BoundObjectSite)
- return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
- }
-
- STDMETHODIMP COleControlSite::XBoundObjectSite::GetCursor(
- DISPID dispid, LPLPCURSOR ppcursorOut, LPVOID *ppcidOut)
- {
- METHOD_PROLOGUE_EX(COleControlSite, BoundObjectSite)
- return pThis->GetCursor(dispid, (LPUNKNOWN*)ppcursorOut, ppcidOut);
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // COleControlSite::XNotifyDBEvents
-
- STDMETHODIMP_(ULONG) COleControlSite::XNotifyDBEvents::AddRef()
- {
- return 1;
- }
-
- STDMETHODIMP_(ULONG) COleControlSite::XNotifyDBEvents::Release()
- {
- return 0;
- }
-
- STDMETHODIMP COleControlSite::XNotifyDBEvents::QueryInterface(
- REFIID iid, LPVOID far * ppvObj)
- {
- METHOD_PROLOGUE_EX_(COleControlSite, NotifyDBEvents)
-
- if (IsEqualIID(iid, IID_IUnknown) ||
- IsEqualIID(iid, IID_INotifyDBEvents))
- {
- *ppvObj = this;
- AddRef();
- return S_OK;
- }
- else
- {
- return E_NOINTERFACE;
- }
- }
-
- STDMETHODIMP COleControlSite::XNotifyDBEvents::OKToDo(
- DWORD dwEventWhat, ULONG cReasons, DBNOTIFYREASON rgReasons[])
- {
- METHOD_PROLOGUE_EX(COleControlSite, NotifyDBEvents)
-
- HRESULT hRes = FireEvent(dwEventWhat, cReasons, rgReasons,
- dscOKToDo);
- if (FAILED(hRes))
- return hRes;
-
- DWORD reason = rgReasons[0].dwReason;
-
- if (reason == DBREASON_SETCOLUMN ||
- reason == DBREASON_INSERTED ||
- reason == DBREASON_MODIFIED)
- return S_OK;
-
- // Mask out all notifications except as currency changes and update
- if (!(dwEventWhat & DBEVENT_CURRENT_ROW_CHANGED) &&
- reason != DBREASON_INSERTED &&
- reason != DBREASON_MODIFIED &&
- reason != DBREASON_DELETED &&
- reason != DBREASON_ADDNEW)
- return S_OK;
-
- CDataSourceControl* pDSC = pThis->m_pDataSourceControl;
- if (pDSC == NULL)
- return S_OK;
-
- if (!(dwEventWhat & DBEVENT_CURRENT_ROW_CHANGED))
- return S_OK;
-
- return pDSC->UpdateCursor();
- }
-
- STDMETHODIMP COleControlSite::XNotifyDBEvents::Cancelled(
- DWORD dwEventWhat, ULONG cReasons, DBNOTIFYREASON rgReasons[])
- {
- METHOD_PROLOGUE_EX(COleControlSite, NotifyDBEvents)
-
- HRESULT hRes = FireEvent(dwEventWhat, cReasons, rgReasons,
- dscCancelled);
- if (FAILED(hRes))
- return hRes;
-
- return S_OK;
- }
-
- STDMETHODIMP COleControlSite::XNotifyDBEvents::SyncBefore(
- DWORD dwEventWhat, ULONG cReasons, DBNOTIFYREASON rgReasons[])
- {
- METHOD_PROLOGUE_EX(COleControlSite, NotifyDBEvents)
-
- HRESULT hRes = FireEvent(dwEventWhat, cReasons, rgReasons,
- dscSyncBefore);
- if (FAILED(hRes))
- return hRes;
-
- DWORD reason = rgReasons[0].dwReason;
-
- // Mask out all notifications except as shown
- if (reason != DBREASON_INSERTED &&
- reason != DBREASON_MODIFIED &&
- reason != DBREASON_ADDNEW)
- return S_OK;
-
- CDataSourceControl* pDSC = pThis->m_pDataSourceControl;
- if (pDSC == NULL)
- return S_OK;
-
- if (dwEventWhat & DBEVENT_METADATA_CHANGED)
- {
- pDSC->UpdateCursor();
- }
-
- return S_OK;
- }
-
- STDMETHODIMP COleControlSite::XNotifyDBEvents::AboutToDo(
- DWORD dwEventWhat, ULONG cReasons, DBNOTIFYREASON rgReasons[])
- {
- METHOD_PROLOGUE_EX(COleControlSite, NotifyDBEvents)
-
- HRESULT hRes = FireEvent(dwEventWhat, cReasons, rgReasons,
- dscAboutToDo);
- if (FAILED(hRes))
- return hRes;
-
- return S_OK;
- }
-
- STDMETHODIMP COleControlSite::XNotifyDBEvents::FailedToDo(
- DWORD dwEventWhat, ULONG cReasons, DBNOTIFYREASON rgReasons[])
- {
- METHOD_PROLOGUE_EX(COleControlSite, NotifyDBEvents)
-
- HRESULT hRes = FireEvent(dwEventWhat, cReasons, rgReasons,
- dscFailedToDo);
- if (FAILED(hRes))
- return hRes;
-
- return S_OK;
- }
-
- STDMETHODIMP COleControlSite::XNotifyDBEvents::SyncAfter(
- DWORD dwEventWhat, ULONG cReasons, DBNOTIFYREASON rgReasons[])
- {
- METHOD_PROLOGUE_EX(COleControlSite, NotifyDBEvents)
-
- HRESULT hRes = FireEvent(dwEventWhat, cReasons, rgReasons,
- dscSyncAfter);
- if (FAILED(hRes))
- return hRes;
-
- DWORD reason = rgReasons[0].dwReason;
-
- CDataSourceControl* pDSC = pThis->m_pDataSourceControl;
- if (pDSC == NULL)
- return S_OK;
-
- //Check semaphore - don't want to collect data during Update if it was due to a Move (it's a NOP!)
- if (pDSC->m_bUpdateInProgress ||
- reason == DBREASON_EDIT ||
- reason == DBREASON_SETCOLUMN)
- return S_OK;
-
- //Mask out all notifications except as shown
- if (!(dwEventWhat & (DBEVENT_CURRENT_ROW_CHANGED | DBEVENT_CURRENT_ROW_DATA_CHANGED)))
- return S_OK;
-
- if (reason != DBREASON_INSERTED &&
- reason != DBREASON_MODIFIED)
- {
- BOOL bUpdateInProgress = pDSC->m_bUpdateInProgress;
- pDSC->m_bUpdateInProgress = TRUE;
- pDSC->GetBoundClientRow();
- pDSC->m_bUpdateInProgress = bUpdateInProgress;
- pDSC->UpdateControls();
- }
-
- return S_OK;
- }
-
- STDMETHODIMP COleControlSite::XNotifyDBEvents::DidEvent(
- DWORD dwEventWhat, ULONG cReasons, DBNOTIFYREASON rgReasons[])
- {
- METHOD_PROLOGUE_EX(COleControlSite, NotifyDBEvents)
-
- HRESULT hRes = FireEvent(dwEventWhat, cReasons, rgReasons,
- dscDidEvent);
- if (FAILED(hRes))
- return hRes;
-
- CDataSourceControl* pDSC = pThis->m_pDataSourceControl;
- if (pDSC == NULL)
- return S_OK;
-
- if (dwEventWhat & DBEVENT_METADATA_CHANGED)
- {
- BOOL bUpdateInProgress = pDSC->m_bUpdateInProgress;
- pDSC->m_bUpdateInProgress = TRUE;
- pDSC->GetBoundClientRow();
- pDSC->m_bUpdateInProgress = bUpdateInProgress;
- pDSC->UpdateControls();
- }
-
- return S_OK;
- }
-
-
- HRESULT COleControlSite::XNotifyDBEvents::FireEvent(
- DWORD dwEventWhat, ULONG cReasons, DBNOTIFYREASON rgReasons[], DSCSTATE nState)
- {
- METHOD_PROLOGUE_EX_(COleControlSite, NotifyDBEvents)
-
- if (dwEventWhat & DBEVENT_CURRENT_ROW_CHANGED
- || dwEventWhat & DBEVENT_CURRENT_ROW_DATA_CHANGED)
- {
- for (UINT i=0; i<cReasons; i++)
- {
- DSCREASON nReason = dscNoReason;
- switch (rgReasons[i].dwReason)
- {
- case DBREASON_CLOSE:
- nReason = dscClose;
- break;
- case DBREASON_FIND:
- case DBREASON_MOVE:
- case DBREASON_MOVEPERCENT:
- case DBREASON_NEWINDEX:
- case DBREASON_NEWPARAMETERS:
- case DBREASON_QUERYSPECCHANGED:
- case DBREASON_REFRESH:
- case DBREASON_SEEK:
- case DBREASON_SETRANGECHANGED:
- nReason = dscMove;
- break;
- case DBREASON_ADDNEW:
- case DBREASON_INSERTED:
- nReason = dscInsert;
- break;
- case DBREASON_EDIT:
- nReason = dscEdit;
- break;
- case DBREASON_MODIFIED:
- case DBREASON_RECALC:
- case DBREASON_ROLLBACK:
- case DBREASON_ROWFIXUP:
- nReason = dscModify;
- break;
- case DBREASON_DELETED:
- nReason = dscDelete;
- break;
- case DBREASON_COMMIT:
- nReason = dscCommit;
- break;
- }
- if (nReason != dscNoReason)
- {
- AFX_EVENT event(AFX_EVENT::propDSCNotify);
- event.m_nDSCState = nState;
- event.m_nDSCReason = nReason;
- pThis->OnEvent(&event);
- return event.m_hResult;
- }
- }
- return S_OK;
- }
- return S_OK;
- }
-
- STDMETHODIMP_(ULONG) COleControlSite::XRowsetNotify::AddRef()
- {
- return 1;
- }
-
- STDMETHODIMP_(ULONG) COleControlSite::XRowsetNotify::Release()
- {
- return 0;
- }
-
- STDMETHODIMP COleControlSite::XRowsetNotify::QueryInterface(
- REFIID iid, LPVOID far * ppvObj)
- {
- METHOD_PROLOGUE_EX_(COleControlSite, RowsetNotify)
-
- if (IsEqualIID(iid, IID_IUnknown) ||
- IsEqualIID(iid, IID_IRowsetNotify))
- {
- *ppvObj = this;
- AddRef();
- return S_OK;
- }
- return E_NOINTERFACE;
- }
-
- STDMETHODIMP COleControlSite::XRowsetNotify::OnFieldChange(
- IRowset* /*pRowset*/, HROW /*hRow*/, ULONG /*cColumns*/, ULONG /*rgColumns*/[],
- DBREASON /*eReason*/, DBEVENTPHASE ePhase, BOOL /*fCantDeny*/)
- {
- METHOD_PROLOGUE_EX(COleControlSite, RowsetNotify)
-
- DSCSTATE nState = dscNoState;
- switch(ePhase)
- {
- case DBEVENTPHASE_OKTODO:
- nState = dscOKToDo;
- break;
- case DBEVENTPHASE_ABOUTTODO:
- nState = dscAboutToDo;
- break;
- case DBEVENTPHASE_SYNCHAFTER:
- nState = dscSyncAfter;
- break;
- case DBEVENTPHASE_FAILEDTODO:
- nState = dscFailedToDo;
- break;
- case DBEVENTPHASE_DIDEVENT:
- nState = dscDidEvent;
- break;
- }
- if(nState == dscDidEvent)
- {
- CDataSourceControl* pDSC = pThis->m_pDataSourceControl;
- if (pDSC == NULL)
- return S_OK;
-
- if(pDSC->m_bUpdateInProgress == FALSE)
- {
- ASSERT(pDSC->m_pRowset);
-
- BOOL bUpdateInProgress = pDSC->m_bUpdateInProgress;
- pDSC->m_bUpdateInProgress = TRUE;
- pDSC->GetBoundClientRow();
- pDSC->m_bUpdateInProgress = bUpdateInProgress;
- pDSC->UpdateControls();
- }
- }
-
- AFX_EVENT event(AFX_EVENT::propDSCNotify);
- event.m_nDSCState = nState;
- event.m_nDSCReason = dscModify;
- pThis->OnEvent(&event);
- return event.m_hResult;
- }
-
- STDMETHODIMP COleControlSite::XRowsetNotify::OnRowChange(
- IRowset* /*pRowset*/, ULONG cRows, const HROW rghRows[],
- DBREASON eReason, DBEVENTPHASE ePhase, BOOL /*fCantDeny*/)
- {
- METHOD_PROLOGUE_EX(COleControlSite, RowsetNotify)
-
- HRESULT hRes = S_OK;
-
- DSCSTATE nState = dscNoState;
- switch(ePhase)
- {
- case DBEVENTPHASE_OKTODO:
- nState = dscOKToDo;
- break;
- case DBEVENTPHASE_ABOUTTODO:
- nState = dscAboutToDo;
- break;
- case DBEVENTPHASE_SYNCHAFTER:
- nState = dscSyncAfter;
- break;
- case DBEVENTPHASE_FAILEDTODO:
- nState = dscFailedToDo;
- break;
- case DBEVENTPHASE_DIDEVENT:
- nState = dscDidEvent;
- break;
- }
- DSCREASON nReason = dscNoReason;
- switch(eReason)
- {
- case DBREASON_ROW_ACTIVATE:
- nReason = dscMove;
- break;
- case DBREASON_ROW_DELETE:
- nReason = dscDelete;
- break;
- case DBREASON_ROW_INSERT:
- nReason = dscInsert;
- break;
- case DBREASON_ROW_UPDATE:
- nReason = dscCommit;
- break;
- }
- CDataSourceControl* pDSC = pThis->m_pDataSourceControl;
- if (pDSC == NULL)
- return S_OK;
-
- ASSERT(pDSC->m_pRowset);
-
- if (nReason == dscCommit && nState == dscAboutToDo)
- {
- pDSC->UpdateCursor();
- }
- else if ((nReason == dscMove && cRows == 1) || (nState == dscSyncAfter && nReason == dscInsert))
- {
- pDSC->UpdateCursor();
- pDSC->m_pRowset->m_hRow = rghRows[0];
-
- BOOL bUpdateInProgress = pDSC->m_bUpdateInProgress;
- pDSC->m_bUpdateInProgress = TRUE;
- pDSC->GetBoundClientRow();
- pDSC->m_bUpdateInProgress = bUpdateInProgress;
- if(!pDSC->m_bUpdateInProgress)
- pDSC->UpdateControls();
- }
- if (nReason != dscNoReason)
- {
- AFX_EVENT event(AFX_EVENT::propDSCNotify);
- event.m_nDSCState = nState;
- event.m_nDSCReason = nReason;
- pThis->OnEvent(&event);
- hRes = event.m_hResult;
- if(FAILED(hRes))
- return hRes;
- }
- return S_OK;
- }
-
- STDMETHODIMP COleControlSite::XRowsetNotify::OnRowsetChange(
- IRowset* /*pRowset*/, DBREASON eReason, DBEVENTPHASE /*ePhase*/, BOOL /*fCantDeny*/)
- {
- METHOD_PROLOGUE_EX(COleControlSite, RowsetNotify)
-
- if(eReason == DBREASON_ROWSET_CHANGED)
- {
- CDataSourceControl* pDSC = pThis->m_pDataSourceControl;
- if (pDSC == NULL)
- return S_OK;
-
- ASSERT(pDSC->m_pRowset);
- ASSERT(pDSC->m_pDynamicAccessor);
-
- pDSC->m_pDynamicAccessor->ReleaseAccessors(pDSC->m_pRowset->m_spRowset);
- pDSC->m_pDynamicAccessor->Close();
- pDSC->m_pDynamicAccessor->BindColumns(pDSC->m_pRowset->m_spRowset);
- if( pDSC->m_nColumns != (int)pDSC->m_pDynamicAccessor->GetColumnCount() )
- {
- pDSC->m_nColumns = pDSC->m_pDynamicAccessor->GetColumnCount();
- ::CoTaskMemFree(pDSC->m_pMetaRowData);
- pDSC->m_pMetaRowData = (CDataSourceControl::METAROWTYPE*)::CoTaskMemAlloc(sizeof(CDataSourceControl::METAROWTYPE) * pDSC->m_nColumns);
- ASSERT(pDSC->m_pMetaRowData);
- memset(pDSC->m_pMetaRowData, 0, sizeof(CDataSourceControl::METAROWTYPE) * pDSC->m_nColumns);
- }
- }
-
- return S_OK;
- }
-