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 MFCSTL_INCL_H_MFCSTL
00060 # include "mfcstl.h"
00061 #endif
00062 #ifndef STLSOFT_INCL_H_STLSOFT_STRING_ACCESS
00063 # include "stlsoft_string_access.h"
00064 #endif
00065 #ifndef STLSOFT_INCL_H_STLSOFT_CONSTRAINTS
00066 # include "stlsoft_constraints.h"
00067 #endif
00068 #ifndef STLSOFT_INCL_H_STLSOFT_CSTRING_MAKER
00069 # include "stlsoft_cstring_maker.h"
00070 #endif
00071
00072 #if defined(__STLSOFT_COMPILER_IS_BORLAND)
00073 # pragma warn -8022
00074 # pragma warn -8084
00075 #endif
00076
00077 #include <afxwin.h>
00078 #if !defined(__AFXCMN_H__) && \
00079 !defined(MFCSTL_STRING_ACCESS_NO_INCLUDE_AFXCMN)
00080 # include <afxcmn.h>
00081 #endif
00082 #if !defined(__AFXCVIEW_H__) && \
00083 !defined(MFCSTL_STRING_ACCESS_NO_INCLUDE_AFXCVIEW)
00084 # include <afxcview.h>
00085 #endif
00086
00087 #if defined(__STLSOFT_COMPILER_IS_BORLAND)
00088 # pragma warn .8022
00089 # pragma warn .8084
00090 #endif
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 #ifndef _MFCSTL_NO_NAMESPACE
00110 # if defined(_STLSOFT_NO_NAMESPACE) || \
00111 defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00112
00113 namespace mfcstl
00114 {
00115 # else
00116
00117
00118 namespace stlsoft
00119 {
00120
00121 namespace mfcstl_project
00122 {
00123
00124 # endif
00125 #endif
00126
00127
00128
00130
00133
00137
00142
00143
00144
00145
00146
00147 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00148
00149 inline ms_size_t GetWindowTextLength__(CWnd const &w)
00150 {
00151 return (NULL != w.m_hWnd) ? static_cast<ms_size_t>(w.GetWindowTextLength()) : 0;
00152 }
00153
00154 inline ms_size_t GetWindowText__(CWnd const &w, LPTSTR buffer, ms_size_t cchBuffer)
00155 {
00156 mfcstl_assert(NULL != w.m_hWnd);
00157
00158 return static_cast<ms_size_t>(w.GetWindowText(buffer, cchBuffer));
00159 }
00160
00161
00162 inline ms_size_t GetWindowTextLength__(CListBox const &w)
00163 {
00164 int sel;
00165
00166 if( 0 == (w.GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) &&
00167 LB_ERR != (sel = w.GetCurSel()))
00168 {
00169 return static_cast<ms_size_t>(w.GetTextLen(sel));
00170 }
00171 else
00172 {
00173 return static_cast<ms_size_t>(w.GetWindowTextLength());
00174 }
00175 }
00176
00177 inline ms_size_t GetWindowText__(CListBox const &w, LPTSTR buffer, ms_size_t cchBuffer)
00178 {
00179 int sel = -1;
00180
00181 if( 0 == (w.GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) &&
00182 LB_ERR != (sel = w.GetCurSel()))
00183 {
00184 ms_size_t cch = static_cast<ms_size_t>(w.GetText(sel, buffer));
00185
00186 mfcstl_message_assert("Invalid item", LB_ERR != cch);
00187 mfcstl_message_assert("Buffer overwrite", !(cchBuffer < cch));
00188
00189 return static_cast<ms_size_t>(cch);
00190 }
00191 else
00192 {
00193 return w.GetWindowText(buffer, cchBuffer);
00194 }
00195 }
00196
00197 #ifdef __AFXCMN_H__
00198 # if _MFC_VER >= 0x0600
00199 inline ms_size_t GetWindowTextLength__(CListCtrl const &w)
00200 {
00201 if(1 == w.GetSelectedCount())
00202 {
00203 POSITION pos = w.GetFirstSelectedItemPosition();
00204 int sel = w.GetNextSelectedItem(pos);
00205
00206 return static_cast<ms_size_t>(w.GetItemText(sel, 0).GetLength());
00207 }
00208 else
00209 {
00210 return static_cast<ms_size_t>(w.GetWindowTextLength());
00211 }
00212 }
00213
00214 inline ms_size_t GetWindowText__(CListCtrl const &w, LPTSTR buffer, ms_size_t cchBuffer)
00215 {
00216 if(1 == w.GetSelectedCount())
00217 {
00218 POSITION pos = w.GetFirstSelectedItemPosition();
00219 int sel = w.GetNextSelectedItem(pos);
00220
00221 return static_cast<ms_size_t>(w.GetItemText(sel, 0, buffer, cchBuffer));
00222 }
00223 else
00224 {
00225 return w.GetWindowText(buffer, cchBuffer);
00226 }
00227 }
00228
00229 # ifdef __AFXCVIEW_H__
00230 inline ms_size_t GetWindowTextLength__(CListView const &w)
00231 {
00232 return GetWindowTextLength__(w.GetListCtrl());
00233 }
00234
00235 inline ms_size_t GetWindowText__(CListView const &w, LPTSTR buffer, ms_size_t cchBuffer)
00236 {
00237 return GetWindowText__(w.GetListCtrl(), buffer, cchBuffer);
00238 }
00239 # endif
00240 # endif
00241 #endif
00242
00243 #endif
00244
00245
00246
00247
00248
00249
00250
00251
00255 class c_str_ptr_null_CWnd_proxy
00256 {
00257 typedef TCHAR char_type;
00258 typedef cstring_maker<TCHAR> string_maker_type;
00259 public:
00260 typedef c_str_ptr_null_CWnd_proxy class_type;
00261
00262
00263 public:
00267 template<ss_typename_param_k W>
00268 c_str_ptr_null_CWnd_proxy(const W &w)
00269 {
00270 stlsoft_constraint_must_have_base(W, CWnd);
00271
00272 ms_size_t length = GetWindowTextLength__(w);
00273
00274 if(length == 0)
00275 {
00276 m_buffer = NULL;
00277 }
00278 else
00279 {
00280 m_buffer = string_maker_type::alloc(length);
00281
00282 if(NULL != m_buffer)
00283 {
00284 GetWindowText__(w, m_buffer, length + 1);
00285 }
00286 }
00287 }
00288
00289 #ifdef __STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT
00298 c_str_ptr_null_CWnd_proxy(class_type &rhs)
00299 : m_buffer(rhs.m_buffer)
00300 {
00301 rhs.m_buffer = NULL;
00302 }
00303 #else
00304
00305 c_str_ptr_null_CWnd_proxy(class_type const &rhs)
00306 : m_buffer(string_maker_type::dup_null(rhs.m_buffer))
00307 {}
00308 #endif
00309
00311 ~c_str_ptr_null_CWnd_proxy()
00312 {
00313 string_maker_type::free(m_buffer);
00314 }
00315
00316
00317 public:
00320 operator LPCTSTR () const
00321 {
00322 return m_buffer;
00323 }
00324
00325
00326 private:
00327 LPTSTR m_buffer;
00328
00329
00330 private:
00331 void operator =(class_type const &rhs);
00332 };
00333
00337 class c_str_ptr_CWnd_proxy
00338 {
00339 typedef TCHAR char_type;
00340 typedef cstring_maker<TCHAR> string_maker_type;
00341 private:
00342 typedef c_str_ptr_CWnd_proxy class_type;
00343
00344
00345 public:
00349 template<ss_typename_param_k W>
00350 c_str_ptr_CWnd_proxy(const W &w)
00351 {
00352 stlsoft_constraint_must_have_base(W, CWnd);
00353
00354 ms_size_t length = GetWindowTextLength__(w);
00355
00356 if(length == 0)
00357 {
00358 m_buffer = string_maker_type::dup(_T(""));
00359 }
00360 else
00361 {
00362 m_buffer = string_maker_type::alloc(length);
00363
00364 if(NULL != m_buffer)
00365 {
00366 GetWindowText__(w, m_buffer, length + 1);
00367 }
00368 }
00369 }
00370
00371 #ifdef __STLSOFT_CF_MOVE_CONSTRUCTOR_SUPPORT
00380 c_str_ptr_CWnd_proxy(class_type &rhs)
00381 : m_buffer(rhs.m_buffer)
00382 {
00383 rhs.m_buffer = NULL;
00384 }
00385 #else
00386
00387 c_str_ptr_CWnd_proxy(class_type const &rhs)
00388 : m_buffer(string_maker_type::dup_null(rhs.m_buffer))
00389 {}
00390 #endif
00391
00393 ~c_str_ptr_CWnd_proxy()
00394 {
00395 string_maker_type::free(m_buffer);
00396 }
00397
00398
00399 public:
00402 operator LPCTSTR () const
00403 {
00404 static char_type s_ch[1] = { '\0' };
00405
00406 return (NULL == m_buffer) ? s_ch : m_buffer;
00407 }
00408
00409
00410 private:
00411
00412 static LPTSTR dup_(LPCTSTR s)
00413 {
00414 return lstrcpy(new TCHAR[1 + lstrlen(s)], s);
00415 }
00416
00417
00418 private:
00419 LPTSTR m_buffer;
00420
00421
00422 private:
00423 void operator =(class_type const &rhs);
00424 };
00425
00426
00427
00428
00429
00430 inline ms_bool_t operator ==(LPCTSTR lhs, c_str_ptr_null_CWnd_proxy const &rhs)
00431 {
00432 return lhs == static_cast<LPCTSTR>(rhs);
00433 }
00434
00435 inline ms_bool_t operator ==(c_str_ptr_null_CWnd_proxy const &lhs, LPCTSTR rhs)
00436 {
00437 return static_cast<LPCTSTR>(lhs) == rhs;
00438 }
00439
00440 inline ms_bool_t operator !=(LPCTSTR lhs, c_str_ptr_null_CWnd_proxy const &rhs)
00441 {
00442 return lhs != static_cast<LPCTSTR>(rhs);
00443 }
00444
00445 inline ms_bool_t operator !=(c_str_ptr_null_CWnd_proxy const &lhs, LPCTSTR rhs)
00446 {
00447 return static_cast<LPCTSTR>(lhs) != rhs;
00448 }
00449
00450
00451
00452
00453
00454 template<ss_typename_param_k S>
00455 inline S &operator <<(S & s, c_str_ptr_null_CWnd_proxy const &shim)
00456 {
00457 s << static_cast<LPCTSTR>(shim);
00458
00459 return s;
00460 }
00461
00462 template <ss_typename_param_k S>
00463 inline S &operator <<(S & s, c_str_ptr_CWnd_proxy const &shim)
00464 {
00465 s << static_cast<LPCTSTR>(shim);
00466
00467 return s;
00468 }
00469
00470
00471
00472
00473
00474
00475
00476
00477
00479 inline c_str_ptr_null_CWnd_proxy c_str_ptr_null(const CWnd &w)
00480 {
00481 return c_str_ptr_null_CWnd_proxy(w);
00482 }
00483
00484 inline c_str_ptr_null_CWnd_proxy c_str_ptr_null(const CListBox &w)
00485 {
00486 return c_str_ptr_null_CWnd_proxy(w);
00487 }
00488
00489 #ifdef __AFXCMN_H__
00490 inline c_str_ptr_null_CWnd_proxy c_str_ptr_null(const CListCtrl &w)
00491 {
00492 return c_str_ptr_null_CWnd_proxy(w);
00493 }
00494
00495 # ifdef __AFXCVIEW_H__
00496 inline c_str_ptr_null_CWnd_proxy c_str_ptr_null(const CListView &w)
00497 {
00498 return c_str_ptr_null(w.GetListCtrl());
00499 }
00500 # endif
00501 #endif
00502
00503
00505 inline LPCTSTR c_str_ptr_null(const CString &s)
00506 {
00507
00508
00509
00510 return s.IsEmpty() ? NULL : (LPCTSTR)s;
00511 }
00512
00513
00514
00515
00516
00517
00518
00519
00520
00522 inline c_str_ptr_CWnd_proxy c_str_ptr(const CWnd &w)
00523 {
00524 return c_str_ptr_CWnd_proxy(w);
00525 }
00526
00527 inline c_str_ptr_CWnd_proxy c_str_ptr(const CListBox &w)
00528 {
00529 return c_str_ptr_CWnd_proxy(w);
00530 }
00531
00532 #ifdef __AFXCMN_H__
00533 inline c_str_ptr_CWnd_proxy c_str_ptr(const CListCtrl &w)
00534 {
00535 return c_str_ptr_CWnd_proxy(w);
00536 }
00537
00538 # ifdef __AFXCVIEW_H__
00539 inline c_str_ptr_CWnd_proxy c_str_ptr(const CListView &w)
00540 {
00541 return c_str_ptr(w.GetListCtrl());
00542 }
00543 # endif
00544 #endif
00545
00546
00548 inline LPCTSTR c_str_ptr(const CString &s)
00549 {
00550
00551
00552
00553 return s;
00554 }
00555
00556
00557
00558
00559
00560
00561
00562
00563
00565 inline ms_size_t c_str_len(const CWnd &w)
00566 {
00567 return GetWindowTextLength__(w);
00568 }
00569
00570 inline ms_size_t c_str_len(const CListBox &w)
00571 {
00572 return GetWindowTextLength__(w);
00573 }
00574
00575 #ifdef __AFXCMN_H__
00576 inline ms_size_t c_str_len(const CListCtrl &w)
00577 {
00578 return GetWindowTextLength__(w);
00579 }
00580
00581 # ifdef __AFXCVIEW_H__
00582 inline ms_size_t c_str_len(const CListView &w)
00583 {
00584 return c_str_len(w.GetListCtrl());
00585 }
00586 # endif
00587 #endif
00588
00589
00591 inline ms_size_t c_str_len(const CString &s)
00592 {
00593 return s.GetLength();
00594 }
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00606 inline ms_size_t c_str_size(const CWnd &w)
00607 {
00608 return c_str_len(w) * sizeof(TCHAR);
00609 }
00610
00611 inline ms_size_t c_str_size(const CListBox &w)
00612 {
00613 return c_str_len(w) * sizeof(TCHAR);
00614 }
00615
00616 #ifdef __AFXCMN_H__
00617 inline ms_size_t c_str_size(const CListCtrl &w)
00618 {
00619 return c_str_len(w) * sizeof(TCHAR);
00620 }
00621
00622 # ifdef __AFXCVIEW_H__
00623 inline ms_size_t c_str_size(const CListView &w)
00624 {
00625 return c_str_size(w.GetListCtrl());
00626 }
00627 # endif
00628 #endif
00629
00630
00632 inline ms_size_t c_str_size(const CString &s)
00633 {
00634 return c_str_len(s) * sizeof(TCHAR);
00635 }
00636
00638
00639
00640 #ifdef STLSOFT_UNITTEST
00641
00642 namespace unittest
00643 {
00644 namespace
00645 {
00646 ss_bool_t test_mfcstl_string_access_CString(unittest_reporter *r)
00647 {
00648 ss_bool_t bSuccess = true;
00649
00650 CString str1("String #1");
00651
00652 if(0 != _tcscmp(_T("String #1"), c_str_ptr(str1)))
00653 {
00654 r->report("c_str_ptr(CString) failed ", __LINE__);
00655 bSuccess = false;
00656 }
00657
00658 if(0 != _tcscmp(_T("String #1"), c_str_ptr_null(str1)))
00659 {
00660 r->report("c_str_ptr_null(CString) failed ", __LINE__);
00661 bSuccess = false;
00662 }
00663
00664 CString str2;
00665
00666 if(NULL != c_str_ptr_null(str2))
00667 {
00668 r->report("c_str_ptr_null(CString) failed ", __LINE__);
00669 bSuccess = false;
00670 }
00671
00672 return bSuccess;
00673 }
00674
00675 ss_bool_t test_mfcstl_string_access_CWnd(unittest_reporter *r)
00676 {
00677 ss_bool_t bSuccess = true;
00678
00679 CWnd wnd1;
00680 CWnd *pwndDesktopWindow = CWnd::GetDesktopWindow();
00681 RECT rc = { 0, 0, 10, 10 };
00682
00683 if( wnd1.Create("BUTTON", "Window #1", NULL, rc, pwndDesktopWindow, 0) &&
00684 0 != strcmp("Window #1", c_str_ptr(wnd1)))
00685 {
00686 r->report("c_str_ptr(CWnd) failed ", __LINE__);
00687 bSuccess = false;
00688 }
00689
00690 wnd1.DestroyWindow();
00691
00692 CWnd wnd2;
00693
00694 if(0 != strcmp("", c_str_ptr(wnd2)))
00695 {
00696 r->report("c_str_ptr(CWnd) failed ", __LINE__);
00697 bSuccess = false;
00698 }
00699
00700 if(NULL != c_str_ptr_null(wnd2))
00701 {
00702 r->report("c_str_ptr_null(CWnd) failed ", __LINE__);
00703 bSuccess = false;
00704 }
00705
00706 return bSuccess;
00707 }
00708
00709 }
00710
00711 ss_bool_t test_mfcstl_string_access(unittest_reporter *r)
00712 {
00713 using stlsoft::unittest::unittest_initialiser;
00714
00715 ss_bool_t bSuccess = true;
00716
00717 unittest_initialiser init(r, "MFCSTL", "string_access", __FILE__);
00718
00719
00720 if(bSuccess)
00721 {
00722 bSuccess = test_mfcstl_string_access_CString(r);
00723 }
00724
00725
00726 if(bSuccess)
00727 {
00728 bSuccess = test_mfcstl_string_access_CWnd(r);
00729 }
00730
00731 return bSuccess;
00732 }
00733
00734 unittest_registrar unittest_mfcstl_string_access(test_mfcstl_string_access);
00735
00736 }
00737
00738 #endif
00739
00740
00741
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754 #endif
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764 #ifndef _MFCSTL_NO_NAMESPACE
00765 # if !defined(_STLSOFT_NO_NAMESPACE) && \
00766 !defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00767 namespace stlsoft
00768 {
00769 # else
00770
00771 # endif
00772
00773 using ::mfcstl::c_str_ptr_null;
00774
00775 using ::mfcstl::c_str_ptr;
00776
00777 using ::mfcstl::c_str_len;
00778
00779 using ::mfcstl::c_str_size;
00780
00781 # if !defined(_STLSOFT_NO_NAMESPACE) && \
00782 !defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00783 }
00784 # else
00785
00786 # endif
00787 #endif
00788
00789
00790
00791
00792
00793