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
00047 #ifndef WINSTL_INCL_WINSTL_WINDOW_HPP_ZORDER_ITERATOR
00048 #define WINSTL_INCL_WINSTL_WINDOW_HPP_ZORDER_ITERATOR
00049
00050 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00051 # define WINSTL_VER_WINSTL_WINDOW_HPP_ZORDER_ITERATOR_MAJOR 2
00052 # define WINSTL_VER_WINSTL_WINDOW_HPP_ZORDER_ITERATOR_MINOR 0
00053 # define WINSTL_VER_WINSTL_WINDOW_HPP_ZORDER_ITERATOR_REVISION 3
00054 # define WINSTL_VER_WINSTL_WINDOW_HPP_ZORDER_ITERATOR_EDIT 40
00055 #endif
00056
00057
00058
00059
00060
00061 #ifndef WINSTL_INCL_WINSTL_H_WINSTL
00062 # include <winstl/winstl.h>
00063 #endif
00064 #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
00065 # include <stlsoft/util/std/iterator_helper.hpp>
00066 #endif
00067 #ifndef STLSOFT_INCL_STLSOFT_ERROR_HPP_EXTERNAL_ITERATOR_INVALIDATION
00068 # include <stlsoft/error/external_iterator_invalidation.hpp>
00069 #endif
00070
00071
00072
00073
00074
00075 #ifndef _WINSTL_NO_NAMESPACE
00076 # if defined(_STLSOFT_NO_NAMESPACE) || \
00077 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00078
00079 namespace winstl
00080 {
00081 # else
00082
00083
00084 namespace stlsoft
00085 {
00086
00087 namespace winstl_project
00088 {
00089
00090 # endif
00091 #endif
00092
00093
00094
00095
00096
00097 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00098
00099 struct zorder_iterator_base
00100 {
00101 public:
00102 enum search
00103 {
00104 fromFirstPeer = 1
00105 , fromCurrent = 2
00106 , atLastPeer = 3
00107 , fromFirstChild = 4
00108 , atLastChild = 5
00109 };
00110 };
00111
00112 struct zorder_iterator_forward_traits;
00113 struct zorder_iterator_reverse_traits;
00114
00115 struct zorder_iterator_forward_traits
00116 {
00117 public:
00118 typedef zorder_iterator_forward_traits this_type;
00119 typedef zorder_iterator_reverse_traits alternate_type;
00120 public:
00121 static HWND get_first_child(HWND hwnd)
00122 {
00123 return ::GetWindow(hwnd, GW_CHILD);
00124 }
00125 static HWND get_first_peer(HWND hwnd)
00126 {
00127 return ::GetWindow(hwnd, GW_HWNDFIRST);
00128 }
00129 static HWND get_next_peer(HWND hwnd)
00130 {
00131 return ::GetWindow(hwnd, GW_HWNDNEXT);
00132 }
00133 static HWND get_previous_peer(HWND hwnd)
00134 {
00135 return ::GetWindow(hwnd, GW_HWNDPREV);
00136 }
00137 static HWND get_last_peer(HWND hwnd)
00138 {
00139 return ::GetWindow(hwnd, GW_HWNDLAST);
00140 }
00141 };
00142
00143 struct zorder_iterator_reverse_traits
00144 {
00145 public:
00146 typedef zorder_iterator_reverse_traits this_type;
00147 typedef zorder_iterator_forward_traits alternate_type;
00148 public:
00149 static HWND get_first_child(HWND hwnd)
00150 {
00151 return ::GetWindow(::GetWindow(hwnd, GW_CHILD), GW_HWNDLAST);
00152 }
00153 static HWND get_first_peer(HWND hwnd)
00154 {
00155 return ::GetWindow(hwnd, GW_HWNDLAST);
00156 }
00157 static HWND get_next_peer(HWND hwnd)
00158 {
00159 return ::GetWindow(hwnd, GW_HWNDPREV);
00160 }
00161 static HWND get_previous_peer(HWND hwnd)
00162 {
00163 return ::GetWindow(hwnd, GW_HWNDNEXT);
00164 }
00165 static HWND get_last_peer(HWND hwnd)
00166 {
00167 return ::GetWindow(hwnd, GW_HWNDFIRST);
00168 }
00169 };
00170
00171 #endif
00172
00177 template <ss_typename_param_k T>
00178 class zorder_iterator_tmpl
00179 : public zorder_iterator_base
00180 #if 0
00181 , public stlsoft_ns_qual(iterator_base)<winstl_ns_qual_std(bidirectional_iterator_tag)
00182 #else
00183 , public stlsoft_ns_qual(iterator_base)<winstl_ns_qual_std(input_iterator_tag)
00184 #endif
00185 , HWND
00186 , ws_ptrdiff_t
00187 , void
00188 , HWND
00189 >
00190 {
00193 public:
00194 typedef T traits_type;
00195 typedef HWND value_type;
00196 typedef ws_size_t size_type;
00197 typedef ws_ptrdiff_t difference_type;
00198 typedef zorder_iterator_tmpl<T> class_type;
00199 typedef zorder_iterator_tmpl<ss_typename_type_k traits_type::alternate_type> base_iterator_type;
00200 typedef base_iterator_type iterator_type;
00202
00205 private:
00206 zorder_iterator_tmpl(HWND hwndRoot, HWND hwndCurrent);
00207 public:
00208 zorder_iterator_tmpl();
00209 ~zorder_iterator_tmpl() stlsoft_throw_0();
00210
00211 class_type& operator =(class_type const&);
00212
00213 static class_type create(HWND hwndRoot, search from);
00215
00218 public:
00221 class_type& operator ++();
00222 class_type operator ++(int);
00223 value_type operator *() const;
00225
00228 class_type& operator --();
00229 class_type operator --(int);
00231 base_iterator_type base() const;
00233
00236 public:
00237 bool equal(class_type const& rhs) const;
00239
00242 private:
00243 static HWND get_next_window_(HWND hwnd, HWND (*pfn)(HWND )) ;
00245
00248 private:
00249 HWND m_hwndRoot;
00250 HWND m_hwndCurrent;
00252 };
00253
00254
00255
00256
00257
00263 typedef zorder_iterator_tmpl<zorder_iterator_forward_traits> zorder_iterator;
00264
00265
00266
00267
00268
00269 #if 0
00270 STLSOFT_TEMPLATE_SPECIALISATION
00271 class std::ostream_iterator<zorder_iterator_tmpl<zorder_iterator_forward_traits> >;
00272
00273 STLSOFT_TEMPLATE_SPECIALISATION
00274 class std::ostream_iterator<zorder_iterator_tmpl<zorder_iterator_reverse_traits> >;
00275 #endif
00276
00277
00278
00279
00280
00281 template <ss_typename_param_k T>
00282 inline bool operator ==(zorder_iterator_tmpl<T> const& lhs
00283 , zorder_iterator_tmpl<T> const& rhs)
00284 {
00285 return lhs.equal(rhs);
00286 }
00287 template <ss_typename_param_k T>
00288 inline bool operator !=(zorder_iterator_tmpl<T> const& lhs
00289 , zorder_iterator_tmpl<T> const& rhs)
00290 {
00291 return !lhs.equal(rhs);
00292 }
00293
00294
00295
00296
00297
00298 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00299
00300 template <ss_typename_param_k T>
00301 inline HWND zorder_iterator_tmpl<T>::get_next_window_(HWND hwnd, HWND (*pfn)(HWND ))
00302 {
00303 hwnd = (*pfn)(hwnd);
00304
00305 if(NULL == hwnd)
00306 {
00307 DWORD dwErr = ::GetLastError();
00308
00309
00310 if(ERROR_SUCCESS != dwErr)
00311 {
00312 STLSOFT_THROW_X(stlsoft_ns_qual(external_iterator_invalidation)("z-order search failed: window has been destroyed", static_cast<long>(dwErr)));
00313 }
00314 }
00315
00316 return hwnd;
00317 }
00318
00319 template <ss_typename_param_k T>
00320 inline zorder_iterator_tmpl<T>::zorder_iterator_tmpl()
00321 : m_hwndRoot(NULL)
00322 , m_hwndCurrent(NULL)
00323 {}
00324
00325 template <ss_typename_param_k T>
00326 inline zorder_iterator_tmpl<T>::zorder_iterator_tmpl(HWND hwndRoot, HWND hwndCurrent)
00327 : m_hwndRoot(hwndRoot)
00328 , m_hwndCurrent(hwndCurrent)
00329 {}
00330
00331 template <ss_typename_param_k T>
00332 inline zorder_iterator_tmpl<T>::~zorder_iterator_tmpl() stlsoft_throw_0()
00333 {}
00334
00335 template <ss_typename_param_k T>
00336 inline ss_typename_type_ret_k zorder_iterator_tmpl<T>::class_type& zorder_iterator_tmpl<T>::operator =(ss_typename_type_k zorder_iterator_tmpl<T>::class_type const& rhs)
00337 {
00338 WINSTL_ASSERT(NULL == m_hwndRoot || NULL == rhs.m_hwndRoot || (rhs.m_hwndRoot == m_hwndRoot));
00339
00340 m_hwndCurrent = rhs.m_hwndCurrent;
00341
00342 return *this;
00343 }
00344
00345 template <ss_typename_param_k T>
00346 inline zorder_iterator_tmpl<T> zorder_iterator_tmpl<T>::create(HWND hwndRoot, search from)
00347 {
00348 HWND hwndCurrent;
00349
00350 switch(from)
00351 {
00352 case fromFirstChild:
00353 case atLastChild:
00354 hwndRoot = get_next_window_(hwndRoot, traits_type::get_first_child);
00355 default:
00356 break;
00357 }
00358
00359 switch(from)
00360 {
00361 case fromCurrent:
00362 hwndCurrent = hwndRoot;
00363 break;
00364 case fromFirstPeer:
00365 case fromFirstChild:
00366 hwndCurrent = get_next_window_(hwndRoot, traits_type::get_first_peer);
00367 break;
00368 case atLastChild:
00369 case atLastPeer:
00370 hwndCurrent = NULL;
00371 break;
00372 }
00373
00374 return zorder_iterator_tmpl<T>(hwndRoot, hwndCurrent);
00375 }
00376
00377 template <ss_typename_param_k T>
00378 inline ss_typename_type_ret_k zorder_iterator_tmpl<T>::class_type& zorder_iterator_tmpl<T>::operator ++()
00379 {
00380 WINSTL_MESSAGE_ASSERT("Attempt to increment an invalid / out-of-range iterator", NULL != m_hwndCurrent);
00381
00382 m_hwndCurrent = class_type::get_next_window_(m_hwndCurrent, traits_type::get_next_peer);
00383
00384 return *this;
00385 }
00386
00387 template <ss_typename_param_k T>
00388 inline ss_typename_type_ret_k zorder_iterator_tmpl<T>::class_type zorder_iterator_tmpl<T>::operator ++(int)
00389 {
00390 class_type ret(*this);
00391
00392 operator ++();
00393
00394 return ret;
00395 }
00396
00397 template <ss_typename_param_k T>
00398 inline ss_typename_type_ret_k zorder_iterator_tmpl<T>::class_type& zorder_iterator_tmpl<T>::operator --()
00399 {
00400 WINSTL_MESSAGE_ASSERT("Attempt to decrement an invalid / out-of-range iterator", NULL != m_hwndRoot);
00401
00402 if(NULL != m_hwndCurrent)
00403 {
00404 m_hwndCurrent = class_type::get_next_window_(m_hwndCurrent, traits_type::get_previous_peer);
00405 }
00406 else
00407 {
00408 m_hwndCurrent = class_type::get_next_window_(m_hwndRoot, traits_type::get_last_peer);
00409 }
00410
00411 return *this;
00412 }
00413
00414 template <ss_typename_param_k T>
00415 inline ss_typename_type_ret_k zorder_iterator_tmpl<T>::class_type zorder_iterator_tmpl<T>::operator --(int)
00416 {
00417 class_type ret(*this);
00418
00419 operator --();
00420
00421 return ret;
00422 }
00423
00424 template <ss_typename_param_k T>
00425 inline ss_typename_type_ret_k zorder_iterator_tmpl<T>::base_iterator_type zorder_iterator_tmpl<T>::base() const
00426 {
00427 base_iterator_type it = base_iterator_type::create(m_hwndCurrent, fromCurrent);
00428
00429 return ++it;
00430 }
00431
00432 template <ss_typename_param_k T>
00433 inline ss_typename_type_ret_k zorder_iterator_tmpl<T>::value_type zorder_iterator_tmpl<T>::operator *() const
00434 {
00435 return m_hwndCurrent;
00436 }
00437
00438 template <ss_typename_param_k T>
00439 inline bool zorder_iterator_tmpl<T>::equal(ss_typename_type_k zorder_iterator_tmpl<T>::class_type const& rhs) const
00440 {
00441 WINSTL_MESSAGE_ASSERT("Iterators are not endpoint iterators, and refer to different collections", (NULL == m_hwndRoot || NULL == rhs.m_hwndRoot || (rhs.m_hwndRoot == m_hwndRoot)));
00442
00443 return m_hwndCurrent == rhs.m_hwndCurrent;
00444 }
00445
00446 #endif
00447
00448
00449
00450
00451
00452 #ifndef _WINSTL_NO_NAMESPACE
00453 # if defined(_STLSOFT_NO_NAMESPACE) || \
00454 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00455 }
00456 # else
00457 }
00458 }
00459 # endif
00460 #endif
00461
00462
00463
00464 #endif
00465
00466