PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/ThirdParty/HTMLayoutSDK/include/wtl_htmlayouthost.h

#
C++ Header | 948 lines | 635 code | 184 blank | 129 comment | 89 complexity | 7eb6d19be1538c70d8c341279eb820ae MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-3.0, MIT, CC-BY-SA-3.0, GPL-2.0
  1. //
  2. // Windows Template Library Extension for
  3. // Terra Informatica Lightweight Embeddable HTMLayout control
  4. // http://terra-informatica.org/htmlayout
  5. //
  6. // Written by Andrew Fedoniouk and Pete Kvitek
  7. //
  8. // This file is NOT part of Windows Template Library.
  9. // The code and information is provided "as-is" without
  10. // warranty of any kind, either expressed or implied.
  11. //
  12. // (C) 2003, Pete Kvitek <pete@kvitek.com>
  13. // and Andrew Fedoniouk <andrew@TerraInformatica.com>
  14. //
  15. #ifndef __WTL_HTMLAYOUTHOST_H__
  16. #define __WTL_HTMLAYOUTHOST_H__
  17. #pragma once
  18. #ifndef __cplusplus
  19. #error ATL requires C++ compilation (use a .cpp suffix)
  20. #endif
  21. #ifndef __ATLAPP_H__
  22. #error wtl_htmlayouthost.h requires atlapp.h to be included first
  23. #endif
  24. #ifndef __ATLWIN_H__
  25. #error wtl_htmlayouthost.h requires atlwin.h to be included first
  26. #endif
  27. #include <atlmisc.h>
  28. #include <atlctrls.h>
  29. #ifdef _WIN32_WCE
  30. #include <commctrl.h>
  31. #define stricmp _stricmp
  32. #else
  33. #include <richedit.h>
  34. #endif
  35. #include "htmlayout.h"
  36. #include "htmlayout_behavior.h"
  37. #include "htmlayout_dom.hpp"
  38. #include "htmlayout_behavior.hpp"
  39. #include "behaviors/notifications.h"
  40. //#include "xool/xool.h"
  41. /////////////////////////////////////////////////////////////////////////////
  42. // Classes in this file
  43. //
  44. // CHTMLayoutHost<T>
  45. //
  46. namespace WTL
  47. {
  48. // Command name handler. Used primarily for handling button clicks
  49. // Mimics COMMAND_ID_HANDLER but uses html defined control name instead of ID
  50. #define HTML_WIDGET_HANDLER(element_name, func) \
  51. if(uMsg == WM_COMMAND) \
  52. { \
  53. LPCTSTR ctlName = GetDlgItemName((HWND)lParam); \
  54. if(ctlName && _tcsicmp(ctlName,element_name) == 0) \
  55. { \
  56. bHandled = TRUE; \
  57. lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
  58. if(bHandled) \
  59. return TRUE; \
  60. } \
  61. }
  62. // handles clicks on elements having behavior 'command'
  63. #define HTML_COMMAND_CLICK_HANDLER(lpwsElementId, func) \
  64. if(uMsg == WM_BEHAVIOR_NOTIFY && HLN_COMMAND_CLICK == ((LPNMHDR)lParam)->code ) \
  65. { \
  66. LPCWSTR srcElementId = ((NMHL_COMMAND_CLICK*)lParam)->szElementID; \
  67. if(wcscmp(srcElementId,lpwsElementId) == 0) \
  68. { \
  69. bHandled = TRUE; \
  70. HELEMENT he = ((NMHL_COMMAND_CLICK*)lParam)->he; \
  71. lResult = func(lpwsElementId, he, bHandled); \
  72. if(bHandled) \
  73. return TRUE; \
  74. } \
  75. }
  76. // George
  77. #define HTML_COMMAND_CLICK_HANDLER_EX(func) \
  78. if (uMsg == WM_BEHAVIOR_NOTIFY && HLN_COMMAND_CLICK == ((LPNMHDR)lParam)->code) \
  79. { \
  80. bHandled = TRUE; \
  81. lResult = func((NMHL_COMMAND_CLICK*)lParam, bHandled); \
  82. if (bHandled) \
  83. return TRUE; \
  84. }
  85. inline bool IsWindowsXP()
  86. {
  87. static int tristate = 0;
  88. if( tristate == 0 )
  89. {
  90. OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) };
  91. ::GetVersionEx(&ovi);
  92. tristate = ((ovi.dwMajorVersion == 5 && ovi.dwMinorVersion >= 1) || (ovi.dwMajorVersion > 5))? 1:-1;
  93. }
  94. return tristate == 1;
  95. }
  96. // HYPERLINK_HANDLER
  97. // Handles clicks on hyperlinks in html document
  98. // To be able to catch this notifications class should provide
  99. // following implementation of
  100. /*
  101. LRESULT OnHyperlink(NMHL_HYPERLINK* pnmhl, BOOL& bHandled);
  102. */
  103. #define HTML_HYPERLINK_HANDLER(func) \
  104. if(uMsg == WM_BEHAVIOR_NOTIFY && HLN_HYPERLINK == ((LPNMHDR)lParam)->code ) \
  105. { \
  106. bHandled = TRUE; \
  107. lResult = func((NMHL_HYPERLINK*)lParam, bHandled); \
  108. if(bHandled) \
  109. return TRUE; \
  110. }
  111. inline int GetAttrInt(HELEMENT he, LPCSTR attrName, int defaultValue = 0)
  112. {
  113. htmlayout::dom::element el = he;
  114. const wchar_t* pv = el.get_attribute(attrName);
  115. if(pv && wcslen(pv) > 0)
  116. return _wtoi(pv);
  117. return defaultValue;
  118. }
  119. inline CString GetElementType(HELEMENT he)
  120. {
  121. htmlayout::dom::element el = he;
  122. CString s = el.get_element_type();
  123. return s;
  124. }
  125. inline CString GetAttr(HELEMENT he, LPCSTR attrName)
  126. {
  127. htmlayout::dom::element el = he;
  128. CString s = el.get_attribute(attrName);
  129. return s;
  130. }
  131. inline bool HasAttr(HELEMENT he, LPCSTR attrName)
  132. {
  133. htmlayout::dom::element el = he;
  134. for(unsigned int i = 0; i < el.get_attribute_count(); ++i)
  135. {
  136. if(stricmp(el.get_attribute_name(i),attrName) == 0)
  137. return true;
  138. }
  139. return false;
  140. }
  141. /////////////////////////////////////////////////////////////////////////////
  142. // CHTMLayoutHost - host side implementation for a HTMLayout control
  143. template <class T>
  144. class CHTMLayoutHost
  145. {
  146. public:
  147. // HTMLayout callback
  148. static LRESULT CALLBACK callback(UINT uMsg, WPARAM wParam, LPARAM lParam, LPVOID vParam)
  149. {
  150. ATLASSERT(vParam);
  151. CHTMLayoutHost<T>* pThis = (CHTMLayoutHost<T>*)vParam;
  152. return pThis->OnHtmlNotify(uMsg, wParam, lParam);
  153. }
  154. void SetCallback()
  155. {
  156. T* pT = static_cast<T*>(this);
  157. ATLASSERT(::IsWindow(pT->m_hWnd));
  158. ::HTMLayoutSetCallback(pT->m_hWnd,callback, (CHTMLayoutHost<T>*)this);
  159. }
  160. void SetEventHandler(htmlayout::event_handler* peh)
  161. {
  162. T* pT = static_cast<T*>(this);
  163. ATLASSERT(::IsWindow(pT->m_hWnd));
  164. HTMLayoutWindowAttachEventHandler(pT->m_hWnd, htmlayout::event_handler::element_proc,peh,peh->subscribed_to);
  165. }
  166. // Overridables
  167. virtual LRESULT OnHtmlNotify(UINT uMsg, WPARAM wParam, LPARAM lParam)
  168. {
  169. ATLASSERT(uMsg == WM_NOTIFY);
  170. // Crack and call appropriate method
  171. // here are all notifiactions
  172. switch(((NMHDR*)lParam)->code)
  173. {
  174. case HLN_CREATE_CONTROL: return OnCreateControl((LPNMHL_CREATE_CONTROL) lParam);
  175. case HLN_CONTROL_CREATED: return OnControlCreated((LPNMHL_CREATE_CONTROL) lParam);
  176. case HLN_DESTROY_CONTROL: return OnDestroyControl((LPNMHL_DESTROY_CONTROL) lParam);
  177. case HLN_LOAD_DATA: return OnLoadData((LPNMHL_LOAD_DATA) lParam);
  178. case HLN_DATA_LOADED: return OnDataLoaded((LPNMHL_DATA_LOADED)lParam);
  179. case HLN_DOCUMENT_COMPLETE: return OnDocumentComplete();
  180. case HLN_ATTACH_BEHAVIOR: return OnAttachBehavior((LPNMHL_ATTACH_BEHAVIOR)lParam );
  181. case HLN_BEHAVIOR_CHANGED:
  182. case HLN_DIALOG_CREATED:
  183. case HLN_DIALOG_CLOSE_RQ:
  184. case HLN_DOCUMENT_LOADED: return 0; // not used in this wrapper.
  185. // generic common control notifications:
  186. /* not used in the wrapper, so they will go to OnHtmlGenericNotifications
  187. case NM_CLICK:
  188. case NM_DBLCLK:
  189. case NM_RETURN:
  190. case NM_RCLICK:
  191. case NM_RDBLCLK:
  192. case NM_SETFOCUS:
  193. case NM_KILLFOCUS:
  194. case NM_NCHITTEST:
  195. case NM_KEYDOWN:
  196. case NM_RELEASEDCAPTURE:
  197. case NM_SETCURSOR:
  198. case NM_CHAR:
  199. etc.
  200. //default:
  201. //ATLASSERT(FALSE); */
  202. }
  203. return OnHtmlGenericNotifications(uMsg,wParam,lParam);
  204. }
  205. virtual LRESULT OnHtmlGenericNotifications(UINT uMsg, WPARAM wParam, LPARAM lParam)
  206. {
  207. // all generic notifications
  208. // are coming to the parent of HTMLayout
  209. T* pT = static_cast<T*>(this);
  210. ATLASSERT(::IsWindow(pT->m_hWnd));
  211. // Pass it to the parent window if any
  212. HWND hWndParent = pT->GetParent();
  213. if (!hWndParent) return 0;
  214. return ::SendMessage(hWndParent, uMsg, wParam, lParam);
  215. }
  216. virtual LRESULT OnCreateControl(LPNMHL_CREATE_CONTROL pnmcc)
  217. {
  218. ATLTRACE(_T("CHTMLayoutHost::OnCreateControl: type='%s' \n"), GetElementType(pnmcc->helement) );
  219. // Try to create control and if failed, proceed with default processing.
  220. // Note that this code assumes that the host and control windows are the same. If
  221. // you are handling HTMLayout control notification in another window, you'll have
  222. // to override this method and provide proper hWnd.
  223. T* pT = static_cast<T*>(this);
  224. ATLASSERT(::IsWindow(pT->m_hWnd));
  225. return CreateControl(pT->m_hWnd, pnmcc);
  226. }
  227. virtual LRESULT OnControlCreated(LPNMHL_CREATE_CONTROL pnmcc)
  228. {
  229. ATLTRACE(_T("CHTMLayoutHost::OnControlCreated: type='%s' \n"), GetElementType(pnmcc->helement) );
  230. return 0;
  231. }
  232. virtual LRESULT OnDestroyControl(LPNMHL_DESTROY_CONTROL pnmhl)
  233. {
  234. ATLTRACE(_T("CHTMLayoutHost::OnDestroyControl: HWND=%x\n"), pnmhl->inoutControlHwnd);
  235. // use this if you don't want this child to be destroyed:
  236. // pnmhl->inoutControlHwnd = 0;
  237. // If you will not change pnmhl->inoutControlHwnd field then HTMLayout
  238. // will call ::DestroyWindow by itself.
  239. return 0;
  240. }
  241. virtual LRESULT OnLoadData(LPNMHL_LOAD_DATA pnmld)
  242. {
  243. ATLTRACE(_T("CHTMLayoutHost::OnLoadData: uri='%s'\n"), CString(pnmld->uri));
  244. // Try to load data from resource and if failed, proceed with default processing.
  245. // Note that this code assumes that the host and control windows are the same. If
  246. // you are handling HTMLayout control notification in another window, you'll have
  247. // to override this method and provide proper hWnd.
  248. T* pT = static_cast<T*>(this);
  249. ATLASSERT(::IsWindow(pT->m_hWnd));
  250. return LoadResourceData(pT->m_hWnd, pnmld->uri);
  251. }
  252. virtual LRESULT OnDataLoaded(LPNMHL_DATA_LOADED pnmld)
  253. {
  254. ATLTRACE(_T("CHTMLayoutHost::OnDataLoaded: uri='%s'\n"), CString(pnmld->uri));
  255. return 0;
  256. }
  257. virtual LRESULT OnDocumentComplete()
  258. {
  259. ATLTRACE(_T("CHTMLayoutHost::OnDocumentComplete\n"));
  260. return 0;
  261. }
  262. virtual LRESULT OnAttachBehavior( LPNMHL_ATTACH_BEHAVIOR lpab )
  263. {
  264. htmlayout::behavior::handle(lpab);
  265. return 0;
  266. }
  267. // Define module manager that will free loaded module upon exit
  268. struct Module
  269. {
  270. HMODULE hModule;
  271. bool freeOnDestruct;
  272. inline Module() : hModule(_Module.GetResourceInstance()), freeOnDestruct(false) {}
  273. inline ~Module() { if (freeOnDestruct && hModule) ::FreeLibrary(hModule); }
  274. HMODULE Load(LPCTSTR pszModule, DWORD flags) { freeOnDestruct = true; return hModule = ::LoadLibraryEx(pszModule, 0, flags); }
  275. operator HMODULE() const { return hModule; }
  276. };
  277. // Load Data helper routines
  278. #ifndef INVALID_FILE_ATTRIBUTES //wince has not it
  279. #define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF
  280. #endif
  281. static LRESULT LoadResourceData(HWND hWnd, LPCSTR uri )
  282. {
  283. USES_CONVERSION;
  284. return LoadResourceData(hWnd,A2CW(uri));
  285. }
  286. static LRESULT LoadResourceData(HWND hWnd, LPCWSTR uri )
  287. {
  288. USES_CONVERSION;
  289. ATLASSERT(::IsWindow(hWnd));
  290. // Check for trivial case
  291. if (!uri || !uri[0]) return LOAD_DISCARD;
  292. if (wcsncmp( uri, L"file:", 5 ) == 0 )
  293. return LOAD_OK;
  294. if (wcsncmp( uri, L"http:", 5 ) == 0 )
  295. return LOAD_OK;
  296. if (wcsncmp( uri, L"https:", 6 ) == 0 )
  297. return LOAD_OK;
  298. if (wcsncmp( uri, L"res:", 4 ) == 0 )
  299. {
  300. uri += 4;
  301. }
  302. //ATTN: you may wish to uncomment this 'else' and it will go further *only if* "res:...." url requested
  303. //else
  304. // return LOAD_OK;
  305. // Retrieve url specification into a local storage since FindResource() expects
  306. // to find its parameters on stack rather then on the heap under Win9x/Me
  307. TCHAR achURL[MAX_PATH]; lstrcpyn(achURL, W2CT(uri), MAX_PATH);
  308. Module module;
  309. // Separate name and handle external resource module specification
  310. LPTSTR psz, pszName = achURL;
  311. if ((psz = _tcsrchr(pszName, '/')) != NULL) {
  312. LPTSTR pszModule = pszName; pszName = psz + 1; *psz = '\0';
  313. DWORD dwAttr = ::GetFileAttributes(pszModule);
  314. if (dwAttr != INVALID_FILE_ATTRIBUTES && !(dwAttr & FILE_ATTRIBUTE_DIRECTORY)) {
  315. module.Load(pszModule, LOAD_LIBRARY_AS_DATAFILE);
  316. }
  317. }
  318. // Separate extension if any
  319. LPTSTR pszExt = _tcsrchr(pszName, '.'); if (pszExt) *pszExt++ = '\0';
  320. // Find specified resource and leave if failed. Note that we use extension
  321. // as the custom resource type specification or assume standard HTML resource
  322. // if no extension is specified
  323. HRSRC hrsrc = 0;
  324. bool isHtml = false;
  325. #ifndef _WIN32_WCE
  326. if( pszExt == 0 || _tcsicmp(pszExt,TEXT("HTML")) == 0)
  327. {
  328. hrsrc = ::FindResource(module, pszName, RT_HTML);
  329. isHtml = true;
  330. }
  331. else
  332. hrsrc = ::FindResource(module, pszName, pszExt);
  333. #else
  334. hrsrc = ::FindResource(module, pszName, pszExt);
  335. #endif
  336. if (!hrsrc) return LOAD_OK; // resource not found here - proceed with default loader
  337. // Load specified resource and check if ok
  338. HGLOBAL hgres = ::LoadResource(module, hrsrc);
  339. if (!hgres) return LOAD_DISCARD;
  340. // Retrieve resource data and check if ok
  341. PBYTE pb = (PBYTE)::LockResource(hgres); if (!pb) return LOAD_DISCARD;
  342. DWORD cb = ::SizeofResource(module, hrsrc); if (!cb) return LOAD_DISCARD;
  343. // Report data ready
  344. ::HTMLayoutDataReady(hWnd, uri, pb, cb);
  345. return LOAD_OK;
  346. }
  347. LRESULT LoadResourceData(LPNMHL_LOAD_DATA pnmld)
  348. {
  349. // This code assumes that the host and control windows are the same
  350. T* pT = static_cast<T*>(this);
  351. ATLASSERT(::IsWindow(pT->m_hWnd));
  352. return LoadResourceData(pT->m_hWnd, pnmld->uri);
  353. }
  354. virtual LRESULT CreateControl(HWND hWnd, LPNMHL_CREATE_CONTROL pnmcc)
  355. {
  356. ATLASSERT(::IsWindow(hWnd));
  357. ATLASSERT(pnmcc != NULL);
  358. CString type = GetAttr(pnmcc->helement, "type");
  359. // Create control of the specified type
  360. #ifndef _WIN32_WCE
  361. //if (type == _T("richedit")) return CreateRichEdit(pnmcc->inHwndParent, pnmcc);
  362. #endif
  363. if (type == _T("sys-datetime")) return CreateDateTime(pnmcc->inHwndParent, pnmcc);
  364. if (type == _T("sys-calendar")) return CreateCalendar(pnmcc->inHwndParent, pnmcc);
  365. //if (type == _T("listview")) return CreateListView(pnmcc->inHwndParent, pnmcc);
  366. //if (type == _T("treeview")) return CreateTreeView(pnmcc->inHwndParent, pnmcc);
  367. CString elementType = GetElementType(pnmcc->helement);
  368. if (elementType == _T("iframe"))
  369. return CreateHTMLayoutFrame(pnmcc->inHwndParent, pnmcc);
  370. return 0;
  371. }
  372. // Style table declarations
  373. #define STYLETABENTRY(prefix, style) { prefix##style, #style }
  374. #define STYLETABLEEND { 0, NULL }
  375. typedef struct _STYLETABLE {
  376. DWORD dwStyle;
  377. LPCSTR pszStyle;
  378. } STYLETABLE;
  379. static DWORD GetCtlStyle(LPNMHL_CREATE_CONTROL pnmcc, const STYLETABLE* pStyles, DWORD dwDefStyle = 0)
  380. {
  381. ATLASSERT(pnmcc != NULL);
  382. // Scan specified style table collecting styles
  383. DWORD dwStyle = 0;
  384. for (; pStyles->pszStyle != NULL; pStyles++) {
  385. if (HasAttr(pnmcc->helement,pStyles->pszStyle)) {
  386. dwStyle|= pStyles->dwStyle;
  387. }
  388. }
  389. // Return collected styles or default style if none specified
  390. return dwStyle | dwDefStyle;
  391. }
  392. // Generic window style handling
  393. static DWORD GetCtlStyle(LPNMHL_CREATE_CONTROL pnmcc, DWORD dwDefStyle = WS_CHILD | WS_TABSTOP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)
  394. {
  395. // Window style table
  396. static STYLETABLE aStyles[] = {
  397. STYLETABENTRY(WS_, OVERLAPPED),
  398. STYLETABENTRY(WS_, POPUP),
  399. STYLETABENTRY(WS_, CHILD),
  400. STYLETABENTRY(WS_, VISIBLE),
  401. STYLETABENTRY(WS_, DISABLED),
  402. STYLETABENTRY(WS_, CLIPSIBLINGS),
  403. STYLETABENTRY(WS_, CLIPCHILDREN),
  404. #ifndef _WIN32_WCE
  405. STYLETABENTRY(WS_, MINIMIZE),
  406. STYLETABENTRY(WS_, MAXIMIZE),
  407. #endif
  408. STYLETABENTRY(WS_, CAPTION),
  409. STYLETABENTRY(WS_, BORDER),
  410. STYLETABENTRY(WS_, DLGFRAME),
  411. STYLETABENTRY(WS_, VSCROLL),
  412. STYLETABENTRY(WS_, HSCROLL),
  413. STYLETABENTRY(WS_, SYSMENU),
  414. STYLETABENTRY(WS_, THICKFRAME),
  415. STYLETABENTRY(WS_, GROUP),
  416. STYLETABENTRY(WS_, TABSTOP),
  417. STYLETABENTRY(WS_, MINIMIZEBOX),
  418. STYLETABENTRY(WS_, MAXIMIZEBOX),
  419. STYLETABLEEND
  420. };
  421. return GetCtlStyle(pnmcc, aStyles, dwDefStyle);
  422. }
  423. static DWORD GetCtlExStyle(LPNMHL_CREATE_CONTROL pnmcc, DWORD dwDefExStyle = 0)
  424. {
  425. // Extended window style table
  426. #ifndef _WIN32_WCE
  427. static STYLETABLE aStyles[] = {
  428. STYLETABENTRY(WS_EX_, DLGMODALFRAME),
  429. STYLETABENTRY(WS_EX_, NOPARENTNOTIFY),
  430. STYLETABENTRY(WS_EX_, TOPMOST),
  431. STYLETABENTRY(WS_EX_, ACCEPTFILES),
  432. STYLETABENTRY(WS_EX_, TRANSPARENT),
  433. #if (WINVER >= 0x0400)
  434. STYLETABENTRY(WS_EX_, MDICHILD),
  435. STYLETABENTRY(WS_EX_, TOOLWINDOW),
  436. STYLETABENTRY(WS_EX_, WINDOWEDGE),
  437. STYLETABENTRY(WS_EX_, CLIENTEDGE),
  438. STYLETABENTRY(WS_EX_, CONTEXTHELP),
  439. #endif
  440. #if (WINVER >= 0x0400)
  441. STYLETABENTRY(WS_EX_, RIGHT),
  442. STYLETABENTRY(WS_EX_, LEFT),
  443. STYLETABENTRY(WS_EX_, RTLREADING),
  444. STYLETABENTRY(WS_EX_, LTRREADING),
  445. STYLETABENTRY(WS_EX_, LEFTSCROLLBAR),
  446. STYLETABENTRY(WS_EX_, RIGHTSCROLLBAR),
  447. STYLETABENTRY(WS_EX_, CONTROLPARENT),
  448. STYLETABENTRY(WS_EX_, STATICEDGE),
  449. STYLETABENTRY(WS_EX_, APPWINDOW),
  450. #endif
  451. #if (_WIN32_WINNT >= 0x0500)
  452. STYLETABENTRY(WS_EX_, LAYERED),
  453. #endif
  454. #if (WINVER >= 0x0500)
  455. STYLETABENTRY(WS_EX_, NOINHERITLAYOUT),
  456. STYLETABENTRY(WS_EX_, LAYOUTRTL),
  457. #endif
  458. #if (_WIN32_WINNT >= 0x0500)
  459. STYLETABENTRY(WS_EX_, NOACTIVATE),
  460. #endif
  461. #if (_WIN32_WINNT >= 0x0501)
  462. STYLETABENTRY(WS_EX_, COMPOSITED),
  463. #endif
  464. STYLETABLEEND
  465. };
  466. return GetCtlStyle(pnmcc, aStyles, dwDefExStyle);
  467. #else
  468. return dwDefExStyle;
  469. #endif
  470. }
  471. // Control factory routines
  472. #ifndef _WIN32_WCE
  473. virtual LRESULT CreateRichEdit(HWND hwndParent, LPNMHL_CREATE_CONTROL pnmcc)
  474. {
  475. ATLASSERT(::IsWindow(hwndParent));
  476. ATLASSERT(pnmcc != NULL);
  477. // Control style table
  478. static STYLETABLE aStyles[] = {
  479. STYLETABENTRY(ES_, LEFT),
  480. STYLETABENTRY(ES_, CENTER),
  481. STYLETABENTRY(ES_, RIGHT),
  482. STYLETABENTRY(ES_, MULTILINE),
  483. STYLETABENTRY(ES_, PASSWORD),
  484. STYLETABENTRY(ES_, AUTOVSCROLL),
  485. STYLETABENTRY(ES_, AUTOHSCROLL),
  486. STYLETABENTRY(ES_, NOHIDESEL),
  487. STYLETABENTRY(ES_, READONLY),
  488. STYLETABENTRY(ES_, WANTRETURN),
  489. #if(WINVER >= 0x0400)
  490. STYLETABENTRY(ES_, NUMBER),
  491. #endif
  492. STYLETABENTRY(ES_, SAVESEL),
  493. STYLETABENTRY(ES_, SUNKEN),
  494. STYLETABENTRY(ES_, DISABLENOSCROLL),
  495. STYLETABENTRY(ES_, SELECTIONBAR),
  496. STYLETABENTRY(ES_, NOOLEDRAGDROP),
  497. STYLETABENTRY(ES_, VERTICAL),
  498. STYLETABENTRY(ES_, NOIME),
  499. STYLETABENTRY(ES_, SELFIME),
  500. STYLETABLEEND
  501. };
  502. // Default richedit style
  503. const DWORD dwDefStyle = ES_MULTILINE
  504. | ES_WANTRETURN
  505. // | ES_AUTOVSCROLL
  506. // | ES_AUTOHSCROLL
  507. ;
  508. // Make up the control window style
  509. DWORD dwStyle = GetCtlStyle(pnmcc) | GetCtlStyle(pnmcc, aStyles, dwDefStyle);
  510. DWORD dwExStyle = GetCtlExStyle(pnmcc);
  511. // Create control and check if ok
  512. pnmcc->outControlHwnd = ::CreateWindowEx(
  513. dwExStyle, CRichEditCtrl::GetWndClassName(), NULL, dwStyle,
  514. 0, 0, 0, 0, hwndParent, (HMENU)(UINT_PTR)(GetAttrInt(pnmcc->helement,"id")), _Module.GetModuleInstance(), pnmcc);
  515. if (!pnmcc->outControlHwnd)
  516. {
  517. pnmcc->outControlHwnd = HWND_DISCARD_CREATION;
  518. return 0;
  519. }
  520. // Handle bottomless RichEdit controls
  521. if (HasAttr(pnmcc->helement,"autoheight")) {
  522. ::SendMessage(pnmcc->outControlHwnd, EM_SETEVENTMASK, 0, ENM_REQUESTRESIZE);
  523. }
  524. return 0;
  525. }
  526. #endif
  527. virtual LRESULT CreateHTMLayoutFrame(HWND hwndParent, LPNMHL_CREATE_CONTROL pnmcc)
  528. {
  529. ATLASSERT(::IsWindow(hwndParent));
  530. ATLASSERT(pnmcc != NULL);
  531. // Make up the control window style
  532. DWORD dwStyle = GetCtlStyle(pnmcc);
  533. DWORD dwExStyle = GetCtlExStyle(pnmcc);
  534. // Create control and check if ok
  535. pnmcc->outControlHwnd = ::CreateWindowEx(
  536. dwExStyle, CHTMLayoutCtrl::GetWndClassName(), NULL, dwStyle,
  537. 0, 0, 0, 0, hwndParent, (HMENU)(UINT_PTR)(GetAttrInt(pnmcc->helement,"id")), _Module.GetModuleInstance(), pnmcc);
  538. if (!pnmcc->outControlHwnd)
  539. {
  540. pnmcc->outControlHwnd = HWND_DISCARD_CREATION;
  541. return 0;
  542. }
  543. CHTMLayoutCtrl ctl = pnmcc->outControlHwnd;
  544. ::HTMLayoutSetCallback(ctl.m_hWnd, callback, (CHTMLayoutHost<T>*)this);
  545. // set inital text with 1 pix margins
  546. const char inittext[] =
  547. "<html><body leftmargin=1 topmargin=1 rightmargin=1 bottommargin=1>&nbsp;</body></html>";
  548. ctl.LoadHtml((LPCBYTE)inittext,sizeof(inittext));
  549. htmlayout::dom::element el = pnmcc->helement;
  550. wchar_t src[2048];
  551. const wchar_t* t = el.get_attribute("src");
  552. if( t )
  553. {
  554. USES_CONVERSION;
  555. wcsncpy(src,t,2047); src[2047] = 0;
  556. el.combine_url(src,2048);
  557. ctl.OpenFile(W2T(src));
  558. }
  559. return 0;
  560. }
  561. virtual LRESULT CreateDateTime(HWND hwndParent, LPNMHL_CREATE_CONTROL pnmcc)
  562. {
  563. ATLASSERT(::IsWindow(hwndParent));
  564. ATLASSERT(pnmcc != NULL);
  565. // Control style table
  566. static STYLETABLE aStyles[] = {
  567. STYLETABENTRY(DTS_, UPDOWN),
  568. STYLETABENTRY(DTS_, SHOWNONE),
  569. STYLETABENTRY(DTS_, SHORTDATEFORMAT),
  570. STYLETABENTRY(DTS_, LONGDATEFORMAT),
  571. #if (_WIN32_IE >= 0x500)
  572. STYLETABENTRY(DTS_, SHORTDATECENTURYFORMAT),
  573. #endif
  574. STYLETABENTRY(DTS_, TIMEFORMAT),
  575. STYLETABENTRY(DTS_, APPCANPARSE),
  576. STYLETABENTRY(DTS_, RIGHTALIGN),
  577. STYLETABLEEND
  578. };
  579. // Make up the control window style
  580. DWORD dwStyle = GetCtlStyle(pnmcc) | GetCtlStyle(pnmcc, aStyles);
  581. DWORD dwExStyle = GetCtlExStyle(pnmcc);
  582. // Create control and check if ok
  583. pnmcc->outControlHwnd = ::CreateWindowEx(
  584. dwExStyle, CDateTimePickerCtrl::GetWndClassName(), NULL, dwStyle,
  585. 0, 0, 0, 0, hwndParent, (HMENU)(UINT_PTR)(GetAttrInt(pnmcc->helement,"id")), _Module.GetModuleInstance(),
  586. pnmcc);
  587. if (!pnmcc->outControlHwnd)
  588. pnmcc->outControlHwnd = HWND_DISCARD_CREATION;
  589. return 0;
  590. }
  591. virtual LRESULT CreateCalendar(HWND hwndParent, LPNMHL_CREATE_CONTROL pnmcc)
  592. {
  593. ATLASSERT(::IsWindow(hwndParent));
  594. ATLASSERT(pnmcc != NULL);
  595. // Control style table
  596. static STYLETABLE aStyles[] = {
  597. STYLETABENTRY(MCS_, DAYSTATE),
  598. STYLETABENTRY(MCS_, MULTISELECT),
  599. STYLETABENTRY(MCS_, WEEKNUMBERS),
  600. #if (_WIN32_IE >= 0x0400)
  601. STYLETABENTRY(MCS_, NOTODAYCIRCLE),
  602. STYLETABENTRY(MCS_, NOTODAY),
  603. #else
  604. STYLETABENTRY(MCS_, NOTODAY),
  605. #endif
  606. STYLETABLEEND
  607. };
  608. // Make up the control window style
  609. DWORD dwStyle = GetCtlStyle(pnmcc) | GetCtlStyle(pnmcc, aStyles);
  610. DWORD dwExStyle = GetCtlExStyle(pnmcc);
  611. // Create control and check if ok
  612. pnmcc->outControlHwnd = ::CreateWindowEx(
  613. dwExStyle, CMonthCalendarCtrl::GetWndClassName(), NULL, dwStyle,
  614. 0, 0, 0, 0, hwndParent, (HMENU)(UINT_PTR)(GetAttrInt(pnmcc->helement,"id")), _Module.GetModuleInstance(),
  615. pnmcc);
  616. if (!pnmcc->outControlHwnd)
  617. pnmcc->outControlHwnd = HWND_DISCARD_CREATION;
  618. return 0;
  619. }
  620. virtual LRESULT CreateListView(HWND hwndParent, LPNMHL_CREATE_CONTROL pnmcc)
  621. {
  622. ATLASSERT(::IsWindow(hwndParent));
  623. ATLASSERT(pnmcc != NULL);
  624. // Control style table
  625. static STYLETABLE aStyles[] = {
  626. STYLETABENTRY(LVS_, ICON),
  627. STYLETABENTRY(LVS_, REPORT),
  628. STYLETABENTRY(LVS_, SMALLICON),
  629. STYLETABENTRY(LVS_, LIST),
  630. STYLETABENTRY(LVS_, SINGLESEL),
  631. STYLETABENTRY(LVS_, SHOWSELALWAYS),
  632. STYLETABENTRY(LVS_, SORTASCENDING),
  633. STYLETABENTRY(LVS_, SORTDESCENDING),
  634. STYLETABENTRY(LVS_, SHAREIMAGELISTS),
  635. STYLETABENTRY(LVS_, NOLABELWRAP),
  636. STYLETABENTRY(LVS_, AUTOARRANGE),
  637. STYLETABENTRY(LVS_, EDITLABELS),
  638. #if (_WIN32_IE >= 0x0300)
  639. STYLETABENTRY(LVS_, OWNERDATA),
  640. #endif
  641. STYLETABENTRY(LVS_, NOSCROLL),
  642. STYLETABENTRY(LVS_, ALIGNTOP),
  643. STYLETABENTRY(LVS_, ALIGNLEFT),
  644. STYLETABENTRY(LVS_, OWNERDRAWFIXED),
  645. STYLETABENTRY(LVS_, NOCOLUMNHEADER),
  646. STYLETABENTRY(LVS_, NOSORTHEADER),
  647. STYLETABLEEND
  648. };
  649. // Extended control style table
  650. static STYLETABLE aExStyles[] = {
  651. STYLETABENTRY(LVS_EX_, GRIDLINES),
  652. STYLETABENTRY(LVS_EX_, SUBITEMIMAGES),
  653. STYLETABENTRY(LVS_EX_, CHECKBOXES),
  654. STYLETABENTRY(LVS_EX_, TRACKSELECT),
  655. STYLETABENTRY(LVS_EX_, HEADERDRAGDROP),
  656. STYLETABENTRY(LVS_EX_, FULLROWSELECT),
  657. STYLETABENTRY(LVS_EX_, ONECLICKACTIVATE),
  658. #ifndef _WIN32_WCE
  659. STYLETABENTRY(LVS_EX_, TWOCLICKACTIVATE),
  660. #if (_WIN32_IE >= 0x0400)
  661. STYLETABENTRY(LVS_EX_, FLATSB),
  662. STYLETABENTRY(LVS_EX_, REGIONAL),
  663. STYLETABENTRY(LVS_EX_, INFOTIP),
  664. STYLETABENTRY(LVS_EX_, UNDERLINEHOT),
  665. STYLETABENTRY(LVS_EX_, UNDERLINECOLD),
  666. STYLETABENTRY(LVS_EX_, MULTIWORKAREAS),
  667. #endif
  668. #if (_WIN32_IE >= 0x0500)
  669. STYLETABENTRY(LVS_EX_, LABELTIP),
  670. STYLETABENTRY(LVS_EX_, BORDERSELECT),
  671. #endif
  672. #if (_WIN32_WINNT >= 0x501)
  673. STYLETABENTRY(LVS_EX_, DOUBLEBUFFER),
  674. STYLETABENTRY(LVS_EX_, HIDELABELS),
  675. STYLETABENTRY(LVS_EX_, SINGLEROW),
  676. STYLETABENTRY(LVS_EX_, SNAPTOGRID),
  677. STYLETABENTRY(LVS_EX_, SIMPLESELECT),
  678. #endif
  679. #endif
  680. STYLETABLEEND
  681. };
  682. // Make up the control window style
  683. DWORD dwStyle = GetCtlStyle(pnmcc) | GetCtlStyle(pnmcc, aStyles);
  684. DWORD dwExStyle = GetCtlExStyle(pnmcc) | GetCtlStyle(pnmcc, aExStyles);
  685. #ifdef FLICKER_FREE_COMCTL // force double buffering for it
  686. if( IsWindowsXP() )
  687. dwExStyle |= WS_EX_COMPOSITED;
  688. #endif
  689. // Create control and check if ok
  690. pnmcc->outControlHwnd = ::CreateWindowEx(
  691. dwExStyle, CListViewCtrl::GetWndClassName(), NULL, dwStyle,
  692. 0, 0, 0, 0, hwndParent, (HMENU)(UINT_PTR)(GetAttrInt(pnmcc->helement,"id")), _Module.GetModuleInstance(),
  693. pnmcc);
  694. if (!pnmcc->outControlHwnd)
  695. pnmcc->outControlHwnd = HWND_DISCARD_CREATION;
  696. return 0;
  697. }
  698. virtual LRESULT CreateTreeView(HWND hwndParent, LPNMHL_CREATE_CONTROL pnmcc)
  699. {
  700. ATLASSERT(::IsWindow(hwndParent));
  701. ATLASSERT(pnmcc != NULL);
  702. // Control style table
  703. static STYLETABLE aStyles[] = {
  704. STYLETABENTRY(TVS_, HASBUTTONS),
  705. STYLETABENTRY(TVS_, HASLINES),
  706. STYLETABENTRY(TVS_, LINESATROOT),
  707. STYLETABENTRY(TVS_, EDITLABELS),
  708. STYLETABENTRY(TVS_, DISABLEDRAGDROP),
  709. STYLETABENTRY(TVS_, SHOWSELALWAYS),
  710. #if (_WIN32_IE >= 0x0300)
  711. STYLETABENTRY(TVS_, RTLREADING),
  712. STYLETABENTRY(TVS_, NOTOOLTIPS),
  713. STYLETABENTRY(TVS_, CHECKBOXES),
  714. STYLETABENTRY(TVS_, TRACKSELECT),
  715. #if (_WIN32_IE >= 0x0400)
  716. STYLETABENTRY(TVS_, SINGLEEXPAND),
  717. #ifndef _WIN32_WCE
  718. STYLETABENTRY(TVS_, INFOTIP),
  719. STYLETABENTRY(TVS_, FULLROWSELECT),
  720. STYLETABENTRY(TVS_, NOSCROLL),
  721. STYLETABENTRY(TVS_, NONEVENHEIGHT),
  722. #endif
  723. #endif
  724. #if (_WIN32_IE >= 0x500)
  725. STYLETABENTRY(TVS_, NOHSCROLL),
  726. #endif
  727. #endif
  728. STYLETABLEEND
  729. };
  730. // Make up the control window style
  731. DWORD dwStyle = GetCtlStyle(pnmcc) | GetCtlStyle(pnmcc, aStyles);
  732. DWORD dwExStyle = GetCtlExStyle(pnmcc);
  733. #ifdef FLICKER_FREE_COMCTL // force double buffering for it
  734. if( IsWindowsXP() )
  735. dwExStyle |= WS_EX_COMPOSITED;
  736. #endif
  737. // Create control and check if ok
  738. pnmcc->outControlHwnd = ::CreateWindowEx(
  739. dwExStyle, CTreeViewCtrl::GetWndClassName(), NULL, dwStyle,
  740. 0, 0, 0, 0, hwndParent, (HMENU)(UINT_PTR)(GetAttrInt(pnmcc->helement,"id")), _Module.GetModuleInstance(),
  741. pnmcc);
  742. /*CTreeViewCtrl ctl = pnmcc->outControlHwnd;
  743. for( int i = 0; i < 30; ++i )
  744. {
  745. char buf[64];
  746. sprintf(buf,"item %d",i);
  747. ctl.InsertItem(buf,0,0);
  748. }*/
  749. if (!pnmcc->outControlHwnd)
  750. pnmcc->outControlHwnd = HWND_DISCARD_CREATION;
  751. return 0;
  752. }
  753. // Cleanup local defines
  754. #undef STYLETABENTRY
  755. #undef STYLETABLEEND
  756. };
  757. }; //namespace WTL
  758. // George - 11.Mar.2005
  759. #ifdef _ATL
  760. #if _ATL_VER >= 7
  761. #undef _Module
  762. #endif
  763. #endif
  764. #endif // __ATLHTMENGINEHOST_H__