PageRenderTime 49ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/src/HTMLayout/include/htmlayout_dom.hpp

#
C++ Header | 1561 lines | 994 code | 213 blank | 354 comment | 106 complexity | 9afa5f724bec80ae39d1d385620def7f MD5 | raw file
Possible License(s): MIT

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Terra Informatica Lightweight Embeddable HTMLayout control
  3. * http://terrainformatica.com/htmlayout
  4. *
  5. * HTMLayout DOM implementation. C++ wrapper
  6. *
  7. * The code and information provided "as-is" without
  8. * warranty of any kind, either expressed or implied.
  9. *
  10. * (C) 2003-2004, Andrew Fedoniouk (andrew@terrainformatica.com)
  11. */
  12. /**\file
  13. * \brief \link htmlayout_dom.h DOM \endlink C++ wrapper
  14. **/
  15. #ifndef __htmlayout_dom_hpp__
  16. #define __htmlayout_dom_hpp__
  17. #pragma once
  18. #include "value.h"
  19. #include "htmlayout_dom.h"
  20. #include "htmlayout_aux.h"
  21. #include "htmlayout_queue.h"
  22. #include <assert.h>
  23. #include <stdio.h> // for vsnprintf
  24. #include <vector> // for dom_iterator
  25. #pragma warning( push )
  26. #pragma warning(disable:4786) //identifier was truncated...
  27. #pragma warning(disable:4996) //'strcpy' was declared deprecated
  28. #pragma warning(disable:4100) //unreferenced formal parameter
  29. /**htmlayout namespace.*/
  30. namespace htmlayout
  31. {
  32. /**dom namespace.*/
  33. namespace dom
  34. {
  35. /**callback structure.
  36. * Used with #htmlayout::dom::element::select() function.
  37. **/
  38. class callback
  39. {
  40. public:
  41. /**Is called for every element that match criteria specified when calling to #htmlayout::dom::element::select() function.*/
  42. virtual bool on_element(HELEMENT he) = 0; /* return false to continue enumeration*/
  43. #if !defined(_MSC_VER) || _MSC_VER > 1200
  44. virtual ~callback() {} // this line causing internal compiler error in VC6
  45. #endif
  46. };
  47. class expando; // DOM element expando structure
  48. /** Helper class for element [] operator **/
  49. class attribute_accessor {
  50. public:
  51. HELEMENT el_;
  52. LPCSTR key_;
  53. attribute_accessor(HELEMENT el, LPCSTR key)
  54. {
  55. el_ = (HTMLayout_UseElement(el) == HLDOM_OK) ? el : 0;
  56. key_ = key;
  57. }
  58. ~attribute_accessor()
  59. {
  60. HLDOM_RESULT r = HTMLayout_UnuseElement(el_);
  61. assert(r == HLDOM_OK);r;
  62. }
  63. attribute_accessor &operator= (const wchar_t* value)
  64. {
  65. HLDOM_RESULT r = HTMLayoutSetAttributeByName(el_, key_, value);
  66. assert(r == HLDOM_OK);r;
  67. return *this;
  68. }
  69. attribute_accessor &operator= (int value)
  70. {
  71. HLDOM_RESULT r = HTMLayoutSetAttributeByName(el_, key_, i2w(value));
  72. assert(r == HLDOM_OK);r;
  73. return *this;
  74. }
  75. bool operator ==(const attribute_accessor &rv) const
  76. {
  77. return wcscmp(this->operator const wchar_t*(), rv.operator const wchar_t*()) == 0;
  78. }
  79. bool operator !=(const attribute_accessor &rv) const
  80. {
  81. return wcscmp(this->operator const wchar_t*(), rv.operator const wchar_t*()) != 0;
  82. }
  83. bool operator <(const attribute_accessor &rv) const
  84. {
  85. return wcscmp(this->operator const wchar_t*(), rv.operator const wchar_t*()) < 0;
  86. }
  87. bool operator >(const attribute_accessor &rv) const
  88. {
  89. return wcscmp(this->operator const wchar_t*(), rv.operator const wchar_t*()) > 0;
  90. }
  91. operator const wchar_t*() const
  92. {
  93. const wchar_t* lpw = 0;
  94. if( key_[0] == '-' && (HTMLayoutGetStyleAttribute(el_, key_, &lpw) == HLDOM_OK) && lpw)
  95. return lpw;
  96. HTMLayoutGetAttributeByName(el_, key_[0] == '-' ? key_ + 1 : key_, &lpw);
  97. return lpw;
  98. }
  99. /** To get int value use it this way: element["attribute"].get(0) **/
  100. int get(int default_value)
  101. {
  102. const wchar_t* attr = this->operator const wchar_t*();
  103. return aux::wtoi(attr,default_value);
  104. }
  105. void remove()
  106. {
  107. HTMLayoutSetAttributeByName(el_, key_, 0);
  108. }
  109. };
  110. /**DOM element.
  111. Smart pointer, pretty much std::shared_ptr thing */
  112. class element
  113. {
  114. protected:
  115. HELEMENT he;
  116. void use(HELEMENT h) { he = (HTMLayout_UseElement(h) == HLDOM_OK)? h: 0; }
  117. void unuse() { if(he) HTMLayout_UnuseElement(he); he = 0; }
  118. void set(HELEMENT h) { unuse(); use(h); }
  119. public:
  120. /**Construct \c undefined element .
  121. **/
  122. element(): he(0) { }
  123. /**Construct \c element from existing element handle.
  124. * \param h \b #HELEMENT
  125. **/
  126. element(HELEMENT h) { use(h); }
  127. /**Copy constructor;
  128. * \param e \b #element
  129. **/
  130. element(const element& e) { use(e.he); }
  131. operator HELEMENT() const { return he; }
  132. /**Destructor.*/
  133. ~element() { unuse(); }
  134. /** Get/set attribute of DOM element. It is possible to get style attribute via placing '-' in the beginning of attribute name */
  135. attribute_accessor operator[](const char* key)
  136. {
  137. return attribute_accessor(he, key);
  138. }
  139. dom::element operator[](unsigned int child_index)
  140. {
  141. assert(children_count() > child_index);
  142. return dom::element(child(child_index));
  143. }
  144. /**Assign \c element an \c #HELEMENT
  145. * \param h \b #HELEMENT
  146. * \return \b #element&
  147. **/
  148. element& operator = (HELEMENT h) { set(h); return *this; }
  149. /**Assign \c element another \c #element
  150. * \param e \b #element
  151. * \return \b #element&
  152. **/
  153. element& operator = (const element& e) { set(e.he); return *this; }
  154. /**Test equality of this and another \c #element's
  155. * \param rs \b const \b #element
  156. * \return \b bool, true if elements are equal, false otherwise
  157. **/
  158. bool operator == (const element& rs ) const { return he == rs.he; }
  159. bool operator == (HELEMENT rs ) const { return he == rs; }
  160. /**Test equality of this and another \c #element's
  161. * \param rs \b const \b #element
  162. * \return \b bool, true if elements are not equal, false otherwise
  163. **/
  164. bool operator != (const element& rs ) const { return he != rs.he; }
  165. /**Test whether element is valid.
  166. * \return \b bool, true if element is valid, false otherwise
  167. **/
  168. bool is_valid() const { return he != 0; }
  169. /**Tests whether element is memeber of the DOM or is it detached.
  170. * \return \b bool, true if element is in the DOM, false otherwise
  171. **/
  172. bool is_alive() const { return root() != 0; }
  173. /**Get number of child elements.
  174. * \return \b int, number of child elements
  175. **/
  176. unsigned int children_count() const
  177. {
  178. UINT count = 0;
  179. HTMLayoutGetChildrenCount(he, &count);
  180. return count;
  181. }
  182. /**Get Nth child element.
  183. * \param index \b unsigned \b int, number of the child element
  184. * \return \b #HELEMENT, child element handle
  185. **/
  186. HELEMENT child( unsigned int index ) const
  187. {
  188. HELEMENT child = 0;
  189. HTMLayoutGetNthChild(he, index, &child);
  190. return child;
  191. }
  192. /**Get parent element.
  193. * \return \b #HELEMENT, handle of the parent element
  194. **/
  195. HELEMENT parent( ) const
  196. {
  197. HELEMENT hparent = 0;
  198. HTMLayoutGetParentElement(he, &hparent);
  199. return hparent;
  200. }
  201. /**Get index of this element in its parent collection.
  202. * \return \b unsigned \b int, index of this element in its parent collection
  203. **/
  204. unsigned int index( ) const
  205. {
  206. UINT index = 0;
  207. HTMLayoutGetElementIndex(he, &index);
  208. return index;
  209. }
  210. /**Get number of the attributes.
  211. * \return \b unsigned \b int, number of the attributes
  212. **/
  213. unsigned int get_attribute_count( ) const
  214. {
  215. UINT n = 0;
  216. HTMLayoutGetAttributeCount(he, &n);
  217. return n;
  218. }
  219. /**Get attribute value by its index.
  220. * \param n \b unsigned \b int, number of the attribute
  221. * \return \b const \b wchar_t*, value of the n-th attribute
  222. **/
  223. const wchar_t* get_attribute( unsigned int n ) const
  224. {
  225. LPCWSTR lpw = 0;
  226. HTMLayoutGetNthAttribute(he, n, 0, &lpw);
  227. return lpw;
  228. }
  229. /**Get attribute name by its index.
  230. * \param n \b unsigned \b int, number of the attribute
  231. * \return \b const \b char*, name of the n-th attribute
  232. **/
  233. const char* get_attribute_name( unsigned int n ) const
  234. {
  235. LPCSTR lpc = 0;
  236. HTMLayoutGetNthAttribute(he, n, &lpc, 0);
  237. return lpc;
  238. }
  239. /**Get attribute value by name.
  240. * \param name \b const \b char*, name of the attribute
  241. * \return \b const \b wchar_t*, value of the n-th attribute
  242. **/
  243. const wchar_t* get_attribute( const char* name ) const
  244. {
  245. LPCWSTR lpw = 0;
  246. HTMLayoutGetAttributeByName(he, name, &lpw);
  247. return lpw;
  248. }
  249. /**Add or replace attribute.
  250. * \param name \b const \b char*, name of the attribute
  251. * \param value \b const \b wchar_t*, name of the attribute
  252. **/
  253. void set_attribute( const char* name, const wchar_t* value )
  254. {
  255. HTMLayoutSetAttributeByName(he, name, value);
  256. }
  257. /**Get attribute integer value by name.
  258. * \param name \b const \b char*, name of the attribute
  259. * \return \b int , value of the attribute
  260. **/
  261. int get_attribute_int( const char* name, int def_val = 0 ) const
  262. {
  263. const wchar_t* txt = get_attribute(name);
  264. if(!txt) return def_val;
  265. return _wtoi(txt);
  266. }
  267. /**Special form of get attribute value by name, it tries to get value from attribute
  268. * collection and if fails then from custom style attribute (that has to start from '-')
  269. * \param name \b const \b char*, name of the attribute that shall start from "-" sign
  270. * \return \b const wchar_t* , value of the attribute
  271. **/
  272. const wchar_t* attribute( const char* name, const wchar_t* default_value ) const
  273. {
  274. assert(name[0] == '-');
  275. const wchar_t* txt = get_attribute(name+1);
  276. if(txt) return txt;
  277. txt = get_style_attribute(name);
  278. if(txt) return txt;
  279. return default_value;
  280. }
  281. int attribute( const char* name, int default_value ) const
  282. {
  283. wchar_t none[1] = {0};
  284. const wchar_t* txt = attribute( name, none );
  285. if(txt == none) return default_value;
  286. return aux::wtoi(txt,default_value);
  287. }
  288. color attribute( const char* name, color default_value ) const
  289. {
  290. wchar_t none[1] = {0};
  291. const wchar_t* txt = attribute( name, none );
  292. if(txt == none) return default_value;
  293. return color::parse(aux::chars_of(txt), default_value);
  294. }
  295. /**Remove attribute.
  296. * \param name \b const \b char*, name of the attribute
  297. **/
  298. void remove_attribute( const char* name )
  299. {
  300. HTMLayoutSetAttributeByName(he, name, 0);
  301. }
  302. /**Get style attribute of the element by its name.
  303. * \param name \b const \b char*, name of the style attribute, e.g. "background-color"
  304. * \return \b const \b wchar_t*, value of the style attribute
  305. *
  306. * Also all style attributes of the element are available in "style" attribute of the element.
  307. **/
  308. const wchar_t* get_style_attribute( const char* name ) const
  309. {
  310. LPCWSTR lpw = 0;
  311. HTMLayoutGetStyleAttribute(he, name, &lpw);
  312. return lpw;
  313. }
  314. /**Set style attribute.
  315. * \param name \b const \b char*, name of the style attribute
  316. * \param value \b const \b wchar_t*, value of the style attribute
  317. *
  318. * \par Example:
  319. * \code e.set_style_attribute("background-color", L"red"); \endcode
  320. **/
  321. void set_style_attribute( const char* name, const wchar_t* value )
  322. {
  323. HTMLayoutSetStyleAttribute(he, name, value);
  324. }
  325. /** Clear style attribute that was defined by set_style_attribute.
  326. * \param name \b const \b char*, name of the style attribute
  327. *
  328. * \par Example:
  329. * \code e.clear_style_attribute("background-color"); \endcode
  330. **/
  331. void clear_style_attribute( const char* name )
  332. {
  333. HTMLayoutSetStyleAttribute(he, name, 0);
  334. }
  335. /** Clear all style attribute that was defined by set_style_attribute.
  336. */
  337. void clear_all_style_attributes()
  338. {
  339. HTMLayoutSetStyleAttribute(he, 0, 0);
  340. }
  341. /**Get root DOM element of the HTMLayout document.
  342. * \param hHTMLayoutWnd \b HWND, HTMLayout window
  343. * \return \b #HELEMENT, root element
  344. * \see also \b #root
  345. **/
  346. static HELEMENT root_element(HWND hHTMLayoutWnd)
  347. {
  348. HELEMENT h = 0;
  349. HTMLayoutGetRootElement(hHTMLayoutWnd,&h);
  350. //HLDOM_RESULT r = HTMLayoutGetRootElement(hHTMLayoutWnd,&h);
  351. //assert(r == HLDOM_OK);r;
  352. return h;
  353. }
  354. /**Get focus DOM element of the HTMLayout document.
  355. * \param hHTMLayoutWnd \b HWND, HTMLayout window
  356. * \return \b #HELEMENT, focus element
  357. *
  358. * COMMENT: to set focus use: set_state(STATE_FOCUS)
  359. *
  360. **/
  361. static HELEMENT focus_element(HWND hHTMLayoutWnd)
  362. {
  363. HELEMENT h = 0;
  364. HTMLayoutGetFocusElement(hHTMLayoutWnd,&h);
  365. return h;
  366. }
  367. /**Find DOM element of the HTMLayout document by coordinates.
  368. * \param hHTMLayoutWnd \b HWND, HTMLayout window
  369. * \param clientPt \b POINT, coordinates.
  370. * \return \b #HELEMENT, found element handle or zero
  371. **/
  372. static HELEMENT find_element(HWND hHTMLayoutWnd, POINT clientPt)
  373. {
  374. HELEMENT h = 0;
  375. HTMLayoutFindElement(hHTMLayoutWnd, clientPt, &h);
  376. return h;
  377. }
  378. /**Set mouse capture.
  379. * After call to this function all mouse events will be targeted to this element.
  380. * To remove mouse capture call #htmlayout::dom::element::release_capture().
  381. **/
  382. void set_capture() { HTMLayoutSetCapture(he); }
  383. /**Setup this element as an event root.
  384. * After that all UI events will be delivered only to this element or its sub-elements.
  385. * This is in principle close to 'capture' but works for DOM subtrees not only for particular elements.
  386. * If focus is set to the element outside of the event root it will be moved insed this element.
  387. **/
  388. void set_event_root() { HTMLayoutSetEventRoot(he, 0); }
  389. void set_event_root(element& prev) { HELEMENT phe = 0; HTMLayoutSetEventRoot(he, &phe); prev = phe; }
  390. /**Reset event root.
  391. **/
  392. void reset_event_root() { HTMLayoutSetEventRoot( dom::element(he).root(), 0); }
  393. /**Release mouse capture.
  394. * Mouse capture can be set with #element:set_capture()
  395. **/
  396. static void release_capture() { ReleaseCapture(); }
  397. inline static BOOL CALLBACK callback_func( HELEMENT he, LPVOID param )
  398. {
  399. callback *pcall = (callback *)param;
  400. return pcall->on_element(he)? TRUE:FALSE; // TRUE - stop enumeration
  401. }
  402. /**Enumerate all descendant elements.
  403. * \param pcall \b #htmlayout::dom::callback*, callback structure. Its member function #htmlayout::dom::callback::on_element() is called for every enumerated element.
  404. * \param tag_name \b const \b char*, comma separated list of tag names to search, e.g. "div", "p", "div,p" etc. Can be NULL.
  405. * \param attr_name \b const \b char*, name of attribute, can contain wildcard characters, see below. Can be NULL.
  406. * \param attr_value \b const \b char*, name of attribute, can contain wildcard characters, see below. Can be NULL.
  407. * \param depth \b int, depth - depth of search. 0 means all descendants, 1 - direct children only,
  408. * 2 - children and their children and so on.
  409. *
  410. * Wildcard characters in attr_name and attr_value:
  411. * - '*' - any substring
  412. * - '?' - any one char
  413. * - '['char set']' = any one char in set
  414. *
  415. * \par Example:
  416. * - [a-z] - all lowercase letters
  417. * - [a-zA-Z] - all letters
  418. * - [abd-z] - all lowercase letters except of 'c'
  419. * - [-a-z] - all lowercase letters and '-'
  420. *
  421. * \par Example:
  422. * \code document.select(mycallback, "a", "href", "http:*.php"); \endcode
  423. * will call mycallback.on_element() on each <A> element in the document
  424. * having 'href' attribute with value
  425. * starting from "http:" and ending with ".php"
  426. *
  427. * \par Example:
  428. * \code document.select(mycallback); \endcode
  429. * will enumerate ALL elements in the document.
  430. **/
  431. inline void select( callback *pcall,
  432. const char* tag_name = 0,
  433. const char* attr_name = 0,
  434. const wchar_t* attr_value = 0,
  435. int depth = 0) const
  436. {
  437. HTMLayoutVisitElements( he, tag_name, attr_name, attr_value, callback_func, pcall, depth);
  438. }
  439. inline HELEMENT select_parent(const char* selectors, // CSS selectors, comma separated list
  440. int depth
  441. ) const
  442. {
  443. HELEMENT heFound = 0;
  444. HLDOM_RESULT r = HTMLayoutSelectParent( he, selectors, depth, &heFound );
  445. assert(r == HLDOM_OK);r;
  446. return heFound;
  447. }
  448. inline HELEMENT select_parent(const wchar_t* selectors, // CSS selectors, comma separated list
  449. int depth
  450. ) const
  451. {
  452. HELEMENT heFound = 0;
  453. HLDOM_RESULT r = HTMLayoutSelectParentW( he, selectors, depth, &heFound );
  454. assert(r == HLDOM_OK);r;
  455. return heFound;
  456. }
  457. inline void select_elements( callback *pcall,
  458. const char* selectors // CSS selectors, comma separated list
  459. ) const
  460. {
  461. HTMLayoutSelectElements( he, selectors, callback_func, pcall);
  462. }
  463. inline void select_elements( callback *pcall,
  464. const wchar_t* selectors // CSS selectors, comma separated list
  465. ) const
  466. {
  467. HTMLayoutSelectElementsW( he, selectors, callback_func, pcall);
  468. }
  469. /**Get element by id.
  470. * \param id \b char*, value of the "id" attribute.
  471. * \return \b #HELEMENT, handle of the first element with the "id" attribute equal to given.
  472. **/
  473. HELEMENT get_element_by_id(const char* id) const
  474. {
  475. find_first_callback cb;
  476. select(&cb,0,"id",aux::a2w(id));
  477. return cb.hfound;
  478. }
  479. HELEMENT get_element_by_id(const wchar_t* id) const
  480. {
  481. find_first_callback cb;
  482. select(&cb,0,"id",id);
  483. return cb.hfound;
  484. }
  485. /** Request to repaint the element. If the element has drawing behavior attached it will receive on_draw() call after that.
  486. **/
  487. void refresh() const
  488. {
  489. RECT rc = get_location(BORDER_BOX);
  490. ::InvalidateRect(get_element_hwnd(false),&rc,FALSE);
  491. }
  492. /** Request update of styles and/or position of the element and refresh element area in its window.
  493. * \param[in] remeasure \b bool, true if method element will be redrawn immediately.
  494. *
  495. * This method is optional since v 3.3.0.4
  496. * Engine will call update internaly when handling DOM mutating methods.
  497. *
  498. **/
  499. void update( bool remeasure = false ) const
  500. {
  501. HTMLayoutUpdateElement(he, remeasure? TRUE:FALSE);
  502. }
  503. /**Apply changes and refresh element area in its window.
  504. * \param[in] render_now \b bool, if true element will be redrawn immediately.
  505. **/
  506. void update( int mode ) const
  507. {
  508. HTMLayoutUpdateElementEx(he, mode);
  509. }
  510. /**Get next sibling element.
  511. * \return \b #HELEMENT, handle of the next sibling element if it exists or 0 otherwise
  512. **/
  513. HELEMENT next_sibling() const
  514. {
  515. unsigned int idx = index() + 1;
  516. element pel = parent();
  517. if(!pel.is_valid())
  518. return 0;
  519. if( idx >= pel.children_count() )
  520. return 0;
  521. return pel.child(idx);
  522. }
  523. /**Get previous sibling element.
  524. * \return \b #HELEMENT, handle of previous sibling element if it exists or 0 otherwise
  525. **/
  526. HELEMENT prev_sibling() const
  527. {
  528. int idx = (int)index() - 1;
  529. element pel = parent();
  530. if(!pel.is_valid())
  531. return 0;
  532. if( idx < 0 )
  533. return 0;
  534. return pel.child(idx);
  535. }
  536. /**Get first sibling element.
  537. * \return \b #HELEMENT, handle of the first sibling element if it exists or 0 otherwise
  538. **/
  539. HELEMENT first_sibling() const
  540. {
  541. element pel = parent();
  542. if(!pel.is_valid())
  543. return 0;
  544. return pel.child(0);
  545. }
  546. /**Get last sibling element.
  547. * \return \b #HELEMENT, handle of last sibling element if it exists or 0 otherwise
  548. **/
  549. HELEMENT last_sibling() const
  550. {
  551. element pel = parent();
  552. if(!pel.is_valid())
  553. return 0;
  554. return pel.child(pel.children_count() - 1);
  555. }
  556. /**Get root of the element
  557. * \return \b #HELEMENT, handle of document root element (html)
  558. **/
  559. HELEMENT root() const
  560. {
  561. element pel = parent();
  562. if(pel.is_valid()) return pel.root();
  563. return he;
  564. }
  565. /**Get bounding rectangle of the element.
  566. * \param root_relative \b bool, if true function returns location of the
  567. * element relative to HTMLayout window, otherwise the location is given
  568. * relative to first scrollable container.
  569. * \return \b RECT, bounding rectangle of the element.
  570. **/
  571. RECT get_location(unsigned int area = ROOT_RELATIVE | CONTENT_BOX) const
  572. {
  573. RECT rc = {0,0,0,0};
  574. HTMLayoutGetElementLocation(he,&rc, area);
  575. return rc;
  576. }
  577. /** Test if point is inside shape rectangle of the element.
  578. client_pt - client rect relative point
  579. **/
  580. bool is_inside( POINT client_pt ) const
  581. {
  582. RECT rc = get_location(ROOT_RELATIVE | BORDER_BOX);
  583. return PtInRect(&rc,client_pt) != FALSE;
  584. }
  585. /**Scroll this element to view.
  586. **/
  587. void scroll_to_view(bool toTopOfView = false, bool smooth = false)
  588. {
  589. UINT flags = 0;
  590. if(toTopOfView) flags |= SCROLL_TO_TOP;
  591. if(smooth) flags |= SCROLL_SMOOTH;
  592. HTMLayoutScrollToView(he,flags);
  593. }
  594. void get_scroll_info(POINT& scroll_pos, RECT& view_rect, SIZE& content_size)
  595. {
  596. HLDOM_RESULT r = HTMLayoutGetScrollInfo(he, &scroll_pos, &view_rect, &content_size);
  597. assert(r == HLDOM_OK); r;
  598. }
  599. void set_scroll_pos(POINT scroll_pos, bool smooth = true)
  600. {
  601. HLDOM_RESULT r = HTMLayoutSetScrollPos(he, scroll_pos, BOOL(smooth));
  602. assert(r == HLDOM_OK); r;
  603. }
  604. /** get min-intrinsic and max-intrinsic widths of the element. */
  605. void get_intrinsic_widths(int& min_width,int& max_width)
  606. {
  607. HLDOM_RESULT r = HTMLayoutGetElementIntrinsicWidths(he, &min_width, &max_width);
  608. assert(r == HLDOM_OK); r;
  609. }
  610. /** get min-intrinsic height of the element calculated for forWidth. */
  611. void get_intrinsic_height(int for_width, int& min_height)
  612. {
  613. HLDOM_RESULT r = HTMLayoutGetElementIntrinsicHeight(he, for_width, &min_height);
  614. assert(r == HLDOM_OK); r;
  615. }
  616. /**Get element's type.
  617. * \return \b const \b char*, name of the elements type
  618. *
  619. * \par Example:
  620. * For &lt;div&gt; tag function will return "div".
  621. **/
  622. const char* get_element_type() const
  623. {
  624. LPCSTR str = 0;
  625. HTMLayoutGetElementType(he,&str);
  626. return str;
  627. }
  628. /**Get HWND of containing window.
  629. * \param root_window \b bool, handle of which window to get:
  630. * - true - HTMLayout window
  631. * - false - nearest parent element having overflow:auto or :scroll
  632. * \return \b HWND
  633. **/
  634. HWND get_element_hwnd(bool root_window) const
  635. {
  636. HWND hwnd = 0;
  637. HTMLayoutGetElementHwnd(he,&hwnd, root_window? TRUE : FALSE);
  638. return hwnd;
  639. }
  640. /**Get element UID - identifier suitable for storage.
  641. * \return \b UID
  642. **/
  643. UINT get_element_uid() const
  644. {
  645. UINT uid = 0;
  646. HTMLayoutGetElementUID(he,&uid);
  647. return uid;
  648. }
  649. /**Get element handle by its UID.
  650. * \param hHTMLayoutWnd \b HWND, HTMLayout window
  651. * \param uid \b UINT, uid of the element
  652. * \return \b #HELEMENT, handle of element with the given uid or 0 if not found
  653. **/
  654. static HELEMENT element_by_uid(HWND hHTMLayoutWnd, UINT uid)
  655. {
  656. HELEMENT h = 0;
  657. HTMLayoutGetElementByUID(hHTMLayoutWnd, uid,&h);
  658. return h;
  659. }
  660. static HELEMENT from_value(const json::value& val)
  661. {
  662. if( val.is_dom_element() )
  663. return (HELEMENT) val.get_object_data();
  664. return 0;
  665. }
  666. /**Combine given URL with URL of the document element belongs to.
  667. * \param[in, out] inOutURL \b LPWSTR, at input this buffer contains
  668. * zero-terminated URL to be combined, after function call it contains
  669. * zero-terminated combined URL
  670. * \param bufferSize \b UINT, size of the buffer pointed by \c inOutURL
  671. **/
  672. void combine_url(LPWSTR inOutURL, UINT bufferSize) const
  673. {
  674. HTMLayoutCombineURL(he,inOutURL,bufferSize);
  675. }
  676. json::string url(const wchar_t* rel_url) const
  677. {
  678. wchar_t buffer[4096]; wcsncpy(buffer,rel_url,4096); buffer[4095] = 0;
  679. HTMLayoutCombineURL(he,buffer,4096);
  680. return buffer;
  681. }
  682. /**Set inner or outer html of the element.
  683. * \param html \b const \b unsigned \b char*, UTF-8 encoded string containing html text
  684. * \param html_length \b size_t, length in bytes of \c html
  685. * \param where \b int, possible values are:
  686. * - SIH_REPLACE_CONTENT - replace content of the element
  687. * - SIH_INSERT_AT_START - insert html before first child of the element
  688. * - SIH_APPEND_AFTER_LAST - insert html after last child of the element
  689. **/
  690. void set_html( const unsigned char* html, size_t html_length, int where = SIH_REPLACE_CONTENT)
  691. {
  692. if(html == 0 || html_length == 0)
  693. clear();
  694. else
  695. {
  696. HLDOM_RESULT r = HTMLayoutSetElementHtml(he, html, DWORD(html_length), where);
  697. assert(r == HLDOM_OK); r;
  698. }
  699. }
  700. /*const unsigned char*
  701. get_html( bool outer = true) const
  702. {
  703. unsigned char* utf8bytes = 0;
  704. HLDOM_RESULT r = HTMLayoutGetElementHtml(he, &utf8bytes, outer? TRUE:FALSE);
  705. assert(r == HLDOM_OK); r;
  706. return utf8bytes;
  707. }*/
  708. static void CALLBACK _writer_a(LPCBYTE utf8, UINT utf8_length, LPVOID pstdstr)
  709. {
  710. json::astring* dst = (json::astring*)pstdstr;
  711. *dst = aux::chars((const char*)utf8,utf8_length);
  712. }
  713. json::astring get_html( bool outer = true) const
  714. {
  715. json::astring str;
  716. HLDOM_RESULT r = HTMLayoutGetElementHtmlCB(he, outer, &_writer_a, &str);
  717. assert(r == HLDOM_OK); r;
  718. return str;
  719. }
  720. // get text as utf8 bytes
  721. /* const unsigned char* get_text() const
  722. {
  723. unsigned char* utf8bytes = 0;
  724. HLDOM_RESULT r = HTMLayoutGetElementInnerText(he, &utf8bytes);
  725. assert(r == HLDOM_OK); r;
  726. return utf8bytes;
  727. } */
  728. static void CALLBACK _writer_w(const wchar_t* text, unsigned int text_length, void* pstdstr)
  729. {
  730. json::string* dst = (json::string*)pstdstr;
  731. *dst = aux::wchars(text,text_length);
  732. }
  733. // get text as wchar_t words
  734. json::string text() const
  735. {
  736. json::string str;
  737. HLDOM_RESULT r = HTMLayoutGetElementInnerTextCB(he, &_writer_w, &str);
  738. assert(r == HLDOM_OK); r;
  739. return str;
  740. }
  741. void set_text(const wchar_t* utf16, size_t utf16_length)
  742. {
  743. HLDOM_RESULT r = HTMLayoutSetElementInnerText16(he, utf16, (UINT)utf16_length);
  744. assert(r == HLDOM_OK); r;
  745. }
  746. void set_text(const wchar_t* t)
  747. {
  748. assert(t);
  749. if( t ) set_text( t, wcslen(t) );
  750. }
  751. void clear() // clears content of the element
  752. {
  753. HLDOM_RESULT r = HTMLayoutSetElementInnerText16(he, L"", 0);
  754. assert(r == HLDOM_OK); r;
  755. }
  756. /**Delete element.
  757. * This function removes element from the DOM tree, detaches all behaviors and deletes it if there are no more references to it.
  758. **/
  759. void destroy()
  760. {
  761. HTMLayoutDeleteElement(he);
  762. unuse();
  763. }
  764. inline int vsnprintf(wchar_t *buffer, size_t count, const wchar_t *format, va_list argptr) const
  765. {
  766. return _vsnwprintf( buffer, count, format, argptr );
  767. }
  768. inline int vsnprintf(char *buffer, size_t count, const char *format, va_list argptr) const
  769. {
  770. return _vsnprintf( buffer, count, format, argptr );
  771. }
  772. // Find first child element matching the selector
  773. // :root is the element itself
  774. template<class char_t>
  775. HELEMENT find_first( const char_t* selector, ... ) const
  776. {
  777. char_t buffer[2049]; buffer[0]=0;
  778. va_list args; va_start ( args, selector ); vsnprintf( buffer, 2048, selector, args ); va_end ( args );
  779. find_first_callback find_first;
  780. select_elements( &find_first, buffer); // find first element satisfying given CSS selector
  781. return find_first.hfound;
  782. }
  783. // Find all child elements matching the selector
  784. // :root is the element itself
  785. template<class char_t>
  786. void find_all( callback* cb, const char_t* selector, ... ) const
  787. {
  788. char_t buffer[2049]; buffer[0]=0;
  789. va_list args; va_start ( args, selector ); vsnprintf( buffer, 2048, selector, args ); va_end ( args );
  790. select_elements( cb, buffer); // find all elements satisfying given CSS selector
  791. //assert(find_first.hfound);
  792. }
  793. class find_all_callback: public callback
  794. {
  795. std::vector<dom::element>* all;
  796. find_all_callback():all(0) {}
  797. public:
  798. find_all_callback(std::vector<dom::element>& _all):all(&_all) {}
  799. ~find_all_callback() {}
  800. bool on_element(HELEMENT he) { all->push_back(dom::element(he)); return false; /*continue enumeration*/ }
  801. };
  802. template<class char_t>
  803. void find_all( std::vector<dom::element>& all, const char_t* selector, ... ) const
  804. {
  805. char_t buffer[2049]; buffer[0]=0;
  806. va_list args; va_start ( args, selector ); vsnprintf( buffer, 2048, selector, args ); va_end ( args );
  807. find_all_callback cb(all);
  808. select_elements( &cb, buffer); // find all elements satisfying given CSS selector
  809. }
  810. // will find first parent satisfying given css selector(s), will check element itself
  811. // :root is document root object
  812. template<class char_t>
  813. HELEMENT find_nearest_parent(const char_t* selector, ...) const
  814. {
  815. char_t buffer[2049]; buffer[0]=0;
  816. va_list args; va_start ( args, selector ); vsnprintf( buffer, 2048, selector, args );
  817. va_end ( args );
  818. return select_parent(buffer, 0);
  819. }
  820. // test this element against CSS selector(s)
  821. // :root is document root object
  822. template<class char_t>
  823. bool test(const char_t* selector, ...) const
  824. {
  825. char_t buffer[2049]; buffer[0]=0;
  826. va_list args; va_start ( args, selector ); _vsnprintf( buffer, 2048, selector, args ); va_end ( args );
  827. return select_parent(buffer, 1) != 0;
  828. }
  829. /**Get UI state bits of the element as set of ELEMENT_STATE_BITS
  830. **/
  831. unsigned int get_state() const
  832. {
  833. UINT state = 0;
  834. HLDOM_RESULT r = HTMLayoutGetElementState(he,&state);
  835. assert(r == HLDOM_OK); r;
  836. return (ELEMENT_STATE_BITS) state;
  837. }
  838. /**Checks if particular UI state bits are set in the element.
  839. **/
  840. bool get_state(/*ELEMENT_STATE_BITS*/ unsigned int bits) const
  841. {
  842. UINT state = 0;
  843. HLDOM_RESULT r = HTMLayoutGetElementState(he,&state);
  844. assert(r == HLDOM_OK); r;
  845. return (state & bits) != 0;
  846. }
  847. /**Set UI state of the element with optional view update.
  848. **/
  849. void set_state(
  850. /*ELEMENT_STATE_BITS*/ unsigned int bitsToSet,
  851. /*ELEMENT_STATE_BITS*/ unsigned int bitsToClear = 0, bool update = true )
  852. {
  853. HLDOM_RESULT r = HTMLayoutSetElementState(he,bitsToSet,bitsToClear, update?TRUE:FALSE);
  854. assert(r == HLDOM_OK); r;
  855. }
  856. void toggle_state(/*ELEMENT_STATE_BITS*/ unsigned int bitsToSet, bool onOff)
  857. {
  858. HLDOM_RESULT r = HTMLayoutSetElementState(he,onOff?bitsToSet:0, onOff?0:bitsToSet, TRUE);
  859. assert(r == HLDOM_OK); r;
  860. }
  861. void start_timer(UINT millis, UINT_PTR tid = 0)
  862. {
  863. HLDOM_RESULT r = HTMLayoutSetTimerEx(he, millis, tid);
  864. assert(r == HLDOM_OK); r;
  865. }
  866. void stop_timer(UINT_PTR tid = 0)
  867. {
  868. HLDOM_RESULT r = HTMLayoutSetTimerEx(he, 0, tid);
  869. assert(r == HLDOM_OK); r;
  870. }
  871. /** "deeply enabled" **/
  872. bool enabled()
  873. {
  874. BOOL b = FALSE;
  875. HLDOM_RESULT r = HTMLayoutIsElementEnabled(he,&b);
  876. assert(r == HLDOM_OK); r;
  877. return b != 0;
  878. }
  879. /** "deeply visible" **/
  880. bool visible()
  881. {
  882. BOOL b = FALSE;
  883. HLDOM_RESULT r = HTMLayoutIsElementVisible(he,&b);
  884. assert(r == HLDOM_OK); r;
  885. return b != 0;
  886. }
  887. /** create brand new element with text (optional).
  888. Example:
  889. element div = element::create("div");
  890. - will create DIV element,
  891. element opt = element::create("option",L"Europe");
  892. - will create OPTION element with text "Europe" in it.
  893. **/
  894. static element create(const char* tagname, const wchar_t* text = 0)
  895. {
  896. element e(0);
  897. HLDOM_RESULT r = HTMLayoutCreateElement( tagname, text, &e.he ); // don't need 'use' here, as it is already "addrefed"
  898. assert(r == HLDOM_OK); r;
  899. return e;
  900. }
  901. /** create brand new copy of this element. Element will be created disconected.
  902. You need to call insert to inject it in some container.
  903. Example:
  904. element select = ...;
  905. element option1 = ...;
  906. element option2 = option1.clone();
  907. select.insert(option2, option1.index() + 1);
  908. - will create copy of option1 element (option2) and insert it after option1,
  909. **/
  910. element clone()
  911. {
  912. element e(0);
  913. HLDOM_RESULT r = HTMLayoutCloneElement( he, &e.he ); // don't need 'use' here, as it is already "addrefed"
  914. assert(r == HLDOM_OK); r;
  915. return e;
  916. }
  917. /** Insert element e at \i index position of this element.
  918. **/
  919. void insert( const element& e, unsigned int index )
  920. {
  921. HLDOM_RESULT r = HTMLayoutInsertElement( e.he, this->he, index );
  922. assert(r == HLDOM_OK); r;
  923. }
  924. /** Append element e as last child of this element.
  925. **/
  926. void append( const element& e ) { insert(e,0x7FFFFFFF); }
  927. /** detach - remove this element from its parent
  928. **/
  929. void detach()
  930. {
  931. HLDOM_RESULT r = HTMLayoutDetachElement( he );
  932. assert(r == HLDOM_OK); r;
  933. }
  934. /** swap two elements in the DOM
  935. **/
  936. void swap(HELEMENT with)
  937. {
  938. HTMLayoutSwapElements(he, with);
  939. }
  940. /** traverse event - send it by sinking/bubbling on the
  941. * parent/child chain of this element
  942. **/
  943. bool send_event(unsigned int event_code, UINT_PTR reason = 0, HELEMENT heSource = 0)
  944. {
  945. BOOL handled = FALSE;
  946. HLDOM_RESULT r = HTMLayoutSendEvent(he, event_code, heSource? heSource: he, reason, &handled);
  947. assert(r == HLDOM_OK); r;
  948. return handled != 0;
  949. }
  950. /** post event - post it in the queue for later sinking/bubbling on the
  951. * parent/child chain of this element.
  952. * method returns immediately
  953. **/
  954. void post_event(unsigned int event_code, unsigned int reason = 0, HELEMENT heSource = 0)
  955. {
  956. HLDOM_RESULT r = HTMLayoutPostEvent(he, event_code, heSource? heSource: he, reason);
  957. assert(r == HLDOM_OK); r;
  958. }
  959. /** move element to new location given by x_view_rel, y_view_rel - view relative coordinates.
  960. * Method defines local styles, so to "stick" it back to the original location you
  961. * should call element::clear_all_style_attributes().
  962. **/
  963. void move(int x_view_rel, int y_view_rel)
  964. {
  965. HLDOM_RESULT r = HTMLayoutMoveElement(he, x_view_rel, y_view_rel);
  966. assert(r == HLDOM_OK); r;
  967. }
  968. void move(int x_view_rel, int y_view_rel, int width, int height)
  969. {
  970. HLDOM_RESULT r = HTMLayoutMoveElementEx(he, x_view_rel, y_view_rel, width, height);
  971. assert(r == HLDOM_OK); r;
  972. }
  973. HELEMENT track_popup(POINT root_pt, bool animate = false)
  974. {
  975. HELEMENT hItem = 0;
  976. HTMLayoutTrackPopupAt(he, root_pt, animate? 1:0, &hItem);
  977. return hItem;
  978. }
  979. // 'placement' here is a point of the popup that corresponds to root_pt
  980. HELEMENT track_popup(uint placement , POINT root_pt, bool animate = false)
  981. {
  982. HELEMENT hItem = 0;
  983. HTMLayoutTrackPopupAt(he, root_pt, (placement << 16) | (animate?1:0), &hItem);
  984. return hItem;
  985. }
  986. void show_popup(POINT root_pt, bool animate = false)
  987. {
  988. HTMLayoutShowPopupAt(he, root_pt, animate? 1:0);
  989. }
  990. void show_popup(uint placement, POINT root_pt, bool animate = false)
  991. {
  992. HTMLayoutShowPopupAt(he, root_pt, (placement << 16) | (animate?1:0));
  993. }
  994. void hide_popup()
  995. {
  996. HTMLayoutHidePopup(he);
  997. }
  998. /** attach event handler to the element
  999. **/
  1000. void attach(event_handler* pevth)
  1001. {
  1002. htmlayout::attach_event_handler(he,pevth);
  1003. }
  1004. /** remove event handler from the list of event handlers of the element.
  1005. **/
  1006. void detach(event_handler* pevth)
  1007. {
  1008. htmlayout::detach_event_handler(he,pevth);
  1009. }
  1010. /** call method, invokes method in all event handlers attached to the element
  1011. **/
  1012. bool call_behavior_method(METHOD_PARAMS* p)
  1013. {
  1014. if(!is_valid())
  1015. return false;
  1016. return ::HTMLayoutCallBehaviorMethod(he,p) == HLDOM_OK;
  1017. }
  1018. json::value xcall(const char* name,
  1019. json::value p0 = json::value(),
  1020. json::value p1 = json::value(),
  1021. json::value p2 = json::value(),
  1022. json::value p3 = json::value(),
  1023. json::value p4 = json::value(),
  1024. json::value p5 = json::value(),
  1025. json::value p6 = json::value(),
  1026. json::value p7 = json::value())
  1027. {
  1028. XCALL_PARAMS prm( name );
  1029. json::value argv[8];
  1030. prm.argv = argv;
  1031. do
  1032. {
  1033. if( p0.is_undefined()) break; argv[prm.argc++] = p0;
  1034. if( p1.is_undefined()) break; argv[prm.argc++] = p1;
  1035. if( p2.is_undefined()) break; argv[prm.argc++] = p2;
  1036. if( p3.is_undefined()) break; argv[prm.argc++] = p3;
  1037. if( p4.is_undefined()) break; argv[prm.argc++] = p4;
  1038. if( p5.is_undefined()) break; argv[prm.argc++] = p5;
  1039. if( p6.is_undefined()) break; argv[prm.argc++] = p6;
  1040. if( p7.is_undefined()) break; argv[prm.argc++] = p7;
  1041. //#pragma warning( suppress:4127 ) // warning C4127: conditional expression is constant
  1042. } while(false);
  1043. bool r = call_behavior_method(&prm);
  1044. assert(r); r;
  1045. return prm.retval;
  1046. }
  1047. void load_html(const wchar_t* url, HELEMENT initiator = 0)
  1048. {
  1049. HLDOM_RESULT r = HTMLayoutRequestElementData(he,url,HLRT_DATA_HTML,initiator);
  1050. assert(r == HLDOM_OK); r;
  1051. }
  1052. struct comparator
  1053. {
  1054. comparator() {}
  1055. virtual ~comparator() {}
  1056. virtual int compare(const htmlayout::dom::element& e1, const htmlayout::dom::element& e2) = 0;
  1057. static INT CALLBACK scmp( HELEMENT he1, HELEMENT he2, LPVOID param )
  1058. {
  1059. htmlayout::dom::element::comparator* self =
  1060. static_cast<htmlayout::dom::element::comparator*>(param);
  1061. htmlayout::dom::element e1 = he1;
  1062. htmlayout::dom::element e2 = he2;
  1063. return self->compare( e1,e2 );
  1064. }
  1065. };
  1066. /** reorders children of the element using sorting order defined by cmp
  1067. **/
  1068. void sort( comparator& cmp, int start = 0, int end = -1 )
  1069. {
  1070. if (end == -1)
  1071. end = children_count();
  1072. HLDOM_RESULT r = HTMLayoutSortElements(he, start, end, &comparator::scmp, &cmp);
  1073. assert(r == HLDOM_OK); r;
  1074. }
  1075. CTL_TYPE get_ctl_type() const
  1076. {
  1077. UINT t = 0;
  1078. HLDOM_RESULT r = ::HTMLayoutControlGetType(he,&t);
  1079. assert(r == HLDOM_OK); r;
  1080. return CTL_TYPE(t);
  1081. }
  1082. json::value get_value() const
  1083. {
  1084. json::value v;
  1085. HLDOM_RESULT r = ::HTMLayoutControlGetValue(he,&v);
  1086. assert(r == HLDOM_OK); r;
  1087. return v;
  1088. }
  1089. void set_value(const json::value& v)
  1090. {
  1091. HLDOM_RESULT r = ::HTMLayoutControlSetValue(he,&v);
  1092. assert(r == HLDOM_OK); r;
  1093. }
  1094. void set_expando( expando* exp );
  1095. expando* get_expando();
  1096. //private:
  1097. struct find_first_callback: callback
  1098. {
  1099. HELEMENT hfound;
  1100. find_first_callback():hfound(0) {}
  1101. ~find_first_callback() {}
  1102. inline bool on_element(HELEMENT he) { hfound = he; return true; /*stop enumeration*/ }
  1103. };
  1104. void delay_measure()
  1105. {
  1106. HLDOM_RESULT r = ::HTMLayoutEnqueueMeasure(he);
  1107. assert(r == HLDOM_OK); r;
  1108. }
  1109. };
  1110. /**Expando - structure that can be associated with the DOM element.
  1111. *
  1112. * In other words: DOM element can be expanded by this structure
  1113. *
  1114. * Derive your own class/structure from this one if you need some data to be associated with DOM element.
  1115. *
  1116. * If you want to handle events here then additionally derive your structure from event_handler and
  1117. * call both: attach_event_handler and set_expando with it.
  1118. *
  1119. **/
  1120. class expando: public HTMLayoutElementExpando
  1121. {
  1122. static void CALLBACK _finalizer(HTMLayoutElementExpando* pexp, HELEMENT he) { static_cast<expando*>(pexp)->finalize(); }
  1123. protected:
  1124. virtual void finalize() { delete this; }
  1125. public:
  1126. expando() { finalizer = _finalizer; }
  1127. virtual ~expando() {}
  1128. };
  1129. inline void element::set_expando( expando* exp )
  1130. {
  1131. HLDOM_RESULT r = HTMLayoutElementSetExpando(he, static_cast<HTMLayoutElementExpando*>(exp));
  1132. assert(r == HLDOM_OK); r;
  1133. }
  1134. inline expando* element::get_expando()
  1135. {
  1136. HTMLayoutElementExpando* pexp = 0;
  1137. HLDOM_RESULT r = HTMLayoutElementGetExpando(he, &pexp);
  1138. assert(r == HLDOM_OK); r;
  1139. return static_cast<expando*>(pexp);
  1140. }
  1141. #define STD_CTORS(T,PT) \
  1142. T() { } \
  1143. T(HELEMENT h): PT(h) { } \
  1144. T(const element& e): PT(e) { } \
  1145. T& operator = (HELEMENT h) { set(h); return *this; } \
  1146. T& operator = (const element& e) { set(e); return *this; }
  1147. class text_selection_params: public TEXT_SELECTION_PARAMS
  1148. {
  1149. pod::buffer<wchar_t>* _wos;
  1150. text_selection_params():TEXT_SELECTION_PARAMS(false),_wos(0){}
  1151. public:
  1152. static BOOL CALLBACK ctl(text_selection_params* prms, UINT data ) { prms->_wos->push(wchar_t(data)); return 1; }
  1153. text_selection_params(pod::buffer<wchar_t>& wos): TEXT_SELECTION_PARAMS(false), _wos(&wos) { outs = (OutputStreamProc*)ctl; }
  1154. };
  1155. class html_selection_params: public TEXT_SELECTION_PARAMS
  1156. {
  1157. pod::buffer<byte>* _bos;
  1158. html_selection_params():TEXT_SELECTION_PARAMS(true),_bos(0){}
  1159. public:
  1160. static BOOL CALLBACK ctl(html_selection_params* prms, UINT data ) { prms->_bos->push(byte(data)); return 1; }
  1161. html_selection_params(pod::buffer<byte>& bos): TEXT_SELECTION_PARAMS(true), _bos(&bos) { outs = (OutputStreamProc*)ctl; }
  1162. };
  1163. class editbox: public element
  1164. {
  1165. public:
  1166. STD_CTORS(editbox, element)
  1167. bool selection( int& start, int& end )
  1168. {
  1169. TEXT_EDIT_SELECTION_PARAMS sp(false);
  1170. if(!call_behavior_method(&sp))
  1171. return false;
  1172. start = sp.selection_start;
  1173. end = sp.selection_end;
  1174. return true;
  1175. }
  1176. bool select( int start = 0, int end = 0x7FFFFFFF )
  1177. {
  1178. TEXT_EDIT_SELECTION_PARAMS sp(true);
  1179. sp.selection_start = start;
  1180. sp.selection_end = end;
  1181. return call_behavior_method(&sp);
  1182. }
  1183. bool replace(const wchar_t* text, size_t text_length)
  1184. {
  1185. TEXT_EDIT_REPLACE_SELECTION_PARAMS sp;
  1186. sp.text = text;
  1187. sp.text_length = UINT(text_length);
  1188. return call_behavior_method(&sp);
  1189. }
  1190. std::wstring text_value() const
  1191. {
  1192. TEXT_VALUE_PARAMS sp(false);
  1193. if( const_cast<editbox*>(this)->call_behavior_method(&sp) && sp.text && sp.length)
  1194. {
  1195. return std::wstring(sp.text, sp.length);
  1196. }
  1197. return std::wstring();
  1198. }
  1199. void text_value(const std::wstring& s)
  1200. {
  1201. text_value(s.c_str(), s.length());
  1202. }
  1203. void text_value(const wchar_t* text, size_t length)
  1204. {
  1205. TEXT_VALUE_PARAMS sp(true);
  1206. sp.text = text;
  1207. sp.length = UINT(length);
  1208. call_behavior_method(&sp);
  1209. update();
  1210. }
  1211. void text_value(const wchar_t* text)
  1212. {
  1213. TEXT_VALUE_PARAMS sp(true);
  1214. sp.text = text;
  1215. sp.length = text? UINT(wcslen(text)):0;
  1216. call_behavior_method(&sp);
  1217. update();
  1218. }
  1219. void caret_position(int& x, int& y, int& w, int& h)
  1220. {
  1221. TEXT_CARET_POSITION_PARAMS cpp;
  1222. x = y = w = h = 0;
  1223. if(call_behavior_method(&cpp))
  1224. {
  1225. x = cpp.left; y = cpp.top;
  1226. w = cpp.width; h = cpp.height;
  1227. }
  1228. }
  1229. void int_value( int v )
  1230. {
  1231. wchar_t buf[64]; int n = _snwprintf(buf,63,L"%d", v); buf[63] = 0;
  1232. text_value(buf,n);
  1233. }
  1234. int int_value( ) const
  1235. {
  1236. return aux::wtoi( text_value().c_str() );
  1237. }
  1238. std::wstring selected_text()
  1239. {
  1240. pod::buffer<wchar_t> wos;
  1241. get_selected_text(wos);
  1242. return std::wstring(wos.data(), wos.length());
  1243. }
  1244. void get_selected_text(pod::buffer<wchar_t>& wos)
  1245. {
  1246. text_selection_params s(wos);
  1247. call_behavior_method(&s);
  1248. }
  1249. void get_selected_html(pod::buffer<byte>& bos)
  1250. {
  1251. html_selection_params s(bos);
  1252. call_behavior_method(&s);
  1253. }
  1254. int char_pos_at_xy(int x, int y) const
  1255. {
  1256. TEXT_EDIT_CHAR_POS_AT_XY_PARAMS sp;
  1257. sp.x = x;
  1258. sp.y = y;
  1259. if(!const_cast<editbox*>(this)->call_behavior_method(&sp))
  1260. return -1;
  1261. return sp.char_pos;
  1262. }
  1263. };
  1264. class scrollbar: public element
  1265. {
  1266. public:
  1267. STD_CTORS(scrollbar, element)
  1268. void get_values( int& val, int& min_val, int& max_val, int& page_val, int& step_val )
  1269. {
  1270. SCROLLBAR_VALUE_PARAMS sbvp;
  1271. call_behavior_method(&sbvp);
  1272. val = sbvp.value;
  1273. min_val = sbvp.min_value;
  1274. max_val = sbvp.max_value;
  1275. page_val = sbvp.page_value; // page increment
  1276. step_val = sbvp.step_value; // step increment (arrow button click)
  1277. }
  1278. void set_values( int val, int min_val, int max_val, int page_val, int step_val )
  1279. {
  1280. SCROLLBAR_VALUE_PARAMS sbvp(true);
  1281. sbvp.value = val;
  1282. sbvp.min_value = min_val;
  1283. sbvp.max_value = max_val;
  1284. sbvp.page_value = page_val;
  1285. sbvp.step_value = step_val;
  1286. call_behavior_method(&sbvp);
  1287. }
  1288. int get_value()
  1289. {
  1290. SCROLLBAR_VALUE_PARAMS sbvp;
  1291. call_behavior_method(&sbvp);
  1292. return sbvp.value;
  1293. }
  1294. vo

Large files files are truncated, but you can click here to view the full file