00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 #ifndef WINSTL_INCL_H_WINSTL
00060 # include "winstl.h"
00061 #endif
00062 #ifndef STLSOFT_INCL_H_STLSOFT_STRING_ACCESS
00063 # include "stlsoft_string_access.h"
00064 #endif
00065 #ifndef WINSTL_INCL_H_WINSTL_WINDOW_FUNCTIONS
00066 # include "winstl_window_functions.h"
00067 #endif
00068 #ifndef WINSTL_INCL_H_WINSTL_WINDOWS_IDENT
00069 # include "winstl_windows_ident.h"
00070 #endif
00071 #ifndef STLSOFT_INCL_H_STLSOFT_CSTRING_MAKER
00072 # include "stlsoft_cstring_maker.h"
00073 #endif
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 #ifndef _WINSTL_NO_NAMESPACE
00093 # if defined(_STLSOFT_NO_NAMESPACE) || \
00094 defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00095
00096 namespace winstl
00097 {
00098 # else
00099
00100
00101 namespace stlsoft
00102 {
00103
00104 namespace winstl_project
00105 {
00106
00107 # endif
00108 #endif
00109
00110
00111
00113
00116
00120
00125
00126
00127
00128
00129
00130 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00131
00132 inline ws_size_t GetWindowTextLength__(HWND hwnd)
00133 {
00134 WindowIdent ident = GetWindowIdent(hwnd);
00135 int sel;
00136
00137 switch(ident)
00138 {
00139 case ListBox:
00140 if(0 == (GetStyle(hwnd) & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)))
00141 {
00142 sel = (int)::SendMessage(hwnd, LB_GETCURSEL, 0, 0l);
00143
00144 if(LB_ERR != sel)
00145 {
00146 return static_cast<ws_size_t>(::SendMessage(hwnd, LB_GETTEXTLEN, static_cast<WPARAM>(sel), 0L));
00147 }
00148 else
00149 {
00150 return 0;
00151 }
00152 }
00153 break;
00154 #if 0
00155 case ListBox:
00156 if(1 == SendMessage(hwnd, LVM_GETSELECTEDCOUNT, 0, 0L))
00157 {
00158 sel =
00159 }
00160 break;
00161 #endif
00162 default:
00163 break;
00164 }
00165
00166 return ::GetWindowTextLength(hwnd);
00167 }
00168
00169 inline ws_size_t GetWindowTextA__(HWND hwnd, ws_char_a_t *buffer, ws_size_t cchBuffer)
00170 {
00171 WindowIdent ident = GetWindowIdent(hwnd);
00172 int sel;
00173 ws_size_t cch;
00174
00175 switch(ident)
00176 {
00177 case ListBox:
00178 if(0 == (GetStyle(hwnd) & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)))
00179 {
00180 sel = (int)::SendMessage(hwnd, LB_GETCURSEL, 0, 0l);
00181
00182 if(LB_ERR != sel)
00183 {
00184 cch = static_cast<ws_size_t>(::SendMessage(hwnd, LB_GETTEXT, static_cast<WPARAM>(sel), reinterpret_cast<LPARAM>(buffer)));
00185
00186
00187
00188 buffer[cch] = '\0';
00189 }
00190 else
00191 {
00192 buffer[0] = '\0';
00193
00194 cch = 0;
00195 }
00196
00197 winstl_message_assert("Buffer overwrite", !(cchBuffer < cch));
00198
00199 return cch;
00200 }
00201 break;
00202 default:
00203 break;
00204 }
00205
00206 return ::GetWindowTextA(hwnd, buffer, static_cast<int>(cchBuffer));
00207 }
00208
00209 inline ws_size_t GetWindowTextW__(HWND hwnd, ws_char_w_t *buffer, ws_size_t cchBuffer)
00210 {
00211 WindowIdent ident = GetWindowIdent(hwnd);
00212 int sel;
00213
00214 switch(ident)
00215 {
00216 case ListBox:
00217 if(0 == (GetStyle(hwnd) & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)))
00218 {
00219 ws_size_t cch;
00220
00221 sel = (int)::SendMessage(hwnd, LB_GETCURSEL, 0, 0l);
00222
00223 if(LB_ERR != sel)
00224 {
00225 cch = static_cast<ws_size_t>(::SendMessage(hwnd, LB_GETTEXT, static_cast<WPARAM>(sel), reinterpret_cast<LPARAM>(buffer)));
00226 }
00227 else
00228 {
00229 buffer[0] = '\0';
00230
00231 cch = 0;
00232 }
00233
00234 winstl_message_assert("Buffer overwrite", !(cchBuffer < cch));
00235
00236 return cch;
00237 }
00238 break;
00239 default:
00240 break;
00241 }
00242
00243 return ::GetWindowTextW(hwnd, buffer, static_cast<int>(cchBuffer));
00244 }
00245 #endif
00246
00247
00248
00249
00250
00251
00252
00256 template <ss_typename_param_k C>
00257 class c_str_ptr_null_HWND_proxy
00258 {
00259 typedef cstring_maker<C> string_maker_type;
00260 public:
00261 typedef C char_type;
00262 typedef c_str_ptr_null_HWND_proxy<C> class_type;
00263
00264
00265 public:
00269 ss_explicit_k c_str_ptr_null_HWND_proxy(HWND h)
00270 {
00271 ws_size_t length = GetWindowTextLength__(h);
00272
00273 if(length == 0)
00274 {
00275 m_buffer = NULL;
00276 }
00277 else
00278 {
00279 m_buffer = string_maker_type::alloc(length);
00280
00281 if(NULL != m_buffer)
00282 {
00283 get_window_text(h, m_buffer, length + 1);
00284 }
00285 }
00286 }
00287
00288 #ifdef __STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT
00297 c_str_ptr_null_HWND_proxy(class_type &rhs)
00298 : m_buffer(rhs.m_buffer)
00299 {
00300 move_lhs_from_rhs(rhs).m_buffer = NULL;
00301 }
00302 #else
00303
00304 c_str_ptr_null_HWND_proxy(class_type const &rhs)
00305 : m_buffer(string_maker_type::dup_null(rhs.m_buffer))
00306 {}
00307 #endif
00308
00310 ~c_str_ptr_null_HWND_proxy()
00311 {
00312 string_maker_type::free(m_buffer);
00313 }
00314
00315
00316 public:
00319 operator char_type const *() const
00320 {
00321 return m_buffer;
00322 }
00323
00324
00325 private:
00326 ws_size_t get_window_text(HWND h, char_type *buffer, ws_size_t cchBuffer);
00327
00328
00329 private:
00330 char_type *m_buffer;
00331
00332
00333 private:
00334 void operator =(class_type const &rhs);
00335 };
00336
00337 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00338
00339 STLSOFT_TEMPLATE_SPECIALISATION
00340 inline ws_size_t c_str_ptr_null_HWND_proxy<ws_char_a_t>::get_window_text(HWND h, ws_char_a_t *buffer, ws_size_t cchBuffer)
00341 {
00342 return GetWindowTextA__(h, buffer, cchBuffer);
00343 }
00344
00345 STLSOFT_TEMPLATE_SPECIALISATION
00346 inline ws_size_t c_str_ptr_null_HWND_proxy<ws_char_w_t>::get_window_text(HWND h, ws_char_w_t *buffer, ws_size_t cchBuffer)
00347 {
00348 return GetWindowTextW__(h, buffer, cchBuffer);
00349 }
00350
00351 #endif
00352
00356 template <ss_typename_param_k C>
00357 class c_str_ptr_HWND_proxy
00358 {
00359 typedef cstring_maker<C> string_maker_type;
00360 public:
00361 typedef C char_type;
00362 typedef c_str_ptr_HWND_proxy<C> class_type;
00363
00364
00365 public:
00369 ss_explicit_k c_str_ptr_HWND_proxy(HWND h)
00370 {
00371 ws_size_t length = GetWindowTextLength__(h);
00372
00373 m_buffer = string_maker_type::alloc(length);
00374
00375 if(NULL != m_buffer)
00376 {
00377 get_window_text(h, m_buffer, length + 1);
00378 }
00379 }
00380
00381 #ifdef __STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT
00390 c_str_ptr_HWND_proxy(class_type &rhs)
00391 : m_buffer(rhs.m_buffer)
00392 {
00393 move_lhs_from_rhs(rhs).m_buffer = NULL;
00394 }
00395 #else
00396
00397 c_str_ptr_HWND_proxy(class_type const &rhs)
00398 : m_buffer(string_maker_type::dup_null(rhs.m_buffer))
00399 {}
00400 #endif
00401
00403 ~c_str_ptr_HWND_proxy()
00404 {
00405 string_maker_type::free(m_buffer);
00406 }
00407
00408
00409 public:
00412 operator char_type const *() const
00413 {
00414 static char_type s_ch[1] = { '\0' };
00415
00416 return (NULL == m_buffer) ? s_ch : m_buffer;
00417 }
00418
00419
00420 private:
00421 ws_size_t get_window_text(HWND h, char_type *buffer, ws_size_t cchBuffer);
00422
00423
00424 private:
00425 char_type *m_buffer;
00426
00427
00428 private:
00429 void operator =(class_type const &rhs);
00430 };
00431
00432 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00433
00434 STLSOFT_TEMPLATE_SPECIALISATION
00435 inline ws_size_t c_str_ptr_HWND_proxy<ws_char_a_t>::get_window_text(HWND h, ws_char_a_t *buffer, ws_size_t cchBuffer)
00436 {
00437 return GetWindowTextA__(h, buffer, cchBuffer);
00438 }
00439
00440 STLSOFT_TEMPLATE_SPECIALISATION
00441 inline ws_size_t c_str_ptr_HWND_proxy<ws_char_w_t>::get_window_text(HWND h, ws_char_w_t *buffer, ws_size_t cchBuffer)
00442 {
00443 return GetWindowTextW__(h, buffer, cchBuffer);
00444 }
00445
00446 #endif
00447
00448
00449
00450 #ifdef _NTSECAPI_
00454 class c_str_ptr_LSA_UNICODE_STRING_proxy
00455 {
00456 typedef cstring_maker<WCHAR> string_maker_type;
00457 public:
00458 typedef c_str_ptr_LSA_UNICODE_STRING_proxy class_type;
00459
00460
00461 public:
00465 ss_explicit_k c_str_ptr_LSA_UNICODE_STRING_proxy(const LSA_UNICODE_STRING &s)
00466 : m_buffer(string_maker_type::alloc(s.Length))
00467 {
00468 if(NULL != m_buffer)
00469 {
00470 wcsncpy(m_buffer, s.Buffer, s.Length);
00471 m_buffer[s.Length] = L'\0';
00472 }
00473 }
00474
00475 #ifdef __STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT
00484 c_str_ptr_LSA_UNICODE_STRING_proxy(class_type &rhs)
00485 : m_buffer(rhs.m_buffer)
00486 {
00487 rhs.m_buffer = NULL;
00488 }
00489 #else
00490
00491 c_str_ptr_LSA_UNICODE_STRING_proxy(class_type const &rhs)
00492 : m_buffer(string_maker_type::dup_null(rhs.m_buffer))
00493 {}
00494 #endif
00495
00497 ~c_str_ptr_LSA_UNICODE_STRING_proxy()
00498 {
00499 string_maker_type::free(m_buffer);
00500 }
00501
00502
00503 public:
00506 operator LPCWSTR () const
00507 {
00508 return m_buffer;
00509 }
00510
00511
00512 private:
00513 LPWSTR m_buffer;
00514
00515
00516 private:
00517 void operator =(class_type const &rhs);
00518 };
00519 #endif
00520
00521 #ifdef _NTSECAPI_
00525 class c_str_ptr_null_LSA_UNICODE_STRING_proxy
00526 {
00527 typedef cstring_maker<WCHAR> string_maker_type;
00528 public:
00529 typedef c_str_ptr_null_LSA_UNICODE_STRING_proxy class_type;
00530
00531
00532 public:
00536 ss_explicit_k c_str_ptr_null_LSA_UNICODE_STRING_proxy(const LSA_UNICODE_STRING &s)
00537 : m_buffer((s.Length != 0) ? string_maker_type::alloc(s.Length) : NULL)
00538 {
00539 if(m_buffer != NULL)
00540 {
00541 wcsncpy(m_buffer, s.Buffer, s.Length);
00542 m_buffer[s.Length] = L'\0';
00543 }
00544 }
00545
00546 #ifdef __STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT
00555 c_str_ptr_null_LSA_UNICODE_STRING_proxy(class_type &rhs)
00556 : m_buffer(rhs.m_buffer)
00557 {
00558 rhs.m_buffer = NULL;
00559 }
00560 #else
00561
00562 c_str_ptr_null_LSA_UNICODE_STRING_proxy(class_type const &rhs)
00563 : m_buffer(string_maker_type::dup_null(rhs.m_buffer))
00564 {}
00565 #endif
00566
00568 ~c_str_ptr_null_LSA_UNICODE_STRING_proxy()
00569 {
00570 string_maker_type::free(m_buffer);
00571 }
00572
00573
00574 public:
00577 operator LPCWSTR () const
00578 {
00579 return m_buffer;
00580 }
00581
00582
00583 private:
00584 LPWSTR m_buffer;
00585
00586
00587 private:
00588 void operator =(class_type const &rhs);
00589 };
00590 #endif
00591
00592
00593
00594
00595
00596 template< ss_typename_param_k C
00597 , ss_typename_param_k S
00598 >
00599 inline S &operator <<(S & s, c_str_ptr_null_HWND_proxy<C> const &shim)
00600 {
00601 s << static_cast<C const *>(shim);
00602
00603 return s;
00604 }
00605
00606 template< ss_typename_param_k C
00607 , ss_typename_param_k S
00608 >
00609 inline S &operator <<(S & s, c_str_ptr_HWND_proxy<C> const &shim)
00610 {
00611 s << static_cast<C const *>(shim);
00612
00613 return s;
00614 }
00615
00616 #ifdef _NTSECAPI_
00617 template<ss_typename_param_k S>
00618 inline S &operator <<(S & s, c_str_ptr_LSA_UNICODE_STRING_proxy const &shim)
00619 {
00620 s << static_cast<LPCWSTR>(shim);
00621
00622 return s;
00623 }
00624
00625 template<ss_typename_param_k S>
00626 inline S &operator <<(S & s, c_str_ptr_null_LSA_UNICODE_STRING_proxy const &shim)
00627 {
00628 s << static_cast<LPCWSTR>(shim);
00629
00630 return s;
00631 }
00632 #endif
00633
00634
00635
00636
00637
00638
00639
00640
00641
00643 inline c_str_ptr_null_HWND_proxy<ws_char_a_t> c_str_ptr_null_a(HWND h)
00644 {
00645 return c_str_ptr_null_HWND_proxy<ws_char_a_t>(h);
00646 }
00647
00649 inline c_str_ptr_null_HWND_proxy<ws_char_w_t> c_str_ptr_null_w(HWND h)
00650 {
00651 return c_str_ptr_null_HWND_proxy<ws_char_w_t>(h);
00652 }
00653
00655 inline c_str_ptr_null_HWND_proxy<TCHAR> c_str_ptr_null(HWND h)
00656 {
00657 return c_str_ptr_null_HWND_proxy<TCHAR>(h);
00658 }
00659
00660
00661 #ifdef _NTSECAPI_
00662
00663 inline c_str_ptr_null_LSA_UNICODE_STRING_proxy c_str_ptr_null(const LSA_UNICODE_STRING &s)
00664 {
00665 return c_str_ptr_null_LSA_UNICODE_STRING_proxy(s);
00666 }
00667 #endif
00668
00669
00670
00671
00672
00673
00674
00675
00676
00678 inline c_str_ptr_HWND_proxy<ws_char_a_t> c_str_ptr_a(HWND h)
00679 {
00680 return c_str_ptr_HWND_proxy<ws_char_a_t>(h);
00681 }
00682
00684 inline c_str_ptr_HWND_proxy<ws_char_w_t> c_str_ptr_w(HWND h)
00685 {
00686 return c_str_ptr_HWND_proxy<ws_char_w_t>(h);
00687 }
00688
00690 inline c_str_ptr_HWND_proxy<TCHAR> c_str_ptr(HWND h)
00691 {
00692 return c_str_ptr_HWND_proxy<TCHAR>(h);
00693 }
00694
00695
00696 #ifdef _NTSECAPI_
00697
00698 inline c_str_ptr_LSA_UNICODE_STRING_proxy c_str_ptr(const LSA_UNICODE_STRING &s)
00699 {
00700 return c_str_ptr_LSA_UNICODE_STRING_proxy(s);
00701 }
00702 #endif
00703
00704
00705
00706
00707
00708
00709
00710
00711
00713 inline ws_size_t c_str_len(HWND h)
00714 {
00715 return GetWindowTextLength__(h);
00716 }
00717
00719 inline ws_size_t c_str_len_a(HWND h)
00720 {
00721 return c_str_len(h);
00722 }
00723
00725 inline ws_size_t c_str_len_w(HWND h)
00726 {
00727 return c_str_len(h);
00728 }
00729
00730
00731 #ifdef _NTSECAPI_
00732
00733 inline ws_size_t c_str_len(const LSA_UNICODE_STRING &s)
00734 {
00735 return s.Length;
00736 }
00737 #endif
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00749 inline ws_size_t c_str_size_a(HWND h)
00750 {
00751 return c_str_len(h) * sizeof(ws_char_a_t);
00752 }
00753
00755 inline ws_size_t c_str_size_w(HWND h)
00756 {
00757 return c_str_len(h) * sizeof(ws_char_w_t);
00758 }
00759
00761 inline ws_size_t c_str_size(HWND h)
00762 {
00763 return c_str_len(h) * sizeof(TCHAR);
00764 }
00765
00766
00767 #ifdef _NTSECAPI_
00768
00769 inline ws_size_t c_str_size(const LSA_UNICODE_STRING &s)
00770 {
00771 return c_str_len(s) * sizeof(WCHAR);
00772 }
00773 #endif
00774
00776
00777
00778 #ifdef STLSOFT_UNITTEST
00779
00780 namespace unittest
00781 {
00782 namespace
00783 {
00784 ss_bool_t test_winstl_string_access_HWND(unittest_reporter *r)
00785 {
00786 ss_bool_t bSuccess = true;
00787
00788 HWND hwnd = ::CreateWindow("BUTTON", "Window #1", 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
00789
00790 if( NULL != hwnd &&
00791 0 != strcmp("Window #1", c_str_ptr_a(hwnd)))
00792 {
00793 r->report("c_str_ptr(HWND) failed ", __LINE__);
00794 bSuccess = false;
00795 }
00796
00797 return bSuccess;
00798 }
00799
00800 ss_bool_t test_winstl_string_access_LSA_UNICODE_STRING(unittest_reporter *r)
00801 {
00802 ss_bool_t bSuccess = true;
00803
00804 #ifdef _NTSECAPI_
00805 WCHAR buffer[100] = L"LSA-String #1";
00806 LSA_UNICODE_STRING lsa1 =
00807 {
00808 static_cast<USHORT>(wcslen(buffer))
00809 , stlsoft_num_elements(buffer)
00810 , buffer
00811 };
00812
00813 if(0 != wcscmp(c_str_ptr(lsa1), L"LSA-String #1"))
00814 {
00815 r->report("c_str_ptr(LSA_UNICODE_STRING) failed ", __LINE__);
00816 bSuccess = false;
00817 }
00818 #else
00819 STLSOFT_SUPPRESS_UNUSED(r);
00820 #endif
00821
00822 return bSuccess;
00823 }
00824
00825 }
00826
00827 ss_bool_t test_winstl_string_access(unittest_reporter *r)
00828 {
00829 using stlsoft::unittest::unittest_initialiser;
00830
00831 ss_bool_t bSuccess = true;
00832
00833 unittest_initialiser init(r, "WinSTL", "string_access", __FILE__);
00834
00835 return bSuccess;
00836 }
00837
00838 unittest_registrar unittest_winstl_string_access(test_winstl_string_access);
00839
00840 }
00841
00842 #endif
00843
00844
00845
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858 #endif
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868 #ifndef _WINSTL_NO_NAMESPACE
00869 # if !defined(_STLSOFT_NO_NAMESPACE) && \
00870 !defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00871 namespace stlsoft
00872 {
00873 # else
00874
00875 # endif
00876
00877 using ::winstl::c_str_ptr_null_a;
00878 using ::winstl::c_str_ptr_a;
00879 using ::winstl::c_str_len_a;
00880 using ::winstl::c_str_size_a;
00881 using ::winstl::c_str_ptr_null_w;
00882 using ::winstl::c_str_ptr_w;
00883 using ::winstl::c_str_len_w;
00884 using ::winstl::c_str_size_w;
00885 using ::winstl::c_str_ptr_null;
00886 using ::winstl::c_str_ptr;
00887 using ::winstl::c_str_len;
00888 using ::winstl::c_str_size;
00889
00890 # if !defined(_STLSOFT_NO_NAMESPACE) && \
00891 !defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00892 }
00893 # else
00894
00895 # endif
00896 #endif
00897
00898
00899
00900
00901
00902