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.

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