Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1277 lines
43 KiB

  1. /*************************************************************************/
  2. /* Copyright (C) 1999 Microsoft Corporation */
  3. /* File: CCObj.cpp */
  4. /* Description: Contains holder for container objects. */
  5. /*************************************************************************/
  6. #include "stdafx.h"
  7. #include "ccobj.h"
  8. #define GET_SITE CComPtr<IOleInPlaceSiteWindowless> pSite; \
  9. HRESULT hr = GetWindowlessSite(pSite); \
  10. if(FAILED(hr)) return(hr);
  11. #define GET_CONTAINER CComPtr<IOleContainer> pContainer; \
  12. HRESULT hr = GetContainer(pContainer); \
  13. if(FAILED(hr)) return(hr);
  14. /*************************************************************************/
  15. /* Function: CContainerObject */
  16. /* Description: Constructor that should set needed objects. */
  17. /*************************************************************************/
  18. CContainerObject::CContainerObject(IUnknown* pUnknown, CHostedObject* pObj){
  19. Init();
  20. SetObjects(pUnknown, pObj);
  21. }/* end of function CContainerObject */
  22. /*************************************************************************/
  23. /* Function: SetObjects */
  24. /* Description: Sets the internal objects. */
  25. /*************************************************************************/
  26. HRESULT CContainerObject::SetObjects(IUnknown* pUnknown, CHostedObject* pObj){
  27. m_pUnkContainer = pUnknown;
  28. m_pObj = pObj;
  29. return(S_OK);
  30. }/* end of function SetObjects */
  31. /*************************************************************************/
  32. /* Function: Init */
  33. /* Description: Initializes the member variables */
  34. /*************************************************************************/
  35. void CContainerObject::Init(){
  36. //m_pUnkContainer = NULL; // using smart pointer
  37. m_pObj = NULL;
  38. m_lRefCount = 1;
  39. m_bLocked = 0;
  40. }/* end of function Init */
  41. /*************************************************************************/
  42. /* Function: QueryInterface */
  43. /* Description: Gets the supported interface rest sends to the aggregated*/
  44. /* object */
  45. /*************************************************************************/
  46. STDMETHODIMP CContainerObject::QueryInterface(const IID& iid, void**ppv){
  47. if(iid == IID_IUnknown){
  48. *ppv = static_cast<CContainerObject*>(this);
  49. }
  50. else if(iid == IID_IOleInPlaceSiteWindowless){
  51. *ppv = static_cast<IOleInPlaceSiteWindowless*>(this);
  52. }
  53. else if(iid == IID_IOleInPlaceSiteEx){
  54. *ppv = static_cast<IOleInPlaceSiteEx*>(this);
  55. }
  56. else if(iid == IID_IOleClientSite){
  57. *ppv = static_cast<IOleClientSite*>(this);
  58. }
  59. else if(iid == IID_IOleContainer){
  60. *ppv = static_cast<IOleContainer*>(this);
  61. }
  62. else if(iid == IID_IOleInPlaceSite){
  63. *ppv = static_cast<IOleInPlaceSite*>(this);
  64. }
  65. else if(iid == IID_IObjectWithSite){
  66. *ppv = static_cast<IObjectWithSite*>(this);
  67. }
  68. else if(iid == IID_IPropertyBag){
  69. *ppv = static_cast<IPropertyBag*>(this);
  70. }
  71. // TODO: Not Right way to agregate
  72. // this breaks the rules since we really do not
  73. // have non delegating object there
  74. else { // blindly aggregate
  75. if(!m_pUnkContainer){
  76. *ppv = NULL;
  77. return (E_NOINTERFACE);
  78. }/* end of if statement */
  79. return(m_pUnkContainer->QueryInterface(iid, ppv));
  80. }/* end of if statement */
  81. reinterpret_cast<IUnknown*>(*ppv)->AddRef();
  82. return(S_OK);
  83. }/* end of function QueryInterface */
  84. /*************************************************************************/
  85. /* Function: AddRef */
  86. /* Description: Adds the reference count. */
  87. /*************************************************************************/
  88. STDMETHODIMP_(ULONG) CContainerObject::AddRef ( void){
  89. return(InterlockedIncrement(&m_lRefCount));
  90. }/* end of function AddRef */
  91. /*************************************************************************/
  92. /* Function: Release */
  93. /* Description: Decrements the reference count and the possibly releases */
  94. /*************************************************************************/
  95. STDMETHODIMP_(ULONG) CContainerObject::Release( void){
  96. if(InterlockedIncrement(&m_lRefCount) <=0){
  97. delete this;
  98. return 0;
  99. }/* end of if statement */
  100. return (m_lRefCount);
  101. }/* end of function Release */
  102. /*************************************************************************/
  103. /* Helper functions */
  104. /*************************************************************************/
  105. /*************************************************************************/
  106. /* Function: GetWindowlessSite */
  107. /* Description: Returns an interface for windowless site. */
  108. /*************************************************************************/
  109. inline HRESULT CContainerObject::GetWindowlessSite(CComPtr<IOleInPlaceSiteWindowless>& pSite){
  110. if(!m_pUnkContainer){
  111. return(E_UNEXPECTED);
  112. }/* end of if statement */
  113. return(m_pUnkContainer->QueryInterface(&pSite));
  114. }/* end of function GetWindowlessSite */
  115. /*************************************************************************/
  116. /* Function: GetContainer */
  117. /* Description: Returns an interface for windowless site. */
  118. /*************************************************************************/
  119. inline HRESULT CContainerObject::GetContainer(CComPtr<IOleContainer>& pContainer){
  120. if(!m_pUnkContainer){
  121. return(E_UNEXPECTED);
  122. }/* end of if statement */
  123. return(m_pUnkContainer->QueryInterface(&pContainer));
  124. }/* end of function GetContainer */
  125. /*************************************************************************/
  126. /* IOleContainer Implementation */
  127. /*************************************************************************/
  128. /*************************************************************************/
  129. /* Function: ParseDisplayName */
  130. /*************************************************************************/
  131. STDMETHODIMP CContainerObject::ParseDisplayName(IBindCtx* /*pbc*/,
  132. LPOLESTR /*pszDisplayName*/, ULONG* /*pchEaten*/, IMoniker** /*ppmkOut*/){
  133. ATLTRACENOTIMPL(_T("IOleClientSite::ParseDisplayName"));
  134. }/* end of function ParseDisplayName */
  135. /*************************************************************************/
  136. /* Function: EnumObjects */
  137. /*************************************************************************/
  138. STDMETHODIMP CContainerObject::EnumObjects(DWORD grfFlags, IEnumUnknown** ppenum){
  139. GET_CONTAINER
  140. return(pContainer->EnumObjects(grfFlags, ppenum));
  141. }/* end of function EnumObjects */
  142. /*************************************************************************/
  143. /* Function: LockContainer */
  144. /* Description: Sets the container locked so it does not go away. */
  145. /*************************************************************************/
  146. STDMETHODIMP CContainerObject::LockContainer(BOOL fLock){
  147. // TODO: Actually do use the m_bLocked flag
  148. m_bLocked = fLock;
  149. return S_OK;
  150. }/* end of function LockContainer */
  151. /*************************************************************************/
  152. /* IOleClientSite Implementation */
  153. /*************************************************************************/
  154. /*************************************************************************/
  155. /* Function: GetContainer */
  156. /* Description: Basically returns our self */
  157. /*************************************************************************/
  158. STDMETHODIMP CContainerObject::GetContainer(IOleContainer** ppContainer){
  159. ATLTRACE2(atlTraceHosting, 0, _T("IOleClientSite::GetContainer\n"));
  160. HRESULT hr = E_POINTER;
  161. if (NULL == ppContainer){
  162. return(hr);
  163. }/* end of if statement */
  164. if (m_pUnkContainer){
  165. (*ppContainer) = NULL;
  166. hr = QueryInterface(IID_IOleContainer, (void**)ppContainer); // return our selfs
  167. }/* end of if statement */
  168. return hr;
  169. }/* end of function GetContainer */
  170. /*************************************************************************/
  171. /* Function: ShowObject */
  172. /* Description: Redraws the object. */
  173. /*************************************************************************/
  174. STDMETHODIMP CContainerObject::ShowObject(){
  175. HRESULT hr = S_OK;
  176. ATLTRACE2(atlTraceHosting, 0, _T("IOleClientSite::ShowObject\r\n"));
  177. if(NULL == m_pObj){
  178. hr = E_UNEXPECTED;
  179. return(hr);
  180. }/* end of if statement */
  181. hr = InvalidateObjectRect();
  182. return (hr);
  183. }/* end of function ShowObject */
  184. /*************************************************************************/
  185. /* Function: OnShowWindow */
  186. /* Description: Shows or hides the window. If no window to show or hide */
  187. /* we deactivate it. */
  188. /*************************************************************************/
  189. STDMETHODIMP CContainerObject::OnShowWindow(BOOL fShow){
  190. HRESULT hr = S_OK;
  191. if(NULL == m_pObj){
  192. hr = E_UNEXPECTED;
  193. return(hr);
  194. }/* end of if statement */
  195. hr = m_pObj->SetActive(fShow ? true: false);
  196. return(hr);
  197. }/* end of function OnShowWindow */
  198. /*************************************************************************/
  199. /* IOleInPlaceSiteEx Implementation */
  200. /* Just pass throw in most cases, in some do some extra house keeping */
  201. /* since we know which object we are containing. */
  202. /*************************************************************************/
  203. // IOleWindow
  204. /*************************************************************************/
  205. /* Function: GetWindow */
  206. /*************************************************************************/
  207. STDMETHODIMP CContainerObject::GetWindow(HWND *phwnd){
  208. GET_SITE
  209. return(pSite->GetWindow(phwnd));
  210. }/* end of function GetWindow */
  211. /*************************************************************************/
  212. /* Function: ContextSensitiveHelp */
  213. /*************************************************************************/
  214. STDMETHODIMP CContainerObject::ContextSensitiveHelp(BOOL fEnterMode){
  215. GET_SITE
  216. return(pSite->ContextSensitiveHelp(fEnterMode));
  217. }/* end of function ContextSensitiveHelp */
  218. //IOleInPlaceSite
  219. /*************************************************************************/
  220. /* Function: CanInPlaceActivate */
  221. /*************************************************************************/
  222. STDMETHODIMP CContainerObject::CanInPlaceActivate(){
  223. GET_SITE
  224. return(pSite->CanInPlaceActivate());
  225. }/* end of function CanInPlaceActivate */
  226. /*************************************************************************/
  227. /* Function: OnUIActivate */
  228. /*************************************************************************/
  229. STDMETHODIMP CContainerObject::OnUIActivate(){
  230. GET_SITE
  231. return(pSite->OnUIActivate());
  232. }/* end of function OnUIActivate */
  233. /*************************************************************************/
  234. /* Function: OnInPlaceActivate */
  235. /* Description: Activates non windowless object. */
  236. /*************************************************************************/
  237. STDMETHODIMP CContainerObject::OnInPlaceActivate(){
  238. ATLTRACE(TEXT("CContainerObject::OnInPlaceActivate \n"));
  239. HRESULT hr = E_FAIL;
  240. if(NULL == m_pObj){
  241. hr = E_UNEXPECTED;
  242. return(hr);
  243. }/* end of if statement */
  244. CComPtr<IUnknown> pUnk = m_pObj->GetUnknown(); // get the control object that is being inserted
  245. if(!pUnk){
  246. return(E_UNEXPECTED);
  247. }/* end of if statement */
  248. //OleLockRunning(pUnk, TRUE, FALSE); // not sure if needed here
  249. m_pObj->SetWindowless(false);
  250. //m_pObj->SetActive(true);
  251. return(hr);
  252. }/* end of function OnInPlaceActivate */
  253. /*************************************************************************/
  254. /* Function: OnUIDeactivate */
  255. /* Description: Deactivates the object. */
  256. /*************************************************************************/
  257. STDMETHODIMP CContainerObject::OnUIDeactivate(BOOL fUndoable){
  258. HRESULT hr = S_OK;
  259. if(NULL == m_pObj){
  260. hr = E_UNEXPECTED;
  261. return(hr);
  262. }/* end of if statement */
  263. m_pObj->SetActive(false);
  264. ATLTRACE(TEXT("TODO: In the deactivation code, time to cleanup the contained object!!! \n"));
  265. return(hr);
  266. }/* end of function OnUIDeactivate */
  267. /*************************************************************************/
  268. /* Function: OnInPlaceDeactivate */
  269. /* Description: Deactivates the object. */
  270. /*************************************************************************/
  271. STDMETHODIMP CContainerObject::OnInPlaceDeactivate(){
  272. HRESULT hr = S_OK;
  273. if(NULL == m_pObj){
  274. hr = E_UNEXPECTED;
  275. return(hr);
  276. }/* end of if statement */
  277. m_pObj->SetActive(false);
  278. ATLTRACE(TEXT("TODO: In the deactivation code, time to cleanup the contained object!!! \n"));
  279. return(hr);
  280. }/* end of function OnInPlaceDeactivate */
  281. /*************************************************************************/
  282. /* Function: DiscardUndoState */
  283. /*************************************************************************/
  284. STDMETHODIMP CContainerObject::DiscardUndoState(){
  285. GET_SITE
  286. return(pSite->DiscardUndoState());
  287. }/* end of function DiscardUndoState */
  288. /*************************************************************************/
  289. /* Function: DeactivateAndUndo */
  290. /*************************************************************************/
  291. STDMETHODIMP CContainerObject::DeactivateAndUndo(){
  292. GET_SITE
  293. return(pSite->DeactivateAndUndo());
  294. // TODO: Handle specific container
  295. }/* end of function DeactivateAndUndo */
  296. /*************************************************************************/
  297. /* Function: OnPosRectChange */
  298. /*************************************************************************/
  299. STDMETHODIMP CContainerObject::OnPosRectChange(LPCRECT lprcPosRect){
  300. GET_SITE
  301. return(pSite->OnPosRectChange(lprcPosRect));
  302. // TODO: Handle specific container
  303. }/* end of function OnPosRectChange */
  304. /*************************************************************************/
  305. /* Function: Scroll */
  306. /*************************************************************************/
  307. STDMETHODIMP CContainerObject::Scroll(SIZE scrollExtent){
  308. GET_SITE
  309. return(pSite->Scroll(scrollExtent));
  310. // TODO: Handle specific container
  311. }/* end of function OnPosRectChange */
  312. /*************************************************************************/
  313. /* Function: GetWindowContext */
  314. /* Description: Finish this function to be container specific. */
  315. /*************************************************************************/
  316. STDMETHODIMP CContainerObject::GetWindowContext(IOleInPlaceFrame** ppFrame,
  317. IOleInPlaceUIWindow** ppDoc, LPRECT lprcPosRect,
  318. LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO pFrameInfo){
  319. HRESULT hr = S_OK;
  320. if(NULL == m_pObj){
  321. hr = E_UNEXPECTED;
  322. return(hr);
  323. }/* end of if statement */
  324. if (ppFrame == NULL || ppDoc == NULL || lprcPosRect == NULL || lprcClipRect == NULL){
  325. hr = E_POINTER;
  326. return(hr);
  327. }/* end of if statement */
  328. if (!m_spInPlaceFrame){
  329. //CComObject<CAxFrameWindow>* pFrameWindow;
  330. //CComObject<CAxFrameWindow>::CreateInstance(&pFrameWindow);
  331. // ?? MODS DJ
  332. QueryInterface(IID_IOleInPlaceFrame, (void**) &m_spInPlaceFrame);
  333. ATLASSERT(m_spInPlaceFrame);
  334. }/* end of if statement */
  335. if (!m_spInPlaceUIWindow){
  336. // ?? MODS DJ
  337. //CComObject<CAxUIWindow>* pUIWindow;
  338. //CComObject<CAxUIWindow>::CreateInstance(&pUIWindow);
  339. QueryInterface(IID_IOleInPlaceUIWindow, (void**) &m_spInPlaceUIWindow);
  340. ATLASSERT(m_spInPlaceUIWindow);
  341. }/* end of if statement */
  342. m_spInPlaceFrame.CopyTo(ppFrame);
  343. m_spInPlaceUIWindow.CopyTo(ppDoc);
  344. RECT rc;
  345. hr = m_pObj->GetPos(&rc);
  346. if(FAILED(hr)){
  347. return(hr);
  348. }/* end of if statement */
  349. *lprcPosRect = rc;
  350. *lprcClipRect = rc;
  351. HWND hwnd;
  352. hr = GetWindow(&hwnd);
  353. if(FAILED(hr)){
  354. hr = S_FALSE;
  355. //return(hr);
  356. }/* end of if statement */
  357. HWND hParent = NULL;
  358. if(NULL != hwnd){
  359. hParent = ::GetParent(hwnd);
  360. }/* end of function GetParent */
  361. ACCEL ac = { 0,0,0 };
  362. HACCEL hac = ::CreateAcceleratorTable(&ac, 1);
  363. pFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO);
  364. pFrameInfo->fMDIApp = 0;
  365. pFrameInfo->hwndFrame = hParent;
  366. pFrameInfo->haccel = hac;
  367. pFrameInfo->cAccelEntries = 1;
  368. return hr;
  369. }/* end of function GetWindowContext */
  370. /*************************************************************************/
  371. /* Function: GetSite */
  372. /* Description: Returns pretty much QI, client sets the site and then */
  373. /* container is using it. */
  374. /*************************************************************************/
  375. STDMETHODIMP CContainerObject::GetSite(REFIID riid, void **ppvSite){
  376. return(QueryInterface(riid, ppvSite));
  377. }/* end of function GetSite */
  378. //IOleInPlaceSiteEx
  379. /*************************************************************************/
  380. /* Function: OnInPlaceActivateEx */
  381. /* Description: Checks what way we shall instantiate the control. */
  382. /*************************************************************************/
  383. STDMETHODIMP CContainerObject::OnInPlaceActivateEx(BOOL* /*pfNoRedraw*/, DWORD dwFlags){
  384. HRESULT hr = E_FAIL;
  385. if(NULL == m_pObj){
  386. hr = E_UNEXPECTED;
  387. return(hr);
  388. }/* end of if statement */
  389. CComPtr<IUnknown> pUnk = m_pObj->GetUnknown(); // get the control object that is being inserted
  390. if(!pUnk){
  391. return(E_UNEXPECTED);
  392. }/* end of if statement */
  393. OleLockRunning(pUnk, TRUE, FALSE);
  394. CComPtr<IOleInPlaceObjectWindowless> spInPlaceObjectWindowless;
  395. bool bWindowless = false;
  396. if (dwFlags & ACTIVATE_WINDOWLESS){
  397. m_pObj->SetWindowless(true);
  398. hr = pUnk->QueryInterface(IID_IOleInPlaceObjectWindowless,(void**) &spInPlaceObjectWindowless);
  399. }/* end of if statement */
  400. if (FAILED(hr)){
  401. m_pObj->SetWindowless(false);
  402. hr = pUnk->QueryInterface(IID_IOleInPlaceObject, (void**) &spInPlaceObjectWindowless);
  403. }/* end of if statement */
  404. if (SUCCEEDED(hr)){
  405. RECT rcPos;
  406. hr = m_pObj->GetPos(&rcPos);
  407. if (FAILED(hr)){
  408. return(hr);
  409. }/* end of if statement */
  410. if(m_pObj->IsWindowless()){
  411. spInPlaceObjectWindowless->SetObjectRects(&rcPos, &rcPos);
  412. ATLTRACE(TEXT("Windowless object is contained object with ID %ls Rect left = %d top %d right %d bottom %d\n"),
  413. m_pObj->GetID(), rcPos.left, rcPos.top, rcPos.right, rcPos.bottom);
  414. }/* end of if statement */
  415. }/* end of if statement */
  416. //m_pObj->SetActive(true);
  417. return S_OK;
  418. }/* end of function OnInPlaceActivateEx */
  419. /*************************************************************************/
  420. /* Function: OnInPlaceDeactivateEx */
  421. /* Description: Deactivates the object. */
  422. /*************************************************************************/
  423. STDMETHODIMP CContainerObject::OnInPlaceDeactivateEx(BOOL fNoRedraw){
  424. HRESULT hr = S_OK;
  425. if(NULL == m_pObj){
  426. hr = E_UNEXPECTED;
  427. return(hr);
  428. }/* end of if statement */
  429. m_pObj->SetActive(false);
  430. ATLTRACE(TEXT("TODO: In the deactivation code, time to cleanup the contained object!!! \n"));
  431. return(hr);
  432. }/* end of function OnInPlaceDeactivateEx */
  433. /*************************************************************************/
  434. /* Function: RequestUIActivate */
  435. /*************************************************************************/
  436. STDMETHODIMP CContainerObject::RequestUIActivate(){
  437. GET_SITE
  438. return(pSite->RequestUIActivate());
  439. }/* end of function RequestUIActivate */
  440. /*************************************************************************/
  441. /* Function: CanWindowlessActivate */
  442. /*************************************************************************/
  443. STDMETHODIMP CContainerObject::CanWindowlessActivate(){
  444. GET_SITE
  445. return(pSite->CanWindowlessActivate());
  446. }/* end of function CanWindowlessActivate */
  447. /*************************************************************************/
  448. /* Function: GetDC */
  449. /*************************************************************************/
  450. STDMETHODIMP CContainerObject::GetDC(LPCRECT pRect, DWORD grfFlags, HDC* phDC){
  451. GET_SITE
  452. return(pSite->GetDC(pRect, grfFlags, phDC));
  453. }/* end of function GetDC */
  454. /*************************************************************************/
  455. /* Function: ReleaseDC */
  456. /*************************************************************************/
  457. STDMETHODIMP CContainerObject::ReleaseDC(HDC hDC){
  458. GET_SITE
  459. return(pSite->ReleaseDC(hDC));
  460. }/* end of function ReleaseDC */
  461. /*************************************************************************/
  462. /* Function: InvalidateRect */
  463. /*************************************************************************/
  464. STDMETHODIMP CContainerObject::InvalidateRect(LPCRECT pRect, BOOL fErase){
  465. GET_SITE
  466. return(pSite->InvalidateRect(pRect, fErase));
  467. }/* end of function InvalidateRect */
  468. /*************************************************************************/
  469. /* Function: InvalidateObjectRect */
  470. /* Description: Invalidates the whole control. */
  471. /*************************************************************************/
  472. HRESULT CContainerObject::InvalidateObjectRect(){
  473. HRESULT hr = S_OK;
  474. if(NULL == m_pObj){
  475. hr = E_UNEXPECTED;
  476. return(hr);
  477. }/* end of if statement */
  478. RECT rc;
  479. hr = m_pObj->GetPos(&rc);
  480. if(FAILED(hr)){
  481. return(hr);
  482. }/* end of if statement */
  483. hr = InvalidateRect(&rc, FALSE); // invalidate the region instead
  484. // of drawing the object directly
  485. return(hr);
  486. }/* end of function InvalidateRect */
  487. /*************************************************************************/
  488. /* Function: InvalidateRgn */
  489. /*************************************************************************/
  490. STDMETHODIMP CContainerObject::InvalidateRgn(HRGN hRGN, BOOL fErase){
  491. GET_SITE
  492. return(pSite->InvalidateRgn(hRGN, fErase));
  493. }/* end of function InvalidateRgn */
  494. /*************************************************************************/
  495. /* Function: ScrollRect */
  496. /*************************************************************************/
  497. STDMETHODIMP CContainerObject::ScrollRect(INT dx, INT dy, LPCRECT pRectScroll, LPCRECT pRectClip){
  498. GET_SITE
  499. return(pSite->ScrollRect(dx, dy, pRectScroll, pRectClip));
  500. }/* end of function ScrollRect */
  501. /*************************************************************************/
  502. /* Function: AdjustRect */
  503. /*************************************************************************/
  504. STDMETHODIMP CContainerObject::AdjustRect(LPRECT prc){
  505. GET_SITE
  506. return(pSite->AdjustRect(prc));
  507. }/* end of function AdjustRect */
  508. /*************************************************************************/
  509. /* Function: OnDefWindowMessage */
  510. /*************************************************************************/
  511. STDMETHODIMP CContainerObject::OnDefWindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT* plResult){
  512. GET_SITE
  513. return(pSite->OnDefWindowMessage(msg, wParam, lParam, plResult));
  514. }/* end of function OnDefWindowMessage */
  515. /*************************************************************************/
  516. /* Function: GetCapture */
  517. /* Description: Used to determine if we have a cupature or not */
  518. /*************************************************************************/
  519. STDMETHODIMP CContainerObject::GetCapture(){
  520. GET_SITE
  521. if(NULL == m_pObj){
  522. hr = E_UNEXPECTED;
  523. return(hr);
  524. }/* end of if statement */
  525. hr = pSite->GetCapture();
  526. if(SUCCEEDED(hr)){
  527. // we checked with the container if we
  528. // have a capture
  529. if(m_pObj->HasCapture() == false){
  530. hr = S_FALSE;
  531. }
  532. else {
  533. if(hr == S_FALSE){
  534. // case when the container say we do not have
  535. // the capture any more
  536. // but the object thinks it has a capture
  537. // we better reset the flag
  538. m_pObj->SetCapture(false);
  539. // and say that we do not have capture
  540. hr = S_FALSE;
  541. }/* end of if statement */
  542. }/* end of if statement */
  543. }/* end of if statement */
  544. return(hr);
  545. }/* end of function GetCapture */
  546. /*************************************************************************/
  547. /* Function: SetCapture */
  548. /* Description: Used to set the capture for mouse events */
  549. /*************************************************************************/
  550. STDMETHODIMP CContainerObject::SetCapture(BOOL fCapture){
  551. GET_SITE
  552. if(NULL == m_pObj){
  553. hr = E_UNEXPECTED;
  554. return(hr);
  555. }/* end of if statement */
  556. if(fCapture && !m_pObj->IsActive()){
  557. hr = S_FALSE;
  558. return(hr);
  559. }/* end of if statement */
  560. if(m_pObj->HasCapture() == (fCapture ? true: false)){
  561. hr = S_FALSE;
  562. return(hr);
  563. }/* end of if statement */
  564. // Call our "real" container object for count keeping
  565. // and signaling to its window or another container
  566. hr = pSite->SetCapture(fCapture);
  567. if(SUCCEEDED(hr)){
  568. m_pObj->SetCapture(fCapture? true: false); // set the capture on the object
  569. }/* end of if statement */
  570. return (hr);
  571. }/* end of function SetCapture */
  572. /*************************************************************************/
  573. /* Function: GetFocus */
  574. /* Description: Determine if we have a focus or not. */
  575. /*************************************************************************/
  576. STDMETHODIMP CContainerObject::GetFocus(){
  577. GET_SITE
  578. if(NULL == m_pObj){
  579. hr = E_UNEXPECTED;
  580. return(hr);
  581. }/* end of if statement */
  582. hr = pSite->GetFocus();
  583. if(SUCCEEDED(hr)){
  584. if(m_pObj->HasFocus() == false){
  585. hr = S_FALSE;
  586. }
  587. else {
  588. if(S_FALSE == hr){
  589. m_pObj->SetFocus(false);
  590. hr = S_FALSE;
  591. }/* end of if statement */
  592. }/* end of if statement */
  593. }/* end of if statement */
  594. return(hr);
  595. }/* end of function GetFocus */
  596. /*************************************************************************/
  597. /* Function: SetFocus */
  598. /* Description: Sets focus to the control */
  599. /*************************************************************************/
  600. STDMETHODIMP CContainerObject::SetFocus(BOOL fFocus){
  601. GET_SITE
  602. if(NULL == m_pObj){
  603. hr = E_UNEXPECTED;
  604. return(hr);
  605. }/* end of if statement */
  606. if(fFocus && !m_pObj->IsActive()){
  607. // can't set focus to not active objects
  608. // but can take away focus from non active ones
  609. hr = S_FALSE;
  610. return(hr);
  611. }/* end of if statement */
  612. if(m_pObj->HasFocus() == (fFocus ? true: false)){
  613. // we are not chaning focus state so do not bother calling container
  614. hr = S_FALSE;
  615. return(hr);
  616. }/* end of if statement */
  617. // Call our "real" container object for count keeping
  618. // and signaling to its window or another container
  619. hr = pSite->SetFocus(fFocus);
  620. if(SUCCEEDED(hr)){
  621. m_pObj->SetFocus(fFocus ? true: false); // set the capture on the object
  622. }/* end of if statement */
  623. InvalidateObjectRect();
  624. return (hr);
  625. }/* end of function SetFocus */
  626. /*************************************************************************/
  627. /* Function: SetHostedObject */
  628. /* Description: Sets the control that we are hosting. */
  629. /*************************************************************************/
  630. STDMETHODIMP CContainerObject::SetHostedObject(LONG lVoid){
  631. // TODO!!!
  632. // THIS WILL BREAK ON WIN64
  633. // NEED TO PASS REAL INTERFACE AROUND
  634. HRESULT hr = S_OK;
  635. try {
  636. m_pObj = reinterpret_cast<CHostedObject*>(lVoid);
  637. }
  638. catch(...){
  639. hr = E_UNEXPECTED;
  640. }/* end of catch statement */
  641. return (hr);
  642. }/* end of function SetHostedObject */
  643. /*************************************************************************/
  644. /* IPropertyBag */
  645. /*************************************************************************/
  646. /*************************************************************************/
  647. /* Function: Read */
  648. /* Description: Reads a specific control property from a bag. */
  649. /* The bag looks like IE compatible <PARAM NAME="PropName" VALUE="value">*/
  650. /*************************************************************************/
  651. STDMETHODIMP CContainerObject::Read(LPCOLESTR pszPropName, VARIANT* pVar,
  652. IErrorLog* pErrorLog){
  653. HRESULT hr = S_OK;
  654. try {
  655. ATLTRACE2(atlTraceHosting, 0, _T("IPropertyBag::Read\r\n"));
  656. if(NULL == m_pObj){
  657. throw(E_UNEXPECTED);
  658. }/* end of if statement */
  659. if (NULL == pVar){
  660. throw(E_POINTER);
  661. }/* end of if statement */
  662. hr = ParsePropertyBag(pszPropName, pVar, pErrorLog);
  663. }
  664. catch(...){
  665. hr = E_UNEXPECTED;
  666. }/* end of catch statement */
  667. return (hr);
  668. }/* end of function Read */
  669. /*************************************************************************/
  670. /* Function: MyIsWhiteSpace */
  671. /* Local function implementation, since we do not have standart C lib */
  672. /* support */
  673. /*************************************************************************/
  674. static bool MyIsWhiteSpace( WCHAR c ){
  675. return c == L' ' ||
  676. c == L'\t' ||
  677. c == L'\r' ||
  678. c == L'\n';
  679. }/* end of function MyIsWhiteSpace */
  680. /*************************************************************************/
  681. /* Function: MyStrToDouble */
  682. /* Description: Reads in string and converts it to double */
  683. /* Returns E_INVALIDARG if there is alpah or some other undesired string*/
  684. /* S_OK if we got some string, S_FALSE if no number string (empty or spac*/
  685. /*************************************************************************/
  686. static HRESULT MyStrToDouble(WCHAR* pstr, double &n)
  687. {
  688. HRESULT hr = S_FALSE;
  689. int Sign = 1;
  690. n = 0; // result wil be n*Sign
  691. bool bBeforeDecimalPoint = true;
  692. double k = 10;
  693. // eat whitespace at start
  694. while( *pstr != L'\n' && MyIsWhiteSpace( *pstr ) ) {
  695. pstr++;
  696. }
  697. while( pstr[lstrlenW(pstr)-1]!= L'\n' && MyIsWhiteSpace( *pstr ) ) {
  698. pstr[lstrlenW(pstr)-1] = L'\0';
  699. }
  700. //lstrcmpiW is not implemented on 98 need to use STDLIB
  701. // TODO: eventaully replace the below _wcsicmp with our own so we can remove support
  702. // on standard C library
  703. if (_wcsicmp(pstr, L"true") == 0) {
  704. n = -1;
  705. return S_OK;
  706. }
  707. if (_wcsicmp(pstr, L"false") == 0) {
  708. n = 0;
  709. return S_OK;
  710. }
  711. if (pstr[0]==L'-'){
  712. Sign = -1;
  713. ++pstr;
  714. }/* end of if statement */
  715. for( ; ; ) {
  716. if (pstr[0]>=L'0' && pstr[0]<=L'9') {
  717. if(bBeforeDecimalPoint == true){
  718. n = 10*n+(int)(pstr[0]-L'0');
  719. } else {
  720. n = n+ ((int)(pstr[0]-L'0'))/k;
  721. k = k * 10; // decrease the decimal point
  722. }/* end of if statement */
  723. hr = S_OK;
  724. } else if ( MyIsWhiteSpace( pstr[0] ) || pstr[0] == L'\0' ) {
  725. break;
  726. } else if( bBeforeDecimalPoint && pstr[0] == L'.') {
  727. bBeforeDecimalPoint = false;
  728. } else {
  729. hr = E_INVALIDARG;
  730. break;
  731. }/* end of if statement */
  732. ++pstr;
  733. }/* end of for loop */
  734. n *= Sign; // adjust the sign
  735. return(hr);
  736. }/* end of function MyStrToDouble */
  737. /*************************************************************************/
  738. /* Function: CompSubstr */
  739. /* Description: ComaparesSubstr, eats up whithe spaces. */
  740. /*************************************************************************/
  741. HRESULT CompSubstr(WCHAR*& strSource, const WCHAR* strKey){
  742. bool bEatSpaces = true;
  743. register WCHAR wcKey = *strKey;
  744. register WCHAR wcSrc = *strSource;
  745. for(INT i = 0; wcKey != NULL; wcSrc = *(++strSource)){
  746. if(bEatSpaces){
  747. // eat up the spaces and tabs and enters and cr
  748. if(MyIsWhiteSpace(wcSrc)){
  749. continue;
  750. }
  751. else {
  752. bEatSpaces = false;
  753. }/* end of if statement */
  754. }/* end of if statement */
  755. if(wcKey != wcSrc){
  756. return(E_FAIL);
  757. }/* end of if statement */
  758. if(NULL == wcSrc){
  759. return(E_FAIL); // ran out of space in the source string
  760. }/* end of if statement */
  761. wcKey = strKey[++i]; // advance the key
  762. }/* end of for loop */
  763. return(S_OK);
  764. }/* end of function CompSubstr */
  765. /*************************************************************************/
  766. /* Function: ParsePropertyBag */
  767. /* Description: Retrives a property from the bag and puts it into variant*/
  768. /* if it fails returns E_FAIL. */
  769. /*************************************************************************/
  770. HRESULT CContainerObject::ParsePropertyBag(LPCOLESTR pszPropName, VARIANT* pVar,
  771. IErrorLog* /* pErrorLog */){
  772. HRESULT hr = S_OK;
  773. try {
  774. BSTR strBag = m_pObj->GetPropBag();
  775. if(NULL == strBag){
  776. throw(E_FAIL);
  777. }/* end of if statement */
  778. WCHAR* strValue = NULL; // the place where we are going to stick the actuall value
  779. // before putting it into variant
  780. WCHAR* strTmpValue = L"";
  781. WCHAR* strTmpBag = strBag;
  782. if(NULL == *strTmpBag){
  783. throw(E_FAIL);
  784. }/* end of if statement */
  785. INT iState = 0; // 0 start
  786. bool fFound = false;
  787. bool fFinished = false;
  788. INT iLength = 0; // noting the start and end of the value string
  789. // now try to parse out the value for the appropriate string
  790. for(INT i = 0; NULL != *strTmpBag && !fFinished; i++){
  791. switch(iState){
  792. case 0: // looking for start <
  793. if(FAILED(CompSubstr(strTmpBag, L"<"))) return (E_FAIL);
  794. iState = 1; break;
  795. case 1: // PARAM
  796. if(FAILED(CompSubstr(strTmpBag, L"PARAM"))) return (E_FAIL);
  797. iState = 2; break;
  798. case 2: // NAME
  799. if(FAILED(CompSubstr(strTmpBag, L"NAME"))) return (E_FAIL);
  800. iState = 3; break;
  801. case 3: // =
  802. if(FAILED(CompSubstr(strTmpBag, L"="))) return (E_FAIL);
  803. iState = 4; break;
  804. case 4: // "
  805. if(FAILED(CompSubstr(strTmpBag, L"\""))) return (E_FAIL);
  806. iState = 5; break;
  807. case 5: // pszPropName (the actual name)
  808. if(SUCCEEDED(CompSubstr(strTmpBag, pszPropName))){
  809. fFound = true; // found the PropName
  810. }/* end of if statement */
  811. iState = 6; break;
  812. case 6: // "
  813. if(SUCCEEDED(CompSubstr(strTmpBag, L"\""))){
  814. iState = 7;
  815. }
  816. else {
  817. strTmpBag++;
  818. }/* end of if statement */
  819. break;
  820. case 7: // VALUE
  821. if(FAILED(CompSubstr(strTmpBag, L"VALUE"))) return (E_FAIL);
  822. iState = 8; break;
  823. case 8: // =
  824. if(FAILED(CompSubstr(strTmpBag, L"="))) return (E_FAIL);
  825. iState = 9; break;
  826. case 9: // "
  827. if(FAILED(CompSubstr(strTmpBag, L"\""))) return (E_FAIL);
  828. iState = 10; break;
  829. case 10: // VALUE
  830. if(fFound){
  831. // read up the string and exit the loop
  832. strTmpValue = strTmpBag;
  833. }/* end of if statement */
  834. iState = 11; break;
  835. case 11: // "
  836. if(SUCCEEDED(CompSubstr(strTmpBag, L"\""))){
  837. iState = 12;
  838. if(fFound){
  839. iLength = strTmpBag - strTmpValue;
  840. strValue = new WCHAR[iLength];
  841. memcpy(strValue, strTmpValue, iLength * sizeof(WCHAR));
  842. strValue[iLength - 1] = NULL;
  843. // read up the string and exit the loop
  844. fFinished = true; // exit the loop
  845. }/* end of if statement */
  846. }
  847. else {
  848. strTmpBag++;
  849. }/* end of if statement */
  850. break;
  851. case 12: // closing brakcet >
  852. if(FAILED(CompSubstr(strTmpBag, L">"))) return (E_FAIL);
  853. iState = 0;
  854. break;
  855. }/* end of switch statement */
  856. }/* end of for loop */
  857. if(!fFinished){
  858. return(E_FAIL);
  859. }/* end of if statement */
  860. // at this moment we have value parsed out
  861. switch(pVar->vt){
  862. case VT_BSTR:
  863. pVar->bstrVal = ::SysAllocString(strValue);
  864. break;
  865. case VT_I4: {
  866. double dbl;
  867. if(MyStrToDouble(strValue, dbl) != S_OK){
  868. // S_FALSE denotes empty string
  869. throw(E_FAIL);
  870. }/* end of if statement */
  871. // TODO: Create MyStrToInt and do not cast
  872. pVar->lVal = (INT)dbl;
  873. }
  874. case VT_UI4:{
  875. double dbl;
  876. if(MyStrToDouble(strValue, dbl) != S_OK){
  877. // S_FALSE denotes empty string
  878. throw(E_FAIL);
  879. }/* end of if statement */
  880. // TODO: Create MyStrToInt and do not cast
  881. pVar->ulVal = (ULONG)dbl;
  882. }
  883. break;
  884. case VT_R4: {
  885. double dbl;
  886. if(MyStrToDouble(strValue, dbl) != S_OK){
  887. // S_FALSE denotes empty string
  888. throw(E_FAIL);
  889. }/* end of if statement */
  890. // TODO: Create MyStrToInt and do not cast
  891. pVar->fltVal = (FLOAT) dbl;
  892. }
  893. break;
  894. case VT_R8: {
  895. double dbl;
  896. if(MyStrToDouble(strValue, dbl) != S_OK){
  897. // S_FALSE denotes empty string
  898. throw(E_FAIL);
  899. }/* end of if statement */
  900. // TODO: Create MyStrToInt and do not cast
  901. pVar->dblVal = dbl;
  902. }
  903. break;
  904. case VT_BOOL: {
  905. double dbl;
  906. if(MyStrToDouble(strValue, dbl) != S_OK){
  907. // S_FALSE denotes empty string
  908. throw(E_FAIL);
  909. }/* end of if statement */
  910. // TODO: Create MyStrToInt and do not cast
  911. if(0.0 == dbl){
  912. pVar->boolVal = VARIANT_FALSE;
  913. }
  914. else if(1.0 == dbl || -1.0 == dbl){
  915. pVar->boolVal = VARIANT_TRUE;
  916. }
  917. else {
  918. throw(E_FAIL);
  919. }/* end of if statement */
  920. }
  921. break;
  922. default:
  923. ATLTRACE2(atlTraceHosting, 0, _T("This type is not implemented please add.\r\n"));
  924. ATLASSERT(FALSE);
  925. throw(E_FAIL);
  926. }/* end of switch statement */
  927. delete strValue; // cleanup our variable
  928. }
  929. catch(...){
  930. hr = E_UNEXPECTED;
  931. }/* end of catch statement */
  932. return (hr);
  933. }/* end of function ParsePropertyBag */
  934. /*************************************************************************/
  935. /* End of file: CCObj.cpp */
  936. /*************************************************************************/