From 3a1bf865b6c1b6b7c096eaf6dab91a465319488a Mon Sep 17 00:00:00 2001 From: Ian C Date: Mon, 4 Apr 2005 00:52:23 +0000 Subject: Added DataX --- src/GNUmakefile | 5 +- src/autocheck.cpp | 43 ++++++++++++- src/button.cpp | 4 +- src/combobox.cpp | 33 +++++++++- src/control.cpp | 38 ++++++++++- src/datax.cpp | 168 ++++++++++++++++++++++++++++++++++++++++++++++++ src/dialog.cpp | 22 +++++++ src/static.cpp | 4 +- src/test/dialog.h | 3 + src/test/dialog.rc | 9 +++ src/test/w32dtst.cpp | 68 ++++++++++++++++---- src/text.cpp | 4 +- src/w32dlib/autocheck.h | 24 ++++++- src/w32dlib/base.h | 11 +++- src/w32dlib/button.h | 4 +- src/w32dlib/combobox.h | 18 +++++- src/w32dlib/common.h | 2 +- src/w32dlib/control.h | 22 ++++++- src/w32dlib/datax.h | 138 +++++++++++++++++++++++++++++++++++++++ src/w32dlib/dialog.h | 19 +++++- src/w32dlib/static.h | 4 +- src/w32dlib/text.h | 4 +- src/w32dlib/w32dlib.h | 1 + src/w32dlib/window.h | 30 +++++++++ src/window.cpp | 54 +++++++++++++++- 25 files changed, 692 insertions(+), 40 deletions(-) create mode 100644 src/datax.cpp create mode 100644 src/w32dlib/datax.h diff --git a/src/GNUmakefile b/src/GNUmakefile index 0bbfac0..5cc058f 100644 --- a/src/GNUmakefile +++ b/src/GNUmakefile @@ -18,7 +18,7 @@ # # ------------------------------------------------------------------------- # -# $Id: GNUmakefile,v 1.5 2005-03-28 01:42:58 ianc Exp $ +# $Id: GNUmakefile,v 1.6 2005-04-04 00:52:23 ianc Exp $ # @@ -57,7 +57,8 @@ SOURCES = autocheck.cpp \ static.cpp \ debug.cpp \ window.cpp \ - combobox.cpp + combobox.cpp \ + datax.cpp HEADERS = w32dlib/*.h diff --git a/src/autocheck.cpp b/src/autocheck.cpp index f713c19..fb7de94 100644 --- a/src/autocheck.cpp +++ b/src/autocheck.cpp @@ -21,6 +21,7 @@ #include "w32dlib/window.h" #include "w32dlib/autocheck.h" #include "w32dlib/dialog.h" +#include "w32dlib/datax.h" namespace W32DLib { @@ -28,8 +29,8 @@ namespace W32DLib // ------------------------------------------------------------ // -AutoCheck::AutoCheck(Dialog *parent, int resource_id) : - Control(parent,resource_id) +AutoCheck::AutoCheck(Dialog *parent, int resource_id, DataX *datax) : + Control(parent,resource_id,datax) { } @@ -87,6 +88,44 @@ bool AutoCheck::GetState() } +// ------------------------------------------------------------ +// +void AutoCheck::DoDataExchange(bool set) +{ + if (m_data) + { + switch(m_data->Type()) + { + case DataX::eString: + Control::DoDataExchange(set); + break; + + case DataX::eInt: + if (set) + { + SetFullState(static_cast(m_data->Int())); + } + else + { + m_data->Set(static_cast(GetFullState())); + } + break; + + case DataX::eBool: + if (set) + { + SetState(m_data->Bool()); + } + else + { + m_data->Set(GetState()); + } + break; + } + } +} + + }; // namespace W32DLib diff --git a/src/button.cpp b/src/button.cpp index 66b4018..3e27581 100644 --- a/src/button.cpp +++ b/src/button.cpp @@ -27,8 +27,8 @@ namespace W32DLib // ------------------------------------------------------------ // -Button::Button(Dialog *parent, int resource_id) : - Control(parent,resource_id) +Button::Button(Dialog *parent, int resource_id, DataX *datax) : + Control(parent,resource_id,datax) { } diff --git a/src/combobox.cpp b/src/combobox.cpp index f16b619..fbf2a6c 100644 --- a/src/combobox.cpp +++ b/src/combobox.cpp @@ -20,14 +20,15 @@ // #include "w32dlib/window.h" #include "w32dlib/combobox.h" +#include "w32dlib/datax.h" namespace W32DLib { // ------------------------------------------------------------ // -ComboBox::ComboBox(Dialog *parent, int resource_id) : - Control(parent,resource_id) +ComboBox::ComboBox(Dialog *parent, int resource_id, DataX *datax) : + Control(parent,resource_id,datax) { } @@ -181,6 +182,34 @@ void ComboBox::SelectedIndex(int index) } +// ------------------------------------------------------------ +// +void ComboBox::DoDataExchange(bool set) +{ + if (m_data) + { + switch(m_data->Type()) + { + case DataX::eString: + case DataX::eBool: + Control::DoDataExchange(set); + break; + + case DataX::eInt: + if (set) + { + SelectedIndex(m_data->Int()); + } + else + { + m_data->Set(SelectedIndex()); + } + break; + } + } +} + + }; // namespace W32DLib // END OF FILE diff --git a/src/control.cpp b/src/control.cpp index a8a221f..fa8e2e7 100644 --- a/src/control.cpp +++ b/src/control.cpp @@ -21,6 +21,7 @@ #include "w32dlib/window.h" #include "w32dlib/control.h" #include "w32dlib/dialog.h" +#include "w32dlib/datax.h" namespace W32DLib { @@ -28,10 +29,11 @@ namespace W32DLib // ------------------------------------------------------------ // -Control::Control(Dialog *parent, int resource_id) : +Control::Control(Dialog *parent, int resource_id, DataX *datax) : Window(), m_parent(parent), m_resid(resource_id), + m_data(datax), m_cblist() { m_parent->AddControl(this); @@ -86,6 +88,40 @@ BOOL Control::ProcessMessage(UINT msg, WPARAM wp, LPARAM lp) } +// ------------------------------------------------------------ +// +void Control::DoDataExchange(bool set) +{ + if (m_data) + { + if (set) + { + switch(m_data->Type()) + { + case DataX::eString: + SetText(m_data->Str()); + break; + + default: + break; + } + } + else + { + switch(m_data->Type()) + { + case DataX::eString: + m_data->Set(GetText()); + break; + + default: + break; + } + } + } +} + + // ------------------------------------------------------------ // void Control::AddCallback(UINT msg, diff --git a/src/datax.cpp b/src/datax.cpp new file mode 100644 index 0000000..e1e3f5f --- /dev/null +++ b/src/datax.cpp @@ -0,0 +1,168 @@ +// w32dlib - Win32 DataX Helpers +// +// Copyright (C) 2005 Ian Cowburn (ianc@noddybox.demon.co.uk) +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// ------------------------------------------------------------------------- +// +#include "w32dlib/datax.h" + + +namespace W32DLib +{ + +// ------------------------------------------------------------ +// +DataX::DataX(DataX::EType type) : m_type(type) +{ + switch(m_type) + { + case eString: + m_data=static_cast(new std::string()); + break; + + case eInt: + m_data=static_cast(new int); + break; + + case eBool: + m_data=static_cast(new bool); + break; + } +} + + +// ------------------------------------------------------------ +// +DataX::~DataX() +{ + switch(m_type) + { + case eString: + delete static_cast(m_data); + break; + + case eInt: + delete static_cast(m_data); + break; + + case eBool: + delete static_cast(m_data); + break; + } +} + + +// ------------------------------------------------------------ +// +DataX::EType DataX::Type() +{ + return m_type; +} + + +// ------------------------------------------------------------ +// +void DataX::Set(int value) +{ + if (m_type==eInt) + { + *(static_cast(m_data))=value; + } +} + + +// ------------------------------------------------------------ +// +void DataX::Set(const std::string& value) +{ + if (m_type==eString) + { + *(static_cast(m_data))=value; + } +} + + +// ------------------------------------------------------------ +// +void DataX::Set(const char *value) +{ + if (m_type==eString) + { + *(static_cast(m_data))=value; + } +} + + +// ------------------------------------------------------------ +// +void DataX::Set(bool value) +{ + if (m_type==eBool) + { + *(static_cast(m_data))=value; + } +} + + +// ------------------------------------------------------------ +// +int DataX::Int() +{ + if (m_type==eInt) + { + return *(static_cast(m_data)); + } + else + { + return 0; + } +} + + +// ------------------------------------------------------------ +// +std::string DataX::Str() +{ + if (m_type==eString) + { + return *(static_cast(m_data)); + } + else + { + return std::string(); + } +} + + +// ------------------------------------------------------------ +// +bool DataX::Bool() +{ + if (m_type==eBool) + { + return *(static_cast(m_data)); + } + else + { + return false; + } +} + + +}; // namespace w32dlib + +// END OF FILE diff --git a/src/dialog.cpp b/src/dialog.cpp index 7a26a16..d8bea39 100644 --- a/src/dialog.cpp +++ b/src/dialog.cpp @@ -102,6 +102,28 @@ void Dialog::SetMenuProc(Window *owner, W32DLibCallback callback) } +// ------------------------------------------------------------ +// +void Dialog::SetData() +{ + for(ControlSet::iterator i=m_cset.begin();i!=m_cset.end();++i) + { + (*i)->DoDataExchange(true); + } +} + + +// ------------------------------------------------------------ +// +void Dialog::GetData() +{ + for(ControlSet::iterator i=m_cset.begin();i!=m_cset.end();++i) + { + (*i)->DoDataExchange(false); + } +} + + // ------------------------------------------------------------ // diff --git a/src/static.cpp b/src/static.cpp index bf0c20e..8c275ee 100644 --- a/src/static.cpp +++ b/src/static.cpp @@ -26,8 +26,8 @@ namespace W32DLib // ------------------------------------------------------------ // -StaticText::StaticText(Dialog *parent, int resource_id) : - Control(parent,resource_id) +StaticText::StaticText(Dialog *parent, int resource_id, DataX *datax) : + Control(parent,resource_id,datax) { } diff --git a/src/test/dialog.h b/src/test/dialog.h index 7123816..6789be0 100644 --- a/src/test/dialog.h +++ b/src/test/dialog.h @@ -19,3 +19,6 @@ #define IDMENUTEST 19 #define IDMENUTESTITEM1 20 #define IDMENUTESTITEM2 21 +#define IDPOPUP 22 +#define IDPOPUP1 23 +#define IDPOPUP2 24 diff --git a/src/test/dialog.rc b/src/test/dialog.rc index ed3508e..0f36ecc 100644 --- a/src/test/dialog.rc +++ b/src/test/dialog.rc @@ -40,3 +40,12 @@ IDMENU MENU } } } + +IDPOPUP MENU +{ + POPUP "File" + { + MENUITEM "Opt 1", IDPOPUP1 + MENUITEM "Opt 2", IDPOPUP2 + } +} diff --git a/src/test/w32dtst.cpp b/src/test/w32dtst.cpp index 75b5b44..838c9f5 100644 --- a/src/test/w32dtst.cpp +++ b/src/test/w32dtst.cpp @@ -24,19 +24,24 @@ #include "dialog.h" +#define DATAX_TEST + class Test : public W32DLib::Dialog { public: - Test() : m_static(this,IDSTATIC1) - , m_text(this,IDTEXT) - , m_check(this,IDCHECK) - , m_button(this,IDBUTTON) - , m_quit(this,IDQUIT) - , m_load(this,IDLOADTXT) - , m_loadbut(this,IDLOADBUT) - , m_save(this,IDSAVETXT) - , m_savebut(this,IDSAVEBUT) - , m_combo(this,IDCOMBO) + Test() : m_check_data(W32DLib::DataX::eBool) + , m_combo_data(W32DLib::DataX::eInt) + , m_text_data(W32DLib::DataX::eString) + , m_static(this,IDSTATIC1) + , m_text(this,IDTEXT,&m_text_data) + , m_check(this,IDCHECK,&m_check_data) + , m_button(this,IDBUTTON) + , m_quit(this,IDQUIT) + , m_load(this,IDLOADTXT) + , m_loadbut(this,IDLOADBUT) + , m_save(this,IDSAVETXT) + , m_savebut(this,IDSAVEBUT) + , m_combo(this,IDCOMBO,&m_combo_data) { m_button.OnPress (this,static_cast(&Test::OnButton)); @@ -76,8 +81,9 @@ public: virtual void OnInit() { std::cout << "OnInit()" << std::endl; - m_text.SetText("Hello"); - m_check.SetState(W32DLib::AutoCheck::eChecked); + std::cout << "Can be used from a thread:" + << (HasMutex() ? "Yes":"No") << std::endl; + m_quit.Enable(true); m_combo.Reset(); @@ -88,10 +94,23 @@ public: std::cout << "count=" << m_combo.Count() << std::endl; std::cout << "HWND=" << m_combo.GetHWND() << std::endl; +#ifdef DATAX_TEST + m_text_data.Set("Hello"); + m_check_data.Set(true); + m_combo_data.Set(2); + SetData(); +#else + m_text.SetText("Hello"); + m_check.SetState(W32DLib::AutoCheck::eChecked); m_combo.SelectedIndex(2); +#endif } private: + W32DLib::DataX m_check_data; + W32DLib::DataX m_combo_data; + W32DLib::DataX m_text_data; + W32DLib::StaticText m_static; W32DLib::Text m_text; W32DLib::AutoCheck m_check; @@ -118,11 +137,18 @@ private: BOOL OnButton(UINT msg, WPARAM wp, LPARAM lp) { +#ifdef DATAX_TEST + GetData(); + bool check=m_check_data.Bool(); + std::string txt=m_text_data.Str(); +#else + bool check=m_check.GetState(); std::string txt=m_text.GetText(); +#endif std::cout << "Called OnButton()" << std::endl; std::cout << "text=" << txt << std::endl; - std::cout << "check=" << m_check.GetState() << std::endl; + std::cout << "check=" << check << std::endl; m_static.SetText(txt); SetText(txt+" [Title]"); m_combo.AddString(m_combo.GetText()); @@ -132,7 +158,12 @@ private: BOOL OnCheck(UINT msg, WPARAM wp, LPARAM lp) { +#ifdef DATAX_TEST + GetData(); + bool checked=m_check_data.Bool(); +#else bool checked=m_check.GetState(); +#endif std::cout << "Called OnCheck() - state " << checked << std::endl; @@ -182,7 +213,12 @@ private: BOOL OnComboDbl(UINT msg, WPARAM wp, LPARAM lp) { +#ifdef DATAX_TEST + GetData(); + int sel=m_combo_data.Int(); +#else int sel=m_combo.SelectedIndex(); +#endif std::string str=m_combo.GetString(sel); std::cout << "Called OnComboDbl()" << std::endl; @@ -201,7 +237,7 @@ private: BOOL OnText(UINT msg, WPARAM wp, LPARAM lp) { std::cout << "Called OnText()" << std::endl; - std::cout << ":GetText=" << m_text.GetText() << std::endl; + std::cout << "OnText::GetText=" << m_text.GetText() << std::endl; return TRUE; } @@ -233,6 +269,10 @@ int WINAPI WinMain (HINSTANCE hInstance, Test t; INT_PTR i; +#ifdef DATAX_TEST + std::cout << "DATAX_TEST enabled" << std::endl; +#endif + i=t.ShowModal(hInstance,NULL); if (i==IDOK) diff --git a/src/text.cpp b/src/text.cpp index 4e77387..fcb419c 100644 --- a/src/text.cpp +++ b/src/text.cpp @@ -26,8 +26,8 @@ namespace W32DLib // ------------------------------------------------------------ // -Text::Text(Dialog *parent, int resource_id) : - Control(parent,resource_id) +Text::Text(Dialog *parent, int resource_id, DataX *datax) : + Control(parent,resource_id,datax) { } diff --git a/src/w32dlib/autocheck.h b/src/w32dlib/autocheck.h index f1b110e..f7aa2fa 100644 --- a/src/w32dlib/autocheck.h +++ b/src/w32dlib/autocheck.h @@ -48,8 +48,10 @@ namespace W32DLib /// /// \param parent The dialog the control belongs to. /// \param resource_id The ID of the control in the resource file. + /// \param datax The DataX to use. The default of 0 means don't + /// use data exchange. /// - AutoCheck(Dialog *parent, int resource_id); + AutoCheck(Dialog *parent, int resource_id, DataX *datax=0); /// \brief Destructor /// @@ -79,12 +81,12 @@ namespace W32DLib /// /// This member allows the indeterminate state to be tested. /// - /// /// \return The tick state /// \sa SetState() /// EState GetFullState(); + /// \brief Sets the tickstate. /// /// \param state The tick state @@ -100,6 +102,24 @@ namespace W32DLib /// bool GetState(); + /// \brief Performs data exchange. + /// + /// Support types: + /// + /// \link DataX::eString eString \endlink -- see + /// Control::DoDataExchange() + /// + /// \link DataX::eInt eInt \endlink -- same as + /// GetFullState() / SetFullState() + /// + /// \link DataX::eBool eBool \endlink -- same as + /// GetState() / SetState() + /// + /// \param set If true the set the Control from the DataX object. If + /// false then set the DataX object from the Control. + /// + virtual void DoDataExchange(bool set); + protected: private: diff --git a/src/w32dlib/base.h b/src/w32dlib/base.h index 062d4c3..e4796ca 100644 --- a/src/w32dlib/base.h +++ b/src/w32dlib/base.h @@ -32,16 +32,23 @@ #include #endif +/// \brief W32DLib Implements a simple wrapper around common Windows +/// dialog functionality. +/// namespace W32DLib { + +// Forward definitions for basic classes. +// class Window; class Dialog; class Control; +class DataX; /// \brief The callback type for W32DLib. /// -/// Simply accepts the usual Windows message parameters, and must return TRUE -/// if the event was handled. +/// Simply accepts the usual Windows message parameters, and generally return +/// TRUE if the event was handled (check individual message rules in MSDN). /// typedef BOOL (Window::*W32DLibCallback) (UINT msg, WPARAM wp, LPARAM lp); diff --git a/src/w32dlib/button.h b/src/w32dlib/button.h index 4ec6449..b674f87 100644 --- a/src/w32dlib/button.h +++ b/src/w32dlib/button.h @@ -38,8 +38,10 @@ namespace W32DLib /// /// \param parent The dialog the control belongs to. /// \param resource_id The ID of the control in the resource file. + /// \param datax The DataX to use. The default of 0 means don't + /// use data exchange. /// - Button(Dialog *parent, int resource_id); + Button(Dialog *parent, int resource_id, DataX *datax=0); /// \brief Destructor /// diff --git a/src/w32dlib/combobox.h b/src/w32dlib/combobox.h index 9dfa50a..2ff9c63 100644 --- a/src/w32dlib/combobox.h +++ b/src/w32dlib/combobox.h @@ -38,8 +38,10 @@ namespace W32DLib /// /// \param parent The dialog the control belongs to. /// \param resource_id The ID of the control in the resource file. + /// \param datax The DataX to use. The default of 0 means don't + /// use data exchange. /// - ComboBox(Dialog *parent, int resource_id); + ComboBox(Dialog *parent, int resource_id, DataX *datax=0); /// \brief Destructor /// @@ -157,6 +159,20 @@ namespace W32DLib /// void SelectedIndex(int index); + /// \brief Performs data exchange. + /// + /// Support types: + /// + /// \link DataX::eString eString \endlink -- see + /// Control::DoDataExchange() + /// + /// \link DataX::eInt eInt \endlink -- same as + /// SelectedIndex() + /// + /// \param set If true the set the Control from the DataX object. If + /// false then set the DataX object from the Control. + /// + virtual void DoDataExchange(bool set); protected: private: diff --git a/src/w32dlib/common.h b/src/w32dlib/common.h index ce22e58..51995b8 100644 --- a/src/w32dlib/common.h +++ b/src/w32dlib/common.h @@ -122,7 +122,7 @@ namespace W32DLib static std::string GetOSError(); - /// \brief Get the application HINSTANCE. + /// \brief Get an HINSTANCE. /// /// \return The HINSTANCE /// diff --git a/src/w32dlib/control.h b/src/w32dlib/control.h index 3cc01e5..f645a98 100644 --- a/src/w32dlib/control.h +++ b/src/w32dlib/control.h @@ -40,8 +40,10 @@ namespace W32DLib /// /// \param parent The Dialog the control belongs to. /// \param resource_id The ID of the control in the resource file. + /// \param datax The DataX to use. The default of 0 means don't + /// use data exchange. /// - Control(Dialog *parent, int resource_id); + Control(Dialog *parent, int resource_id, DataX *datax=0); /// \brief Destructor /// @@ -63,6 +65,20 @@ namespace W32DLib /// BOOL ProcessMessage(UINT msg, WPARAM wp, LPARAM lp); + /// \brief Provides a base DoDataExchange. + /// + /// This interface is called by the Dialog to say that data exchange + /// should take place. + /// + /// This base version simply honours DataX \link DataX::eString eString + /// \endlink objects and calls + /// Window::SetText or Window::GetText accordingly. + /// + /// \param set If true the set the Control from the DataX object. If + /// false then set the DataX object from the Control. + /// + virtual void DoDataExchange(bool set); + protected: /// \brief Add a callback for the control. @@ -88,6 +104,10 @@ namespace W32DLib /// int m_resid; + /// \brief Filled in by the constructor with the DataX object. + /// + DataX *m_data; + private: struct CallbackDetails diff --git a/src/w32dlib/datax.h b/src/w32dlib/datax.h new file mode 100644 index 0000000..1ed4088 --- /dev/null +++ b/src/w32dlib/datax.h @@ -0,0 +1,138 @@ +// w32dlib - Win32 Control Helpers +// +// Copyright (C) 2005 Ian Cowburn (ianc@noddybox.demon.co.uk) +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// ------------------------------------------------------------------------- +// +#ifndef W32DLIB_DATAX_H + +#define W32DLIB_DATAX_H "$Id$" + +#include "w32dlib/base.h" + +namespace W32DLib +{ + + /// \brief The DataX class. + /// + /// This class is used to manage data exchanges between variables and + /// controls. + /// + /// Illegal operations, such as trying to set or get a string from an + /// int DataX instance will silently fail or return default empty/false + /// values. + /// + class DataX + { + public: + + /// \brief Describes the types allowed using DataX. + /// + enum EType + { + eInt, ///< Standard int + eString, ///< std::string + eBool ///< Standard bool + }; + + + /// \brief Constructor + /// + /// \param type The type of DataX object to create. + /// + DataX(EType type); + + + /// \brief Destructor + /// + virtual ~DataX(); + + + /// \brief Get the type + /// + /// \return The data type. + /// \sa EType + /// + EType Type(); + + + /// \brief Sets the value of an \link DataX::eInt eInt \endlink + /// instance. + /// + /// \param value The value to set. + /// + void Set(int value); + + /// \brief Sets the value of an \link DataX::eString eString \endlink + /// instance. + /// + /// \param value The value to set. + /// + void Set(const std::string& value); + + /// \brief Sets the value of an \link DataX::eString eString \endlink + /// instance. + /// + /// \param value The value to set. + /// + void Set(const char *value); + + /// \brief Sets the value of an \link DataX::eBool eBool \endlink + /// instance. + /// + /// \param value The value to set. + /// + void Set(bool value); + + + /// \brief Gets the value of an \link DataX::eInt eInt \endlink + /// instance. + /// + /// \return The value. + /// + int Int(); + + /// \brief Gets the value of an \link DataX::eString eString \endlink + /// instance. + /// + /// \return The value. + /// + std::string Str(); + + /// \brief Gets the value of an \link DataX::eBool eBool \endlink + /// instance. + /// + /// \return The value. + /// + bool Bool(); + + + protected: + + private: + + EType m_type; + void *m_data; + + }; // class DataX + +}; // namespace w32dlib + +#endif // W32DLIB_DATAX_H + + +// END OF FILE diff --git a/src/w32dlib/dialog.h b/src/w32dlib/dialog.h index 34c22f4..409ed69 100644 --- a/src/w32dlib/dialog.h +++ b/src/w32dlib/dialog.h @@ -70,7 +70,7 @@ namespace W32DLib /// Call this to display the dialog. /// /// \param instance The HINSTANCE. Call Common::GetInstance() - /// to get the applications instance (from a DLL, for example). + /// to get an instance (from a DLL, for example) if all else fails. /// \param parent The parent window of the dialog (NULL for none). /// \return The result from Close(). /// \sa Close() @@ -111,6 +111,23 @@ namespace W32DLib /// void SetMenuProc(Window *owner, W32DLibCallback callback); + /// \brief Request data exchange with all controls. + /// + /// Values will be set from DataX objects registered with the controls. + /// + /// This shouldn't be called any earlier than when OnInit() is invoked. + /// + void SetData(); + + /// \brief Request data exchange with all controls. + /// + /// Values will be stored in the DataX objects registered with the + /// controls. + /// + /// This shouldn't be called any earlier than when OnInit() is invoked. + /// + void GetData(); + protected: diff --git a/src/w32dlib/static.h b/src/w32dlib/static.h index a0c4951..b593b2c 100644 --- a/src/w32dlib/static.h +++ b/src/w32dlib/static.h @@ -38,8 +38,10 @@ namespace W32DLib /// /// \param parent The dialog the control belongs to. /// \param resource_id The ID of the control in the resource file. + /// \param datax The DataX to use. The default of 0 means don't + /// use data exchange. /// - StaticText(Dialog *parent, int resource_id); + StaticText(Dialog *parent, int resource_id, DataX *datax=0); /// \brief Destructor /// diff --git a/src/w32dlib/text.h b/src/w32dlib/text.h index 8b68c22..73013fb 100644 --- a/src/w32dlib/text.h +++ b/src/w32dlib/text.h @@ -38,8 +38,10 @@ namespace W32DLib /// /// \param parent The dialog the control belongs to. /// \param resource_id The ID of the control in the resource file. + /// \param datax The DataX to use. The default of 0 means don't + /// use data exchange. /// - Text(Dialog *parent, int resource_id); + Text(Dialog *parent, int resource_id, DataX *datax=0); /// \brief Destructor /// diff --git a/src/w32dlib/w32dlib.h b/src/w32dlib/w32dlib.h index 0df8bed..abc91f0 100644 --- a/src/w32dlib/w32dlib.h +++ b/src/w32dlib/w32dlib.h @@ -22,6 +22,7 @@ #define W32DLIB_H "$Id$" +#include #include #include #include diff --git a/src/w32dlib/window.h b/src/w32dlib/window.h index bd17ede..1a60c58 100644 --- a/src/w32dlib/window.h +++ b/src/w32dlib/window.h @@ -40,6 +40,22 @@ namespace W32DLib /// virtual ~Window(); + /// \brief Whether the Window() constructor could create a mutex. + /// + /// Window will create a mutex when constructed to ensure that behaviour + /// is correct if there are multiple threads in the application with + /// their own windows (note that none of the classes are thread-safe + /// in themselves -- two threads cannot share a Window instance). + /// + /// As I'm not overly fond of exceptions, this call means you can + /// detect whether this worked or not if your program requires it. It + /// also means that single-threaded applications aren't stopped by the + /// failure to create a mutex. + /// + /// \return True if this Window can be used safely in a thread. + /// + bool HasMutex(); + /// \brief Returns the HWND for the window. /// /// This call will only work while the window is on display. @@ -54,6 +70,16 @@ namespace W32DLib /// HMENU GetHMENU(); + /// \brief Sets the HMENU associated with this window. + /// + /// This call will only work while the window is on display. + /// The behaviour is undefined if it is called at any other time. + /// + /// \param menu The menu to set. + /// \return True if the call succeeds. + /// + bool SetHMENU(HMENU menu); + /// \brief Send a message to the window. /// /// This call will only work while the window is on display. @@ -165,6 +191,10 @@ namespace W32DLib static ProcSet m_procset; + // Defines a MUTEX to protect Window if threading is being used + // + HANDLE m_mutex; + }; // class Window }; // namespace w32dlib diff --git a/src/window.cpp b/src/window.cpp index 5ab893e..1646d70 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -18,10 +18,14 @@ // // ------------------------------------------------------------------------- // +#include + #include "w32dlib/window.h" + namespace W32DLib { + // ------------------------------------------------------------ // Window::ProcSet Window::m_procset; @@ -31,6 +35,11 @@ Window::ProcSet Window::m_procset; // Window::Window() : m_wnd(0) { + std::ostringstream name; + + name << "W32DLIB_MUTEX_" << GetCurrentProcessId(); + + m_mutex=CreateMutex(NULL,FALSE,name.str().c_str()); } @@ -38,6 +47,18 @@ Window::Window() : m_wnd(0) // Window::~Window() { + if (m_mutex!=NULL) + { + CloseHandle(m_mutex); + } +} + + +// ------------------------------------------------------------ +// +bool Window::HasMutex() +{ + return m_mutex!=NULL; } @@ -57,6 +78,14 @@ HMENU Window::GetHMENU() } +// ------------------------------------------------------------ +// +bool Window::SetHMENU(HMENU menu) +{ + return SetMenu(m_wnd,menu) ? true:false; +} + + // ------------------------------------------------------------ // LRESULT Window::SendMsg(UINT msg, WPARAM wp, LPARAM lp) @@ -105,7 +134,7 @@ std::string Window::GetText() // void Window::Enable(bool enable) { - ::EnableWindow(m_wnd,enable); + EnableWindow(m_wnd,enable); } @@ -114,6 +143,7 @@ void Window::Enable(bool enable) BOOL Window::InstanceProc(HWND wnd, UINT msg, WPARAM wp, LPARAM lp) { + DWORD res=WAIT_OBJECT_0; bool ret=FALSE; switch(msg) @@ -121,7 +151,27 @@ BOOL Window::InstanceProc(HWND wnd, UINT msg, WPARAM wp, LPARAM lp) case WM_INITDIALOG: case WM_CREATE: m_wnd=wnd; - m_procset[wnd]=this; + + if (m_mutex) + { + res=WaitForSingleObject(m_mutex,INFINITE); + } + + if (res==WAIT_OBJECT_0) + { + try + { + m_procset[wnd]=this; + } + catch (...) + { + } + + if (m_mutex) + { + ReleaseMutex(m_mutex); + } + } ret=TRUE; break; -- cgit v1.2.3