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.

512 lines
15 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: atlstl/shims/access/string/cwindow.hpp
  3. *
  4. * Purpose: Contains classes and functions for dealing with OLE/COM strings.
  5. *
  6. * Created: 27th May 2002
  7. * Updated: 10th August 2009
  8. *
  9. * Home: http://stlsoft.org/
  10. *
  11. * Copyright (c) 2002-2009, Matthew Wilson and Synesis Software
  12. * All rights reserved.
  13. *
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted provided that the following conditions are met:
  16. *
  17. * - Redistributions of source code must retain the above copyright notice, this
  18. * list of conditions and the following disclaimer.
  19. * - Redistributions in binary form must reproduce the above copyright notice,
  20. * this list of conditions and the following disclaimer in the documentation
  21. * and/or other materials provided with the distribution.
  22. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
  23. * any contributors may be used to endorse or promote products derived from
  24. * this software without specific prior written permission.
  25. *
  26. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  27. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  30. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  31. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  32. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  33. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  34. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  35. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36. * POSSIBILITY OF SUCH DAMAGE.
  37. *
  38. * ////////////////////////////////////////////////////////////////////// */
  39. /** \file atlstl/shims/access/string/cwindow.hpp
  40. *
  41. * \brief [C++] Definition of the string access shims for
  42. * <code>CWindow</code>
  43. * (\ref group__concept__shim__string_access "String Access Shims" Concept).
  44. */
  45. #ifndef ATLSTL_INCL_ATLSTL_SHIMS_ACCESS_STRING_HPP_CWINDOW
  46. #define ATLSTL_INCL_ATLSTL_SHIMS_ACCESS_STRING_HPP_CWINDOW
  47. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  48. # define ATLSTL_VER_ATLSTL_SHIMS_ACCESS_STRING_HPP_CWINDOW_MAJOR 4
  49. # define ATLSTL_VER_ATLSTL_SHIMS_ACCESS_STRING_HPP_CWINDOW_MINOR 0
  50. # define ATLSTL_VER_ATLSTL_SHIMS_ACCESS_STRING_HPP_CWINDOW_REVISION 3
  51. # define ATLSTL_VER_ATLSTL_SHIMS_ACCESS_STRING_HPP_CWINDOW_EDIT 102
  52. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  53. /* /////////////////////////////////////////////////////////////////////////
  54. * Includes
  55. */
  56. #ifndef ATLSTL_INCL_ATLSTL_HPP_ATLSTL
  57. # include <atlstl/atlstl.hpp>
  58. #endif /* !ATLSTL_INCL_ATLSTL_HPP_ATLSTL */
  59. #ifndef STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING
  60. # include <stlsoft/shims/access/string.hpp>
  61. #endif /* !STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING */
  62. #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_CSTRING_MAKER
  63. # include <stlsoft/string/cstring_maker.hpp>
  64. #endif /* !STLSOFT_INCL_STLSOFT_STRING_HPP_CSTRING_MAKER */
  65. #ifdef STLSOFT_UNITTEST
  66. # include <wchar.h>
  67. #endif /* STLSOFT_UNITTEST */
  68. #ifndef STLSOFT_INCL_SYS_H_ATLWIN
  69. # define STLSOFT_INCL_SYS_H_ATLWIN
  70. # include <atlwin.h>
  71. #endif /* !STLSOFT_INCL_SYS_H_ATLWIN */
  72. /* /////////////////////////////////////////////////////////////////////////
  73. * Namespace
  74. */
  75. #ifndef _ATLSTL_NO_NAMESPACE
  76. # if defined(_STLSOFT_NO_NAMESPACE) || \
  77. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  78. /* There is no stlsoft namespace, so must define ::atlstl */
  79. namespace atlstl
  80. {
  81. # else
  82. /* Define stlsoft::atlstl_project */
  83. namespace stlsoft
  84. {
  85. namespace atlstl_project
  86. {
  87. # endif /* _STLSOFT_NO_NAMESPACE */
  88. #endif /* !_ATLSTL_NO_NAMESPACE */
  89. /* /////////////////////////////////////////////////////////////////////////
  90. * Classes
  91. */
  92. /* CWindow */
  93. /** \brief This class provides an intermediary object that may be returned by the
  94. * c_str_ptr_null() function, such that the window text of a given window
  95. * may be accessed as a null-terminated string.
  96. *
  97. * \ingroup group__concept__shim__string_access
  98. *
  99. */
  100. struct c_str_ptr_null_CWindow_proxy
  101. {
  102. private:
  103. typedef cstring_maker<TCHAR> string_maker_type;
  104. typedef c_str_ptr_null_CWindow_proxy class_type;
  105. // Construction
  106. public:
  107. /// Constructs an instance of the proxy from the given CWindow instance
  108. ///
  109. /// \param w The CWindow instance from which the text will be retrieved
  110. ss_explicit_k c_str_ptr_null_CWindow_proxy(CWindow const& w)
  111. {
  112. int length = (NULL == w.m_hWnd) ? 0 : w.GetWindowTextLength();
  113. if(length == 0)
  114. {
  115. m_buffer = NULL;
  116. }
  117. else
  118. {
  119. m_buffer = string_maker_type::alloc(length);
  120. if(NULL != m_buffer)
  121. {
  122. w.GetWindowText(m_buffer, length + 1);
  123. }
  124. }
  125. }
  126. #ifdef STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT
  127. /// Move constructor
  128. ///
  129. /// This <a href = "http://synesis.com.au/resources/articles/cpp/movectors.pdf">move constructor</a>
  130. /// is for circumstances when the compiler does not, or cannot, apply the
  131. /// return value optimisation. It causes the contents of \c rhs to be
  132. /// transferred into the constructing instance. This is completely safe
  133. /// because the \c rhs instance will never be accessed in its own right, so
  134. /// does not need to maintain ownership of its contents.
  135. c_str_ptr_null_CWindow_proxy(class_type& rhs)
  136. : m_buffer(rhs.m_buffer)
  137. {
  138. rhs.m_buffer = 0;
  139. }
  140. #else /* ? STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT */
  141. // Copy constructor
  142. c_str_ptr_null_CWindow_proxy(class_type const& rhs)
  143. : m_buffer(string_maker_type::dup_null(rhs.m_buffer))
  144. {}
  145. #endif /* STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT */
  146. /// Releases any storage aquired by the proxy
  147. ~c_str_ptr_null_CWindow_proxy() stlsoft_throw_0()
  148. {
  149. string_maker_type::free(m_buffer);
  150. }
  151. // Accessors
  152. public:
  153. /// Returns a null-terminated string representing the window contents, or
  154. /// NULL if the window contains no text.
  155. operator LPCTSTR () const
  156. {
  157. return m_buffer;
  158. }
  159. // Members
  160. private:
  161. LPTSTR m_buffer;
  162. // Not to be implemented
  163. private:
  164. void operator =(class_type const& rhs);
  165. };
  166. /** \brief This class provides an intermediary object that may be returned by the
  167. * c_str_ptr() function, such that the window text of a given window may be
  168. * accessed as a null-terminated string.
  169. *
  170. * \ingroup group__concept__shim__string_access
  171. *
  172. */
  173. struct c_str_ptr_CWindow_proxy
  174. {
  175. private:
  176. typedef cstring_maker<TCHAR> string_maker_type;
  177. typedef c_str_ptr_CWindow_proxy class_type;
  178. // Construction
  179. public:
  180. /// Constructs an instance of the proxy from the given CWindow instance
  181. ///
  182. /// \param w The CWindow instance from which the text will be retrieved
  183. ss_explicit_k c_str_ptr_CWindow_proxy(CWindow const& w)
  184. {
  185. int length = (NULL == w.m_hWnd) ? 0 : w.GetWindowTextLength();
  186. if(length == 0)
  187. {
  188. m_buffer = string_maker_type::dup("");
  189. }
  190. else
  191. {
  192. m_buffer = string_maker_type::alloc(length);
  193. if(NULL != m_buffer)
  194. {
  195. w.GetWindowText(m_buffer, length + 1);
  196. }
  197. }
  198. }
  199. #ifdef STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT
  200. /// Move constructor
  201. ///
  202. /// This <a href = "http://synesis.com.au/resources/articles/cpp/movectors.pdf">move constructor</a>
  203. /// is for circumstances when the compiler does not, or cannot, apply the
  204. /// return value optimisation. It causes the contents of \c rhs to be
  205. /// transferred into the constructing instance. This is completely safe
  206. /// because the \c rhs instance will never be accessed in its own right, so
  207. /// does not need to maintain ownership of its contents.
  208. c_str_ptr_CWindow_proxy(class_type& rhs)
  209. : m_buffer(rhs.m_buffer)
  210. {
  211. rhs.m_buffer = 0;
  212. }
  213. #else /* ? STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT */
  214. // Copy constructor
  215. c_str_ptr_CWindow_proxy(class_type const& rhs)
  216. : m_buffer(string_maker_type::dup_null(rhs.m_buffer))
  217. {}
  218. #endif /* STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT */
  219. /// Releases any storage aquired by the proxy
  220. ~c_str_ptr_CWindow_proxy() stlsoft_throw_0()
  221. {
  222. string_maker_type::free(m_buffer);
  223. }
  224. // Accessors
  225. public:
  226. /// Returns a null-terminated string representing the window contents, or
  227. /// the empty string "" if the window contains no text.
  228. operator LPCTSTR () const
  229. {
  230. return (NULL == m_buffer) ? "" : m_buffer;
  231. }
  232. // Members
  233. private:
  234. LPTSTR m_buffer;
  235. // Not to be implemented
  236. private:
  237. void operator =(class_type const& rhs);
  238. };
  239. /* /////////////////////////////////////////////////////////////////////////
  240. * Equivalence testing
  241. */
  242. inline as_bool_t operator ==(LPCTSTR lhs, c_str_ptr_null_CWindow_proxy const& rhs)
  243. {
  244. return lhs == static_cast<LPCTSTR>(rhs);
  245. }
  246. inline as_bool_t operator ==(c_str_ptr_null_CWindow_proxy const& lhs, LPCTSTR rhs)
  247. {
  248. return static_cast<LPCTSTR>(lhs) == rhs;
  249. }
  250. inline as_bool_t operator !=(LPCTSTR lhs, c_str_ptr_null_CWindow_proxy const& rhs)
  251. {
  252. return lhs != static_cast<LPCTSTR>(rhs);
  253. }
  254. inline as_bool_t operator !=(c_str_ptr_null_CWindow_proxy const& lhs, LPCTSTR rhs)
  255. {
  256. return static_cast<LPCTSTR>(lhs) != rhs;
  257. }
  258. /* /////////////////////////////////////////////////////////////////////////
  259. * IOStream compatibility
  260. */
  261. template<ss_typename_param_k S>
  262. inline S& operator <<(S& s, c_str_ptr_null_CWindow_proxy const& shim)
  263. {
  264. s << static_cast<LPCTSTR>(shim);
  265. return s;
  266. }
  267. template <ss_typename_param_k S>
  268. inline S& operator <<(S& s, c_str_ptr_CWindow_proxy const& shim)
  269. {
  270. s << static_cast<LPCTSTR>(shim);
  271. return s;
  272. }
  273. /* /////////////////////////////////////////////////////////////////////////
  274. * c_str_data
  275. *
  276. * This can be applied to an expression, and the return value is either a
  277. * pointer to the character string or to an empty string.
  278. */
  279. /* CWindow */
  280. /** \brief \ref group__concept__shim__string_access__c_str_data for CWindow
  281. *
  282. * \ingroup group__concept__shim__string_access
  283. *
  284. */
  285. inline c_str_ptr_CWindow_proxy c_str_data(atlstl_ns_qual_atl(CWindow) const& w)
  286. {
  287. return c_str_ptr_CWindow_proxy(w);
  288. }
  289. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  290. # ifdef UNICODE
  291. inline c_str_ptr_CWindow_proxy c_str_data_w(atlstl_ns_qual_atl(CWindow) const& w)
  292. # else /* ? UNICODE */
  293. inline c_str_ptr_CWindow_proxy c_str_data_a(atlstl_ns_qual_atl(CWindow) const& w)
  294. # endif /* UNICODE */
  295. {
  296. return c_str_data(w);
  297. }
  298. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  299. /* /////////////////////////////////////////////////////////////////////////
  300. * c_str_len
  301. *
  302. * This can be applied to an expression, and the return value is the number
  303. * of characters in the character string in the expression.
  304. */
  305. /* CWindow */
  306. /** \brief \ref group__concept__shim__string_access__c_str_len for CWindow
  307. *
  308. * \ingroup group__concept__shim__string_access
  309. *
  310. */
  311. inline as_size_t c_str_len(atlstl_ns_qual_atl(CWindow) const& w)
  312. {
  313. return static_cast<as_size_t>(w.GetWindowTextLength());
  314. }
  315. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  316. # ifdef UNICODE
  317. inline as_size_t c_str_len_w(atlstl_ns_qual_atl(CWindow) const& w)
  318. # else /* ? UNICODE */
  319. inline as_size_t c_str_len_a(atlstl_ns_qual_atl(CWindow) const& w)
  320. # endif /* UNICODE */
  321. {
  322. return c_str_len(w);
  323. }
  324. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  325. /* /////////////////////////////////////////////////////////////////////////
  326. * c_str_ptr
  327. *
  328. * This can be applied to an expression, and the return value is either a
  329. * pointer to the character string or to an empty string.
  330. */
  331. /* CWindow */
  332. /** \brief \ref group__concept__shim__string_access__c_str_ptr for CWindow
  333. *
  334. * \ingroup group__concept__shim__string_access
  335. *
  336. */
  337. inline c_str_ptr_CWindow_proxy c_str_ptr(atlstl_ns_qual_atl(CWindow) const& w)
  338. {
  339. return c_str_ptr_CWindow_proxy(w);
  340. }
  341. # ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  342. # ifdef UNICODE
  343. inline c_str_ptr_CWindow_proxy c_str_ptr_w(atlstl_ns_qual_atl(CWindow) const& w)
  344. # else /* ? UNICODE */
  345. inline c_str_ptr_CWindow_proxy c_str_ptr_a(atlstl_ns_qual_atl(CWindow) const& w)
  346. # endif /* UNICODE */
  347. {
  348. return c_str_ptr(w);
  349. }
  350. # endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  351. /* /////////////////////////////////////////////////////////////////////////
  352. * c_str_ptr_null
  353. *
  354. * This can be applied to an expression, and the return value is either a
  355. * pointer to the character string or NULL.
  356. */
  357. /* CWindow */
  358. /** \brief \ref group__concept__shim__string_access__c_str_ptr_null for CWindow
  359. *
  360. * \ingroup group__concept__shim__string_access
  361. *
  362. */
  363. inline c_str_ptr_null_CWindow_proxy c_str_ptr_null(atlstl_ns_qual_atl(CWindow) const& w)
  364. {
  365. return c_str_ptr_null_CWindow_proxy(w);
  366. }
  367. # ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  368. # ifdef UNICODE
  369. inline c_str_ptr_null_CWindow_proxy c_str_ptr_null_w(atlstl_ns_qual_atl(CWindow) const& w)
  370. # else /* ? UNICODE */
  371. inline c_str_ptr_null_CWindow_proxy c_str_ptr_null_a(atlstl_ns_qual_atl(CWindow) const& w)
  372. # endif /* UNICODE */
  373. {
  374. return c_str_ptr_null(w);
  375. }
  376. # endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  377. ////////////////////////////////////////////////////////////////////////////
  378. // Unit-testing
  379. #ifdef STLSOFT_UNITTEST
  380. # include "./unittest/cwindow_unittest_.h"
  381. #endif /* STLSOFT_UNITTEST */
  382. /* ////////////////////////////////////////////////////////////////////// */
  383. #ifndef _ATLSTL_NO_NAMESPACE
  384. # if defined(_STLSOFT_NO_NAMESPACE) || \
  385. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  386. } // namespace atlstl
  387. # else
  388. } // namespace stlsoft::atlstl_project
  389. } // namespace stlsoft
  390. # endif /* _STLSOFT_NO_NAMESPACE */
  391. #endif /* !_ATLSTL_NO_NAMESPACE */
  392. /* /////////////////////////////////////////////////////////////////////////
  393. * Namespace
  394. *
  395. * The string access shims exist either in the stlsoft namespace, or in the
  396. * global namespace. This is required by the lookup rules.
  397. *
  398. */
  399. #ifndef _ATLSTL_NO_NAMESPACE
  400. # if !defined(_STLSOFT_NO_NAMESPACE) && \
  401. !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  402. namespace stlsoft
  403. {
  404. # else /* ? _STLSOFT_NO_NAMESPACE */
  405. /* There is no stlsoft namespace, so must define in the global namespace */
  406. # endif /* !_STLSOFT_NO_NAMESPACE */
  407. using ::atlstl::c_str_data;
  408. #if defined(UNICODE)
  409. using ::atlstl::c_str_data_w;
  410. #else /* ? UNICODE*/
  411. using ::atlstl::c_str_data_a;
  412. #endif /* UNICODE*/
  413. using ::atlstl::c_str_len;
  414. #if defined(UNICODE)
  415. using ::atlstl::c_str_len_w;
  416. #else /* ? UNICODE*/
  417. using ::atlstl::c_str_len_a;
  418. #endif /* UNICODE*/
  419. using ::atlstl::c_str_ptr;
  420. #if defined(UNICODE)
  421. using ::atlstl::c_str_ptr_w;
  422. #else /* ? UNICODE*/
  423. using ::atlstl::c_str_ptr_a;
  424. #endif /* UNICODE*/
  425. using ::atlstl::c_str_ptr_null;
  426. #if defined(UNICODE)
  427. using ::atlstl::c_str_ptr_null_w;
  428. #else /* ? UNICODE*/
  429. using ::atlstl::c_str_ptr_null_a;
  430. #endif /* UNICODE*/
  431. # if !defined(_STLSOFT_NO_NAMESPACE) && \
  432. !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  433. } // namespace stlsoft
  434. # else /* ? _STLSOFT_NO_NAMESPACE */
  435. /* There is no stlsoft namespace, so must define in the global namespace */
  436. # endif /* !_STLSOFT_NO_NAMESPACE */
  437. #endif /* !_ATLSTL_NO_NAMESPACE */
  438. /* ////////////////////////////////////////////////////////////////////// */
  439. #endif /* !ATLSTL_INCL_ATLSTL_SHIMS_ACCESS_STRING_HPP_CWINDOW */
  440. /* ///////////////////////////// end of file //////////////////////////// */