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.

300 lines
8.2 KiB

  1. // Page.cpp: implementation of the TaskPage class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "Page.h"
  6. ////////////////////////////////////////////////////////
  7. // ActiveX Host Element
  8. class AxHost : public HWNDHost
  9. {
  10. public:
  11. static HRESULT Create(Element**) { return E_NOTIMPL; } // Required for ClassInfo
  12. static HRESULT Create(OUT AxHost** ppElement) { return Create(0, AE_MouseAndKeyboard, ppElement); }
  13. static HRESULT Create(UINT nCreate, UINT nActive, OUT AxHost** ppElement);
  14. ~AxHost() { ATOMICRELEASE(_pOleObject); }
  15. // Initialization
  16. HRESULT AttachControl(IUnknown* punkObject);
  17. // Rendering
  18. virtual SIZE GetContentSize(int dConstW, int dConstH, Surface* psrf);
  19. // ClassInfo accessors (static and virtual instance-based)
  20. static IClassInfo* Class;
  21. virtual IClassInfo* GetClassInfo() { return Class; }
  22. protected:
  23. AxHost() : _pOleObject(NULL) {}
  24. virtual HWND CreateHWND(HWND hwndParent)
  25. {
  26. return CreateWindowEx(0,
  27. CAxWindow::GetWndClassName(),
  28. NULL,
  29. WS_CHILD | WS_VISIBLE,
  30. 0, 0, 0, 0,
  31. hwndParent,
  32. NULL,
  33. NULL,
  34. NULL);
  35. }
  36. private:
  37. IOleObject* _pOleObject;
  38. };
  39. ////////////////////////////////////////////////////////
  40. // AxHost Initialization
  41. HRESULT AxHost::Create(UINT nCreate, UINT nActive, OUT AxHost** ppElement)
  42. {
  43. if (!ppElement)
  44. return E_POINTER;
  45. *ppElement = NULL;
  46. AxHost* pe = new AxHost;
  47. if (!pe)
  48. return E_OUTOFMEMORY;
  49. HRESULT hr = pe->Initialize(nCreate, nActive);
  50. if (FAILED(hr))
  51. {
  52. pe->Destroy();
  53. }
  54. else
  55. {
  56. *ppElement = pe;
  57. }
  58. return hr;
  59. }
  60. HRESULT AxHost::AttachControl(IUnknown* punkObject)
  61. {
  62. HRESULT hr;
  63. if (NULL == GetHWND())
  64. return E_UNEXPECTED;
  65. if (NULL == punkObject)
  66. return E_INVALIDARG;
  67. ATOMICRELEASE(_pOleObject);
  68. hr = punkObject->QueryInterface(IID_IOleObject, (void**)&_pOleObject);
  69. if (SUCCEEDED(hr))
  70. {
  71. CComPtr<IUnknown> spUnk;
  72. hr = AtlAxGetHost(GetHWND(), &spUnk);
  73. if (SUCCEEDED(hr))
  74. {
  75. CComPtr<IAxWinHostWindow> spAxHostWindow;
  76. hr = spUnk->QueryInterface(&spAxHostWindow);
  77. if (SUCCEEDED(hr))
  78. {
  79. hr = spAxHostWindow->AttachControl(punkObject, GetHWND());
  80. }
  81. }
  82. }
  83. return hr;
  84. }
  85. ////////////////////////////////////////////////////////
  86. // AxHost Rendering
  87. SIZE AxHost::GetContentSize(int dConstW, int dConstH, Surface* psrf)
  88. {
  89. SIZE size = { 0, 0 };
  90. // Ask the attached ActiveX control for its preferred size
  91. if (NULL != _pOleObject)
  92. {
  93. SIZEL sizeT;
  94. if (SUCCEEDED(_pOleObject->GetExtent(DVASPECT_CONTENT, &sizeT)))
  95. {
  96. int dpiX;
  97. int dpiY;
  98. switch (psrf->GetType())
  99. {
  100. case Surface::stDC:
  101. {
  102. HDC hDC = CastHDC(psrf);
  103. dpiX = GetDeviceCaps(hDC, LOGPIXELSX);
  104. dpiY = GetDeviceCaps(hDC, LOGPIXELSX);
  105. }
  106. break;
  107. #ifdef GADGET_ENABLE_GDIPLUS
  108. case Surface::stGdiPlus:
  109. {
  110. Gdiplus::Graphics * pgpgr = CastGraphics(psrf);
  111. dpiX = (int)pgpgr->GetDpiX();
  112. dpiY = (int)pgpgr->GetDpiY();
  113. }
  114. break;
  115. #endif
  116. default:
  117. dpiX = dpiY = 96;
  118. break;
  119. }
  120. // Convert from HIMETRIC to pixels
  121. size.cx = (MAXLONG == sizeT.cx) ? MAXLONG : MulDiv(sizeT.cx, dpiX, 2540);
  122. size.cy = (MAXLONG == sizeT.cy) ? MAXLONG : MulDiv(sizeT.cy, dpiY, 2540);
  123. if (-1 != dConstW && size.cx > dConstW) size.cx = dConstW;
  124. if (-1 != dConstH && size.cy > dConstH) size.cy = dConstH;
  125. }
  126. }
  127. return size;
  128. }
  129. ////////////////////////////////////////////////////////
  130. // Property definitions
  131. /** Property template (replace !!!), also update private PropertyInfo* parray and class header (element.h)
  132. // !!! property
  133. static int vv!!![] = { DUIV_INT, -1 }; StaticValue(svDefault!!!, DUIV_INT, 0);
  134. static PropertyInfo imp!!!Prop = { L"!!!", PF_Normal, 0, vv!!!, (Value*)&svDefault!!! };
  135. PropertyInfo* Element::!!!Prop = &imp!!!Prop;
  136. **/
  137. ////////////////////////////////////////////////////////
  138. // ClassInfo (must appear after property definitions)
  139. // Class properties
  140. //static PropertyInfo* _aPI[] = {;};
  141. // Define class info with type and base type, set static class pointer
  142. static ClassInfo<AxHost,HWNDHost> _ciAxHost(L"AxHost", NULL, 0);
  143. //static ClassInfo<AxHost,HWNDHost> _ciAxHost(L"AxHost", _aPI, sizeof(_aPI) / sizeof(PropertyInfo*));
  144. IClassInfo* AxHost::Class = &_ciAxHost;
  145. //////////////////////////////////////////////////////////////////////
  146. // Construction/Destruction
  147. //////////////////////////////////////////////////////////////////////
  148. HRESULT TaskPage::Create(REFCLSID rclsidPage, HWND hParent, OUT TaskPage** ppElement)
  149. {
  150. if (!ppElement)
  151. return E_POINTER;
  152. *ppElement = NULL;
  153. TaskPage* pe = new TaskPage(rclsidPage);
  154. if (!pe)
  155. return E_OUTOFMEMORY;
  156. HRESULT hr = pe->Initialize(hParent, /*double-buffer*/ true, 0);
  157. if (FAILED(hr))
  158. {
  159. pe->Destroy();
  160. }
  161. else
  162. {
  163. *ppElement = pe;
  164. }
  165. return hr;
  166. }
  167. HRESULT TaskPage::CreateContent(ITaskPage* pPage)
  168. {
  169. HRESULT hr;
  170. UINT nPane;
  171. if (NULL != _pTaskPage)
  172. return E_UNEXPECTED;
  173. if (NULL == _hWnd)
  174. return E_FAIL;
  175. if (NULL == pPage)
  176. return E_INVALIDARG;
  177. _pTaskPage = pPage;
  178. _pTaskPage->AddRef();
  179. for (nPane = 0; ; nPane++)
  180. {
  181. // Panes are sequentially numbered, starting at 0, with id names
  182. // "Pane0", "Pane1", etc.
  183. WCHAR szPane[16] = L"Pane";
  184. _ultow(nPane, &szPane[4], 10);
  185. // Don't use StrToID here since it asserts success
  186. // but we expect it to fail.
  187. ATOM atomID = FindAtomW(szPane);
  188. if (INVALID_ATOM == atomID)
  189. {
  190. // No more panes
  191. break;
  192. }
  193. Element *pePane = FindDescendent(atomID);
  194. if (NULL != pePane)
  195. {
  196. // How many objects are in this pane?
  197. UINT cObjects = 0;
  198. hr = _pTaskPage->GetObjectCount(nPane, &cObjects);
  199. if (SUCCEEDED(hr) && 0 != cObjects)
  200. {
  201. UINT nObject;
  202. for (nObject = 0; nObject < cObjects; nObject++)
  203. {
  204. // Create the object
  205. CComPtr<IUnknown> spObject;
  206. hr = _pTaskPage->CreateObject(nPane, nObject, IID_IUnknown, (void**)&spObject);
  207. if (SUCCEEDED(hr))
  208. {
  209. AxHost* pAxHost;
  210. // Create an AxHost container for the object
  211. hr = AxHost::Create(&pAxHost);
  212. if (SUCCEEDED(hr))
  213. {
  214. // Add the element to the heirarchy
  215. // Note: this is where AxHost::CreateHWND() is called
  216. hr = pePane->Add(pAxHost);
  217. if (SUCCEEDED(hr))
  218. {
  219. // Must have an HWND for this to work, so do
  220. // this after pePane->Add.
  221. hr = pAxHost->AttachControl(spObject);
  222. if (FAILED(hr))
  223. {
  224. pePane->Remove(pAxHost);
  225. delete pAxHost; //::DestroyWindow(pAxHost->GetHWND());
  226. }
  227. }
  228. }
  229. }
  230. }
  231. }
  232. }
  233. }
  234. // Turn on WS_VISIBLE
  235. SetVisible(true);
  236. return S_OK;
  237. }
  238. HRESULT TaskPage::Reinitialize()
  239. {
  240. if (NULL == _pTaskPage)
  241. return E_UNEXPECTED;
  242. return _pTaskPage->Reinitialize(0);
  243. }