| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539 |
- // 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"
- #define DBINITCONSTANTS // __BORLANDC__ fix: must define this here so that
- // the ocdb.h symbols get defined
- #include "initguid.h"
- #define INITGUID // __BORLANDC__ fix: must define this here so that
- // the guids from ocdbid.h get generated
- #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 ==
- #ifdef __BORLANDC__ // MS Ambiguity error fix
- CString(
- #endif
- m_pDynamicAccessor->GetColumnName(nCol + 1)
- #ifdef __BORLANDC__
- )
- #endif
- )
- {
- 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;
- }
|