From 316189733a8b7f28aa7f9f555884bb45da30da33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?W=C5=82odzimierz=20Skiba?= Date: Sat, 5 Nov 2005 22:49:33 +0000 Subject: [PATCH] Native wxCheckListBox implementation for wxWinCE. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@36093 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- build/bakefiles/files.bkl | 6 +- docs/changes.txt | 1 + docs/latex/wx/wxmsw.tex | 17 +- include/wx/checklst.h | 10 +- include/wx/msw/wince/checklst.h | 93 ++++++++++ include/wx/msw/wince/setup.h | 6 +- src/msw/wince/checklst.cpp | 319 ++++++++++++++++++++++++++++++++ 7 files changed, 438 insertions(+), 14 deletions(-) create mode 100644 include/wx/msw/wince/checklst.h create mode 100644 src/msw/wince/checklst.cpp diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index 64002664cd..065142453b 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -1302,7 +1302,6 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/msw/bmpbuttn.cpp src/msw/button.cpp src/msw/checkbox.cpp - src/msw/checklst.cpp src/msw/choice.cpp src/msw/colordlg.cpp src/msw/combobox.cpp @@ -1352,7 +1351,6 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/msw/button.h wx/msw/caret.h wx/msw/checkbox.h - wx/msw/checklst.h wx/msw/choice.h wx/msw/clipbrd.h wx/msw/colordlg.h @@ -1467,10 +1465,12 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! + src/msw/checklst.cpp src/msw/fdrepdlg.cpp src/msw/fontdlg.cpp + wx/msw/checklst.h wx/msw/fdrepdlg.h wx/msw/fontdlg.h wx/msw/helpbest.h @@ -1483,6 +1483,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/generic/dirdlgg.cpp src/generic/fdrepdlg.cpp src/generic/fontdlgg.cpp + src/msw/wince/checklst.cpp src/msw/wince/choicece.cpp src/msw/wince/crt.cpp src/msw/wince/filedlgwce.cpp @@ -1495,6 +1496,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/generic/fdrepdlg.h wx/generic/fontdlgg.h + wx/msw/wince/checklst.h wx/msw/wince/choicece.h wx/msw/wince/helpwce.h wx/msw/wince/libraries.h diff --git a/docs/changes.txt b/docs/changes.txt index 6a62500c8d..7ab2fe790b 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -38,6 +38,7 @@ wxMSW: wxWinCE: - Pressing build-in joystick on WinCE phones fires wxEVT_JOY_BUTTON_DOWN event. +- Native wxCheckListBox implementation. Unix: diff --git a/docs/latex/wx/wxmsw.tex b/docs/latex/wx/wxmsw.tex index d73426584c..a8689ef7e4 100644 --- a/docs/latex/wx/wxmsw.tex +++ b/docs/latex/wx/wxmsw.tex @@ -1,3 +1,14 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Name: wxmsw.tex +%% Purpose: wxMSW and wxWinCE platform specific informations +%% Author: wxWidgets Team +%% Modified by: +%% Created: +%% RCS-ID: $Id$ +%% Copyright: (c) wxWidgets Team +%% License: wxWindows license +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + \section{wxMSW port}\label{wxmswport} wxMSW is a port of wxWidgets for the Windows platforms @@ -242,8 +253,6 @@ These controls are missing from wxWinCE: \itemsep=0pt \begin{itemize} -\item {\bf wxCheckListBox} This can be implemented using a wxListCtrl in report mode -with checked/unchecked images. \item {\bf MDI classes} MDI is not supported under Windows CE. \item {\bf wxMiniFrame} Not supported under Windows CE. \end{itemize} @@ -345,9 +354,6 @@ show the SIP automatically using the WC\_SIPREF control. the correct size on the emulator, but too small on a VGA Pocket Loox device. \item {\bf wxStaticLine.} Lines don't show up, and the documentation suggests that missing styles are implemented with WM\_PAINT. -\item {\bf wxCheckListBox.} This class needs to be implemented in terms of a wxListCtrl -in report mode, using icons for checkbox states. This is necessary because owner-draw listboxes -are not supported on Windows CE. \item {\bf wxFileDialog.} A more flexible dialog needs to be written (probably using wxGenericFileDialog) that can access arbitrary locations. \item {\bf HTML control.} PocketPC has its own HTML control which can be used for showing @@ -379,4 +385,3 @@ a specified location. \item {\bf Further abstraction.} We should be able to abstract away more of the differences between desktop and mobile applications, in particular for sizer layout. \end{itemize} - diff --git a/include/wx/checklst.h b/include/wx/checklst.h index 8e33246eca..cd0933ca25 100644 --- a/include/wx/checklst.h +++ b/include/wx/checklst.h @@ -20,7 +20,13 @@ // wxCheckListBox: a listbox whose items may be checked // ---------------------------------------------------------------------------- -class WXDLLEXPORT wxCheckListBoxBase : public wxListBox +class WXDLLEXPORT wxCheckListBoxBase : public + #ifdef __WXWINCE__ + // keep virtuals synchronised + wxListBoxBase + #else + wxListBox + #endif { public: wxCheckListBoxBase() { } @@ -34,6 +40,8 @@ public: #if defined(__WXUNIVERSAL__) #include "wx/univ/checklst.h" +#elif defined(__WXWINCE__) + #include "wx/msw/wince/checklst.h" #elif defined(__WXMSW__) #include "wx/msw/checklst.h" #elif defined(__WXMOTIF__) diff --git a/include/wx/msw/wince/checklst.h b/include/wx/msw/wince/checklst.h new file mode 100644 index 0000000000..4218f09444 --- /dev/null +++ b/include/wx/msw/wince/checklst.h @@ -0,0 +1,93 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/msw/wince/checklst.h +// Purpose: wxCheckListBox class - a listbox with checkable items +// Author: Wlodzimierz ABX Skiba +// Modified by: +// Created: 30.10.2005 +// RCS-ID: $Id$ +// Copyright: (c) Wlodzimierz Skiba +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __CHECKLSTCE__H_ +#define __CHECKLSTCE__H_ + +class WXDLLEXPORT wxCheckListBox : public wxCheckListBoxBase +{ +public: + // ctors + wxCheckListBox(); + wxCheckListBox(wxWindow *parent, wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + int nStrings = 0, + const wxString choices[] = NULL, + long style = 0, + const wxValidator& validator = wxDefaultValidator, + const wxString& name = wxListBoxNameStr); + wxCheckListBox(wxWindow *parent, wxWindowID id, + const wxPoint& pos, + const wxSize& size, + const wxArrayString& choices, + long style = 0, + const wxValidator& validator = wxDefaultValidator, + const wxString& name = wxListBoxNameStr); + virtual ~wxCheckListBox(); + + bool Create(wxWindow *parent, wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + int n = 0, const wxString choices[] = NULL, + long style = 0, + const wxValidator& validator = wxDefaultValidator, + const wxString& name = wxListBoxNameStr); + bool Create(wxWindow *parent, wxWindowID id, + const wxPoint& pos, + const wxSize& size, + const wxArrayString& choices, + long style = 0, + const wxValidator& validator = wxDefaultValidator, + const wxString& name = wxListBoxNameStr); + + // override base class virtuals + virtual void Delete(int n); + + // items may be checked + virtual bool IsChecked(size_t uiIndex) const; + virtual void Check(size_t uiIndex, bool bCheck = true); + + // public interface derived from wxListBox and lower classes + virtual void Clear(); + virtual int GetCount() const; + virtual int GetSelection() const; + virtual int GetSelections(wxArrayInt& aSelections) const; + virtual wxString GetString(int n) const; + virtual bool IsSelected(int n) const; + virtual void SetString(int n, const wxString& s); + +protected: + + void OnSize(wxSizeEvent& event); + + // protected interface derived from wxListBox and lower classes + virtual int DoAppend(const wxString& item); + virtual void* DoGetItemClientData(int n) const; + virtual wxClientData* DoGetItemClientObject(int n) const; + virtual void DoInsertItems(const wxArrayString& items, int pos); + virtual void DoSetFirstItem(int n); + virtual void DoSetItemClientData(int n, void* clientData); + virtual void DoSetItemClientObject(int n, wxClientData* clientData); + virtual void DoSetItems(const wxArrayString& items, void **clientData); + virtual void DoSetSelection(int n, bool select); + // convert our styles to Windows + virtual WXDWORD MSWGetStyle(long style, WXDWORD *exstyle) const; + +private: + + wxArrayPtrVoid m_itemsClientData; + + DECLARE_EVENT_TABLE() + DECLARE_DYNAMIC_CLASS_NO_COPY(wxCheckListBox) +}; + +#endif //_CHECKLSTCE_H diff --git a/include/wx/msw/wince/setup.h b/include/wx/msw/wince/setup.h index 3ebbcc9077..e2d6e95095 100644 --- a/include/wx/msw/wince/setup.h +++ b/include/wx/msw/wince/setup.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: wx/msw/setup.h +// Name: wx/msw/wince/setup.h // Purpose: Configuration for the library // Author: Julian Smart // Modified by: @@ -1069,10 +1069,6 @@ // NB: stuff which doesn't work at all under CE is forcefully disabled in // wx/msw/wince/chkconf.h -// wxCheckListBox requires wxOwnerDrawn which is disabled below -#undef wxUSE_CHECKLISTBOX -#define wxUSE_CHECKLISTBOX 0 - // Windows CE doesn't use RAS so wxDialUpManager doesn't work under it #undef wxUSE_DIALUP_MANAGER #define wxUSE_DIALUP_MANAGER 0 diff --git a/src/msw/wince/checklst.cpp b/src/msw/wince/checklst.cpp new file mode 100644 index 0000000000..8cfaca6972 --- /dev/null +++ b/src/msw/wince/checklst.cpp @@ -0,0 +1,319 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: src/msw/wince/checklst.cpp +// Purpose: implementation of wxCheckListBox class +// Author: Wlodzimierz ABX Skiba +// Modified by: +// Created: 30.10.2005 +// RCS-ID: $Id$ +// Copyright: (c) Wlodzimierz Skiba +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#if wxUSE_CHECKLISTBOX + +#ifndef WX_PRECOMP +#endif + +#include "wx/checklst.h" + +// include "properly" +#include "wx/msw/wrapcctl.h" + +// ============================================================================ +// implementation +// ============================================================================ + +IMPLEMENT_DYNAMIC_CLASS(wxCheckListBox, wxControl) + +// ---------------------------------------------------------------------------- +// implementation of wxCheckListBox class +// ---------------------------------------------------------------------------- + +// define event table +// ------------------ +BEGIN_EVENT_TABLE(wxCheckListBox, wxControl) + EVT_SIZE(wxCheckListBox::OnSize) +END_EVENT_TABLE() + +// control creation +// ---------------- + +// def ctor: use Create() to really create the control +wxCheckListBox::wxCheckListBox() +{ +} + +// ctor which creates the associated control +wxCheckListBox::wxCheckListBox(wxWindow *parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, + int nStrings, const wxString choices[], + long style, const wxValidator& val, + const wxString& name) +{ + Create(parent, id, pos, size, nStrings, choices, style, val, name); +} + +wxCheckListBox::wxCheckListBox(wxWindow *parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, + const wxArrayString& choices, + long style, const wxValidator& val, + const wxString& name) +{ + Create(parent, id, pos, size, choices, style, val, name); +} + +wxCheckListBox::~wxCheckListBox() +{ + m_itemsClientData.Clear(); +} + +bool wxCheckListBox::Create(wxWindow *parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, + int n, const wxString choices[], + long style, + const wxValidator& validator, const wxString& name) +{ + // initialize base class fields + if ( !CreateControl(parent, id, pos, size, style, validator, name) ) + return false; + + // create the native control + if ( !MSWCreateControl(WC_LISTVIEW, wxEmptyString, pos, size) ) + { + // control creation failed + return false; + } + + ::SendMessage(GetHwnd(), LVM_SETEXTENDEDLISTVIEWSTYLE, 0, + LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT ); + + // insert single column with checkboxes and labels + LV_COLUMN col; + wxZeroMemory(col); + ListView_InsertColumn(GetHwnd(), 0, &col ); + + // initialize the contents + for ( int i = 0; i < n; i++ ) + { + Append(choices[i]); + } + + m_itemsClientData.SetCount(n); + + // now we can compute our best size correctly, so do it if necessary + SetBestSize(size); + + return true; +} + +bool wxCheckListBox::Create(wxWindow *parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, + const wxArrayString& choices, + long style, + const wxValidator& validator, const wxString& name) +{ + wxCArrayString chs(choices); + return Create(parent, id, pos, size, chs.GetCount(), chs.GetStrings(), + style, validator, name); +} + +WXDWORD wxCheckListBox::MSWGetStyle(long style, WXDWORD *exstyle) const +{ + WXDWORD wstyle = wxControl::MSWGetStyle(style, exstyle); + + wstyle |= LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER; + + return wstyle; +} + +void wxCheckListBox::OnSize(wxSizeEvent& event) +{ + // set width of the column we use to the width of list client area + event.Skip(); + int w = GetClientSize().x; + ListView_SetColumnWidth( GetHwnd(), 0, w ); +} + +// misc overloaded methods +// ----------------------- + +void wxCheckListBox::Delete(int n) +{ + wxCHECK_RET( n >= 0 && n < GetCount(), + _T("invalid index in wxCheckListBox::Delete") ); + + if ( !ListView_DeleteItem(GetHwnd(), n) ) + { + wxLogLastError(_T("ListView_DeleteItem")); + } + m_itemsClientData.RemoveAt(n); +} + +// check items +// ----------- + +bool wxCheckListBox::IsChecked(size_t uiIndex) const +{ + wxCHECK_MSG( uiIndex < (size_t)GetCount(), false, + _T("invalid index in wxCheckListBox::IsChecked") ); + + return (ListView_GetCheckState(((HWND)GetHWND()), uiIndex) != 0); +} + +void wxCheckListBox::Check(size_t uiIndex, bool bCheck) +{ + wxCHECK_RET( uiIndex < (size_t)GetCount(), + _T("invalid index in wxCheckListBox::Check") ); + + ListView_SetCheckState(((HWND)GetHWND()), uiIndex, bCheck) +} + +// interface derived from wxListBox and lower classes +// -------------------------------------------------- + +void wxCheckListBox::Clear() +{ + int n = GetCount(); + + while ( n > 0 ) + { + n--; + Delete(n); + } + + m_itemsClientData.Clear(); + + wxCHECK_RET( n == GetCount(), + _T("broken wxCheckListBox::Clear()") ); +} + +int wxCheckListBox::GetCount() const +{ + return ListView_GetItemCount( (HWND)GetHWND() ); +} + +int wxCheckListBox::GetSelection() const +{ + return wxNOT_FOUND; +} + +int wxCheckListBox::GetSelections(wxArrayInt& aSelections) const +{ + int n = GetCount(); + while ( n > 0 ) + { + n--; + if(IsChecked(n)) aSelections.Insert(n,0); + } + + return aSelections.GetCount(); +} + +wxString wxCheckListBox::GetString(int n) const +{ + const int bufSize = 513; + wxChar buf[bufSize]; + ListView_GetItemText( (HWND)GetHWND(), n, 0, buf, bufSize - 1 ); + buf[bufSize-1] = _T('\0'); + wxString str(buf); + return str; +} + +bool wxCheckListBox::IsSelected(int n) const +{ + return IsChecked(n); +} + +void wxCheckListBox::SetString(int n, const wxString& s) +{ + wxCHECK_RET( n < GetCount(), + _T("invalid index in wxCheckListBox::SetString") ); + wxChar *buf = new wxChar[s.length()+1]; + wxStrcpy(buf, s.c_str()); + ListView_SetItemText( (HWND)GetHWND(), n, 0, buf ); + delete [] buf; +} + +int wxCheckListBox::DoAppend(const wxString& item) +{ + int n = GetCount(); + LVITEM newItem; + wxZeroMemory(newItem); + newItem.iItem = n; + int ret = ListView_InsertItem( (HWND)GetHWND(), & newItem ); + wxCHECK_MSG( n == ret , -1, _T("Item not added") ); + SetString( ret , item ); + m_itemsClientData.Insert(NULL, ret); + return ret; +} + +void* wxCheckListBox::DoGetItemClientData(int n) const +{ + return m_itemsClientData.Item(n); +} + +wxClientData* wxCheckListBox::DoGetItemClientObject(int n) const +{ + return (wxClientData *)DoGetItemClientData(n); +} + +void wxCheckListBox::DoInsertItems(const wxArrayString& items, int pos) +{ + for( size_t i = 0; i < items.GetCount(); i++ ) + { + Insert(items[i],pos+i); + } +} + +void wxCheckListBox::DoSetFirstItem(int n) +{ + int pos = ListView_GetTopIndex( (HWND)GetHWND() ); + if(pos == n) return; + POINT ppt; + BOOL ret = ListView_GetItemPosition( (HWND)GetHWND(), n, &ppt ); + wxCHECK_RET( ret == TRUE, _T("Broken DoSetFirstItem") ); + ListView_Scroll( (HWND)GetHWND(), 0, 0 ); + ListView_Scroll( (HWND)GetHWND(), 0, ppt.y ); +} + +void wxCheckListBox::DoSetItemClientData(int n, void* clientData) +{ + m_itemsClientData.Item(n) = clientData; +} + +void wxCheckListBox::DoSetItemClientObject(int n, wxClientData* clientData) +{ + DoSetItemClientData(n, clientData); +} + +void wxCheckListBox::DoSetItems(const wxArrayString& items, void **clientData) +{ + for( size_t i = 0; i < items.GetCount(); i++ ) + { + int pos = Append(items[i]); + if( pos >= 0 && clientData ) + DoSetItemClientData(pos, clientData[i]); + } +} + +void wxCheckListBox::DoSetSelection(int n, bool select) +{ + Check(n,select); +} + +#endif