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
00051 #ifndef WINSTL_INCL_WINSTL_CONTROL_PANEL_HPP_APPLET_MODULE
00052 #define WINSTL_INCL_WINSTL_CONTROL_PANEL_HPP_APPLET_MODULE
00053
00054 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00055 # define WINSTL_VER_WINSTL_CONTROL_PANEL_HPP_APPLET_MODULE_MAJOR 1
00056 # define WINSTL_VER_WINSTL_CONTROL_PANEL_HPP_APPLET_MODULE_MINOR 1
00057 # define WINSTL_VER_WINSTL_CONTROL_PANEL_HPP_APPLET_MODULE_REVISION 11
00058 # define WINSTL_VER_WINSTL_CONTROL_PANEL_HPP_APPLET_MODULE_EDIT 23
00059 #endif
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 #ifndef WINSTL_INCL_WINSTL_H_WINSTL
00076 # include <winstl/winstl.h>
00077 #endif
00078
00079 #ifndef WINSTL_INCL_WINSTL_CONTROL_PANEL_H_FUNCTIONS
00080 # include <winstl/control_panel/functions.h>
00081 #endif
00082 #ifndef WINSTL_INCL_WINSTL_CONTROL_PANEL_ERROR_HPP_EXCEPTIONS
00083 # include <winstl/control_panel/error/exceptions.hpp>
00084 #endif
00085 #ifndef WINSTL_INCL_WINSTL_STRING_HPP_RESOURCE_STRING
00086 # include <winstl/string/resource_string.hpp>
00087 #endif
00088 #ifndef WINSTL_INCL_WINSTL_DL_HPP_MODULE
00089 # include <winstl/dl/module.hpp>
00090 #endif
00091 #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_SIMPLE_STRING
00092 # include <stlsoft/string/simple_string.hpp>
00093 #endif
00094
00095 #ifndef STLSOFT_INCL_VECTOR
00096 # define STLSOFT_INCL_VECTOR
00097 # include <vector>
00098 #endif
00099
00100
00101
00102
00103
00104 #ifndef _WINSTL_NO_NAMESPACE
00105 # if defined(_STLSOFT_NO_NAMESPACE) || \
00106 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00107
00108 namespace winstl
00109 {
00110 # else
00111
00112
00113 namespace stlsoft
00114 {
00115
00116 namespace winstl_project
00117 {
00118
00119 # endif
00120 #endif
00121
00122
00123
00124
00125
00126 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00127 class applet_module;
00128 #endif
00129
00130
00131
00132
00133
00134 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00135
00137 struct applet_module_base
00138 {
00139 HINSTANCE m_hinst;
00140 APPLET_PROC m_pfn;
00141 HWND m_hwnd;
00142 int m_flags;
00143
00144 public:
00145 applet_module_base()
00146 : m_hinst(NULL)
00147 , m_pfn(NULL)
00148 , m_hwnd(NULL)
00149 , m_flags(0)
00150 {}
00151 };
00152 #endif
00153
00169 class applet
00170 {
00173 public:
00175 typedef applet class_type;
00177 typedef stlsoft_ns_qual(basic_simple_string)<TCHAR> string_type;
00179 typedef ss_size_t index_type;
00180 private:
00181 typedef basic_resource_string< string_type
00182 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00183 , resource_exception_policy
00184 #else
00185 , stlsoft_ns_qual(null_exception_policy)
00186 #endif
00187 > resource_string_type_;
00189
00192 private:
00193 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00194 friend class applet_module;
00195 #endif
00196
00197 applet(applet_module_base *module, index_type index);
00198 public:
00201 ~applet() stlsoft_throw_0();
00203
00206 public:
00213 void open(HWND hwnd = NULL);
00221 void open(HWND hwnd, TCHAR const* arguments);
00223
00226 public:
00228 index_type get_index() const;
00230 string_type get_name() const;
00232 string_type get_description() const;
00234 HICON get_icon() const;
00236 LONG get_data() const;
00238
00241 private:
00242 applet_module_base *m_module;
00243 index_type m_index;
00244 HICON m_icon;
00245 string_type m_name;
00246 string_type m_description;
00247 LONG m_data;
00249 };
00250
00308 class applet_module
00309 #if defined(STLSOFT_COMPILER_IS_DMC)
00310 : public applet_module_base
00311 #else
00312 : private applet_module_base
00313 #endif
00314 {
00317 public:
00319 typedef applet_module class_type;
00321 typedef applet value_type;
00323 typedef ss_size_t size_type;
00325 typedef ss_size_t index_type;
00327 typedef stlsoft_ns_qual(basic_simple_string)<TCHAR> string_type;
00328 private:
00329 typedef stlsoft_ns_qual_std(vector)<value_type> applets_type_;
00330 public:
00332 typedef applets_type_::iterator iterator;
00334 typedef applets_type_::const_iterator const_iterator;
00335
00337 typedef void (STLSOFT_CDECL *onFailureC)(TCHAR const* path);
00339 typedef void (STLSOFT_STDCALL *onFailureS)(TCHAR const* path);
00340 private:
00341 struct error_translator
00342 {
00343 public:
00344 error_translator();
00345 error_translator(onFailureC pfn);
00346 error_translator(onFailureS pfn);
00347
00348 private:
00349 static void STLSOFT_CDECL on_failure(TCHAR const* path);
00350
00351 private:
00352 int cc;
00353 union
00354 {
00355 onFailureC pfnC;
00356 onFailureS pfnS;
00357 };
00358 };
00360
00363 public:
00365 enum load_flags
00366 {
00367 ignoreIconLoadFailures = 0x0001
00368 , dontExpectNonZeroInit = 0x0002
00369 , assumeOneAppletIfNone = 0x0004
00370 };
00372
00375 public:
00389 ss_explicit_k applet_module(TCHAR const* path, int flags = ignoreIconLoadFailures, HWND hwndParent = NULL);
00390 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00391 ss_explicit_k applet_module(TCHAR const* path, onFailureC pfn, int flags = ignoreIconLoadFailures, HWND hwndParent = NULL);
00392 ss_explicit_k applet_module(TCHAR const* path, onFailureS pfn, int flags = ignoreIconLoadFailures, HWND hwndParent = NULL);
00393 #endif
00395
00398 public:
00400 string_type const &get_path() const;
00402
00405 public:
00407 size_type size() const;
00413 value_type& operator [](index_type index);
00419 value_type const& operator [](index_type index) const;
00421
00424 public:
00428 iterator begin();
00432 iterator end();
00436 const_iterator begin() const;
00440 const_iterator end() const;
00442
00445 private:
00446 void init_(int flags, HWND hwndParent);
00448
00451 private:
00452 const string_type m_path;
00453 module m_module;
00454 applets_type_ m_applets;
00455 error_translator m_errorTranslator;
00457
00460 private:
00461 applet_module(class_type const&);
00462 class_type& operator =(class_type const&);
00464 };
00465
00466
00467
00468
00469
00470 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00471
00472
00473
00474 inline applet::applet(applet_module_base *module, applet::index_type index)
00475 : m_module(module)
00476 , m_index(index)
00477 , m_icon(NULL)
00478 , m_name()
00479 , m_description()
00480 , m_data(0)
00481 {
00482 WINSTL_ASSERT(NULL != module);
00483 WINSTL_ASSERT(0 == index || index < control_panel_get_count(m_module->m_pfn, m_module->m_hwnd));
00484
00485 ::SetLastError(0);
00486
00487 if( !control_panel_init(m_module->m_pfn, m_module->m_hwnd) &&
00488 0 == (m_module->m_flags & applet_module::dontExpectNonZeroInit))
00489 {
00490 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00491 STLSOFT_THROW_X(control_panel_exception("Applet initialisation failed", ::GetLastError()));
00492 #else
00493 ::SetLastError(ERROR_DLL_INIT_FAILED);
00494
00495 m_module = NULL;
00496 #endif
00497 }
00498 else
00499 {
00500 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00501 try
00502 {
00503 #endif
00504 CPLINFO info = { CPL_DYNAMIC_RES, CPL_DYNAMIC_RES, CPL_DYNAMIC_RES, 0 };
00505
00506 control_panel_inquire(m_module->m_pfn, m_module->m_hwnd, m_index, &info);
00507
00508 if(CPL_DYNAMIC_RES != info.idIcon)
00509 {
00510 m_icon = ::LoadIcon(m_module->m_hinst, MAKEINTRESOURCE(info.idIcon));
00511
00512 if( NULL == m_icon &&
00513 applet_module::ignoreIconLoadFailures == (m_module->m_flags & applet_module::ignoreIconLoadFailures))
00514 {
00515 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00516 STLSOFT_THROW_X(resource_exception("Could not load the applet icon", ::GetLastError(), MAKEINTRESOURCE(info.idIcon), RT_ICON));
00517 #endif
00518 }
00519 }
00520
00521 if(CPL_DYNAMIC_RES != info.idName)
00522 {
00523 m_name = resource_string_type_(m_module->m_hinst, info.idName);
00524 }
00525
00526 if(CPL_DYNAMIC_RES != info.idInfo)
00527 {
00528 m_description = resource_string_type_(m_module->m_hinst, info.idInfo);
00529 }
00530
00531 m_data = info.lData;
00532
00533 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00534 }
00535 catch(...)
00536 {
00537 control_panel_uninit(m_module->m_pfn, m_module->m_hwnd);
00538
00539 throw;
00540 }
00541 #endif
00542 }
00543 }
00544
00545 inline applet::~applet() stlsoft_throw_0()
00546 {
00547 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00548 WINSTL_ASSERT(NULL != m_module);
00549 #else
00550 if(NULL != NULL)
00551 #endif
00552 {
00553 control_panel_uninit(m_module->m_pfn, m_module->m_hwnd);
00554 }
00555 }
00556
00557 inline void applet::open(HWND hwnd)
00558 {
00559 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00560 WINSTL_ASSERT(NULL != m_module);
00561 #else
00562 if(NULL != NULL)
00563 #endif
00564 {
00565 if(NULL == hwnd)
00566 {
00567 hwnd = m_module->m_hwnd;
00568 }
00569
00570 control_panel_run(m_module->m_pfn, hwnd, m_index, m_data);
00571 }
00572 }
00573
00574 inline void applet::open(HWND hwnd, TCHAR const* arguments)
00575 {
00576 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00577 WINSTL_ASSERT(NULL != m_module);
00578 #else
00579 if(NULL != NULL)
00580 #endif
00581 {
00582 if( NULL == arguments ||
00583 '\0' == *arguments)
00584 {
00585 this->open(hwnd);
00586 }
00587 else
00588 {
00589 if(NULL == hwnd)
00590 {
00591 hwnd = m_module->m_hwnd;
00592 }
00593
00594 control_panel_run(m_module->m_pfn, hwnd, m_index, arguments);
00595 }
00596 }
00597 }
00598
00599 inline applet::index_type applet::get_index() const
00600 {
00601 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00602 WINSTL_ASSERT(NULL != m_module);
00603 #else
00604 if(NULL == m_module)
00605 {
00606 return ~index_type(0);
00607 }
00608 #endif
00609
00610 return m_index;
00611 }
00612
00613 inline applet::string_type applet::get_name() const
00614 {
00615 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00616 WINSTL_ASSERT(NULL != m_module);
00617 #else
00618 if(NULL == m_module)
00619 {
00620 return m_name;
00621 }
00622 #endif
00623
00624 if(m_name.empty())
00625 {
00626 NEWCPLINFO info = { sizeof(info), 0, 0, 0, NULL, { '\0' }, { '\0' }, { '\0' } };
00627
00628 control_panel_newinquire(m_module->m_pfn, m_module->m_hwnd, m_index, &info);
00629
00630 return info.szName;
00631 }
00632
00633 return m_name;
00634 }
00635
00636 inline applet::string_type applet::get_description() const
00637 {
00638 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00639 WINSTL_ASSERT(NULL != m_module);
00640 #else
00641 if(NULL == m_module)
00642 {
00643 return m_description;
00644 }
00645 #endif
00646
00647 if(m_description.empty())
00648 {
00649 NEWCPLINFO info = { sizeof(info), 0, 0, 0, NULL, { '\0' }, { '\0' }, { '\0' } };
00650
00651 control_panel_newinquire(m_module->m_pfn, m_module->m_hwnd, m_index, &info);
00652
00653 return info.szInfo;
00654 }
00655
00656 return m_description;
00657 }
00658
00659 inline HICON applet::get_icon() const
00660 {
00661 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00662 WINSTL_ASSERT(NULL != m_module);
00663 #else
00664 if(NULL == m_module)
00665 {
00666 return NULL;
00667 }
00668 #endif
00669
00670 if(NULL == m_icon)
00671 {
00672 NEWCPLINFO info = { sizeof(info), 0, 0, 0, NULL, { '\0' }, { '\0' }, { '\0' } };
00673
00674 control_panel_newinquire(m_module->m_pfn, m_module->m_hwnd, m_index, &info);
00675
00676 return info.hIcon;
00677 }
00678
00679 return m_icon;
00680 }
00681
00682 inline LONG applet::get_data() const
00683 {
00684 return m_data;
00685 }
00686
00687
00688
00689 inline applet_module::error_translator::error_translator()
00690 : cc(STLSOFT_CDECL_VALUE)
00691 {
00692 pfnC = on_failure;
00693 }
00694
00695 inline applet_module::error_translator::error_translator(applet_module::onFailureC pfn)
00696 : cc(STLSOFT_CDECL_VALUE)
00697 {
00698 pfnC = pfn;
00699 }
00700
00701 inline applet_module::error_translator::error_translator(applet_module::onFailureS pfn)
00702 : cc(STLSOFT_STDCALL_VALUE)
00703 {
00704 pfnS = pfn;
00705 }
00706
00707 inline void STLSOFT_CDECL applet_module::error_translator::on_failure(TCHAR const* )
00708 {}
00709
00710
00711
00712 inline void applet_module::init_(int flags, HWND hwndParent)
00713 {
00714 WINSTL_ASSERT(NULL == m_hwnd);
00715 WINSTL_ASSERT(NULL == m_pfn);
00716
00717 ::SetLastError(0);
00718
00719 if(NULL == m_module.get_symbol("CPlApplet", m_pfn))
00720 {
00721 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00722 STLSOFT_THROW_X(control_panel_exception("Control panel entry point not found", ::GetLastError()));
00723 #endif
00724 }
00725 else
00726 {
00727 m_flags = flags;
00728 m_hwnd = hwndParent;
00729 m_hinst = m_module.get_module_handle();
00730
00731 size_type numApplets = control_panel_get_count(m_pfn, m_hwnd);
00732
00733 if( 0 == numApplets &&
00734 assumeOneAppletIfNone == (m_flags & assumeOneAppletIfNone))
00735 {
00736 numApplets = 1;
00737 }
00738
00739 { for(size_type index = 0; index < numApplets; ++index)
00740 {
00741 m_applets.push_back(applet(this, index));
00742 }}
00743 }
00744 }
00745
00746 inline applet_module::applet_module(TCHAR const* path, int flags , HWND hwndParent )
00747 : m_path(path)
00748 , m_module(path)
00749 , m_applets()
00750 , m_errorTranslator()
00751 {
00752 init_(flags, hwndParent);
00753 }
00754
00755 inline applet_module::applet_module(TCHAR const* path, applet_module::onFailureC pfn, int flags , HWND hwndParent )
00756 : m_path(path)
00757 , m_module(path)
00758 , m_applets()
00759 , m_errorTranslator(pfn)
00760 {
00761 init_(flags, hwndParent);
00762 }
00763
00764 inline applet_module::applet_module(TCHAR const* path, applet_module::onFailureS pfn, int flags , HWND hwndParent )
00765 : m_path(path)
00766 , m_module(path)
00767 , m_applets()
00768 , m_errorTranslator(pfn)
00769 {
00770 init_(flags, hwndParent);
00771 }
00772
00773 inline applet_module::string_type const& applet_module::get_path() const
00774 {
00775 return m_path;
00776 }
00777
00778 inline applet_module::size_type applet_module::size() const
00779 {
00780 return m_applets.size();
00781 }
00782
00783 inline applet_module::value_type &applet_module::operator [](index_type index)
00784 {
00785 WINSTL_MESSAGE_ASSERT("Invalid index", index < size());
00786
00787 return m_applets[index];
00788 }
00789
00790 inline applet_module::value_type const& applet_module::operator [](index_type index) const
00791 {
00792 WINSTL_MESSAGE_ASSERT("Invalid index", index < size());
00793
00794 return m_applets[index];
00795 }
00796
00797 inline applet_module::iterator applet_module::begin()
00798 {
00799 return m_applets.begin();
00800 }
00801
00802 inline applet_module::iterator applet_module::end()
00803 {
00804 return m_applets.end();
00805 }
00806
00807 inline applet_module::const_iterator applet_module::begin() const
00808 {
00809 return m_applets.begin();
00810 }
00811
00812 inline applet_module::const_iterator applet_module::end() const
00813 {
00814 return m_applets.end();
00815 }
00816
00817 #endif
00818
00819
00820
00821
00822
00823 #ifdef STLSOFT_UNITTEST
00824 # include "./unittest/applet_module_unittest_.h"
00825 #endif
00826
00827
00828
00829 #ifndef _WINSTL_NO_NAMESPACE
00830 # if defined(_STLSOFT_NO_NAMESPACE) || \
00831 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00832 }
00833 # else
00834 }
00835 }
00836 # endif
00837 #endif
00838
00839
00840
00841 #endif
00842
00843