From 82f1d860690dc0a2d0210db12344f7ea5e88b6a4 Mon Sep 17 00:00:00 2001 From: Ian C Date: Mon, 28 Mar 2005 01:42:58 +0000 Subject: Added ComboBox. Also improved callback filtering and made controls auto register themselves. --- src/GNUmakefile | 9 ++- src/autocheck.cpp | 2 +- src/button.cpp | 2 +- src/combobox.cpp | 170 +++++++++++++++++++++++++++++++++++++++++++++++++ src/control.cpp | 31 ++++++--- src/dialog.cpp | 21 ++++-- src/test/dialog.h | 1 + src/test/dialog.rc | 8 ++- src/test/w32dtst.cpp | 59 ++++++++++++++--- src/w32dlib/combobox.h | 156 +++++++++++++++++++++++++++++++++++++++++++++ src/w32dlib/control.h | 10 ++- src/w32dlib/dialog.h | 4 +- src/w32dlib/w32dlib.h | 1 + src/w32dlib/window.h | 16 ++++- src/window.cpp | 13 +++- 15 files changed, 465 insertions(+), 38 deletions(-) create mode 100644 src/combobox.cpp create mode 100644 src/w32dlib/combobox.h diff --git a/src/GNUmakefile b/src/GNUmakefile index 4ab212c..0bbfac0 100644 --- a/src/GNUmakefile +++ b/src/GNUmakefile @@ -18,7 +18,7 @@ # # ------------------------------------------------------------------------- # -# $Id: GNUmakefile,v 1.4 2005-03-25 01:23:52 ianc Exp $ +# $Id: GNUmakefile,v 1.5 2005-03-28 01:42:58 ianc Exp $ # @@ -56,7 +56,8 @@ SOURCES = autocheck.cpp \ text.cpp \ static.cpp \ debug.cpp \ - window.cpp + window.cpp \ + combobox.cpp HEADERS = w32dlib/*.h @@ -90,9 +91,7 @@ $(DOCDIR)/html/index.html: $(HEADERS) clean: -rm -f $(TARGET) $(OBJECTS) depend.mak -depend: $(DEPEND) - -$(DEPEND): $(SOURCES) $(HEADERS) GNUMakefile +depend: @echo Dependencies updated.... $(CXX) -MM $(FLAGS) $(SOURCES) > $(DEPEND) diff --git a/src/autocheck.cpp b/src/autocheck.cpp index bfb45c7..57ec5bd 100644 --- a/src/autocheck.cpp +++ b/src/autocheck.cpp @@ -45,7 +45,7 @@ AutoCheck::~AutoCheck() // void AutoCheck::OnPress(Window *owner, W32DLibCallback callback) { - Control::AddCallback(WM_COMMAND,owner,callback); + Control::AddCallback(WM_COMMAND,0,owner,callback); } diff --git a/src/button.cpp b/src/button.cpp index f08f474..66b4018 100644 --- a/src/button.cpp +++ b/src/button.cpp @@ -44,7 +44,7 @@ Button::~Button() // void Button::OnPress(Window *owner, W32DLibCallback callback) { - Control::AddCallback(WM_COMMAND,owner,callback); + Control::AddCallback(WM_COMMAND,0,owner,callback); } diff --git a/src/combobox.cpp b/src/combobox.cpp new file mode 100644 index 0000000..9f1108e --- /dev/null +++ b/src/combobox.cpp @@ -0,0 +1,170 @@ +// 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 +// +// ------------------------------------------------------------------------- +// +#include "w32dlib/window.h" +#include "w32dlib/combobox.h" + +namespace W32DLib +{ + +// ------------------------------------------------------------ +// +ComboBox::ComboBox(Dialog *parent, int resource_id) : + Control(parent,resource_id) +{ +} + + +// ------------------------------------------------------------ +// +ComboBox::~ComboBox() +{ +} + + +// ------------------------------------------------------------ +// +void ComboBox::OnSelection(Window *owner, W32DLibCallback callback) +{ + Control::AddCallback(WM_COMMAND,CBN_SELCHANGE,owner,callback); +} + + +// ------------------------------------------------------------ +// +void ComboBox::OnDoubleClick(Window *owner, W32DLibCallback callback) +{ + Control::AddCallback(WM_COMMAND,CBN_DBLCLK,owner,callback); +} + + +// ------------------------------------------------------------ +// +void ComboBox::OnTextChanged(Window *owner, W32DLibCallback callback) +{ + Control::AddCallback(WM_COMMAND,CBN_EDITCHANGE,owner,callback); +} + + +// ------------------------------------------------------------ +// +void ComboBox::Reset() +{ + SendMsg(CB_RESETCONTENT,0,0); +} + + +// ------------------------------------------------------------ +// +void ComboBox::MaxLen(int count) +{ + SendMsg(CB_LIMITTEXT,count,0); +} + + +// ------------------------------------------------------------ +// +int ComboBox::Count() +{ + return SendMsg(CB_GETCOUNT,0,0); +} + + +// ------------------------------------------------------------ +// +int ComboBox::AddString(const char *text) +{ + return SendMsg(CB_ADDSTRING,0,reinterpret_cast(text)); +} + + +// ------------------------------------------------------------ +// +int ComboBox::AddString(const char *text, int index) +{ + return SendMsg(CB_INSERTSTRING,index,reinterpret_cast(text)); +} + + +// ------------------------------------------------------------ +// +int ComboBox::RemoveString(int index) +{ + return SendMsg(CB_DELETESTRING,index,0); +} + + +// ------------------------------------------------------------ +// +std::string ComboBox::GetString(int index) +{ + std::string result; + LRESULT len=SendMsg(CB_GETLBTEXTLEN,index,0); + + if (len!=CB_ERR) + { + char *text=new char[len+1]; + + SendMsg(CB_GETLBTEXT,index,reinterpret_cast(text)); + + result=text; + + delete[] text; + } + + return result; +} + + +// ------------------------------------------------------------ +// +int ComboBox::TopRowIndex() +{ + return SendMsg(CB_GETTOPINDEX,0,0); +} + + +// ------------------------------------------------------------ +// +void ComboBox::TopRowIndex(int index) +{ + SendMsg(CB_SETTOPINDEX,index,0); +} + + +// ------------------------------------------------------------ +// +int ComboBox::SelectedIndex() +{ + return SendMsg(CB_GETCURSEL,0,0); +} + + +// ------------------------------------------------------------ +// +void ComboBox::SelectedIndex(int index) +{ + SendMsg(CB_SETCURSEL,index,0); +} + + +}; // namespace W32DLib + +// END OF FILE diff --git a/src/control.cpp b/src/control.cpp index 75f96a1..a8a221f 100644 --- a/src/control.cpp +++ b/src/control.cpp @@ -34,6 +34,7 @@ Control::Control(Dialog *parent, int resource_id) : m_resid(resource_id), m_cblist() { + m_parent->AddControl(this); } @@ -59,32 +60,46 @@ BOOL Control::ProcessMessage(UINT msg, WPARAM wp, LPARAM lp) if (msg==WM_INITDIALOG) { m_wnd=GetDlgItem(m_parent->GetHWND(),m_resid); + W32DEBUGOUT("Got HWND " << m_wnd << " for " << m_resid); } - if (m_cblist.count(msg)>0) - { - CallbackDetails details=m_cblist[msg]; - Window *owner=details.owner; - W32DLibCallback cb=details.cb; + WORD hi=HIWORD(wp); + CallbackList::const_iterator i; - return (owner->*cb)(msg,wp,lp); + for(i=m_cblist.begin();i!=m_cblist.end();++i) + { + CallbackDetails details=*i; + + if (details.msg==msg) + { + if (details.notif==0 || details.notif==hi) + { + Window *owner=details.owner; + W32DLibCallback cb=details.cb; + + return (owner->*cb)(msg,wp,lp); + } + } } - return false; + return FALSE; } // ------------------------------------------------------------ // void Control::AddCallback(UINT msg, + UINT notification, Window *owner, W32DLibCallback callback) { CallbackDetails details; + details.msg=msg; + details.notif=notification; details.owner=owner; details.cb=callback; - m_cblist[msg]=details; + m_cblist.push_back(details); } diff --git a/src/dialog.cpp b/src/dialog.cpp index 96d80f9..512dbdd 100644 --- a/src/dialog.cpp +++ b/src/dialog.cpp @@ -108,7 +108,10 @@ BOOL Dialog::InstanceProc(HWND wnd, UINT msg, WPARAM wp, LPARAM lp) for(ControlSet::iterator i=m_cset.begin();i!=m_cset.end();++i) { - W32DEBUGOUT(MsgName(msg) << " for resource " << lo); + W32DEBUGOUT(MsgName(msg) << " (" << msg << + ", " << wp << ", " << lp << ")" << + " for resource " << (*i)->ResourceID()); + (*i)->ProcessMessage(msg,wp,lp); } @@ -124,17 +127,27 @@ BOOL Dialog::InstanceProc(HWND wnd, UINT msg, WPARAM wp, LPARAM lp) ret=Window::InstanceProc(wnd,msg,wp,lp); break; - default: + // Messages passed onto controls + // + case WM_COMMAND: + // Check for windows and resources in the wp + // for(ControlSet::iterator i=m_cset.begin();i!=m_cset.end();++i) { - if (lo==(*i)->ResourceID()) + if (lo==(*i)->ResourceID()) { - W32DEBUGOUT(MsgName(msg) << " for resource " << lo); + W32DEBUGOUT(MsgName(msg) << " (" << msg << + ", " << wp << ", " << lp << ")" << + " for resource " << (*i)->ResourceID()); + ret=(*i)->ProcessMessage(msg,wp,lp); break; } } break; + + default: + break; } return ret; diff --git a/src/test/dialog.h b/src/test/dialog.h index ac47a4e..5b08673 100644 --- a/src/test/dialog.h +++ b/src/test/dialog.h @@ -10,3 +10,4 @@ #define IDSAVEBUT 10 #define IDDIRTXT 11 #define IDDIRBUT 12 +#define IDCOMBO 13 diff --git a/src/test/dialog.rc b/src/test/dialog.rc index 27f1ea6..e96fa9f 100644 --- a/src/test/dialog.rc +++ b/src/test/dialog.rc @@ -1,9 +1,9 @@ #include #include "dialog.h" -TESTDLG DIALOG 10, 10, 240, 180 - STYLE WS_POPUP | WS_BORDER CAPTION - "Test Dialog" +TESTDLG DIALOG 10, 10, 240, 300 + STYLE WS_POPUP | WS_BORDER + CAPTION "Test Dialog" FONT 8,"MS Shell Dlg" { LTEXT "Text:", IDSTATIC1, 10, 10, 35, 12 @@ -17,4 +17,6 @@ TESTDLG DIALOG 10, 10, 240, 180 EDITTEXT IDSAVETXT, 10, 140, 200, 12 PUSHBUTTON "Save ...",IDSAVEBUT, 10, 155, 100, 18 + + COMBOBOX IDCOMBO, 10, 180, 100, 100, CBS_SIMPLE | CBS_SORT | WS_VSCROLL | WS_TABSTOP } diff --git a/src/test/w32dtst.cpp b/src/test/w32dtst.cpp index 5f14a6d..663c63d 100644 --- a/src/test/w32dtst.cpp +++ b/src/test/w32dtst.cpp @@ -36,16 +36,8 @@ public: , m_loadbut(this,IDLOADBUT) , m_save(this,IDSAVETXT) , m_savebut(this,IDSAVEBUT) + , m_combo(this,IDCOMBO) { - AddControl(&m_text); - AddControl(&m_check); - AddControl(&m_button); - AddControl(&m_quit); - AddControl(&m_load); - AddControl(&m_loadbut); - AddControl(&m_save); - AddControl(&m_savebut); - m_button.OnPress (this,static_cast(&Test::OnButton)); m_quit.OnPress @@ -57,6 +49,13 @@ public: (this,static_cast(&Test::OnLoad)); m_savebut.OnPress (this,static_cast(&Test::OnSave)); + + m_combo.OnSelection + (this,static_cast(&Test::OnComboSel)); + m_combo.OnDoubleClick + (this,static_cast(&Test::OnComboDbl)); + m_combo.OnTextChanged + (this,static_cast(&Test::OnComboTxt)); } virtual ~Test() @@ -74,6 +73,16 @@ public: m_text.SetText("Hello"); m_check.SetState(W32DLib::AutoCheck::eChecked); m_quit.Enable(true); + + m_combo.Reset(); + std::cout << "addstring=" << m_combo.AddString("Entry 1") << std::endl; + std::cout << "addstring=" << m_combo.AddString("Entry 2") << std::endl; + std::cout << "addstring=" << m_combo.AddString("Entry 3") << std::endl; + + std::cout << "count=" << m_combo.Count() << std::endl; + std::cout << "HWND=" << m_combo.GetHWND() << std::endl; + + m_combo.SelectedIndex(2); } private: @@ -89,6 +98,8 @@ private: W32DLib::Text m_save; W32DLib::Button m_savebut; + W32DLib::ComboBox m_combo; + std::string m_loadpath; std::string m_savepath; @@ -108,6 +119,7 @@ private: std::cout << "check=" << m_check.GetState() << std::endl; m_static.SetText(txt.c_str()); SetText((txt+" [Title]").c_str()); + m_combo.AddString(m_combo.GetText().c_str()); return TRUE; } @@ -147,6 +159,35 @@ private: return TRUE; } + + BOOL OnComboSel(UINT msg, WPARAM wp, LPARAM lp) + { + int sel=m_combo.SelectedIndex(); + std::string str=m_combo.GetString(sel); + + std::cout << "Called OnComboSel()" << std::endl; + std::cout << "Sel:selection=" << sel << " (" << str << ")" << std::endl; + std::cout << "Sel:Window::GetText=" << m_combo.GetText(512) << std::endl; + return TRUE; + } + + BOOL OnComboDbl(UINT msg, WPARAM wp, LPARAM lp) + { + int sel=m_combo.SelectedIndex(); + std::string str=m_combo.GetString(sel); + + std::cout << "Called OnComboDbl()" << std::endl; + std::cout << "Dbl:selection=" << sel << " (" << str << ")" << std::endl; + std::cout << "Dbl:Window::GetText=" << m_combo.GetText(512) << std::endl; + return TRUE; + } + + BOOL OnComboTxt(UINT msg, WPARAM wp, LPARAM lp) + { + std::cout << "Called OnComboSel()" << std::endl; + std::cout << "Txt:Window::GetText=" << m_combo.GetText(512) << std::endl; + return TRUE; + } }; int WINAPI WinMain (HINSTANCE hInstance, diff --git a/src/w32dlib/combobox.h b/src/w32dlib/combobox.h new file mode 100644 index 0000000..dae30a0 --- /dev/null +++ b/src/w32dlib/combobox.h @@ -0,0 +1,156 @@ +// 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_COMBOBOX_H + +#define W32DLIB_COMBOBOX_H "$Id$" + +#include "w32dlib/base.h" +#include "w32dlib/control.h" + +namespace W32DLib +{ + + /// \brief The ComboBox class. + /// + class ComboBox : public Control + { + public: + + /// \brief Constructor + /// + /// \param parent The dialog the control belongs to. + /// \param resource_id The ID of the control in the resource file. + /// + ComboBox(Dialog *parent, int resource_id); + + /// \brief Destructor + /// + virtual ~ComboBox(); + + /// \brief Sets a callback for when selection changes. + /// + /// \param owner The class the callback reside in. + /// \param callback The callback. + /// + void OnSelection(Window *owner, + W32DLibCallback callback); + + /// \brief Sets a callback for when a list entry is double clicked. + /// + /// Note this only works of the list has a CBS_SIMPLE style. + /// + /// \param owner The class the callback reside in. + /// \param callback The callback. + /// + void OnDoubleClick(Window *owner, + W32DLibCallback callback); + + /// \brief Sets a callback for when the text is altered. + /// + /// Note this will not work if the list has a CBS_DROPDOWNLIST style. + /// + /// \param owner The class the callback reside in. + /// \param callback The callback. + /// + void OnTextChanged(Window *owner, + W32DLibCallback callback); + + /// \brief Resets the items in a combo box. + /// + void Reset(); + + /// \brief Sets the maximum length the user can enter. + /// + /// \param count The maximum number of characters the user can enter. + /// + void MaxLen(int count); + + /// \brief The number of strings in the combo box. + /// + /// \return The count or CB_ERR. + /// + int Count(); + + /// \brief Adds a string to the combo box. + /// + /// \param text The string to add. + /// \return The index of the added string, or CB_ERR or CB_ERRSPACE. + /// + int AddString(const char *text); + + /// \brief Adds a string to the combo box. + /// + /// \param text The string to add. + /// \param index The index to insert in front of + /// \return The index of the added string, or CB_ERR or CB_ERRSPACE. + /// + int AddString(const char *text,int index); + + /// \brief Removes a string from the combo box. + /// + /// \param index The index of the string to remove. + /// \return The count of remaining items, or CB_ERR. + /// + int RemoveString(int index); + + /// \brief Gets a string from the combo box. + /// + /// \param index The index of the string to retrieve. + /// \return The string. + /// + std::string GetString(int index); + + /// \brief Gets the index of the item at the top of the list. + /// + /// \return The index, or CB_ERR. + /// + int TopRowIndex(); + + /// \brief Sets the index of the item at the top of the list. + /// + /// \param index The index. + /// + void TopRowIndex(int index); + + /// \brief Gets the index of the current selection. + /// + /// \return The index, or CB_ERR. + /// + int SelectedIndex(); + + /// \brief Sets the index of the current selection. + /// + /// \param index The index. + /// + void SelectedIndex(int index); + + protected: + + private: + + }; // class ComboBox + +}; // namespace w32dlib + +#endif // W32DLIB_COMBOBOX_H + + +// END OF FILE diff --git a/src/w32dlib/control.h b/src/w32dlib/control.h index 5096abf..3cc01e5 100644 --- a/src/w32dlib/control.h +++ b/src/w32dlib/control.h @@ -35,6 +35,9 @@ namespace W32DLib /// \brief Constructor /// + /// When a control is constructed it calls Dialog::AddControl to add + /// itself to the dialog. + /// /// \param parent The Dialog the control belongs to. /// \param resource_id The ID of the control in the resource file. /// @@ -65,12 +68,15 @@ namespace W32DLib /// \brief Add a callback for the control. /// /// \param msg The Windows event message to respond to. + /// \param notification The top word of the WPARAM will be checked + /// against this. If zero, then ignored. /// \param owner The class (generally a Dialog derived one) in which /// the callback resides. The class must be derived from /// Window. /// \param callback The callback. /// void AddCallback(UINT msg, + UINT notification, Window *owner, W32DLibCallback callback); @@ -87,10 +93,12 @@ namespace W32DLib struct CallbackDetails { Window *owner; + UINT msg; + UINT notif; W32DLibCallback cb; }; - typedef std::map CallbackList; + typedef std::vector CallbackList; CallbackList m_cblist; diff --git a/src/w32dlib/dialog.h b/src/w32dlib/dialog.h index ea9ce4b..f4ba5c6 100644 --- a/src/w32dlib/dialog.h +++ b/src/w32dlib/dialog.h @@ -87,8 +87,6 @@ namespace W32DLib /// void Close(INT_PTR result); - protected: - /// \brief Adds a control to the dialog. /// /// Note that the pointer to the control is stored, so the control @@ -96,6 +94,8 @@ namespace W32DLib /// void AddControl(Control *control); + protected: + /// \brief Handles windows messages. /// /// \param wnd The window handle diff --git a/src/w32dlib/w32dlib.h b/src/w32dlib/w32dlib.h index b1b813c..0df8bed 100644 --- a/src/w32dlib/w32dlib.h +++ b/src/w32dlib/w32dlib.h @@ -30,6 +30,7 @@ #include #include #include +#include #endif // W32DLIB_H diff --git a/src/w32dlib/window.h b/src/w32dlib/window.h index 2f2d1a6..94c6179 100644 --- a/src/w32dlib/window.h +++ b/src/w32dlib/window.h @@ -47,6 +47,18 @@ namespace W32DLib /// HWND GetHWND(); + /// \brief Send a message to the 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 msg The message to send. + /// \param wp The WPARAM for that message type. + /// \param lp The LPARAM for that message type. + /// \return The LRESULT from sending the message. + /// + LRESULT SendMsg(UINT msg, WPARAM wp, LPARAM lp); + /// \brief Sets the window text. /// /// This call will only work while the window is on display. @@ -62,11 +74,11 @@ namespace W32DLib /// This call will only work while the window is on display. /// The behaviour is undefined if it is called at any other time. /// - /// \param maxlen The maximum length to fetch + /// \param maxlen The maximum length to fetch /// \return The control's text /// \sa SetText() /// - virtual std::string GetText(int maxlen); + virtual std::string GetText(int maxlen=512); /// \brief Enables or disables the window. /// diff --git a/src/window.cpp b/src/window.cpp index c34c5ca..492ecfd 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -49,11 +49,20 @@ HWND Window::GetHWND() } +// ------------------------------------------------------------ +// +LRESULT Window::SendMsg(UINT msg, WPARAM wp, LPARAM lp) + +{ + return SendMessage(m_wnd,msg,wp,lp); +} + + // ------------------------------------------------------------ // void Window::SetText(const char *text) { - ::SendMessage(m_wnd,WM_SETTEXT,0,reinterpret_cast(text)); + SendMsg(WM_SETTEXT,0,reinterpret_cast(text)); } @@ -66,7 +75,7 @@ std::string Window::GetText(int maxlen) buff[0]=0; - ::SendMessage(m_wnd,WM_GETTEXT,maxlen,reinterpret_cast(buff)); + SendMsg(WM_GETTEXT,maxlen,reinterpret_cast(buff)); res=buff; delete[] buff; -- cgit v1.2.3