occsite.cpp 88 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539
  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10. #include "stdafx.h"
  11. #define DBINITCONSTANTS // __BORLANDC__ fix: must define this here so that
  12. // the ocdb.h symbols get defined
  13. #include "initguid.h"
  14. #define INITGUID // __BORLANDC__ fix: must define this here so that
  15. // the guids from ocdbid.h get generated
  16. #include "occimpl.h"
  17. #include "msdadc.h"
  18. #ifdef AFX_OCC_SEG
  19. #pragma code_seg(AFX_OCC_SEG)
  20. #endif
  21. #ifdef _DEBUG
  22. #undef THIS_FILE
  23. static char THIS_FILE[] = __FILE__;
  24. #endif
  25. #define new DEBUG_NEW
  26. #define S_QUICKACTIVATED S_FALSE
  27. #include "initguid.h"
  28. #define DBINITCONSTANTS
  29. #define INITGUID
  30. DEFINE_GUID(IID_IDataSourceListener,0x7C0FFAB2L,0xCD84,0x11D0,0x94,0x9A,0x00,0xA0,0xC9,0x11,0x10,0xED);
  31. DEFINE_GUID(IID_IDataSource,0x7c0ffab3L, 0xcd84, 0x11d0, 0x94, 0x9a, 0x00, 0xa0, 0xc9, 0x11, 0x10, 0xed);
  32. /////////////////////////////////////////////////////////////////////////////
  33. // COleControlSite
  34. BEGIN_INTERFACE_MAP(COleControlSite, CCmdTarget)
  35. INTERFACE_PART(COleControlSite, IID_IOleClientSite, OleClientSite)
  36. INTERFACE_PART(COleControlSite, IID_IOleInPlaceSite, OleIPSite)
  37. INTERFACE_PART(COleControlSite, IID_IOleControlSite, OleControlSite)
  38. INTERFACE_PART(COleControlSite, IID_IDispatch, AmbientProps)
  39. INTERFACE_PART(COleControlSite, IID_IBoundObjectSite, BoundObjectSite)
  40. INTERFACE_PART(COleControlSite, IID_INotifyDBEvents, NotifyDBEvents)
  41. INTERFACE_PART(COleControlSite, IID_IRowsetNotify, RowsetNotify)
  42. END_INTERFACE_MAP()
  43. COleControlSite::COleControlSite(COleControlContainer* pCtrlCont) :
  44. m_pCtrlCont(pCtrlCont),
  45. m_pWndCtrl(NULL),
  46. m_nID((UINT)-1),
  47. m_pObject(NULL),
  48. m_pInPlaceObject(NULL),
  49. m_pActiveObject(NULL),
  50. m_dwEventSink(0),
  51. m_dwPropNotifySink(0),
  52. m_dwMiscStatus(0),
  53. m_dwNotifyDBEvents(0),
  54. m_pDataSourceControl(NULL),
  55. m_pDSCSite(NULL),
  56. m_defdispid(0),
  57. m_dwType(0),
  58. m_pBindings(NULL),
  59. m_bIgnoreNotify(FALSE),
  60. m_bIsDirty(FALSE)
  61. {
  62. memset(&m_varResult, 0, sizeof(VARIANT));
  63. m_varResult.vt = VT_EMPTY;
  64. }
  65. COleControlSite::~COleControlSite()
  66. {
  67. delete m_pDataSourceControl;
  68. DetachWindow();
  69. DisconnectSink(m_iidEvents, m_dwEventSink);
  70. DisconnectSink(IID_IPropertyNotifySink, m_dwPropNotifySink);
  71. DisconnectSink(IID_INotifyDBEvents, m_dwNotifyDBEvents);
  72. if (m_pInPlaceObject != NULL)
  73. {
  74. m_pInPlaceObject->InPlaceDeactivate();
  75. m_pInPlaceObject->Release();
  76. m_pInPlaceObject = NULL;
  77. }
  78. if (m_pActiveObject != NULL)
  79. {
  80. m_pActiveObject->Release();
  81. m_pActiveObject = NULL;
  82. }
  83. if (m_pObject != NULL)
  84. {
  85. m_pObject->SetClientSite(NULL);
  86. m_pObject->Close(OLECLOSE_NOSAVE);
  87. m_pObject->Release();
  88. m_pObject = NULL;
  89. }
  90. ::VariantClear(&m_varResult);
  91. BindProperty(DISPID_UNKNOWN, NULL); // gets rid of complex bindings
  92. if (m_defdispid != 0 && m_pDSCSite != NULL &&
  93. m_pDSCSite->m_pDataSourceControl != NULL)
  94. {
  95. // get rid of simple bindings
  96. m_pDSCSite->m_pDataSourceControl->BindProp(this, FALSE);
  97. }
  98. }
  99. BOOL COleControlSite::SetExtent()
  100. {
  101. CSize size(m_rect.Size());
  102. CClientDC dc(NULL);
  103. dc.DPtoHIMETRIC(&size);
  104. HRESULT hr;
  105. if (SUCCEEDED(hr = m_pObject->SetExtent(DVASPECT_CONTENT, (SIZEL*)&size)))
  106. {
  107. if (SUCCEEDED(m_pObject->GetExtent(DVASPECT_CONTENT, (SIZEL*)&size)))
  108. {
  109. dc.HIMETRICtoDP(&size);
  110. m_rect.right = m_rect.left + size.cx;
  111. m_rect.bottom = m_rect.top + size.cy;
  112. }
  113. }
  114. return SUCCEEDED(hr);
  115. }
  116. HRESULT COleControlSite::CreateControl(CWnd* pWndCtrl, REFCLSID clsid,
  117. LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, UINT nID,
  118. CFile* pPersist, BOOL bStorage, BSTR bstrLicKey)
  119. {
  120. CRect rect2( rect );
  121. CPoint pt;
  122. CSize size;
  123. pt = rect2.TopLeft();
  124. size = rect2.Size();
  125. return( CreateControl( pWndCtrl, clsid, lpszWindowName, dwStyle, &pt, &size,
  126. nID, pPersist, bStorage, bstrLicKey ) );
  127. }
  128. HRESULT COleControlSite::CreateControl(CWnd* pWndCtrl, REFCLSID clsid,
  129. LPCTSTR lpszWindowName, DWORD dwStyle, const POINT* ppt, const SIZE* psize,
  130. UINT nID, CFile* pPersist, BOOL bStorage, BSTR bstrLicKey)
  131. {
  132. HRESULT hr = E_FAIL;
  133. m_hWnd = NULL;
  134. CSize size;
  135. // Connect the OLE Control with its proxy CWnd object
  136. if (pWndCtrl != NULL)
  137. {
  138. ASSERT(pWndCtrl->m_pCtrlSite == NULL);
  139. m_pWndCtrl = pWndCtrl;
  140. pWndCtrl->m_pCtrlSite = this;
  141. }
  142. // Initialize OLE, if necessary
  143. _AFX_THREAD_STATE* pState = AfxGetThreadState();
  144. if (!pState->m_bNeedTerm && !AfxOleInit())
  145. return hr;
  146. if (SUCCEEDED(hr = CreateOrLoad(clsid, pPersist, bStorage, bstrLicKey)))
  147. {
  148. ASSERT(m_pObject != NULL);
  149. m_nID = nID;
  150. if (psize == NULL)
  151. {
  152. // If psize is NULL, ask the object how big it wants to be.
  153. CClientDC dc(NULL);
  154. m_pObject->GetExtent(DVASPECT_CONTENT, &size);
  155. dc.HIMETRICtoDP(&size);
  156. m_rect = CRect(*ppt, size);
  157. }
  158. else
  159. {
  160. m_rect = CRect(*ppt, *psize);
  161. }
  162. m_dwStyleMask = WS_GROUP | WS_TABSTOP;
  163. if (m_dwMiscStatus & OLEMISC_ACTSLIKEBUTTON)
  164. m_dwStyleMask |= BS_DEFPUSHBUTTON;
  165. if (m_dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME)
  166. dwStyle &= ~WS_VISIBLE;
  167. m_dwStyle = dwStyle & m_dwStyleMask;
  168. // If control wasn't quick-activated, then connect sinks now.
  169. if (hr != S_QUICKACTIVATED)
  170. {
  171. m_dwEventSink = ConnectSink(m_iidEvents, &m_xEventSink);
  172. m_dwPropNotifySink = ConnectSink(IID_IPropertyNotifySink,
  173. &m_xPropertyNotifySink);
  174. }
  175. m_dwNotifyDBEvents = ConnectSink(IID_INotifyDBEvents, &m_xNotifyDBEvents);
  176. // Now that the object has been created, attempt to
  177. // in-place activate it.
  178. SetExtent();
  179. if (SUCCEEDED(hr = m_pObject->QueryInterface(IID_IOleInPlaceObject,
  180. (LPVOID*)&m_pInPlaceObject)))
  181. {
  182. if (dwStyle & WS_VISIBLE)
  183. {
  184. // control is visible: just activate it
  185. hr = DoVerb(OLEIVERB_INPLACEACTIVATE);
  186. }
  187. else
  188. {
  189. // control is not visible: activate off-screen, hide, then move
  190. m_rect.OffsetRect(-32000, -32000);
  191. if (SUCCEEDED(hr = DoVerb(OLEIVERB_INPLACEACTIVATE)) &&
  192. SUCCEEDED(hr = DoVerb(OLEIVERB_HIDE)))
  193. {
  194. m_rect.OffsetRect(32000, 32000);
  195. hr = m_pInPlaceObject->SetObjectRects(m_rect, m_rect);
  196. }
  197. }
  198. }
  199. else
  200. {
  201. TRACE1("IOleInPlaceObject not supported on OLE control (dialog ID %d).\n", nID);
  202. TRACE1(">>> Result code: 0x%08lx\n", hr);
  203. }
  204. if (SUCCEEDED(hr))
  205. GetControlInfo();
  206. // if QueryInterface or activation failed, cleanup everything
  207. if (FAILED(hr))
  208. {
  209. if (m_pInPlaceObject != NULL)
  210. {
  211. m_pInPlaceObject->Release();
  212. m_pInPlaceObject = NULL;
  213. }
  214. DisconnectSink(m_iidEvents, m_dwEventSink);
  215. DisconnectSink(IID_IPropertyNotifySink, m_dwPropNotifySink);
  216. DisconnectSink(IID_INotifyDBEvents, m_dwNotifyDBEvents);
  217. m_dwEventSink = 0;
  218. m_dwPropNotifySink = 0;
  219. m_dwNotifyDBEvents = 0;
  220. m_pObject->Release();
  221. m_pObject = NULL;
  222. }
  223. }
  224. if (SUCCEEDED(hr))
  225. {
  226. AttachWindow();
  227. ASSERT(m_hWnd != NULL);
  228. // Initialize the control's Caption or Text property, if any
  229. if (lpszWindowName != NULL)
  230. SetWindowText(lpszWindowName);
  231. // Initialize styles
  232. ModifyStyle(0, m_dwStyle | (dwStyle & (WS_DISABLED|WS_BORDER)), 0);
  233. }
  234. return hr;
  235. }
  236. BOOL COleControlSite::DestroyControl()
  237. {
  238. ASSERT(m_hWnd != NULL); // was control ever successfully created?
  239. m_pCtrlCont->m_siteMap.RemoveKey(m_hWnd);
  240. //VBBUG: VB controls will crash if IOleObject::Close is called on them
  241. // when they have focus (and unfortunately, deactivating them does not
  242. // always move the focus). To work around this problem, we always hide
  243. // the control before closing it.
  244. ShowWindow(SW_HIDE);
  245. // Now it is safe to close the control.
  246. delete this;
  247. return TRUE;
  248. }
  249. AFX_STATIC HRESULT AFXAPI _AfxCoCreateInstanceLic(REFCLSID clsid, LPUNKNOWN pUnkOuter,
  250. DWORD dwClsCtx, REFIID iid, LPVOID* ppv, BSTR bstrLicKey)
  251. {
  252. HRESULT hr;
  253. if (bstrLicKey == NULL)
  254. {
  255. LPCLASSFACTORY pClassFactory = NULL;
  256. if (SUCCEEDED(hr = CoGetClassObject(clsid, dwClsCtx, NULL,
  257. IID_IClassFactory, (void**)&pClassFactory)))
  258. {
  259. ASSERT(pClassFactory != NULL);
  260. hr = pClassFactory->CreateInstance(pUnkOuter, iid, ppv);
  261. pClassFactory->Release();
  262. }
  263. }
  264. else
  265. {
  266. LPCLASSFACTORY2 pClassFactory = NULL;
  267. if (SUCCEEDED(hr = CoGetClassObject(clsid, dwClsCtx, NULL,
  268. IID_IClassFactory2, (void**)&pClassFactory)))
  269. {
  270. ASSERT(pClassFactory != NULL);
  271. hr = pClassFactory->CreateInstanceLic(pUnkOuter, NULL, iid,
  272. bstrLicKey, ppv);
  273. pClassFactory->Release();
  274. }
  275. }
  276. return hr;
  277. }
  278. AFX_STATIC_DATA const struct { DISPID dwDispID; DWORD dwFlag; } _afxAmbients[] =
  279. {
  280. { DISPID_AMBIENT_USERMODE, QACONTAINER_USERMODE },
  281. { DISPID_AMBIENT_UIDEAD, QACONTAINER_UIDEAD },
  282. { DISPID_AMBIENT_SHOWGRABHANDLES, QACONTAINER_SHOWGRABHANDLES },
  283. { DISPID_AMBIENT_SHOWHATCHING, QACONTAINER_SHOWHATCHING },
  284. { DISPID_AMBIENT_DISPLAYASDEFAULT, QACONTAINER_DISPLAYASDEFAULT },
  285. { DISPID_AMBIENT_AUTOCLIP, QACONTAINER_AUTOCLIP },
  286. { DISPID_AMBIENT_MESSAGEREFLECT, QACONTAINER_MESSAGEREFLECT },
  287. { DISPID_AMBIENT_SUPPORTSMNEMONICS, QACONTAINER_SUPPORTSMNEMONICS },
  288. };
  289. BOOL COleControlSite::QuickActivate()
  290. {
  291. BOOL bQuickActivated = FALSE;
  292. IQuickActivate* pQuick = NULL;
  293. if (SUCCEEDED(m_pObject->QueryInterface(IID_IQuickActivate,
  294. reinterpret_cast<void**>(&pQuick))))
  295. {
  296. ASSERT(pQuick != NULL);
  297. // Initialize QACONTAINER structure.
  298. QACONTAINER qaContainer;
  299. qaContainer.cbSize = sizeof(QACONTAINER);
  300. qaContainer.pClientSite = &m_xOleClientSite;
  301. qaContainer.pAdviseSink = NULL;
  302. qaContainer.pPropertyNotifySink = &m_xPropertyNotifySink;
  303. qaContainer.pUnkEventSink = &m_xEventSink;
  304. qaContainer.pUndoMgr = NULL;
  305. qaContainer.hpal = NULL;
  306. qaContainer.pBindHost = NULL;
  307. // Fill ambient property values in QACONTAINER.
  308. COleVariant var;
  309. CWnd* pWndContain = m_pCtrlCont->m_pWnd;
  310. qaContainer.dwAmbientFlags = 0;
  311. for (int i = 0; i < _countof(_afxAmbients); i++)
  312. {
  313. pWndContain->OnAmbientProperty(this, _afxAmbients[i].dwDispID, &var);
  314. if (V_BOOL(&var))
  315. qaContainer.dwAmbientFlags |= _afxAmbients[i].dwFlag;
  316. }
  317. pWndContain->OnAmbientProperty(this, DISPID_AMBIENT_FORECOLOR, &var);
  318. qaContainer.colorFore = V_I4(&var);
  319. pWndContain->OnAmbientProperty(this, DISPID_AMBIENT_BACKCOLOR, &var);
  320. qaContainer.colorBack = V_I4(&var);
  321. pWndContain->OnAmbientProperty(this, DISPID_AMBIENT_APPEARANCE, &var);
  322. qaContainer.dwAppearance = V_I2(&var);
  323. pWndContain->OnAmbientProperty(this, DISPID_AMBIENT_LOCALEID, &var);
  324. qaContainer.lcid = V_I4(&var);
  325. pWndContain->OnAmbientProperty(this, DISPID_AMBIENT_FONT, &var);
  326. if (FAILED(V_DISPATCH(&var)->QueryInterface(IID_IFont,
  327. reinterpret_cast<void**>(&qaContainer.pFont))))
  328. {
  329. qaContainer.pFont = NULL;
  330. }
  331. // Initialize QACONTROL structure.
  332. QACONTROL qaControl;
  333. qaControl.cbSize = sizeof(QACONTROL);
  334. // Do the quick activation.
  335. if (SUCCEEDED(pQuick->QuickActivate(&qaContainer, &qaControl)))
  336. {
  337. // Extract return values from QACONTROL structure.
  338. m_dwMiscStatus = qaControl.dwMiscStatus;
  339. m_dwEventSink = qaControl.dwEventCookie;
  340. m_dwPropNotifySink = qaControl.dwPropNotifyCookie;
  341. bQuickActivated = TRUE;
  342. }
  343. pQuick->Release();
  344. if (qaContainer.pFont != NULL)
  345. qaContainer.pFont->Release();
  346. }
  347. return bQuickActivated;
  348. }
  349. HRESULT COleControlSite::CreateOrLoad(REFCLSID clsid, CFile* pFile,
  350. BOOL bStorage, BSTR bstrLicKey)
  351. {
  352. ASSERT(m_pObject == NULL);
  353. #ifdef _DEBUG
  354. OLECHAR wszClsid[40];
  355. StringFromGUID2(clsid, wszClsid, 40);
  356. #endif //_DEBUG
  357. HRESULT hr;
  358. if (FAILED(hr = _AfxCoCreateInstanceLic(clsid, NULL,
  359. CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, IID_IOleObject,
  360. (void**)&m_pObject, bstrLicKey)))
  361. {
  362. TRACE1("CoCreateInstance of OLE control %ls failed.\n", wszClsid);
  363. TRACE1(">>> Result code: 0x%08lx\n", hr);
  364. TRACE0(">>> Is the control is properly registered?\n");
  365. return hr;
  366. }
  367. LPPERSISTSTREAMINIT pPersStm = NULL;
  368. LPPERSISTSTORAGE pPersStg = NULL;
  369. LPPERSISTMEMORY pPersMem = NULL;
  370. GetEventIID(&m_iidEvents);
  371. // Try to quick-activate first
  372. BOOL bQuickActivated = QuickActivate();
  373. if (!bQuickActivated)
  374. {
  375. m_pObject->GetMiscStatus(DVASPECT_CONTENT, &m_dwMiscStatus);
  376. // set client site first, if appropriate
  377. if (m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)
  378. {
  379. if (FAILED(hr = m_pObject->SetClientSite(&m_xOleClientSite)))
  380. {
  381. TRACE1("SetClientSite on OLE control %ls failed.\n", wszClsid);
  382. TRACE1(">>> Result code: 0x%08lx\n", hr);
  383. goto CreateOrLoadFailed;
  384. }
  385. }
  386. }
  387. ASSERT(!bStorage || pFile != NULL);
  388. // initialize via IPersistMemory (direct buffering)
  389. if (pFile != NULL && !bStorage &&
  390. SUCCEEDED(m_pObject->QueryInterface(IID_IPersistMemory, (void**)&pPersMem)) &&
  391. pFile->GetBufferPtr(CFile::bufferCheck) != 0)
  392. {
  393. ASSERT(pPersMem != NULL);
  394. // file supports direct buffering, get its buffer pointer and size
  395. LPVOID pvBuffer = NULL;
  396. LPVOID pvEnd;
  397. ULONG cbBuffer = pFile->GetBufferPtr(
  398. CFile::bufferRead, (UINT)-1, &pvBuffer, &pvEnd);
  399. ASSERT(((LPBYTE)pvEnd - (LPBYTE)pvBuffer) == (int)cbBuffer);
  400. // and then load it directly
  401. hr = pPersMem->Load(pvBuffer, cbBuffer);
  402. pPersMem->Release();
  403. pPersMem = NULL;
  404. if (FAILED(hr))
  405. goto CreateOrLoadFailed;
  406. }
  407. // initialize via IPersistStreamInit
  408. else if (!bStorage && SUCCEEDED(m_pObject->QueryInterface(
  409. IID_IPersistStreamInit, (void**)&pPersStm)))
  410. {
  411. ASSERT(pPersStm != NULL);
  412. if (pFile == NULL)
  413. {
  414. // just call InitNew
  415. hr = pPersStm->InitNew();
  416. }
  417. else
  418. {
  419. // open an IStream on the data and pass it to Load
  420. CArchive ar(pFile, CArchive::load);
  421. CArchiveStream stm(&ar);
  422. hr = pPersStm->Load(&stm);
  423. }
  424. pPersStm->Release();
  425. if (FAILED(hr))
  426. {
  427. TRACE1("InitNew or Load on OLE control %ls failed.\n", wszClsid);
  428. TRACE1(">>> Result code: 0x%08lx\n", hr);
  429. goto CreateOrLoadFailed;
  430. }
  431. }
  432. // initialize via IPersistStorage
  433. else if (SUCCEEDED(m_pObject->QueryInterface(
  434. IID_IPersistStorage, (void**)&pPersStg)))
  435. {
  436. ASSERT(pPersStg != NULL);
  437. if (pFile == NULL)
  438. {
  439. // create a scratch IStorage and pass it to InitNew
  440. LPLOCKBYTES pLockBytes = NULL;
  441. if (SUCCEEDED(hr = CreateILockBytesOnHGlobal(NULL, TRUE,
  442. &pLockBytes)))
  443. {
  444. ASSERT(pLockBytes != NULL);
  445. LPSTORAGE pStorage = NULL;
  446. if (SUCCEEDED(hr = StgCreateDocfileOnILockBytes(pLockBytes,
  447. STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0,
  448. &pStorage)))
  449. {
  450. ASSERT(pStorage != NULL);
  451. hr = pPersStg->InitNew(pStorage);
  452. pStorage->Release();
  453. }
  454. pLockBytes->Release();
  455. }
  456. }
  457. else if (bStorage)
  458. {
  459. // copy data to an HGLOBAL, so we can build an IStorage on it
  460. UINT cb = pFile->GetLength();
  461. HGLOBAL hGlobal;
  462. BYTE* pbData;
  463. if (((hGlobal = GlobalAlloc(GMEM_FIXED, cb)) != NULL) &&
  464. ((pbData = (BYTE*)GlobalLock(hGlobal)) != NULL))
  465. {
  466. pFile->Read(pbData, cb);
  467. GlobalUnlock(hGlobal);
  468. }
  469. else
  470. {
  471. hr = E_OUTOFMEMORY;
  472. hGlobal = NULL;
  473. }
  474. // open an IStorage on the data and pass it to Load
  475. LPLOCKBYTES pLockBytes = NULL;
  476. if ((hGlobal != NULL) &&
  477. SUCCEEDED(hr = CreateILockBytesOnHGlobal(hGlobal, TRUE,
  478. &pLockBytes)))
  479. {
  480. ASSERT(pLockBytes != NULL);
  481. LPSTORAGE pStorage = NULL;
  482. if (SUCCEEDED(hr = StgOpenStorageOnILockBytes(pLockBytes, NULL,
  483. STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &pStorage)))
  484. {
  485. ASSERT(pStorage != NULL);
  486. hr = pPersStg->Load(pStorage);
  487. pStorage->Release();
  488. }
  489. pLockBytes->Release();
  490. }
  491. }
  492. else
  493. {
  494. hr = E_UNEXPECTED;
  495. }
  496. pPersStg->Release();
  497. if (FAILED(hr))
  498. {
  499. TRACE1("InitNew or Load on OLE control %ls failed.\n", wszClsid);
  500. TRACE1(">>> Result code: 0x%08lx\n", hr);
  501. goto CreateOrLoadFailed;
  502. }
  503. }
  504. else
  505. {
  506. TRACE1("Persistence not supported on OLE control %ls.\n", wszClsid);
  507. TRACE1(">>> Result code: 0x%08lx\n", hr);
  508. goto CreateOrLoadFailed;
  509. }
  510. if (!bQuickActivated)
  511. {
  512. // set client site last, if appropriate
  513. if (!(m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))
  514. {
  515. if (FAILED(hr = m_pObject->SetClientSite(&m_xOleClientSite)))
  516. {
  517. TRACE1("SetClientSite on OLE control %ls failed.\n", wszClsid);
  518. TRACE1(">>> Result code: 0x%08lx\n", hr);
  519. goto CreateOrLoadFailed;
  520. }
  521. }
  522. }
  523. CreateOrLoadFailed:
  524. if (FAILED(hr) && (m_pObject != NULL))
  525. {
  526. m_pObject->Close(OLECLOSE_NOSAVE);
  527. m_pObject->Release();
  528. m_pObject = NULL;
  529. }
  530. if (pPersMem != NULL)
  531. pPersMem->Release();
  532. if (bQuickActivated && SUCCEEDED(hr))
  533. hr = S_QUICKACTIVATED;
  534. return hr;
  535. }
  536. UINT COleControlSite::GetID()
  537. {
  538. return m_nID;
  539. }
  540. HRESULT COleControlSite::DoVerb(LONG nVerb, LPMSG lpMsg)
  541. {
  542. return m_pObject->DoVerb(nVerb, lpMsg, &m_xOleClientSite, 0,
  543. m_pCtrlCont->m_pWnd->m_hWnd, m_rect);
  544. }
  545. BOOL COleControlSite::IsDefaultButton()
  546. {
  547. return ((m_dwMiscStatus & OLEMISC_ACTSLIKEBUTTON) &&
  548. (m_dwStyle & BS_DEFPUSHBUTTON));
  549. }
  550. DWORD COleControlSite::GetDefBtnCode()
  551. {
  552. if (m_dwMiscStatus & OLEMISC_ACTSLIKEBUTTON)
  553. return (m_dwStyle & BS_DEFPUSHBUTTON) ?
  554. DLGC_DEFPUSHBUTTON :
  555. DLGC_UNDEFPUSHBUTTON;
  556. else
  557. return 0;
  558. }
  559. void COleControlSite::SetDefaultButton(BOOL bDefault)
  560. {
  561. if (!(m_dwMiscStatus & OLEMISC_ACTSLIKEBUTTON))
  562. return;
  563. if (((m_dwStyle & BS_DEFPUSHBUTTON) != 0) == bDefault)
  564. return;
  565. m_dwStyle ^= BS_DEFPUSHBUTTON;
  566. // Notify control that its "defaultness" has changed.
  567. LPOLECONTROL pOleCtl = NULL;
  568. if (SUCCEEDED(m_pObject->QueryInterface(IID_IOleControl,
  569. (LPVOID*)&pOleCtl)))
  570. {
  571. ASSERT(pOleCtl != NULL);
  572. pOleCtl->OnAmbientPropertyChange(DISPID_AMBIENT_DISPLAYASDEFAULT);
  573. pOleCtl->Release();
  574. }
  575. }
  576. DWORD COleControlSite::ConnectSink(REFIID iid, LPUNKNOWN punkSink)
  577. {
  578. ASSERT(m_pObject != NULL);
  579. LPCONNECTIONPOINTCONTAINER pConnPtCont;
  580. if ((m_pObject != NULL) &&
  581. SUCCEEDED(m_pObject->QueryInterface(IID_IConnectionPointContainer,
  582. (LPVOID*)&pConnPtCont)))
  583. {
  584. ASSERT(pConnPtCont != NULL);
  585. LPCONNECTIONPOINT pConnPt = NULL;
  586. DWORD dwCookie = 0;
  587. if (SUCCEEDED(pConnPtCont->FindConnectionPoint(iid, &pConnPt)))
  588. {
  589. ASSERT(pConnPt != NULL);
  590. pConnPt->Advise(punkSink, &dwCookie);
  591. pConnPt->Release();
  592. }
  593. pConnPtCont->Release();
  594. return dwCookie;
  595. }
  596. return 0;
  597. }
  598. void COleControlSite::DisconnectSink(REFIID iid, DWORD dwCookie)
  599. {
  600. if (dwCookie == 0 || m_pObject == NULL)
  601. return;
  602. LPCONNECTIONPOINTCONTAINER pConnPtCont;
  603. if (SUCCEEDED(m_pObject->QueryInterface(IID_IConnectionPointContainer,
  604. (LPVOID*)&pConnPtCont)))
  605. {
  606. ASSERT(pConnPtCont != NULL);
  607. LPCONNECTIONPOINT pConnPt = NULL;
  608. if (SUCCEEDED(pConnPtCont->FindConnectionPoint(iid, &pConnPt)))
  609. {
  610. ASSERT(pConnPt != NULL);
  611. pConnPt->Unadvise(dwCookie);
  612. pConnPt->Release();
  613. }
  614. pConnPtCont->Release();
  615. }
  616. }
  617. #define IMPLTYPE_MASK \
  618. (IMPLTYPEFLAG_FDEFAULT | IMPLTYPEFLAG_FSOURCE | IMPLTYPEFLAG_FRESTRICTED)
  619. #define IMPLTYPE_DEFAULTSOURCE \
  620. (IMPLTYPEFLAG_FDEFAULT | IMPLTYPEFLAG_FSOURCE)
  621. BOOL COleControlSite::GetEventIID(IID* piid)
  622. {
  623. *piid = GUID_NULL;
  624. ASSERT(m_pObject != NULL);
  625. // Use IProvideClassInfo2, if control supports it.
  626. LPPROVIDECLASSINFO2 pPCI2 = NULL;
  627. if (SUCCEEDED(m_pObject->QueryInterface(IID_IProvideClassInfo2,
  628. (LPVOID*)&pPCI2)))
  629. {
  630. ASSERT(pPCI2 != NULL);
  631. if (SUCCEEDED(pPCI2->GetGUID(GUIDKIND_DEFAULT_SOURCE_DISP_IID, piid)))
  632. ASSERT(!IsEqualIID(*piid, GUID_NULL));
  633. else
  634. ASSERT(IsEqualIID(*piid, GUID_NULL));
  635. pPCI2->Release();
  636. }
  637. // Fall back on IProvideClassInfo, if IProvideClassInfo2 not supported.
  638. LPPROVIDECLASSINFO pPCI = NULL;
  639. if (IsEqualIID(*piid, GUID_NULL) &&
  640. SUCCEEDED(m_pObject->QueryInterface(IID_IProvideClassInfo,
  641. (LPVOID*)&pPCI)))
  642. {
  643. ASSERT(pPCI != NULL);
  644. LPTYPEINFO pClassInfo = NULL;
  645. if (SUCCEEDED(pPCI->GetClassInfo(&pClassInfo)))
  646. {
  647. ASSERT(pClassInfo != NULL);
  648. LPTYPEATTR pClassAttr;
  649. if (SUCCEEDED(pClassInfo->GetTypeAttr(&pClassAttr)))
  650. {
  651. ASSERT(pClassAttr != NULL);
  652. ASSERT(pClassAttr->typekind == TKIND_COCLASS);
  653. // Search for typeinfo of the default events interface.
  654. int nFlags;
  655. HREFTYPE hRefType;
  656. for (unsigned int i = 0; i < pClassAttr->cImplTypes; i++)
  657. {
  658. if (SUCCEEDED(pClassInfo->GetImplTypeFlags(i, &nFlags)) &&
  659. ((nFlags & IMPLTYPE_MASK) == IMPLTYPE_DEFAULTSOURCE))
  660. {
  661. // Found it. Now look at its attributes to get IID.
  662. LPTYPEINFO pEventInfo = NULL;
  663. if (SUCCEEDED(pClassInfo->GetRefTypeOfImplType(i,
  664. &hRefType)) &&
  665. SUCCEEDED(pClassInfo->GetRefTypeInfo(hRefType,
  666. &pEventInfo)))
  667. {
  668. ASSERT(pEventInfo != NULL);
  669. LPTYPEATTR pEventAttr;
  670. if (SUCCEEDED(pEventInfo->GetTypeAttr(&pEventAttr)))
  671. {
  672. ASSERT(pEventAttr != NULL);
  673. *piid = pEventAttr->guid;
  674. pEventInfo->ReleaseTypeAttr(pEventAttr);
  675. }
  676. pEventInfo->Release();
  677. }
  678. break;
  679. }
  680. }
  681. pClassInfo->ReleaseTypeAttr(pClassAttr);
  682. }
  683. pClassInfo->Release();
  684. }
  685. pPCI->Release();
  686. }
  687. return (!IsEqualIID(*piid, GUID_NULL));
  688. }
  689. void COleControlSite::GetControlInfo()
  690. {
  691. memset(&m_ctlInfo, 0, sizeof(CONTROLINFO));
  692. m_ctlInfo.cb = sizeof(CONTROLINFO);
  693. LPOLECONTROL pOleCtl = NULL;
  694. if (SUCCEEDED(m_pObject->QueryInterface(IID_IOleControl,
  695. (LPVOID*)&pOleCtl)))
  696. {
  697. ASSERT(pOleCtl != NULL);
  698. pOleCtl->GetControlInfo(&m_ctlInfo);
  699. pOleCtl->Release();
  700. }
  701. }
  702. BOOL COleControlSite::IsMatchingMnemonic(LPMSG lpMsg)
  703. {
  704. // return IsAccelerator(m_ctlInfo.hAccel, m_ctlInfo.cAccel, lpMsg, NULL);
  705. if ((m_ctlInfo.cAccel == 0) || (m_ctlInfo.hAccel == NULL))
  706. return FALSE;
  707. ACCEL* pAccel = new ACCEL[m_ctlInfo.cAccel];
  708. int cAccel = CopyAcceleratorTable(m_ctlInfo.hAccel, pAccel, m_ctlInfo.cAccel);
  709. ASSERT(cAccel == m_ctlInfo.cAccel);
  710. BOOL bMatch = FALSE;
  711. for (int i = 0; i < cAccel; i++)
  712. {
  713. BOOL fVirt = (lpMsg->message == WM_SYSCHAR ? FALT : 0);
  714. WORD key = LOWORD(lpMsg->wParam);
  715. if (((pAccel[i].fVirt & ~FNOINVERT) == fVirt) &&
  716. (pAccel[i].key == key))
  717. {
  718. bMatch = TRUE;
  719. break;
  720. }
  721. }
  722. delete [] pAccel;
  723. return bMatch;
  724. }
  725. void COleControlSite::SendMnemonic(LPMSG lpMsg)
  726. {
  727. if (!(m_dwMiscStatus & OLEMISC_NOUIACTIVATE))
  728. SetFocus();
  729. LPOLECONTROL pOleCtl = NULL;
  730. if (SUCCEEDED(m_pObject->QueryInterface(IID_IOleControl,
  731. (LPVOID*)&pOleCtl)))
  732. {
  733. ASSERT(pOleCtl != NULL);
  734. pOleCtl->OnMnemonic(lpMsg);
  735. pOleCtl->Release();
  736. }
  737. }
  738. void COleControlSite::FreezeEvents(BOOL bFreeze)
  739. {
  740. LPOLECONTROL pOleCtl = NULL;
  741. if (SUCCEEDED(m_pObject->QueryInterface(IID_IOleControl,
  742. (LPVOID*)&pOleCtl)))
  743. {
  744. ASSERT(pOleCtl != NULL);
  745. pOleCtl->FreezeEvents(bFreeze);
  746. pOleCtl->Release();
  747. }
  748. }
  749. void COleControlSite::AttachWindow()
  750. {
  751. HWND hWnd = NULL;
  752. if (SUCCEEDED(m_pInPlaceObject->GetWindow(&hWnd)))
  753. {
  754. ASSERT(hWnd != NULL);
  755. if (m_hWnd != hWnd)
  756. {
  757. m_hWnd = hWnd;
  758. if (m_pWndCtrl != NULL)
  759. {
  760. ASSERT(m_pWndCtrl->m_hWnd == NULL); // Window already attached?
  761. m_pWndCtrl->Attach(m_hWnd);
  762. ASSERT(m_pWndCtrl->m_pCtrlSite == NULL ||
  763. m_pWndCtrl->m_pCtrlSite == this);
  764. m_pWndCtrl->m_pCtrlSite = this;
  765. }
  766. }
  767. }
  768. }
  769. void COleControlSite::DetachWindow()
  770. {
  771. m_hWnd = NULL;
  772. if (m_pWndCtrl != NULL)
  773. {
  774. if (m_pWndCtrl->m_hWnd != NULL)
  775. {
  776. WNDPROC* lplpfn = m_pWndCtrl->GetSuperWndProcAddr();
  777. ASSERT(lplpfn != NULL);
  778. if (::IsWindow(m_pWndCtrl->m_hWnd) && *lplpfn != NULL)
  779. m_pWndCtrl->UnsubclassWindow();
  780. m_pWndCtrl->Detach();
  781. }
  782. m_pWndCtrl->m_pCtrlSite = NULL;
  783. }
  784. }
  785. BOOL COleControlSite::OnEvent(AFX_EVENT* pEvent)
  786. {
  787. // If this control has a proxy CWnd, look for a matching ON_*_REFLECT
  788. // entry for this event in its event map.
  789. if ((m_pWndCtrl != NULL) &&
  790. m_pWndCtrl->OnCmdMsg(m_nID, CN_EVENT, pEvent, NULL))
  791. {
  792. return TRUE;
  793. }
  794. // Proxy CWnd isn't interested, so pass the event along to the container.
  795. return m_pCtrlCont->m_pWnd->OnCmdMsg(m_nID, CN_EVENT, pEvent, NULL);
  796. }
  797. /////////////////////////////////////////////////////////////////////////////
  798. // invoke helpers
  799. void COleControlSite::InvokeHelperV(DISPID dwDispID, WORD wFlags,
  800. VARTYPE vtRet, void* pvRet, const BYTE* pbParamInfo, va_list argList)
  801. {
  802. if (m_dispDriver.m_lpDispatch == NULL)
  803. {
  804. // no dispatch pointer yet; find it now
  805. LPDISPATCH pDispatch;
  806. if ((m_pObject != NULL) &&
  807. SUCCEEDED(m_pObject->QueryInterface(IID_IDispatch,
  808. (LPVOID*)&pDispatch)))
  809. {
  810. ASSERT(pDispatch != NULL);
  811. m_dispDriver.AttachDispatch(pDispatch);
  812. }
  813. }
  814. if (m_dispDriver.m_lpDispatch == NULL)
  815. {
  816. // couldn't find dispatch pointer
  817. TRACE0("Warning: control has no IDispatch interface.");
  818. return;
  819. }
  820. // delegate call to m_dispDriver
  821. m_dispDriver.InvokeHelperV(dwDispID, wFlags, vtRet, pvRet, pbParamInfo,
  822. argList);
  823. }
  824. void COleControlSite::SetPropertyV(DISPID dwDispID, VARTYPE vtProp, va_list argList)
  825. {
  826. BYTE rgbParams[2];
  827. if (vtProp & VT_BYREF)
  828. {
  829. vtProp &= ~VT_BYREF;
  830. vtProp |= VT_MFCBYREF;
  831. }
  832. #if !defined(_UNICODE) && !defined(OLE2ANSI)
  833. if (vtProp == VT_BSTR)
  834. vtProp = VT_BSTRA;
  835. #endif
  836. WORD wFlags;
  837. if (vtProp & VT_MFCFORCEPUTREF)
  838. {
  839. wFlags = DISPATCH_PROPERTYPUTREF;
  840. vtProp &= ~VT_MFCFORCEPUTREF;
  841. }
  842. else
  843. {
  844. if (vtProp == VT_DISPATCH)
  845. wFlags = DISPATCH_PROPERTYPUTREF;
  846. else
  847. wFlags = DISPATCH_PROPERTYPUT;
  848. }
  849. rgbParams[0] = (BYTE)vtProp;
  850. rgbParams[1] = 0;
  851. InvokeHelperV(dwDispID, wFlags, VT_EMPTY, NULL, rgbParams, argList);
  852. }
  853. void AFX_CDECL COleControlSite::InvokeHelper(DISPID dwDispID, WORD wFlags, VARTYPE vtRet,
  854. void* pvRet, const BYTE* pbParamInfo, ...)
  855. {
  856. va_list argList;
  857. va_start(argList, pbParamInfo);
  858. InvokeHelperV(dwDispID, wFlags, vtRet, pvRet, pbParamInfo, argList);
  859. va_end(argList);
  860. }
  861. void COleControlSite::GetProperty(DISPID dwDispID, VARTYPE vtProp,
  862. void* pvProp) const
  863. {
  864. const_cast<COleControlSite*>(this)->InvokeHelper(dwDispID,
  865. DISPATCH_PROPERTYGET, vtProp, pvProp, NULL);
  866. }
  867. void AFX_CDECL COleControlSite::SetProperty(DISPID dwDispID, VARTYPE vtProp, ...)
  868. {
  869. va_list argList; // really only one arg, but...
  870. va_start(argList, vtProp);
  871. SetPropertyV(dwDispID, vtProp, argList);
  872. va_end(argList);
  873. }
  874. BOOL AFX_CDECL COleControlSite::SafeSetProperty(DISPID dwDispID, VARTYPE vtProp, ...)
  875. {
  876. va_list argList; // really only one arg, but...
  877. va_start(argList, vtProp);
  878. BOOL bSuccess;
  879. TRY
  880. {
  881. SetPropertyV(dwDispID, vtProp, argList);
  882. bSuccess = TRUE;
  883. }
  884. CATCH_ALL(e)
  885. {
  886. DELETE_EXCEPTION(e);
  887. bSuccess = FALSE;
  888. }
  889. END_CATCH_ALL
  890. va_end(argList);
  891. return bSuccess;
  892. }
  893. /////////////////////////////////////////////////////////////////////////////
  894. // special cases for CWnd functions
  895. DWORD COleControlSite::GetStyle() const
  896. {
  897. DWORD dwStyle = m_dwStyle |
  898. (::GetWindowLong(m_hWnd, GWL_STYLE) & WS_VISIBLE);
  899. TRY
  900. {
  901. BOOL bEnabled = TRUE;
  902. GetProperty(DISPID_ENABLED, VT_BOOL, &bEnabled);
  903. if (!bEnabled)
  904. dwStyle |= WS_DISABLED;
  905. }
  906. END_TRY
  907. TRY
  908. {
  909. short sBorderStyle = 0;
  910. GetProperty(DISPID_BORDERSTYLE, VT_I2, &sBorderStyle);
  911. if (sBorderStyle == 1)
  912. dwStyle |= WS_BORDER;
  913. }
  914. END_TRY
  915. return dwStyle;
  916. }
  917. DWORD COleControlSite::GetExStyle() const
  918. {
  919. DWORD dwExStyle = ::GetWindowLong(m_hWnd, GWL_EXSTYLE);
  920. TRY
  921. {
  922. short sAppearance = 0;
  923. GetProperty(DISPID_APPEARANCE, VT_I2, &sAppearance);
  924. if (sAppearance == 1)
  925. dwExStyle |= WS_EX_CLIENTEDGE;
  926. }
  927. END_TRY
  928. return dwExStyle;
  929. }
  930. BOOL COleControlSite::ModifyStyle(DWORD dwRemove, DWORD dwAdd, UINT nFlags)
  931. {
  932. m_dwStyle = ((m_dwStyle & ~dwRemove) | dwAdd) & m_dwStyleMask;
  933. // Enabled property
  934. if ((dwRemove & WS_DISABLED) || (dwAdd & WS_DISABLED))
  935. {
  936. if (SafeSetProperty(DISPID_ENABLED, VT_BOOL, (~dwAdd & WS_DISABLED)))
  937. {
  938. dwRemove &= ~WS_DISABLED;
  939. dwAdd &= ~WS_DISABLED;
  940. }
  941. }
  942. // BorderStyle property
  943. if ((dwRemove & WS_BORDER) || (dwAdd & WS_BORDER))
  944. {
  945. if (SafeSetProperty(DISPID_BORDERSTYLE, VT_I2, (dwAdd & WS_BORDER)))
  946. {
  947. dwRemove &= ~WS_BORDER;
  948. dwAdd &= ~WS_BORDER;
  949. }
  950. }
  951. return CWnd::ModifyStyle(m_hWnd, dwRemove, dwAdd, nFlags);
  952. }
  953. BOOL COleControlSite::ModifyStyleEx(DWORD dwRemove, DWORD dwAdd, UINT nFlags)
  954. {
  955. // BorderStyle property
  956. if ((dwRemove & WS_EX_CLIENTEDGE) || (dwAdd & WS_EX_CLIENTEDGE))
  957. {
  958. if (SafeSetProperty(DISPID_APPEARANCE, VT_I2, (dwAdd & WS_EX_CLIENTEDGE)))
  959. {
  960. dwRemove &= ~WS_EX_CLIENTEDGE;
  961. dwAdd &= ~WS_EX_CLIENTEDGE;
  962. }
  963. }
  964. return CWnd::ModifyStyleEx(m_hWnd, dwRemove, dwAdd, nFlags);
  965. }
  966. void COleControlSite::SetWindowText(LPCTSTR lpszString)
  967. {
  968. ASSERT(::IsWindow(m_hWnd));
  969. if (!SafeSetProperty(DISPID_CAPTION, VT_BSTR, lpszString))
  970. SafeSetProperty(DISPID_TEXT, VT_BSTR, lpszString);
  971. }
  972. void COleControlSite::GetWindowText(CString& str) const
  973. {
  974. ASSERT(::IsWindow(m_hWnd));
  975. TRY
  976. {
  977. GetProperty(DISPID_CAPTION, VT_BSTR, &str);
  978. }
  979. CATCH_ALL(e)
  980. {
  981. DELETE_EXCEPTION(e);
  982. TRY
  983. {
  984. GetProperty(DISPID_TEXT, VT_BSTR, &str);
  985. }
  986. END_TRY
  987. }
  988. END_CATCH_ALL
  989. }
  990. int COleControlSite::GetWindowText(LPTSTR lpszString, int nMaxCount) const
  991. {
  992. ASSERT(nMaxCount > 0);
  993. CString str;
  994. GetWindowText(str);
  995. lstrcpyn(lpszString, str, nMaxCount);
  996. return lstrlen(lpszString);
  997. }
  998. int COleControlSite::GetWindowTextLength() const
  999. {
  1000. CString str;
  1001. GetWindowText(str);
  1002. return str.GetLength();
  1003. }
  1004. int COleControlSite::GetDlgCtrlID() const
  1005. {
  1006. return (int)m_nID;
  1007. }
  1008. int COleControlSite::SetDlgCtrlID(int nID)
  1009. {
  1010. int nPrevID = (int)m_nID;
  1011. m_nID = (UINT)nID;
  1012. return nPrevID;
  1013. }
  1014. void COleControlSite::MoveWindow(int x, int y, int nWidth, int nHeight, BOOL)
  1015. {
  1016. ASSERT(m_pInPlaceObject != NULL);
  1017. ASSERT(m_pObject != NULL);
  1018. CRect rectOld(m_rect);
  1019. m_rect.SetRect(x, y, x + nWidth, y + nHeight);
  1020. if (SetExtent())
  1021. {
  1022. m_rect.SetRect(x, y, x + m_rect.Width(), y + m_rect.Height());
  1023. m_pInPlaceObject->SetObjectRects(m_rect, m_rect);
  1024. }
  1025. else
  1026. {
  1027. m_rect = rectOld;
  1028. }
  1029. }
  1030. BOOL COleControlSite::SetWindowPos(const CWnd* pWndInsertAfter, int x, int y, int cx,
  1031. int cy, UINT nFlags)
  1032. {
  1033. if (nFlags & SWP_HIDEWINDOW)
  1034. ShowWindow(SW_HIDE);
  1035. if ((nFlags & (SWP_NOMOVE|SWP_NOSIZE)) != (SWP_NOMOVE|SWP_NOSIZE))
  1036. {
  1037. int xNew;
  1038. int yNew;
  1039. if (nFlags & SWP_NOMOVE)
  1040. {
  1041. xNew = m_rect.left;
  1042. yNew = m_rect.top;
  1043. }
  1044. else
  1045. {
  1046. xNew = x;
  1047. yNew = y;
  1048. }
  1049. int cxNew;
  1050. int cyNew;
  1051. if (nFlags & SWP_NOSIZE)
  1052. {
  1053. cxNew = m_rect.Width();
  1054. cyNew = m_rect.Height();
  1055. }
  1056. else
  1057. {
  1058. cxNew = cx;
  1059. cyNew = cy;
  1060. }
  1061. MoveWindow(xNew, yNew, cxNew, cyNew, !(nFlags & SWP_NOREDRAW));
  1062. }
  1063. if (nFlags & SWP_SHOWWINDOW)
  1064. ShowWindow(SW_SHOW);
  1065. // we've handled hide, move, size, and show; let Windows do the rest
  1066. nFlags &= ~(SWP_HIDEWINDOW|SWP_SHOWWINDOW);
  1067. nFlags |= (SWP_NOMOVE|SWP_NOSIZE);
  1068. return ::SetWindowPos(m_hWnd, pWndInsertAfter->GetSafeHwnd(),
  1069. x, y, cx, cy, nFlags);
  1070. }
  1071. BOOL COleControlSite::ShowWindow(int nCmdShow)
  1072. {
  1073. BOOL bReturn = ::IsWindowVisible(m_hWnd);
  1074. int iVerb = 0;
  1075. switch (nCmdShow)
  1076. {
  1077. case SW_SHOW:
  1078. case SW_SHOWNORMAL:
  1079. case SW_SHOWNOACTIVATE:
  1080. iVerb = OLEIVERB_SHOW;
  1081. break;
  1082. case SW_HIDE:
  1083. iVerb = OLEIVERB_HIDE;
  1084. break;
  1085. }
  1086. if (iVerb != 0)
  1087. DoVerb(iVerb);
  1088. return bReturn;
  1089. }
  1090. BOOL COleControlSite::IsWindowEnabled() const
  1091. {
  1092. BOOL bEnabled = TRUE;
  1093. TRY
  1094. GetProperty(DISPID_ENABLED, VT_BOOL, &bEnabled);
  1095. END_TRY
  1096. return bEnabled;
  1097. }
  1098. BOOL COleControlSite::EnableWindow(BOOL bEnable)
  1099. {
  1100. BOOL bResult;
  1101. TRY
  1102. {
  1103. GetProperty(DISPID_ENABLED, VT_BOOL, &bResult);
  1104. SetProperty(DISPID_ENABLED, VT_BOOL, bEnable);
  1105. }
  1106. CATCH_ALL(e)
  1107. {
  1108. DELETE_EXCEPTION(e);
  1109. bResult = TRUE;
  1110. }
  1111. END_CATCH_ALL
  1112. return !bResult; // return TRUE if previously disabled
  1113. }
  1114. CWnd* COleControlSite::SetFocus()
  1115. {
  1116. if (m_dwMiscStatus & OLEMISC_NOUIACTIVATE)
  1117. return CWnd::FromHandle(::SetFocus(m_hWnd));
  1118. CWnd* pWndPrev = CWnd::GetFocus();
  1119. DoVerb(OLEIVERB_UIACTIVATE);
  1120. return pWndPrev;
  1121. }
  1122. void COleControlSite::EnableDSC()
  1123. {
  1124. if (m_pDataSourceControl == NULL)
  1125. {
  1126. m_pDataSourceControl = new CDataSourceControl(this);
  1127. m_pDataSourceControl->Initialize();
  1128. }
  1129. }
  1130. void COleControlSite::BindDefaultProperty(DISPID dwDispID, VARTYPE vtProp, LPCTSTR szFieldName, CWnd* pDSCWnd)
  1131. {
  1132. // Remove any previous binding
  1133. if (m_pDSCSite != NULL)
  1134. {
  1135. m_pDSCSite->m_pDataSourceControl->BindProp(this, FALSE);
  1136. m_pDSCSite->m_pDataSourceControl->BindColumns();
  1137. m_pDSCSite = NULL;
  1138. }
  1139. if (pDSCWnd != NULL)
  1140. {
  1141. ASSERT(pDSCWnd->m_pCtrlSite); // must be an OLE control
  1142. pDSCWnd->m_pCtrlSite->EnableDSC();
  1143. m_pDSCSite = pDSCWnd->m_pCtrlSite;
  1144. m_defdispid = dwDispID;
  1145. m_dwType = vtProp;
  1146. m_strDataField = szFieldName;
  1147. m_pDSCSite->m_pDataSourceControl->BindProp(this, TRUE);
  1148. if (m_pDSCSite != NULL)
  1149. m_pDSCSite->m_pDataSourceControl->BindColumns();
  1150. }
  1151. }
  1152. void COleControlSite::BindProperty(DISPID dwDispId, CWnd* pWndDSC)
  1153. {
  1154. ASSERT(pWndDSC == NULL || pWndDSC->m_pCtrlSite);
  1155. if (pWndDSC != NULL && dwDispId != DISPID_UNKNOWN)
  1156. {
  1157. m_pBindings = new CDataBoundProperty(m_pBindings, dwDispId, 0);
  1158. m_pBindings->m_pDSCSite = pWndDSC->m_pCtrlSite;
  1159. m_pBindings->m_pClientSite = this;
  1160. m_pBindings->m_pDSCSite->EnableDSC();
  1161. m_pBindings->m_pDSCSite->m_pDataSourceControl->BindProp(m_pBindings, TRUE);
  1162. }
  1163. else
  1164. {
  1165. // Try and locate the particular property to unbind
  1166. // if dwDispId == DISPID_UNKNOWN && pWndDSC == NULL it unbinds all properties
  1167. // if dwDispId == DISPID_UNKNOWN && pWndDSC != NULL it unbinds properties for that DSC
  1168. CDataBoundProperty *pCurrent = m_pBindings;
  1169. CDataBoundProperty* pPrev = NULL;
  1170. while (pCurrent != NULL)
  1171. {
  1172. CDataBoundProperty* pNext = pCurrent->GetNext();
  1173. if (dwDispId == DISPID_UNKNOWN || pCurrent->m_dispid == dwDispId)
  1174. {
  1175. if (pWndDSC == NULL || pWndDSC->m_pCtrlSite == pCurrent->m_pDSCSite)
  1176. {
  1177. if (pPrev != NULL)
  1178. pPrev->m_pNext = pNext;
  1179. else
  1180. m_pBindings = pNext;
  1181. if (pCurrent->m_pDSCSite != NULL && pCurrent->m_pDSCSite->m_pDataSourceControl != NULL)
  1182. pCurrent->m_pDSCSite->m_pDataSourceControl->BindProp(pCurrent, FALSE);
  1183. delete pCurrent;
  1184. }
  1185. }
  1186. if (pPrev != NULL)
  1187. pPrev = pPrev->GetNext();
  1188. pCurrent = pNext;
  1189. }
  1190. }
  1191. }
  1192. /////////////////////////////////////////////////////////////////////////////
  1193. // COleControlSite::XOleClientSite
  1194. STDMETHODIMP_(ULONG) COleControlSite::XOleClientSite::AddRef()
  1195. {
  1196. METHOD_PROLOGUE_EX_(COleControlSite, OleClientSite)
  1197. return (ULONG)pThis->InternalAddRef();
  1198. }
  1199. STDMETHODIMP_(ULONG) COleControlSite::XOleClientSite::Release()
  1200. {
  1201. METHOD_PROLOGUE_EX_(COleControlSite, OleClientSite)
  1202. return (ULONG)pThis->InternalRelease();
  1203. }
  1204. STDMETHODIMP COleControlSite::XOleClientSite::QueryInterface(
  1205. REFIID iid, LPVOID* ppvObj)
  1206. {
  1207. METHOD_PROLOGUE_EX_(COleControlSite, OleClientSite)
  1208. return (HRESULT)pThis->InternalQueryInterface(&iid, ppvObj);
  1209. }
  1210. STDMETHODIMP COleControlSite::XOleClientSite::SaveObject()
  1211. {
  1212. return E_NOTIMPL;
  1213. }
  1214. STDMETHODIMP COleControlSite::XOleClientSite::GetMoniker(DWORD, DWORD,
  1215. LPMONIKER*)
  1216. {
  1217. return E_NOTIMPL;
  1218. }
  1219. STDMETHODIMP COleControlSite::XOleClientSite::GetContainer(
  1220. LPOLECONTAINER* ppContainer)
  1221. {
  1222. METHOD_PROLOGUE_EX_(COleControlSite, OleClientSite)
  1223. return (HRESULT)pThis->m_pCtrlCont->InternalQueryInterface(
  1224. &IID_IOleContainer, (LPVOID*)ppContainer);
  1225. }
  1226. STDMETHODIMP COleControlSite::XOleClientSite::ShowObject()
  1227. {
  1228. METHOD_PROLOGUE_EX(COleControlSite, OleClientSite)
  1229. pThis->AttachWindow();
  1230. return S_OK;
  1231. }
  1232. STDMETHODIMP COleControlSite::XOleClientSite::OnShowWindow(BOOL)
  1233. {
  1234. return S_OK;
  1235. }
  1236. STDMETHODIMP COleControlSite::XOleClientSite::RequestNewObjectLayout()
  1237. {
  1238. return E_NOTIMPL;
  1239. }
  1240. /////////////////////////////////////////////////////////////////////////////
  1241. // COleControlSite::XOleIPSite
  1242. STDMETHODIMP_(ULONG) COleControlSite::XOleIPSite::AddRef()
  1243. {
  1244. METHOD_PROLOGUE_EX_(COleControlSite, OleIPSite)
  1245. return (ULONG)pThis->InternalAddRef();
  1246. }
  1247. STDMETHODIMP_(ULONG) COleControlSite::XOleIPSite::Release()
  1248. {
  1249. METHOD_PROLOGUE_EX_(COleControlSite, OleIPSite)
  1250. return (ULONG)pThis->InternalRelease();
  1251. }
  1252. STDMETHODIMP COleControlSite::XOleIPSite::QueryInterface(
  1253. REFIID iid, LPVOID* ppvObj)
  1254. {
  1255. METHOD_PROLOGUE_EX_(COleControlSite, OleIPSite)
  1256. return (HRESULT)pThis->InternalQueryInterface(&iid, ppvObj);
  1257. }
  1258. STDMETHODIMP COleControlSite::XOleIPSite::GetWindow(HWND* phWnd)
  1259. {
  1260. METHOD_PROLOGUE_EX_(COleControlSite, OleIPSite)
  1261. *phWnd = pThis->m_pCtrlCont->m_pWnd->GetSafeHwnd();
  1262. return *phWnd != NULL ? S_OK : E_FAIL;
  1263. }
  1264. STDMETHODIMP COleControlSite::XOleIPSite::ContextSensitiveHelp(BOOL)
  1265. {
  1266. return E_NOTIMPL;
  1267. }
  1268. STDMETHODIMP COleControlSite::XOleIPSite::CanInPlaceActivate()
  1269. {
  1270. return S_OK;
  1271. }
  1272. STDMETHODIMP COleControlSite::XOleIPSite::OnInPlaceActivate()
  1273. {
  1274. return S_OK;
  1275. }
  1276. STDMETHODIMP COleControlSite::XOleIPSite::OnUIActivate()
  1277. {
  1278. METHOD_PROLOGUE_EX_(COleControlSite, OleIPSite)
  1279. pThis->m_pCtrlCont->OnUIActivate(pThis);
  1280. return S_OK;
  1281. }
  1282. STDMETHODIMP COleControlSite::XOleIPSite::GetWindowContext(
  1283. LPOLEINPLACEFRAME* ppFrame, LPOLEINPLACEUIWINDOW* ppDoc, LPRECT prectPos,
  1284. LPRECT prectClip, LPOLEINPLACEFRAMEINFO pFrameInfo)
  1285. {
  1286. METHOD_PROLOGUE_EX(COleControlSite, OleIPSite)
  1287. ASSERT_VALID(pThis->m_pCtrlCont);
  1288. ASSERT_VALID(pThis->m_pCtrlCont->m_pWnd);
  1289. ASSERT(AfxIsValidAddress(ppFrame, sizeof(LPOLEINPLACEFRAME)));
  1290. ASSERT((ppDoc == NULL) ||
  1291. AfxIsValidAddress(ppDoc, sizeof(LPOLEINPLACEUIWINDOW)));
  1292. ASSERT(AfxIsValidAddress(prectPos, sizeof(RECT)));
  1293. ASSERT(AfxIsValidAddress(prectClip, sizeof(RECT)));
  1294. ASSERT(AfxIsValidAddress(pFrameInfo, pFrameInfo->cb));
  1295. //WINBUG: This is a temporary patch for IE3 beta. When IE3 is fixed, this
  1296. // assert can be re-enabled. Otherwise it fires everytime you browse via
  1297. // the CWebBrowser control.
  1298. //
  1299. // ASSERT(pFrameInfo->cb >= offsetof(OLEINPLACEFRAMEINFO, cAccelEntries) +
  1300. // sizeof(int));
  1301. // There is no separate doc window
  1302. if (ppDoc != NULL)
  1303. *ppDoc = NULL;
  1304. // Set pointer to frame
  1305. if (FAILED(pThis->m_pCtrlCont->InternalQueryInterface(
  1306. &IID_IOleInPlaceFrame, (LPVOID*)ppFrame)))
  1307. return E_FAIL;
  1308. // Fill in position and clip rectangles
  1309. CWnd* pWndContainer = pThis->m_pCtrlCont->m_pWnd;
  1310. CopyRect(prectPos, pThis->m_rect);
  1311. pWndContainer->GetClientRect(prectClip);
  1312. // Fill in frame info
  1313. pFrameInfo->fMDIApp = FALSE;
  1314. pFrameInfo->hwndFrame = pWndContainer->GetSafeHwnd();
  1315. pFrameInfo->haccel = NULL;
  1316. pFrameInfo->cAccelEntries = 0;
  1317. return S_OK;
  1318. }
  1319. STDMETHODIMP COleControlSite::XOleIPSite::Scroll(SIZE)
  1320. {
  1321. return S_FALSE;
  1322. }
  1323. STDMETHODIMP COleControlSite::XOleIPSite::OnUIDeactivate(BOOL)
  1324. {
  1325. METHOD_PROLOGUE_EX_(COleControlSite, OleIPSite)
  1326. pThis->m_pCtrlCont->OnUIDeactivate(pThis);
  1327. return S_OK;
  1328. }
  1329. STDMETHODIMP COleControlSite::XOleIPSite::OnInPlaceDeactivate()
  1330. {
  1331. METHOD_PROLOGUE_EX(COleControlSite, OleIPSite)
  1332. pThis->DetachWindow();
  1333. return S_OK;
  1334. }
  1335. STDMETHODIMP COleControlSite::XOleIPSite::DiscardUndoState()
  1336. {
  1337. return S_OK;
  1338. }
  1339. STDMETHODIMP COleControlSite::XOleIPSite::DeactivateAndUndo()
  1340. {
  1341. METHOD_PROLOGUE_EX_(COleControlSite, OleIPSite)
  1342. pThis->m_pInPlaceObject->UIDeactivate();
  1343. return S_OK;
  1344. }
  1345. STDMETHODIMP COleControlSite::XOleIPSite::OnPosRectChange(LPCRECT lprcPosRect)
  1346. {
  1347. METHOD_PROLOGUE_EX_(COleControlSite, OleIPSite)
  1348. CRect rectClip;
  1349. pThis->m_pCtrlCont->m_pWnd->GetClientRect(rectClip);
  1350. pThis->m_rect = lprcPosRect;
  1351. return pThis->m_pInPlaceObject->SetObjectRects(pThis->m_rect, rectClip);
  1352. }
  1353. /////////////////////////////////////////////////////////////////////////////
  1354. // COleControlSite::XOleControlSite
  1355. STDMETHODIMP_(ULONG) COleControlSite::XOleControlSite::AddRef()
  1356. {
  1357. METHOD_PROLOGUE_EX_(COleControlSite, OleControlSite)
  1358. return (ULONG)pThis->InternalAddRef();
  1359. }
  1360. STDMETHODIMP_(ULONG) COleControlSite::XOleControlSite::Release()
  1361. {
  1362. METHOD_PROLOGUE_EX_(COleControlSite, OleControlSite)
  1363. return (ULONG)pThis->InternalRelease();
  1364. }
  1365. STDMETHODIMP COleControlSite::XOleControlSite::QueryInterface(
  1366. REFIID iid, LPVOID* ppvObj)
  1367. {
  1368. METHOD_PROLOGUE_EX_(COleControlSite, OleControlSite)
  1369. return (HRESULT)pThis->InternalQueryInterface(&iid, ppvObj);
  1370. }
  1371. STDMETHODIMP COleControlSite::XOleControlSite::OnControlInfoChanged()
  1372. {
  1373. METHOD_PROLOGUE_EX_(COleControlSite, OleControlSite)
  1374. pThis->GetControlInfo();
  1375. return NOERROR;
  1376. }
  1377. STDMETHODIMP COleControlSite::XOleControlSite::LockInPlaceActive(BOOL)
  1378. {
  1379. return E_NOTIMPL;
  1380. }
  1381. STDMETHODIMP COleControlSite::XOleControlSite::GetExtendedControl(
  1382. LPDISPATCH*)
  1383. {
  1384. return E_NOTIMPL;
  1385. }
  1386. STDMETHODIMP COleControlSite::XOleControlSite::TransformCoords(
  1387. POINTL* pptHimetric, POINTF* pptContainer, DWORD dwFlags)
  1388. {
  1389. METHOD_PROLOGUE_EX_(COleControlSite, OleControlSite)
  1390. HRESULT hr = NOERROR;
  1391. HDC hDC = ::GetDC(pThis->m_hWnd);
  1392. ::SetMapMode(hDC, MM_HIMETRIC);
  1393. POINT rgptConvert[2];
  1394. rgptConvert[0].x = 0;
  1395. rgptConvert[0].y = 0;
  1396. if (dwFlags & XFORMCOORDS_HIMETRICTOCONTAINER)
  1397. {
  1398. rgptConvert[1].x = pptHimetric->x;
  1399. rgptConvert[1].y = pptHimetric->y;
  1400. ::LPtoDP(hDC, rgptConvert, 2);
  1401. if (dwFlags & XFORMCOORDS_SIZE)
  1402. {
  1403. pptContainer->x = (float)(rgptConvert[1].x - rgptConvert[0].x);
  1404. pptContainer->y = (float)(rgptConvert[0].y - rgptConvert[1].y);
  1405. }
  1406. else if (dwFlags & XFORMCOORDS_POSITION)
  1407. {
  1408. pptContainer->x = (float)rgptConvert[1].x;
  1409. pptContainer->y = (float)rgptConvert[1].y;
  1410. }
  1411. else
  1412. {
  1413. hr = E_INVALIDARG;
  1414. }
  1415. }
  1416. else if (dwFlags & XFORMCOORDS_CONTAINERTOHIMETRIC)
  1417. {
  1418. rgptConvert[1].x = (int)(pptContainer->x);
  1419. rgptConvert[1].y = (int)(pptContainer->y);
  1420. ::DPtoLP(hDC, rgptConvert, 2);
  1421. if (dwFlags & XFORMCOORDS_SIZE)
  1422. {
  1423. pptHimetric->x = rgptConvert[1].x - rgptConvert[0].x;
  1424. pptHimetric->y = rgptConvert[0].y - rgptConvert[1].y;
  1425. }
  1426. else if (dwFlags & XFORMCOORDS_POSITION)
  1427. {
  1428. pptHimetric->x = rgptConvert[1].x;
  1429. pptHimetric->y = rgptConvert[1].y;
  1430. }
  1431. else
  1432. {
  1433. hr = E_INVALIDARG;
  1434. }
  1435. }
  1436. else
  1437. {
  1438. hr = E_INVALIDARG;
  1439. }
  1440. ::ReleaseDC(pThis->m_hWnd, hDC);
  1441. return hr;
  1442. }
  1443. STDMETHODIMP COleControlSite::XOleControlSite::TranslateAccelerator(
  1444. LPMSG, DWORD)
  1445. {
  1446. return E_NOTIMPL;
  1447. }
  1448. STDMETHODIMP COleControlSite::XOleControlSite::OnFocus(BOOL)
  1449. {
  1450. return S_OK;
  1451. }
  1452. STDMETHODIMP COleControlSite::XOleControlSite::ShowPropertyFrame()
  1453. {
  1454. return E_NOTIMPL;
  1455. }
  1456. /////////////////////////////////////////////////////////////////////////////
  1457. // COleControlSite::XAmbientProps
  1458. STDMETHODIMP_(ULONG) COleControlSite::XAmbientProps::AddRef()
  1459. {
  1460. METHOD_PROLOGUE_EX_(COleControlSite, AmbientProps)
  1461. return (ULONG)pThis->InternalAddRef();
  1462. }
  1463. STDMETHODIMP_(ULONG) COleControlSite::XAmbientProps::Release()
  1464. {
  1465. METHOD_PROLOGUE_EX_(COleControlSite, AmbientProps)
  1466. return (ULONG)pThis->InternalRelease();
  1467. }
  1468. STDMETHODIMP COleControlSite::XAmbientProps::QueryInterface(
  1469. REFIID iid, LPVOID* ppvObj)
  1470. {
  1471. METHOD_PROLOGUE_EX_(COleControlSite, AmbientProps)
  1472. return (HRESULT)pThis->InternalQueryInterface(&iid, ppvObj);
  1473. }
  1474. STDMETHODIMP COleControlSite::XAmbientProps::GetTypeInfoCount(
  1475. unsigned int*)
  1476. {
  1477. return E_NOTIMPL;
  1478. }
  1479. STDMETHODIMP COleControlSite::XAmbientProps::GetTypeInfo(
  1480. unsigned int, LCID, ITypeInfo**)
  1481. {
  1482. return E_NOTIMPL;
  1483. }
  1484. STDMETHODIMP COleControlSite::XAmbientProps::GetIDsOfNames(
  1485. REFIID, LPOLESTR*, unsigned int, LCID, DISPID*)
  1486. {
  1487. return E_NOTIMPL;
  1488. }
  1489. STDMETHODIMP COleControlSite::XAmbientProps::Invoke(
  1490. DISPID dispid, REFIID, LCID, unsigned short wFlags,
  1491. DISPPARAMS* pDispParams, VARIANT* pvarResult,
  1492. EXCEPINFO*, unsigned int*)
  1493. {
  1494. UNUSED(wFlags);
  1495. UNUSED(pDispParams);
  1496. METHOD_PROLOGUE_EX(COleControlSite, AmbientProps)
  1497. ASSERT(wFlags & DISPATCH_PROPERTYGET);
  1498. ASSERT(pDispParams->cArgs == 0);
  1499. ASSERT(pThis->m_pCtrlCont != NULL);
  1500. ASSERT(pThis->m_pCtrlCont->m_pWnd != NULL);
  1501. return pThis->m_pCtrlCont->m_pWnd->OnAmbientProperty(pThis, dispid, pvarResult) ?
  1502. S_OK : DISP_E_MEMBERNOTFOUND;
  1503. }
  1504. /////////////////////////////////////////////////////////////////////////////
  1505. // COleControlSite::XPropertyNotifySink
  1506. STDMETHODIMP COleControlSite::XPropertyNotifySink::QueryInterface(
  1507. REFIID iid, LPVOID* ppvObj)
  1508. {
  1509. METHOD_PROLOGUE_EX_(COleControlSite, PropertyNotifySink)
  1510. if (IsEqualIID(iid, IID_IUnknown) ||
  1511. IsEqualIID(iid, IID_IPropertyNotifySink))
  1512. {
  1513. *ppvObj = this;
  1514. AddRef();
  1515. return S_OK;
  1516. }
  1517. else
  1518. {
  1519. return E_NOINTERFACE;
  1520. }
  1521. }
  1522. STDMETHODIMP_(ULONG) COleControlSite::XPropertyNotifySink::AddRef()
  1523. {
  1524. return 1;
  1525. }
  1526. STDMETHODIMP_(ULONG) COleControlSite::XPropertyNotifySink::Release()
  1527. {
  1528. return 0;
  1529. }
  1530. STDMETHODIMP COleControlSite::XPropertyNotifySink::OnChanged(
  1531. DISPID dispid)
  1532. {
  1533. METHOD_PROLOGUE_EX(COleControlSite, PropertyNotifySink)
  1534. // If we are currently updating the control ignore notifications
  1535. if (pThis->m_bIgnoreNotify)
  1536. return S_OK;
  1537. // Give user chance to override
  1538. if (!pThis->m_pDataSourceControl)
  1539. {
  1540. AFX_EVENT event(AFX_EVENT::propChanged, dispid);
  1541. pThis->OnEvent(&event);
  1542. if (event.m_hResult != S_OK)
  1543. return event.m_hResult;
  1544. }
  1545. if (pThis->m_defdispid == dispid)
  1546. {
  1547. ::VariantClear(&pThis->m_varResult);
  1548. HRESULT hRes;
  1549. LPDISPATCH pDispatch = NULL;
  1550. hRes = pThis->m_pObject->QueryInterface(IID_IDispatch, (LPVOID *) &pDispatch);
  1551. if (FAILED(hRes))
  1552. return S_OK;
  1553. EXCEPINFO excepinfo;
  1554. memset(&excepinfo, 0, sizeof(EXCEPINFO));
  1555. UINT uArgErr;
  1556. DISPPARAMS dispparamsGetProp;
  1557. memset (&dispparamsGetProp, 0, sizeof(DISPPARAMS));
  1558. hRes = pDispatch->Invoke(dispid, IID_NULL, 0, INVOKE_PROPERTYGET, &dispparamsGetProp,
  1559. &pThis->m_varResult, &excepinfo, &uArgErr); //Get bound control property
  1560. if (excepinfo.bstrSource)
  1561. SysFreeString(excepinfo.bstrSource);
  1562. if (excepinfo.bstrDescription)
  1563. SysFreeString(excepinfo.bstrDescription);
  1564. if (excepinfo.bstrHelpFile)
  1565. SysFreeString(excepinfo.bstrHelpFile);
  1566. pDispatch->Release();
  1567. if (FAILED(hRes))
  1568. return S_OK;
  1569. pThis->m_bIsDirty = TRUE;
  1570. }
  1571. return S_OK;
  1572. }
  1573. STDMETHODIMP COleControlSite::XPropertyNotifySink::OnRequestEdit(
  1574. DISPID dispid)
  1575. {
  1576. METHOD_PROLOGUE_EX(COleControlSite, PropertyNotifySink)
  1577. // If we are currently updating the control ignore notifications
  1578. if (pThis->m_bIgnoreNotify)
  1579. return S_OK;
  1580. // If not bound fire regular MFC event
  1581. if (!pThis->m_pDataSourceControl)
  1582. {
  1583. AFX_EVENT event(AFX_EVENT::propRequest, dispid);
  1584. pThis->OnEvent(&event);
  1585. if (event.m_hResult != S_OK)
  1586. return event.m_hResult;
  1587. }
  1588. // Currently we only support Optimistic binding ala VB4
  1589. // In this model, requests always succeed
  1590. return S_OK;
  1591. }
  1592. /////////////////////////////////////////////////////////////////////////////
  1593. // COleControlSite::XEventSink
  1594. STDMETHODIMP_(ULONG) COleControlSite::XEventSink::AddRef()
  1595. {
  1596. return 1;
  1597. }
  1598. STDMETHODIMP_(ULONG) COleControlSite::XEventSink::Release()
  1599. {
  1600. return 0;
  1601. }
  1602. STDMETHODIMP COleControlSite::XEventSink::QueryInterface(
  1603. REFIID iid, LPVOID* ppvObj)
  1604. {
  1605. METHOD_PROLOGUE_EX_(COleControlSite, EventSink)
  1606. if (IsEqualIID(iid, IID_IUnknown) ||
  1607. IsEqualIID(iid, IID_IDispatch) ||
  1608. IsEqualIID(iid, pThis->m_iidEvents))
  1609. {
  1610. *ppvObj = this;
  1611. AddRef();
  1612. return S_OK;
  1613. }
  1614. else
  1615. {
  1616. return E_NOINTERFACE;
  1617. }
  1618. }
  1619. STDMETHODIMP COleControlSite::XEventSink::GetTypeInfoCount(
  1620. unsigned int*)
  1621. {
  1622. return E_NOTIMPL;
  1623. }
  1624. STDMETHODIMP COleControlSite::XEventSink::GetTypeInfo(
  1625. unsigned int, LCID, ITypeInfo**)
  1626. {
  1627. return E_NOTIMPL;
  1628. }
  1629. STDMETHODIMP COleControlSite::XEventSink::GetIDsOfNames(
  1630. REFIID, LPOLESTR*, unsigned int, LCID, DISPID*)
  1631. {
  1632. return E_NOTIMPL;
  1633. }
  1634. STDMETHODIMP COleControlSite::XEventSink::Invoke(
  1635. DISPID dispid, REFIID, LCID, unsigned short wFlags,
  1636. DISPPARAMS* pDispParams, VARIANT* pvarResult,
  1637. EXCEPINFO* pExcepInfo, unsigned int* puArgError)
  1638. {
  1639. UNUSED(wFlags);
  1640. METHOD_PROLOGUE_EX(COleControlSite, EventSink)
  1641. ASSERT(pThis->m_pCtrlCont != NULL);
  1642. ASSERT(pThis->m_pCtrlCont->m_pWnd != NULL);
  1643. ASSERT(wFlags == DISPATCH_METHOD);
  1644. AFX_EVENT event(AFX_EVENT::event, dispid, pDispParams, pExcepInfo,
  1645. puArgError);
  1646. pThis->OnEvent(&event);
  1647. if (pvarResult != NULL)
  1648. ::VariantClear(pvarResult);
  1649. return event.m_hResult;
  1650. }
  1651. /////////////////////////////////////////////////////////////////////////////
  1652. // CDataSourceControl
  1653. CDataSourceControl::CDataSourceControl(COleControlSite *pClientSite) :
  1654. m_pClientSite(pClientSite),
  1655. m_pCursorMove(NULL),
  1656. m_pCursorUpdateARow(NULL),
  1657. m_pMetaRowData(NULL),
  1658. m_pVarData(NULL),
  1659. m_nColumns(0),
  1660. m_nBindings(0),
  1661. m_pColumnBindings(NULL),
  1662. m_pValues(NULL),
  1663. m_bUpdateInProgress(FALSE),
  1664. m_pDataSource(NULL),
  1665. m_pRowPosition(NULL),
  1666. m_pRowset(NULL),
  1667. m_pDynamicAccessor(NULL),
  1668. m_dwRowsetNotify(0)
  1669. {
  1670. ASSERT(pClientSite);
  1671. }
  1672. CDataSourceControl::~CDataSourceControl()
  1673. {
  1674. // cancel ole/db notifications
  1675. if (m_dwRowsetNotify != 0 && m_pRowset != NULL)
  1676. {
  1677. LPCONNECTIONPOINTCONTAINER pConnPtCont;
  1678. if (SUCCEEDED(m_pRowset->m_spRowset->QueryInterface(IID_IConnectionPointContainer,
  1679. (LPVOID*)&pConnPtCont)))
  1680. {
  1681. ASSERT(pConnPtCont != NULL);
  1682. LPCONNECTIONPOINT pConnPt = NULL;
  1683. if (SUCCEEDED(pConnPtCont->FindConnectionPoint(IID_IRowsetNotify, &pConnPt)))
  1684. {
  1685. ASSERT(pConnPt != NULL);
  1686. pConnPt->Unadvise(m_dwRowsetNotify);
  1687. pConnPt->Release();
  1688. }
  1689. pConnPtCont->Release();
  1690. }
  1691. }
  1692. // Now go through all cursor bound properties
  1693. while (!m_CursorBoundProps.IsEmpty())
  1694. {
  1695. CDataBoundProperty* pProp = (CDataBoundProperty*) m_CursorBoundProps.GetHead();
  1696. pProp->m_pClientSite->BindProperty(pProp->m_dispid, NULL);
  1697. pProp->m_pClientSite->m_pDSCSite = NULL;
  1698. }
  1699. m_CursorBoundProps.RemoveAll();
  1700. if (m_pValues)
  1701. {
  1702. for (int i=0; i<m_nBindings; i++)
  1703. ::VariantClear(&m_pValues[i]);
  1704. if (m_nBindings)
  1705. {
  1706. delete[] m_pColumnBindings;
  1707. delete[] m_pValues;
  1708. }
  1709. }
  1710. if (m_pCursorMove)
  1711. m_pCursorMove->Release();
  1712. if (m_pCursorUpdateARow)
  1713. m_pCursorUpdateARow->Release();
  1714. if (m_pMetaRowData)
  1715. {
  1716. for (int nCol=0; nCol<m_nColumns; nCol++)
  1717. {
  1718. POSITION pos = m_pMetaRowData[nCol].m_pClientList->GetHeadPosition();
  1719. while (pos)
  1720. {
  1721. COleControlSite* pSite = (COleControlSite *)
  1722. m_pMetaRowData[nCol].m_pClientList->GetNext(pos);
  1723. pSite->m_pDSCSite = NULL;
  1724. }
  1725. m_pMetaRowData[nCol].m_pClientList->RemoveAll();
  1726. delete m_pMetaRowData[nCol].m_pClientList;
  1727. }
  1728. ::CoTaskMemFree(m_pMetaRowData);
  1729. }
  1730. if (m_pVarData)
  1731. ::CoTaskMemFree(m_pVarData);
  1732. if(m_pDynamicAccessor != NULL)
  1733. {
  1734. m_pDynamicAccessor->ReleaseAccessors(m_pRowset->m_spRowset);
  1735. m_pDynamicAccessor->Close();
  1736. }
  1737. delete m_pDynamicAccessor;
  1738. delete m_pRowset;
  1739. if (m_pRowPosition != NULL)
  1740. m_pRowPosition->Release();
  1741. if (m_pDataSource != NULL)
  1742. m_pDataSource->Release();
  1743. }
  1744. interface IVBDSC : public IUnknown
  1745. {
  1746. public:
  1747. virtual HRESULT STDMETHODCALLTYPE CancelUnload(BOOL __RPC_FAR* pfCancel) = 0;
  1748. virtual HRESULT STDMETHODCALLTYPE Error(DWORD dwErr, BOOL __RPC_FAR* pfShowError) = 0;
  1749. virtual HRESULT STDMETHODCALLTYPE CreateCursor(ICursor __RPC_FAR* __RPC_FAR* ppCursor) = 0;
  1750. };
  1751. const IID IID_IVBDSC = {0x1ab42240,0x8c70,0x11ce,{0x94,0x21,0x0,0xaa,0x0,0x62,0xbe,0x57}};
  1752. const IID CLSID_DataAdapter = {0x3A08E130L,0x8F65,0x11D0,{0x94,0x84,0x00,0xA0,0xC9,0x11,0x10,0xED}};
  1753. HRESULT CDataSourceControl::Initialize()
  1754. {
  1755. // The following is a work around for RDC behaviour when on an invisible dlg
  1756. // When the dlg is invisible it cannot display the ODBC connect dialog
  1757. // So check if visible, if not make it so and move it to the center
  1758. // of the screen with null size. Then do the connect dialog
  1759. // Finally put it all back like it was.
  1760. CWnd* pParent = m_pClientSite->m_pWndCtrl->GetTopLevelParent();
  1761. BOOL bHidden = !pParent->IsWindowVisible();
  1762. CRect rcParent;
  1763. if (bHidden)
  1764. {
  1765. CRect rcDesktop;
  1766. CWnd::GetDesktopWindow()->GetWindowRect(&rcDesktop);
  1767. pParent->GetWindowRect(&rcParent);
  1768. pParent->MoveWindow((rcDesktop.right - rcDesktop.left)/2, (rcDesktop.bottom - rcDesktop.top)/2, 0, 0, FALSE);
  1769. pParent->ShowWindow(SW_SHOWNORMAL);
  1770. }
  1771. IVBDSC* pDSC;
  1772. HRESULT hRes;
  1773. hRes = m_pClientSite->m_pObject->QueryInterface(IID_IDataSource, (void**)&m_pDataSource);
  1774. if (SUCCEEDED(hRes))
  1775. {
  1776. hRes = m_pDataSource->GetDataMember(NULL, &IID_IRowPosition, (IUnknown**)&m_pRowPosition);
  1777. if (m_pRowPosition == NULL)
  1778. hRes = E_POINTER;
  1779. if (FAILED(hRes))
  1780. {
  1781. if (bHidden)
  1782. {
  1783. pParent->MoveWindow(rcParent.left, rcParent.top, rcParent.right - rcParent.left, rcParent.bottom - rcParent.top, FALSE);
  1784. pParent->ShowWindow(SW_HIDE);
  1785. }
  1786. return hRes;
  1787. }
  1788. }
  1789. else
  1790. {
  1791. hRes = m_pClientSite->m_pObject->QueryInterface(IID_IVBDSC, (void**)&pDSC);
  1792. if (FAILED(hRes))
  1793. return hRes;
  1794. ICursor* pCursor;
  1795. pDSC->CreateCursor(&pCursor);
  1796. pDSC->Release();
  1797. if (!pCursor)
  1798. return E_FAIL;
  1799. hRes = pCursor->QueryInterface(IID_ICursorMove,
  1800. (LPVOID *)&m_pCursorMove);
  1801. pCursor->Release();
  1802. if (FAILED(hRes))
  1803. return hRes;
  1804. hRes = m_pCursorMove->QueryInterface(IID_ICursorUpdateARow,
  1805. (LPVOID *)&m_pCursorUpdateARow);
  1806. }
  1807. hRes = GetMetaData();
  1808. if (bHidden)
  1809. {
  1810. pParent->MoveWindow(rcParent.left, rcParent.top, rcParent.right - rcParent.left, rcParent.bottom - rcParent.top, FALSE);
  1811. pParent->ShowWindow(SW_HIDE);
  1812. }
  1813. return hRes;
  1814. }
  1815. IUnknown* CDataSourceControl::GetCursor()
  1816. {
  1817. ASSERT(m_pClientSite != NULL);
  1818. if (m_pDataSource != NULL)
  1819. {
  1820. if(m_pRowset != NULL)
  1821. return m_pDataSource;
  1822. return NULL;
  1823. }
  1824. ICursor* pCursor;
  1825. if (!m_pCursorMove)
  1826. {
  1827. IVBDSC* pDSC;
  1828. HRESULT hRes;
  1829. hRes = m_pClientSite->m_pObject->QueryInterface(IID_IVBDSC, (void**)&pDSC);
  1830. if (FAILED(hRes))
  1831. return NULL;
  1832. pDSC->CreateCursor(&pCursor);
  1833. pDSC->Release();
  1834. if (!pCursor)
  1835. return NULL;
  1836. return pCursor;
  1837. }
  1838. if (SUCCEEDED(m_pCursorMove->QueryInterface(IID_ICursor, (LPVOID *) &pCursor)))
  1839. return pCursor;
  1840. ASSERT(FALSE); // DSC Cursor Not Found
  1841. return NULL;
  1842. }
  1843. HRESULT CDataSourceControl::GetMetaData()
  1844. {
  1845. HRESULT hRes;
  1846. METAROWTYPE* pOldMetaData = m_pMetaRowData;
  1847. int nOldColumns = m_nColumns;
  1848. if (m_pDataSource != NULL)
  1849. {
  1850. IRowset* pRowset;
  1851. hRes = m_pRowPosition->GetRowset(IID_IRowset, reinterpret_cast<IUnknown**>(&pRowset));
  1852. if (FAILED(hRes))
  1853. return hRes;
  1854. {
  1855. LPCONNECTIONPOINTCONTAINER pConnPtCont;
  1856. if (SUCCEEDED(pRowset->QueryInterface(IID_IConnectionPointContainer,
  1857. (LPVOID*)&pConnPtCont)))
  1858. {
  1859. ASSERT(pConnPtCont != NULL);
  1860. LPCONNECTIONPOINT pConnPt = NULL;
  1861. if (SUCCEEDED(pConnPtCont->FindConnectionPoint(IID_IRowsetNotify, &pConnPt)))
  1862. {
  1863. ASSERT(pConnPt != NULL);
  1864. pConnPt->Advise(&m_pClientSite->m_xRowsetNotify, &m_dwRowsetNotify);
  1865. pConnPt->Release();
  1866. }
  1867. pConnPtCont->Release();
  1868. }
  1869. }
  1870. m_pRowset = new CRowset(pRowset);
  1871. pRowset->Release();
  1872. m_pRowset->SetupOptionalRowsetInterfaces();
  1873. m_pDynamicAccessor = new CDynamicAccessor;
  1874. m_pDynamicAccessor->BindColumns(m_pRowset->m_spRowset);
  1875. m_pRowset->SetAccessor(m_pDynamicAccessor);
  1876. m_nColumns = m_pDynamicAccessor->GetColumnCount();
  1877. m_pMetaRowData = (METAROWTYPE*)::CoTaskMemAlloc(sizeof(METAROWTYPE) * m_nColumns);
  1878. ASSERT(m_pMetaRowData);
  1879. memset(m_pMetaRowData, 0, sizeof(METAROWTYPE) * m_nColumns);
  1880. m_pRowset->MoveFirst();
  1881. m_pRowset->ReleaseRows();
  1882. }
  1883. else
  1884. {
  1885. ULONG nRows;
  1886. ICursor* pCursor = (LPCURSOR)m_pCursorMove;
  1887. ICursor* pColumnCursor;
  1888. if (pCursor == NULL)
  1889. return S_OK;
  1890. hRes = pCursor->GetColumnsCursor(IID_ICursor, (IUnknown **) &pColumnCursor, &nRows);
  1891. if (FAILED(hRes))
  1892. return hRes;
  1893. DBCOLUMNBINDING MetaColumns[2];
  1894. CopyColumnID(&MetaColumns[0].columnID, &COLUMN_COLUMNID);
  1895. MetaColumns[0].obData = offsetof(METAROWTYPE, idColumnID);
  1896. MetaColumns[0].cbMaxLen = DB_NOMAXLENGTH;
  1897. MetaColumns[0].obInfo = offsetof(METAROWTYPE, dwColumnID);
  1898. MetaColumns[0].obVarDataLen = DB_NOVALUE;
  1899. MetaColumns[0].dwBinding = DBBINDING_DEFAULT;
  1900. MetaColumns[0].dwDataType = DBTYPE_COLUMNID;
  1901. CopyColumnID(&MetaColumns[1].columnID, &COLUMN_NAME);
  1902. MetaColumns[1].obData = offsetof(METAROWTYPE, lpstrName);
  1903. MetaColumns[1].cbMaxLen = DB_NOMAXLENGTH;
  1904. MetaColumns[1].obInfo = offsetof(METAROWTYPE, dwName);
  1905. MetaColumns[1].obVarDataLen = DB_NOVALUE;
  1906. MetaColumns[1].dwBinding = DBBINDING_DEFAULT;
  1907. MetaColumns[1].dwDataType = VT_LPSTR;
  1908. hRes = pColumnCursor->SetBindings(2, MetaColumns, sizeof(METAROWTYPE),
  1909. DBCOLUMNBINDOPTS_REPLACE);
  1910. if (FAILED(hRes))
  1911. {
  1912. pColumnCursor->Release();
  1913. return hRes;
  1914. }
  1915. DBFETCHROWS FetchRows;
  1916. FetchRows.cRowsRequested = nRows;
  1917. FetchRows.dwFlags = DBROWFETCH_CALLEEALLOCATES;
  1918. FetchRows.pData = NULL;
  1919. FetchRows.pVarData = NULL;
  1920. FetchRows.cbVarData = 0;
  1921. LARGE_INTEGER dlZero;
  1922. LISet32(dlZero, 0);
  1923. hRes = pColumnCursor->GetNextRows(dlZero, &FetchRows);
  1924. if (FAILED(hRes))
  1925. {
  1926. pColumnCursor->Release();
  1927. return hRes;
  1928. }
  1929. m_pMetaRowData = (METAROWTYPE *)FetchRows.pData;
  1930. ASSERT(m_pMetaRowData);
  1931. nRows = FetchRows.cRowsReturned; // in case it changed
  1932. m_pVarData = FetchRows.pVarData;
  1933. m_nColumns = nRows;
  1934. pColumnCursor->Release();
  1935. }
  1936. for (int nCol=0; nCol<m_nColumns; nCol++)
  1937. m_pMetaRowData[nCol].m_pClientList = new CPtrList;
  1938. // re-establish all bound property sites and then delete old meta-data
  1939. if (pOldMetaData != NULL)
  1940. {
  1941. for (int nCol=0; nCol<nOldColumns; nCol++)
  1942. {
  1943. POSITION pos = pOldMetaData[nCol].m_pClientList->GetHeadPosition();
  1944. while (pos)
  1945. {
  1946. COleControlSite* pSite = (COleControlSite *)
  1947. m_pMetaRowData[nCol].m_pClientList->GetNext(pos);
  1948. BindProp(pSite, TRUE);
  1949. }
  1950. pOldMetaData[nCol].m_pClientList->RemoveAll();
  1951. delete pOldMetaData[nCol].m_pClientList;
  1952. }
  1953. ::CoTaskMemFree(pOldMetaData);
  1954. }
  1955. return hRes;
  1956. }
  1957. BOOL CDataSourceControl::CopyColumnID(
  1958. DBCOLUMNID* pcidDst, DBCOLUMNID const *pcidSrc)
  1959. {
  1960. pcidDst->dwKind = pcidSrc->dwKind;
  1961. switch (pcidSrc->dwKind)
  1962. {
  1963. case DBCOLKIND_GUID_NUMBER:
  1964. pcidDst->guid = pcidSrc->guid;
  1965. pcidDst->lNumber = pcidSrc->lNumber;
  1966. break;
  1967. case DBCOLKIND_GUID_NAME:
  1968. pcidDst->guid = pcidSrc->guid;
  1969. // fall through
  1970. case DBCOLKIND_NAME:
  1971. pcidDst->lpdbsz = (LPDBSTR) ::CoTaskMemAlloc(sizeof(DBCHAR) * (ldbstrlen(pcidSrc->lpdbsz) + 1));
  1972. if (!pcidDst->lpdbsz)
  1973. return FALSE;
  1974. ldbstrcpy(pcidDst->lpdbsz, pcidSrc->lpdbsz);
  1975. break;
  1976. }
  1977. return TRUE;
  1978. }
  1979. // Make a bound control/bound property a consumer to a particular column in this DSC
  1980. void CDataSourceControl::BindProp(COleControlSite* pClientSite, BOOL bBind)
  1981. {
  1982. ASSERT(pClientSite);
  1983. if (bBind)
  1984. {
  1985. BindProp(pClientSite, FALSE);
  1986. ASSERT(pClientSite->m_pDSCSite == m_pClientSite);
  1987. if (m_pDataSource != NULL)
  1988. {
  1989. for (int nCol=0; nCol<m_nColumns; nCol++)
  1990. {
  1991. if (pClientSite->m_strDataField ==
  1992. #ifdef __BORLANDC__ // MS Ambiguity error fix
  1993. CString(
  1994. #endif
  1995. m_pDynamicAccessor->GetColumnName(nCol + 1)
  1996. #ifdef __BORLANDC__
  1997. )
  1998. #endif
  1999. )
  2000. {
  2001. m_pMetaRowData[nCol].m_pClientList->AddTail(pClientSite);
  2002. return;
  2003. }
  2004. }
  2005. }
  2006. else
  2007. {
  2008. for (int nCol=0; nCol<m_nColumns; nCol++)
  2009. {
  2010. if (m_pMetaRowData[nCol].lpstrName == NULL)
  2011. continue;
  2012. if (pClientSite->m_strDataField == m_pMetaRowData[nCol].lpstrName)
  2013. {
  2014. m_pMetaRowData[nCol].m_pClientList->AddTail(pClientSite);
  2015. return;
  2016. }
  2017. }
  2018. }
  2019. pClientSite->m_pDSCSite = NULL;
  2020. return;
  2021. }
  2022. UpdateCursor();
  2023. // UnBind
  2024. for (int nCol=0; nCol<m_nColumns; nCol++)
  2025. {
  2026. POSITION pos = m_pMetaRowData[nCol].m_pClientList->GetHeadPosition();
  2027. POSITION prev;
  2028. while (pos)
  2029. {
  2030. prev = pos;
  2031. COleControlSite* pSite = (COleControlSite *)
  2032. m_pMetaRowData[nCol].m_pClientList->GetNext(pos);
  2033. if (pSite == pClientSite)
  2034. {
  2035. m_pMetaRowData[nCol].m_pClientList->RemoveAt(prev);
  2036. return;
  2037. }
  2038. }
  2039. }
  2040. }
  2041. // Make a cursor bound control property a client to this control
  2042. void CDataSourceControl::BindProp(CDataBoundProperty* pProperty, BOOL bBind)
  2043. {
  2044. ASSERT(pProperty);
  2045. if (bBind)
  2046. {
  2047. BindProp(pProperty, FALSE);
  2048. m_CursorBoundProps.AddTail(pProperty);
  2049. }
  2050. else
  2051. {
  2052. UpdateCursor();
  2053. POSITION pos = m_CursorBoundProps.Find(pProperty);
  2054. if (pos != NULL)
  2055. m_CursorBoundProps.RemoveAt(pos);
  2056. }
  2057. }
  2058. void CDataSourceControl::BindColumns()
  2059. {
  2060. if (m_pDataSource != NULL)
  2061. {
  2062. // this is done automatically by CDynamicAccessor
  2063. GetBoundClientRow();
  2064. UpdateControls();
  2065. return;
  2066. }
  2067. if (m_pValues)
  2068. {
  2069. for (int i=0; i<m_nBindings; i++)
  2070. ::VariantClear(&m_pValues[i]);
  2071. if (m_nBindings > 0)
  2072. {
  2073. delete[] m_pValues;
  2074. delete[] m_pColumnBindings;
  2075. }
  2076. m_pValues = NULL;
  2077. }
  2078. m_nBindings = 0;
  2079. for (int nCol=0; nCol<m_nColumns; nCol++)
  2080. {
  2081. m_nBindings += m_pMetaRowData[nCol].m_pClientList->GetCount();
  2082. }
  2083. if (m_nBindings > 0)
  2084. m_pColumnBindings = new DBCOLUMNBINDING[m_nBindings];
  2085. int nItem = 0;
  2086. for (nCol=0; nCol<m_nColumns; nCol++)
  2087. {
  2088. POSITION pos = m_pMetaRowData[nCol].m_pClientList->GetHeadPosition();
  2089. while (pos)
  2090. {
  2091. COleControlSite* pSite = (COleControlSite *)
  2092. m_pMetaRowData[nCol].m_pClientList->GetNext(pos);
  2093. CopyColumnID(&m_pColumnBindings[nItem].columnID, &m_pMetaRowData[nCol].idColumnID);
  2094. m_pColumnBindings[nItem].obData = sizeof(VARIANT) * nItem;
  2095. m_pColumnBindings[nItem].cbMaxLen = DB_NOMAXLENGTH;
  2096. m_pColumnBindings[nItem].obInfo = DB_NOVALUE;
  2097. m_pColumnBindings[nItem].obVarDataLen = DB_NOVALUE;
  2098. m_pColumnBindings[nItem].dwBinding = DBBINDING_VARIANT;
  2099. m_pColumnBindings[nItem].dwDataType = pSite->m_dwType;
  2100. nItem++;
  2101. }
  2102. }
  2103. m_pCursorMove->SetBindings(m_nBindings, m_pColumnBindings,
  2104. sizeof(VARIANT) * m_nBindings, DBCOLUMNBINDOPTS_REPLACE);
  2105. if (m_nBindings)
  2106. m_pValues = new VARIANT[m_nBindings];
  2107. for (int i=0; i<m_nBindings; i++)
  2108. {
  2109. memset(&m_pValues[i], 0, sizeof(VARIANT));
  2110. m_pValues[i].vt = VT_EMPTY;
  2111. }
  2112. GetBoundClientRow();
  2113. UpdateControls();
  2114. }
  2115. HRESULT CDataSourceControl::GetBoundClientRow()
  2116. {
  2117. DBFETCHROWS FetchRows;
  2118. if (m_pDataSource != NULL)
  2119. {
  2120. if(m_pRowset == NULL)
  2121. return S_OK;
  2122. if(m_pRowset->m_hRow == NULL)
  2123. return S_OK;
  2124. return m_pRowset->GetData();
  2125. }
  2126. if (m_nBindings == 0)
  2127. return S_OK;
  2128. FetchRows.pData = m_pValues;
  2129. FetchRows.pVarData = NULL;
  2130. FetchRows.cbVarData = NULL;
  2131. FetchRows.cRowsRequested = 1;
  2132. FetchRows.dwFlags = 0;
  2133. LARGE_INTEGER dl = { 0, 0};
  2134. return m_pCursorMove->Move(1, (LPVOID)&DBBMK_CURRENT, dl, &FetchRows);
  2135. }
  2136. COleVariant CDataSourceControl::ToVariant(int nCol)
  2137. {
  2138. ASSERT(m_pDataSource != NULL);
  2139. ASSERT(m_pDynamicAccessor != NULL);
  2140. COleVariant vt;
  2141. DBSTATUS dbStatus;
  2142. DBTYPE dbType;
  2143. m_pDynamicAccessor->GetStatus(nCol, &dbStatus);
  2144. if(dbStatus == DBSTATUS_S_ISNULL)
  2145. return vt; // just return a blank variant
  2146. if(!m_pDynamicAccessor->GetColumnType(nCol, &dbType))
  2147. return vt;
  2148. switch (dbType)
  2149. {
  2150. case DBTYPE_VARIANT:
  2151. vt = COleVariant((LPCVARIANT)m_pDynamicAccessor->GetValue(nCol));
  2152. break;
  2153. case DBTYPE_STR:
  2154. vt = COleVariant(CString((LPCSTR)m_pDynamicAccessor->GetValue(nCol)), VT_BSTR);
  2155. break;
  2156. case DBTYPE_WSTR:
  2157. case DBTYPE_BSTR:
  2158. vt = COleVariant(CString((LPCWSTR)m_pDynamicAccessor->GetValue(nCol)), VT_BSTR);
  2159. break;
  2160. case DBTYPE_I1:
  2161. case DBTYPE_UI1:
  2162. vt = COleVariant(*((BYTE*)m_pDynamicAccessor->GetValue(nCol)));
  2163. break;
  2164. case DBTYPE_I2:
  2165. case DBTYPE_UI2:
  2166. vt = COleVariant(*((short*)m_pDynamicAccessor->GetValue(nCol)));
  2167. break;
  2168. case DBTYPE_I4:
  2169. case DBTYPE_UI4:
  2170. vt = COleVariant(*((long*)m_pDynamicAccessor->GetValue(nCol)));
  2171. break;
  2172. case DBTYPE_R4:
  2173. vt = COleVariant(*((float*)m_pDynamicAccessor->GetValue(nCol)));
  2174. break;
  2175. case DBTYPE_R8:
  2176. vt = COleVariant(*((double*)m_pDynamicAccessor->GetValue(nCol)));
  2177. break;
  2178. case DBTYPE_BOOL:
  2179. vt = COleVariant((short)*(BOOL*)m_pDynamicAccessor->GetValue(nCol), VT_BOOL);
  2180. break;
  2181. case DBTYPE_DATE:
  2182. {
  2183. COleDateTime dt(*((DATE*)m_pDynamicAccessor->GetValue(nCol)));
  2184. vt = COleVariant(dt);
  2185. }
  2186. break;
  2187. case DBTYPE_CY:
  2188. {
  2189. COleCurrency cy(*((CURRENCY*)m_pDynamicAccessor->GetValue(nCol)));
  2190. vt = COleVariant(cy);
  2191. }
  2192. break;
  2193. case DBTYPE_NUMERIC:
  2194. {
  2195. DB_NUMERIC num;
  2196. if(m_pDynamicAccessor->GetValue(nCol, &num))
  2197. {
  2198. double dbl;
  2199. dbl = (double)*((__int64*)num.val);
  2200. while(num.scale-- > 0)
  2201. dbl /= 10;
  2202. if(num.sign == 0)
  2203. dbl = -dbl;
  2204. vt = COleVariant(dbl);
  2205. }
  2206. }
  2207. break;
  2208. case DBTYPE_DBDATE:
  2209. {
  2210. DBDATE dbDate;
  2211. if(m_pDynamicAccessor->GetValue(nCol, &dbDate))
  2212. {
  2213. COleDateTime dt;
  2214. dt.SetDate(dbDate.year, dbDate.month, dbDate.day);
  2215. vt = COleVariant(dt);
  2216. }
  2217. }
  2218. break;
  2219. case DBTYPE_DBTIME:
  2220. {
  2221. DBTIME dbTime;
  2222. if(m_pDynamicAccessor->GetValue(nCol, &dbTime))
  2223. {
  2224. COleDateTime dt;
  2225. dt.SetTime(dbTime.hour, dbTime.minute, dbTime.second);
  2226. vt = COleVariant(dt);
  2227. }
  2228. }
  2229. break;
  2230. case DBTYPE_DBTIMESTAMP:
  2231. {
  2232. DBTIMESTAMP dbTimeStamp;
  2233. if(m_pDynamicAccessor->GetValue(nCol, &dbTimeStamp))
  2234. {
  2235. vt = COleVariant(COleDateTime(dbTimeStamp.year, dbTimeStamp.month, dbTimeStamp.day,
  2236. dbTimeStamp.hour, dbTimeStamp.minute, dbTimeStamp.second));
  2237. }
  2238. }
  2239. break;
  2240. case DBTYPE_NULL:
  2241. case DBTYPE_EMPTY:
  2242. break;
  2243. default:
  2244. TRACE2("Unsupported DBTYPE (%d) in column %d\n", dbType, nCol);
  2245. break;
  2246. }
  2247. return vt;
  2248. }
  2249. HRESULT CDataSourceControl::UpdateControls()
  2250. {
  2251. m_bUpdateInProgress = TRUE;
  2252. int nItem = 0;
  2253. for (int nCol=0; nCol<m_nColumns; nCol++)
  2254. {
  2255. POSITION pos = m_pMetaRowData[nCol].m_pClientList->GetHeadPosition();
  2256. while (pos)
  2257. {
  2258. COleControlSite* pSite = (COleControlSite *)
  2259. m_pMetaRowData[nCol].m_pClientList->GetNext(pos);
  2260. DISPPARAMS dispparamsSetProp;
  2261. DISPID dispidNamed = DISPID_PROPERTYPUT;
  2262. EXCEPINFO excepinfo;
  2263. memset(&excepinfo, 0, sizeof(EXCEPINFO));
  2264. UINT uArgErr;
  2265. COleVariant vt;
  2266. if (m_pDataSource != NULL)
  2267. {
  2268. vt = ToVariant(nCol + 1);
  2269. dispparamsSetProp.rgvarg = &vt;
  2270. }
  2271. else
  2272. {
  2273. dispparamsSetProp.rgvarg = &m_pValues[nItem];
  2274. }
  2275. dispparamsSetProp.rgdispidNamedArgs = &dispidNamed;
  2276. dispparamsSetProp.cArgs = 1;
  2277. dispparamsSetProp.cNamedArgs = 1;
  2278. HRESULT hRes;
  2279. LPDISPATCH pDispatch;
  2280. pSite->m_bIgnoreNotify = TRUE;
  2281. if (pSite->m_pObject == NULL)
  2282. continue;
  2283. hRes = pSite->m_pObject->QueryInterface(IID_IDispatch, (LPVOID *) &pDispatch);
  2284. if (FAILED(hRes))
  2285. continue;
  2286. hRes = pDispatch->Invoke(pSite->m_defdispid, IID_NULL, 0, INVOKE_PROPERTYPUT, &dispparamsSetProp,
  2287. NULL, &excepinfo, &uArgErr); //Set the bound control property
  2288. pDispatch->Release();
  2289. pSite->m_bIgnoreNotify = FALSE;
  2290. if (excepinfo.bstrSource)
  2291. SysFreeString(excepinfo.bstrSource);
  2292. if (excepinfo.bstrDescription)
  2293. SysFreeString(excepinfo.bstrDescription);
  2294. if (excepinfo.bstrHelpFile)
  2295. SysFreeString(excepinfo.bstrHelpFile);
  2296. vt.Clear();
  2297. nItem++;
  2298. }
  2299. }
  2300. m_bUpdateInProgress = FALSE;
  2301. return S_OK;
  2302. }
  2303. HRESULT CDataSourceControl::UpdateCursor()
  2304. {
  2305. HRESULT hRes;
  2306. int nVariant = 0;
  2307. int nDirtyField = 0;
  2308. if (m_pDataSource != NULL)
  2309. {
  2310. if(m_pDynamicAccessor == NULL)
  2311. return S_OK;
  2312. // First go through all simple bound properties
  2313. for (int nCol=1; nCol<=m_nColumns; nCol++)
  2314. {
  2315. POSITION pos = m_pMetaRowData[nCol - 1].m_pClientList->GetHeadPosition();
  2316. while (pos)
  2317. {
  2318. COleControlSite* pSite = (COleControlSite *)
  2319. m_pMetaRowData[nCol - 1].m_pClientList->GetNext(pos);
  2320. DBTYPE dbType;
  2321. if (pSite->m_bIsDirty)
  2322. {
  2323. pSite->m_bIsDirty = FALSE;
  2324. nDirtyField++;
  2325. if (nDirtyField == 1)
  2326. {
  2327. // UpdateinProgress semaphore - unexpected state
  2328. ASSERT(!m_bUpdateInProgress);
  2329. m_bUpdateInProgress = TRUE;
  2330. }
  2331. COleVariant var(pSite->m_varResult);
  2332. CManualAccessor accessor;
  2333. // Create accessor for output column
  2334. accessor.CreateAccessor(1, m_pDynamicAccessor->GetValue(nCol), m_pDynamicAccessor->m_pColumnInfo[nCol].ulColumnSize);
  2335. accessor.AddBindEntry(m_pDynamicAccessor->m_pColumnInfo[nCol].iOrdinal,
  2336. m_pDynamicAccessor->m_pColumnInfo[nCol].wType,
  2337. m_pDynamicAccessor->m_pColumnInfo[nCol].ulColumnSize,
  2338. m_pDynamicAccessor->GetValue(nCol));
  2339. accessor.BindColumns(m_pRowset->m_spRowset);
  2340. VERIFY(m_pDynamicAccessor->GetColumnType(nCol, &dbType));
  2341. switch(dbType)
  2342. {
  2343. case DBTYPE_I2:
  2344. var.ChangeType(VT_I2);
  2345. m_pDynamicAccessor->SetValue(nCol, var.iVal);
  2346. break;
  2347. case DBTYPE_I4:
  2348. var.ChangeType(VT_I4);
  2349. m_pDynamicAccessor->SetValue(nCol, var.lVal);
  2350. break;
  2351. case DBTYPE_R4:
  2352. var.ChangeType(VT_R4);
  2353. m_pDynamicAccessor->SetValue(nCol, var.fltVal);
  2354. break;
  2355. case DBTYPE_R8:
  2356. var.ChangeType(VT_R8);
  2357. m_pDynamicAccessor->SetValue(nCol, var.dblVal);
  2358. break;
  2359. case DBTYPE_CY:
  2360. var.ChangeType(VT_CY);
  2361. *(CY*)m_pDynamicAccessor->GetValue(nCol) = var.cyVal;
  2362. break;
  2363. case DBTYPE_DATE:
  2364. var.ChangeType(VT_DATE);
  2365. m_pDynamicAccessor->SetValue(nCol, var.date);
  2366. break;
  2367. case DBTYPE_BSTR:
  2368. case DBTYPE_WSTR:
  2369. var.ChangeType(VT_BSTR);
  2370. wcsncpy((wchar_t*)m_pDynamicAccessor->GetValue(nCol), var.bstrVal, m_pDynamicAccessor->m_pColumnInfo[nCol].ulColumnSize);
  2371. break;
  2372. case DBTYPE_BOOL:
  2373. var.ChangeType(VT_BOOL);
  2374. m_pDynamicAccessor->SetValue(nCol, var.boolVal);
  2375. break;
  2376. case DBTYPE_DECIMAL:
  2377. var.ChangeType(VT_DECIMAL);
  2378. m_pDynamicAccessor->SetValue(nCol, var.decVal);
  2379. break;
  2380. case DBTYPE_UI1:
  2381. var.ChangeType(VT_UI1);
  2382. m_pDynamicAccessor->SetValue(nCol, var.bVal);
  2383. break;
  2384. case DBTYPE_I1:
  2385. var.ChangeType(VT_I1);
  2386. m_pDynamicAccessor->SetValue(nCol, (signed char)var.cVal);
  2387. break;
  2388. case DBTYPE_UI2:
  2389. var.ChangeType(VT_UI2);
  2390. m_pDynamicAccessor->SetValue(nCol, var.uiVal);
  2391. break;
  2392. case DBTYPE_UI4:
  2393. var.ChangeType(VT_UI4);
  2394. m_pDynamicAccessor->SetValue(nCol, var.ulVal);
  2395. break;
  2396. case DBTYPE_STR:
  2397. var.ChangeType(VT_BSTR);
  2398. WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, (char*)m_pDynamicAccessor->GetValue(nCol),
  2399. m_pDynamicAccessor->m_pColumnInfo[nCol].ulColumnSize, NULL, NULL);
  2400. break;
  2401. case DBTYPE_DBTIMESTAMP:
  2402. DBTIMESTAMP ts;
  2403. SYSTEMTIME sysTime;
  2404. var.ChangeType(VT_DATE);
  2405. memset(&ts, 0, sizeof(DBTIMESTAMP));
  2406. VariantTimeToSystemTime(var.date, &sysTime);
  2407. ts.year = sysTime.wYear;
  2408. ts.month = sysTime.wMonth;
  2409. ts.day = sysTime.wDay;
  2410. ts.hour = sysTime.wHour;
  2411. ts.minute = sysTime.wMinute;
  2412. ts.second = sysTime.wSecond;
  2413. ts.fraction = sysTime.wMilliseconds / 1000000;
  2414. m_pDynamicAccessor->SetValue(nCol, ts);
  2415. break;
  2416. default:
  2417. TRACE2("Unsupported DBTYPE (%d) in column %d\n", dbType, nCol);
  2418. break;
  2419. }
  2420. m_pRowset->SetAccessor(&accessor);
  2421. m_pRowset->SetData();
  2422. m_pRowset->SetAccessor(m_pDynamicAccessor);
  2423. ::VariantClear(&pSite->m_varResult);
  2424. }
  2425. nVariant++;
  2426. }
  2427. }
  2428. if (nDirtyField > 0)
  2429. {
  2430. m_bUpdateInProgress = FALSE;
  2431. }
  2432. return S_OK;
  2433. }
  2434. // Do we have an updateable cursor?
  2435. if (m_pCursorUpdateARow == NULL)
  2436. {
  2437. // If not attempt to get one
  2438. hRes = m_pCursorMove->QueryInterface(IID_ICursorUpdateARow,
  2439. (LPVOID *)&m_pCursorUpdateARow);
  2440. if (FAILED(hRes))
  2441. return S_OK; // no update cursor, so forget updating
  2442. }
  2443. // First go through all simple bound properties
  2444. for (int nCol=0; nCol<m_nColumns; nCol++)
  2445. {
  2446. POSITION pos = m_pMetaRowData[nCol].m_pClientList->GetHeadPosition();
  2447. while (pos)
  2448. {
  2449. COleControlSite* pSite = (COleControlSite *)
  2450. m_pMetaRowData[nCol].m_pClientList->GetNext(pos);
  2451. if (pSite->m_bIsDirty)
  2452. {
  2453. pSite->m_bIsDirty = FALSE;
  2454. nDirtyField++;
  2455. if (nDirtyField == 1)
  2456. {
  2457. DWORD dwEdit;
  2458. hRes = m_pCursorUpdateARow->GetEditMode(&dwEdit);
  2459. if (FAILED(hRes))
  2460. return hRes;
  2461. if (dwEdit == DBEDITMODE_NONE)
  2462. {
  2463. hRes = m_pCursorUpdateARow->BeginUpdate(DBROWACTION_UPDATE);
  2464. if (FAILED(hRes))
  2465. return hRes;
  2466. }
  2467. // UpdateinProgress semaphore - unexpected state
  2468. ASSERT(!m_bUpdateInProgress);
  2469. m_bUpdateInProgress = TRUE;
  2470. }
  2471. DBBINDPARAMS bpBindParams;
  2472. DWORD dwIndicator = sizeof(VARIANT);
  2473. COleVariant vt;
  2474. switch (V_VT(&pSite->m_varResult))
  2475. {
  2476. case VT_EMPTY:
  2477. case VT_NULL:
  2478. case VT_ERROR:
  2479. dwIndicator = DB_NULL;
  2480. vt = pSite->m_varResult;
  2481. break;
  2482. case VT_BSTR:
  2483. if(*pSite->m_varResult.bstrVal == 0)
  2484. {
  2485. dwIndicator = DB_NULL;
  2486. break;
  2487. }
  2488. default:
  2489. vt = pSite->m_varResult;
  2490. break;
  2491. }
  2492. bpBindParams.cbMaxLen = 0L;
  2493. bpBindParams.dwBinding = DBBINDING_VARIANT;
  2494. bpBindParams.dwDataType = m_pColumnBindings[nVariant].dwDataType;
  2495. bpBindParams.cbVarDataLen = 0L;
  2496. bpBindParams.dwInfo = dwIndicator;
  2497. bpBindParams.pData = &vt;
  2498. hRes = m_pCursorUpdateARow->SetColumn(&m_pColumnBindings[nVariant].columnID, &bpBindParams);
  2499. ::VariantClear(&pSite->m_varResult);
  2500. }
  2501. nVariant++;
  2502. }
  2503. }
  2504. // Now go through all cursor bound properties
  2505. POSITION pos = m_CursorBoundProps.GetHeadPosition();
  2506. while (pos != NULL)
  2507. {
  2508. CDataBoundProperty* pProp = (CDataBoundProperty*) m_CursorBoundProps.GetNext(pos);
  2509. if (pProp->m_pClientSite->m_pObject == NULL)
  2510. continue;
  2511. IBoundObject *pBO;
  2512. if (SUCCEEDED(pProp->m_pClientSite->m_pObject->QueryInterface(IID_IBoundObject,
  2513. (LPVOID *) &pBO)))
  2514. {
  2515. if (pBO->IsDirty(pProp->m_dispid) == S_OK)
  2516. {
  2517. nDirtyField++;
  2518. if (nDirtyField == 1)
  2519. {
  2520. DWORD dwEdit;
  2521. hRes = m_pCursorUpdateARow->GetEditMode(&dwEdit);
  2522. if (FAILED(hRes))
  2523. return hRes;
  2524. if (dwEdit == DBEDITMODE_NONE)
  2525. {
  2526. hRes = m_pCursorUpdateARow->BeginUpdate(DBROWACTION_UPDATE);
  2527. if (FAILED(hRes))
  2528. return hRes;
  2529. }
  2530. // UpdateinProgress semaphore - unexpected state
  2531. ASSERT(!m_bUpdateInProgress);
  2532. m_bUpdateInProgress = TRUE;
  2533. }
  2534. }
  2535. pBO->Release();
  2536. }
  2537. }
  2538. if (nDirtyField > 0)
  2539. {
  2540. hRes = m_pCursorUpdateARow->Update(0,0,0);
  2541. m_bUpdateInProgress = FALSE;
  2542. if (FAILED(hRes))
  2543. {
  2544. // Update failed w/dirty controls
  2545. ASSERT(hRes!= S_OK);
  2546. UpdateControls();
  2547. return hRes;
  2548. }
  2549. }
  2550. return S_OK;
  2551. }
  2552. /////////////////////////////////////////////////////////////////////////////
  2553. // CDataBoundProperty Handles Databound Controls
  2554. CDataBoundProperty::CDataBoundProperty(CDataBoundProperty* pLast, DISPID dispid, WORD ctlid) :
  2555. m_dispid(dispid),
  2556. m_ctlid(ctlid),
  2557. m_pClientSite(NULL),
  2558. m_pDSCSite(NULL),
  2559. m_bIsDirty(FALSE),
  2560. m_pNext(pLast)
  2561. {
  2562. }
  2563. void CDataBoundProperty::SetClientSite(COleControlSite *pClientSite)
  2564. {
  2565. m_pClientSite = pClientSite;
  2566. }
  2567. // (Re)bind a cursor bound property to a DSC
  2568. void CDataBoundProperty::SetDSCSite(COleControlSite *pDSCSite)
  2569. {
  2570. if (m_pDSCSite == pDSCSite)
  2571. return;
  2572. m_pDSCSite = pDSCSite;
  2573. Notify();
  2574. }
  2575. CDataBoundProperty* CDataBoundProperty::GetNext()
  2576. {
  2577. return m_pNext;
  2578. }
  2579. void CDataBoundProperty::RemoveSource()
  2580. {
  2581. m_pDSCSite = NULL;
  2582. Notify();
  2583. }
  2584. void CDataBoundProperty::Notify()
  2585. {
  2586. if (m_dispid != DISPID_DATASOURCE)
  2587. {
  2588. IBoundObject *pBO;
  2589. if (m_pClientSite != NULL)
  2590. {
  2591. if (SUCCEEDED(m_pClientSite->m_pObject->QueryInterface(IID_IBoundObject,
  2592. (LPVOID *) &pBO)))
  2593. {
  2594. pBO->OnSourceChanged(m_dispid, m_pDSCSite != NULL, &m_bOwnXferOut);
  2595. pBO->Release();
  2596. }
  2597. else
  2598. {
  2599. IUnknown* pUnk = GetCursor();
  2600. if (pUnk != NULL)
  2601. {
  2602. VARTYPE vt = VT_UNKNOWN;
  2603. if (m_pDSCSite->m_pDataSourceControl != NULL)
  2604. vt |= VT_MFCFORCEPUTREF;
  2605. m_pClientSite->SetProperty(m_dispid, vt, pUnk);
  2606. }
  2607. }
  2608. }
  2609. }
  2610. }
  2611. IUnknown* CDataBoundProperty::GetCursor()
  2612. {
  2613. if(m_pDSCSite == NULL)
  2614. return NULL;
  2615. m_pDSCSite->EnableDSC();
  2616. ASSERT(m_pDSCSite->m_pDataSourceControl);
  2617. m_pDSCSite->m_pDataSourceControl->BindProp(this);
  2618. return m_pDSCSite->m_pDataSourceControl->GetCursor();
  2619. }
  2620. /////////////////////////////////////////////////////////////////////////////
  2621. // COleControlSite::XBoundObjectSite
  2622. HRESULT COleControlSite::GetCursor(
  2623. DISPID dispid, LPUNKNOWN* ppcursorOut, LPVOID *ppcidOut)
  2624. {
  2625. if (ppcidOut != NULL)
  2626. *ppcidOut = NULL;
  2627. CDataBoundProperty* pBinding = m_pBindings;
  2628. while (pBinding != NULL)
  2629. {
  2630. if (pBinding->m_dispid == dispid)
  2631. {
  2632. *ppcursorOut = pBinding->GetCursor();
  2633. return S_OK;
  2634. }
  2635. pBinding = pBinding->GetNext();
  2636. }
  2637. return S_OK;
  2638. }
  2639. STDMETHODIMP_(ULONG) COleControlSite::XBoundObjectSite::AddRef()
  2640. {
  2641. METHOD_PROLOGUE_EX(COleControlSite, BoundObjectSite)
  2642. return (ULONG)pThis->ExternalAddRef();
  2643. }
  2644. STDMETHODIMP_(ULONG) COleControlSite::XBoundObjectSite::Release()
  2645. {
  2646. METHOD_PROLOGUE_EX(COleControlSite, BoundObjectSite)
  2647. return (ULONG)pThis->ExternalRelease();
  2648. }
  2649. STDMETHODIMP COleControlSite::XBoundObjectSite::QueryInterface(
  2650. REFIID iid, LPVOID far * ppvObj)
  2651. {
  2652. METHOD_PROLOGUE_EX(COleControlSite, BoundObjectSite)
  2653. return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
  2654. }
  2655. STDMETHODIMP COleControlSite::XBoundObjectSite::GetCursor(
  2656. DISPID dispid, LPLPCURSOR ppcursorOut, LPVOID *ppcidOut)
  2657. {
  2658. METHOD_PROLOGUE_EX(COleControlSite, BoundObjectSite)
  2659. return pThis->GetCursor(dispid, (LPUNKNOWN*)ppcursorOut, ppcidOut);
  2660. }
  2661. /////////////////////////////////////////////////////////////////////////////
  2662. // COleControlSite::XNotifyDBEvents
  2663. STDMETHODIMP_(ULONG) COleControlSite::XNotifyDBEvents::AddRef()
  2664. {
  2665. return 1;
  2666. }
  2667. STDMETHODIMP_(ULONG) COleControlSite::XNotifyDBEvents::Release()
  2668. {
  2669. return 0;
  2670. }
  2671. STDMETHODIMP COleControlSite::XNotifyDBEvents::QueryInterface(
  2672. REFIID iid, LPVOID far * ppvObj)
  2673. {
  2674. METHOD_PROLOGUE_EX_(COleControlSite, NotifyDBEvents)
  2675. if (IsEqualIID(iid, IID_IUnknown) ||
  2676. IsEqualIID(iid, IID_INotifyDBEvents))
  2677. {
  2678. *ppvObj = this;
  2679. AddRef();
  2680. return S_OK;
  2681. }
  2682. else
  2683. {
  2684. return E_NOINTERFACE;
  2685. }
  2686. }
  2687. STDMETHODIMP COleControlSite::XNotifyDBEvents::OKToDo(
  2688. DWORD dwEventWhat, ULONG cReasons, DBNOTIFYREASON rgReasons[])
  2689. {
  2690. METHOD_PROLOGUE_EX(COleControlSite, NotifyDBEvents)
  2691. HRESULT hRes = FireEvent(dwEventWhat, cReasons, rgReasons,
  2692. dscOKToDo);
  2693. if (FAILED(hRes))
  2694. return hRes;
  2695. DWORD reason = rgReasons[0].dwReason;
  2696. if (reason == DBREASON_SETCOLUMN ||
  2697. reason == DBREASON_INSERTED ||
  2698. reason == DBREASON_MODIFIED)
  2699. return S_OK;
  2700. // Mask out all notifications except as currency changes and update
  2701. if (!(dwEventWhat & DBEVENT_CURRENT_ROW_CHANGED) &&
  2702. reason != DBREASON_INSERTED &&
  2703. reason != DBREASON_MODIFIED &&
  2704. reason != DBREASON_DELETED &&
  2705. reason != DBREASON_ADDNEW)
  2706. return S_OK;
  2707. CDataSourceControl* pDSC = pThis->m_pDataSourceControl;
  2708. if (pDSC == NULL)
  2709. return S_OK;
  2710. if (!(dwEventWhat & DBEVENT_CURRENT_ROW_CHANGED))
  2711. return S_OK;
  2712. return pDSC->UpdateCursor();
  2713. }
  2714. STDMETHODIMP COleControlSite::XNotifyDBEvents::Cancelled(
  2715. DWORD dwEventWhat, ULONG cReasons, DBNOTIFYREASON rgReasons[])
  2716. {
  2717. METHOD_PROLOGUE_EX(COleControlSite, NotifyDBEvents)
  2718. HRESULT hRes = FireEvent(dwEventWhat, cReasons, rgReasons,
  2719. dscCancelled);
  2720. if (FAILED(hRes))
  2721. return hRes;
  2722. return S_OK;
  2723. }
  2724. STDMETHODIMP COleControlSite::XNotifyDBEvents::SyncBefore(
  2725. DWORD dwEventWhat, ULONG cReasons, DBNOTIFYREASON rgReasons[])
  2726. {
  2727. METHOD_PROLOGUE_EX(COleControlSite, NotifyDBEvents)
  2728. HRESULT hRes = FireEvent(dwEventWhat, cReasons, rgReasons,
  2729. dscSyncBefore);
  2730. if (FAILED(hRes))
  2731. return hRes;
  2732. DWORD reason = rgReasons[0].dwReason;
  2733. // Mask out all notifications except as shown
  2734. if (reason != DBREASON_INSERTED &&
  2735. reason != DBREASON_MODIFIED &&
  2736. reason != DBREASON_ADDNEW)
  2737. return S_OK;
  2738. CDataSourceControl* pDSC = pThis->m_pDataSourceControl;
  2739. if (pDSC == NULL)
  2740. return S_OK;
  2741. if (dwEventWhat & DBEVENT_METADATA_CHANGED)
  2742. {
  2743. pDSC->UpdateCursor();
  2744. }
  2745. return S_OK;
  2746. }
  2747. STDMETHODIMP COleControlSite::XNotifyDBEvents::AboutToDo(
  2748. DWORD dwEventWhat, ULONG cReasons, DBNOTIFYREASON rgReasons[])
  2749. {
  2750. METHOD_PROLOGUE_EX(COleControlSite, NotifyDBEvents)
  2751. HRESULT hRes = FireEvent(dwEventWhat, cReasons, rgReasons,
  2752. dscAboutToDo);
  2753. if (FAILED(hRes))
  2754. return hRes;
  2755. return S_OK;
  2756. }
  2757. STDMETHODIMP COleControlSite::XNotifyDBEvents::FailedToDo(
  2758. DWORD dwEventWhat, ULONG cReasons, DBNOTIFYREASON rgReasons[])
  2759. {
  2760. METHOD_PROLOGUE_EX(COleControlSite, NotifyDBEvents)
  2761. HRESULT hRes = FireEvent(dwEventWhat, cReasons, rgReasons,
  2762. dscFailedToDo);
  2763. if (FAILED(hRes))
  2764. return hRes;
  2765. return S_OK;
  2766. }
  2767. STDMETHODIMP COleControlSite::XNotifyDBEvents::SyncAfter(
  2768. DWORD dwEventWhat, ULONG cReasons, DBNOTIFYREASON rgReasons[])
  2769. {
  2770. METHOD_PROLOGUE_EX(COleControlSite, NotifyDBEvents)
  2771. HRESULT hRes = FireEvent(dwEventWhat, cReasons, rgReasons,
  2772. dscSyncAfter);
  2773. if (FAILED(hRes))
  2774. return hRes;
  2775. DWORD reason = rgReasons[0].dwReason;
  2776. CDataSourceControl* pDSC = pThis->m_pDataSourceControl;
  2777. if (pDSC == NULL)
  2778. return S_OK;
  2779. //Check semaphore - don't want to collect data during Update if it was due to a Move (it's a NOP!)
  2780. if (pDSC->m_bUpdateInProgress ||
  2781. reason == DBREASON_EDIT ||
  2782. reason == DBREASON_SETCOLUMN)
  2783. return S_OK;
  2784. //Mask out all notifications except as shown
  2785. if (!(dwEventWhat & (DBEVENT_CURRENT_ROW_CHANGED | DBEVENT_CURRENT_ROW_DATA_CHANGED)))
  2786. return S_OK;
  2787. if (reason != DBREASON_INSERTED &&
  2788. reason != DBREASON_MODIFIED)
  2789. {
  2790. BOOL bUpdateInProgress = pDSC->m_bUpdateInProgress;
  2791. pDSC->m_bUpdateInProgress = TRUE;
  2792. pDSC->GetBoundClientRow();
  2793. pDSC->m_bUpdateInProgress = bUpdateInProgress;
  2794. pDSC->UpdateControls();
  2795. }
  2796. return S_OK;
  2797. }
  2798. STDMETHODIMP COleControlSite::XNotifyDBEvents::DidEvent(
  2799. DWORD dwEventWhat, ULONG cReasons, DBNOTIFYREASON rgReasons[])
  2800. {
  2801. METHOD_PROLOGUE_EX(COleControlSite, NotifyDBEvents)
  2802. HRESULT hRes = FireEvent(dwEventWhat, cReasons, rgReasons,
  2803. dscDidEvent);
  2804. if (FAILED(hRes))
  2805. return hRes;
  2806. CDataSourceControl* pDSC = pThis->m_pDataSourceControl;
  2807. if (pDSC == NULL)
  2808. return S_OK;
  2809. if (dwEventWhat & DBEVENT_METADATA_CHANGED)
  2810. {
  2811. BOOL bUpdateInProgress = pDSC->m_bUpdateInProgress;
  2812. pDSC->m_bUpdateInProgress = TRUE;
  2813. pDSC->GetBoundClientRow();
  2814. pDSC->m_bUpdateInProgress = bUpdateInProgress;
  2815. pDSC->UpdateControls();
  2816. }
  2817. return S_OK;
  2818. }
  2819. HRESULT COleControlSite::XNotifyDBEvents::FireEvent(
  2820. DWORD dwEventWhat, ULONG cReasons, DBNOTIFYREASON rgReasons[], DSCSTATE nState)
  2821. {
  2822. METHOD_PROLOGUE_EX_(COleControlSite, NotifyDBEvents)
  2823. if (dwEventWhat & DBEVENT_CURRENT_ROW_CHANGED
  2824. || dwEventWhat & DBEVENT_CURRENT_ROW_DATA_CHANGED)
  2825. {
  2826. for (UINT i=0; i<cReasons; i++)
  2827. {
  2828. DSCREASON nReason = dscNoReason;
  2829. switch (rgReasons[i].dwReason)
  2830. {
  2831. case DBREASON_CLOSE:
  2832. nReason = dscClose;
  2833. break;
  2834. case DBREASON_FIND:
  2835. case DBREASON_MOVE:
  2836. case DBREASON_MOVEPERCENT:
  2837. case DBREASON_NEWINDEX:
  2838. case DBREASON_NEWPARAMETERS:
  2839. case DBREASON_QUERYSPECCHANGED:
  2840. case DBREASON_REFRESH:
  2841. case DBREASON_SEEK:
  2842. case DBREASON_SETRANGECHANGED:
  2843. nReason = dscMove;
  2844. break;
  2845. case DBREASON_ADDNEW:
  2846. case DBREASON_INSERTED:
  2847. nReason = dscInsert;
  2848. break;
  2849. case DBREASON_EDIT:
  2850. nReason = dscEdit;
  2851. break;
  2852. case DBREASON_MODIFIED:
  2853. case DBREASON_RECALC:
  2854. case DBREASON_ROLLBACK:
  2855. case DBREASON_ROWFIXUP:
  2856. nReason = dscModify;
  2857. break;
  2858. case DBREASON_DELETED:
  2859. nReason = dscDelete;
  2860. break;
  2861. case DBREASON_COMMIT:
  2862. nReason = dscCommit;
  2863. break;
  2864. }
  2865. if (nReason != dscNoReason)
  2866. {
  2867. AFX_EVENT event(AFX_EVENT::propDSCNotify);
  2868. event.m_nDSCState = nState;
  2869. event.m_nDSCReason = nReason;
  2870. pThis->OnEvent(&event);
  2871. return event.m_hResult;
  2872. }
  2873. }
  2874. return S_OK;
  2875. }
  2876. return S_OK;
  2877. }
  2878. STDMETHODIMP_(ULONG) COleControlSite::XRowsetNotify::AddRef()
  2879. {
  2880. return 1;
  2881. }
  2882. STDMETHODIMP_(ULONG) COleControlSite::XRowsetNotify::Release()
  2883. {
  2884. return 0;
  2885. }
  2886. STDMETHODIMP COleControlSite::XRowsetNotify::QueryInterface(
  2887. REFIID iid, LPVOID far * ppvObj)
  2888. {
  2889. METHOD_PROLOGUE_EX_(COleControlSite, RowsetNotify)
  2890. if (IsEqualIID(iid, IID_IUnknown) ||
  2891. IsEqualIID(iid, IID_IRowsetNotify))
  2892. {
  2893. *ppvObj = this;
  2894. AddRef();
  2895. return S_OK;
  2896. }
  2897. return E_NOINTERFACE;
  2898. }
  2899. STDMETHODIMP COleControlSite::XRowsetNotify::OnFieldChange(
  2900. IRowset* /*pRowset*/, HROW /*hRow*/, ULONG /*cColumns*/, ULONG /*rgColumns*/[],
  2901. DBREASON /*eReason*/, DBEVENTPHASE ePhase, BOOL /*fCantDeny*/)
  2902. {
  2903. METHOD_PROLOGUE_EX(COleControlSite, RowsetNotify)
  2904. DSCSTATE nState = dscNoState;
  2905. switch(ePhase)
  2906. {
  2907. case DBEVENTPHASE_OKTODO:
  2908. nState = dscOKToDo;
  2909. break;
  2910. case DBEVENTPHASE_ABOUTTODO:
  2911. nState = dscAboutToDo;
  2912. break;
  2913. case DBEVENTPHASE_SYNCHAFTER:
  2914. nState = dscSyncAfter;
  2915. break;
  2916. case DBEVENTPHASE_FAILEDTODO:
  2917. nState = dscFailedToDo;
  2918. break;
  2919. case DBEVENTPHASE_DIDEVENT:
  2920. nState = dscDidEvent;
  2921. break;
  2922. }
  2923. if(nState == dscDidEvent)
  2924. {
  2925. CDataSourceControl* pDSC = pThis->m_pDataSourceControl;
  2926. if (pDSC == NULL)
  2927. return S_OK;
  2928. if(pDSC->m_bUpdateInProgress == FALSE)
  2929. {
  2930. ASSERT(pDSC->m_pRowset);
  2931. BOOL bUpdateInProgress = pDSC->m_bUpdateInProgress;
  2932. pDSC->m_bUpdateInProgress = TRUE;
  2933. pDSC->GetBoundClientRow();
  2934. pDSC->m_bUpdateInProgress = bUpdateInProgress;
  2935. pDSC->UpdateControls();
  2936. }
  2937. }
  2938. AFX_EVENT event(AFX_EVENT::propDSCNotify);
  2939. event.m_nDSCState = nState;
  2940. event.m_nDSCReason = dscModify;
  2941. pThis->OnEvent(&event);
  2942. return event.m_hResult;
  2943. }
  2944. STDMETHODIMP COleControlSite::XRowsetNotify::OnRowChange(
  2945. IRowset* /*pRowset*/, ULONG cRows, const HROW rghRows[],
  2946. DBREASON eReason, DBEVENTPHASE ePhase, BOOL /*fCantDeny*/)
  2947. {
  2948. METHOD_PROLOGUE_EX(COleControlSite, RowsetNotify)
  2949. HRESULT hRes = S_OK;
  2950. DSCSTATE nState = dscNoState;
  2951. switch(ePhase)
  2952. {
  2953. case DBEVENTPHASE_OKTODO:
  2954. nState = dscOKToDo;
  2955. break;
  2956. case DBEVENTPHASE_ABOUTTODO:
  2957. nState = dscAboutToDo;
  2958. break;
  2959. case DBEVENTPHASE_SYNCHAFTER:
  2960. nState = dscSyncAfter;
  2961. break;
  2962. case DBEVENTPHASE_FAILEDTODO:
  2963. nState = dscFailedToDo;
  2964. break;
  2965. case DBEVENTPHASE_DIDEVENT:
  2966. nState = dscDidEvent;
  2967. break;
  2968. }
  2969. DSCREASON nReason = dscNoReason;
  2970. switch(eReason)
  2971. {
  2972. case DBREASON_ROW_ACTIVATE:
  2973. nReason = dscMove;
  2974. break;
  2975. case DBREASON_ROW_DELETE:
  2976. nReason = dscDelete;
  2977. break;
  2978. case DBREASON_ROW_INSERT:
  2979. nReason = dscInsert;
  2980. break;
  2981. case DBREASON_ROW_UPDATE:
  2982. nReason = dscCommit;
  2983. break;
  2984. }
  2985. CDataSourceControl* pDSC = pThis->m_pDataSourceControl;
  2986. if (pDSC == NULL)
  2987. return S_OK;
  2988. ASSERT(pDSC->m_pRowset);
  2989. if (nReason == dscCommit && nState == dscAboutToDo)
  2990. {
  2991. pDSC->UpdateCursor();
  2992. }
  2993. else if ((nReason == dscMove && cRows == 1) || (nState == dscSyncAfter && nReason == dscInsert))
  2994. {
  2995. pDSC->UpdateCursor();
  2996. pDSC->m_pRowset->m_hRow = rghRows[0];
  2997. BOOL bUpdateInProgress = pDSC->m_bUpdateInProgress;
  2998. pDSC->m_bUpdateInProgress = TRUE;
  2999. pDSC->GetBoundClientRow();
  3000. pDSC->m_bUpdateInProgress = bUpdateInProgress;
  3001. if(!pDSC->m_bUpdateInProgress)
  3002. pDSC->UpdateControls();
  3003. }
  3004. if (nReason != dscNoReason)
  3005. {
  3006. AFX_EVENT event(AFX_EVENT::propDSCNotify);
  3007. event.m_nDSCState = nState;
  3008. event.m_nDSCReason = nReason;
  3009. pThis->OnEvent(&event);
  3010. hRes = event.m_hResult;
  3011. if(FAILED(hRes))
  3012. return hRes;
  3013. }
  3014. return S_OK;
  3015. }
  3016. STDMETHODIMP COleControlSite::XRowsetNotify::OnRowsetChange(
  3017. IRowset* /*pRowset*/, DBREASON eReason, DBEVENTPHASE /*ePhase*/, BOOL /*fCantDeny*/)
  3018. {
  3019. METHOD_PROLOGUE_EX(COleControlSite, RowsetNotify)
  3020. if(eReason == DBREASON_ROWSET_CHANGED)
  3021. {
  3022. CDataSourceControl* pDSC = pThis->m_pDataSourceControl;
  3023. if (pDSC == NULL)
  3024. return S_OK;
  3025. ASSERT(pDSC->m_pRowset);
  3026. ASSERT(pDSC->m_pDynamicAccessor);
  3027. pDSC->m_pDynamicAccessor->ReleaseAccessors(pDSC->m_pRowset->m_spRowset);
  3028. pDSC->m_pDynamicAccessor->Close();
  3029. pDSC->m_pDynamicAccessor->BindColumns(pDSC->m_pRowset->m_spRowset);
  3030. if( pDSC->m_nColumns != (int)pDSC->m_pDynamicAccessor->GetColumnCount() )
  3031. {
  3032. pDSC->m_nColumns = pDSC->m_pDynamicAccessor->GetColumnCount();
  3033. ::CoTaskMemFree(pDSC->m_pMetaRowData);
  3034. pDSC->m_pMetaRowData = (CDataSourceControl::METAROWTYPE*)::CoTaskMemAlloc(sizeof(CDataSourceControl::METAROWTYPE) * pDSC->m_nColumns);
  3035. ASSERT(pDSC->m_pMetaRowData);
  3036. memset(pDSC->m_pMetaRowData, 0, sizeof(CDataSourceControl::METAROWTYPE) * pDSC->m_nColumns);
  3037. }
  3038. }
  3039. return S_OK;
  3040. }