summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/GNUmakefile5
-rw-r--r--src/autocheck.cpp43
-rw-r--r--src/button.cpp4
-rw-r--r--src/combobox.cpp33
-rw-r--r--src/control.cpp38
-rw-r--r--src/datax.cpp168
-rw-r--r--src/dialog.cpp22
-rw-r--r--src/static.cpp4
-rw-r--r--src/test/dialog.h3
-rw-r--r--src/test/dialog.rc9
-rw-r--r--src/test/w32dtst.cpp68
-rw-r--r--src/text.cpp4
-rw-r--r--src/w32dlib/autocheck.h24
-rw-r--r--src/w32dlib/base.h11
-rw-r--r--src/w32dlib/button.h4
-rw-r--r--src/w32dlib/combobox.h18
-rw-r--r--src/w32dlib/common.h2
-rw-r--r--src/w32dlib/control.h22
-rw-r--r--src/w32dlib/datax.h138
-rw-r--r--src/w32dlib/dialog.h19
-rw-r--r--src/w32dlib/static.h4
-rw-r--r--src/w32dlib/text.h4
-rw-r--r--src/w32dlib/w32dlib.h1
-rw-r--r--src/w32dlib/window.h30
-rw-r--r--src/window.cpp54
25 files changed, 692 insertions, 40 deletions
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<EState>(m_data->Int()));
+ }
+ else
+ {
+ m_data->Set(static_cast<int>(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);
@@ -88,6 +90,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,
UINT notification,
Window *owner,
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<void*>(new std::string());
+ break;
+
+ case eInt:
+ m_data=static_cast<void*>(new int);
+ break;
+
+ case eBool:
+ m_data=static_cast<void*>(new bool);
+ break;
+ }
+}
+
+
+// ------------------------------------------------------------
+//
+DataX::~DataX()
+{
+ switch(m_type)
+ {
+ case eString:
+ delete static_cast<std::string*>(m_data);
+ break;
+
+ case eInt:
+ delete static_cast<int*>(m_data);
+ break;
+
+ case eBool:
+ delete static_cast<bool*>(m_data);
+ break;
+ }
+}
+
+
+// ------------------------------------------------------------
+//
+DataX::EType DataX::Type()
+{
+ return m_type;
+}
+
+
+// ------------------------------------------------------------
+//
+void DataX::Set(int value)
+{
+ if (m_type==eInt)
+ {
+ *(static_cast<int*>(m_data))=value;
+ }
+}
+
+
+// ------------------------------------------------------------
+//
+void DataX::Set(const std::string& value)
+{
+ if (m_type==eString)
+ {
+ *(static_cast<std::string*>(m_data))=value;
+ }
+}
+
+
+// ------------------------------------------------------------
+//
+void DataX::Set(const char *value)
+{
+ if (m_type==eString)
+ {
+ *(static_cast<std::string*>(m_data))=value;
+ }
+}
+
+
+// ------------------------------------------------------------
+//
+void DataX::Set(bool value)
+{
+ if (m_type==eBool)
+ {
+ *(static_cast<bool*>(m_data))=value;
+ }
+}
+
+
+// ------------------------------------------------------------
+//
+int DataX::Int()
+{
+ if (m_type==eInt)
+ {
+ return *(static_cast<int*>(m_data));
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+
+// ------------------------------------------------------------
+//
+std::string DataX::Str()
+{
+ if (m_type==eString)
+ {
+ return *(static_cast<std::string*>(m_data));
+ }
+ else
+ {
+ return std::string();
+ }
+}
+
+
+// ------------------------------------------------------------
+//
+bool DataX::Bool()
+{
+ if (m_type==eBool)
+ {
+ return *(static_cast<bool*>(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
@@ -104,6 +104,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);
+ }
+}
+
+
+// ------------------------------------------------------------
+//
BOOL Dialog::InstanceProc(HWND wnd, UINT msg, WPARAM wp, LPARAM lp)
{
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<W32DLib::W32DLibCallback>(&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 <sstream>
#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 <w32dlib/datax.h>
#include <w32dlib/window.h>
#include <w32dlib/dialog.h>
#include <w32dlib/control.h>
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 <sstream>
+
#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;
}
@@ -59,6 +80,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;