X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/dcd307ee1f13834bdfe43a0964db657bcd860142..c1d8296a78d1f630952fc5395e4072c8a654b8ef:/src/os2/choice.cpp diff --git a/src/os2/choice.cpp b/src/os2/choice.cpp index 7448ef7e50..8235ed3532 100644 --- a/src/os2/choice.cpp +++ b/src/os2/choice.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: choice.cpp +// Name: src/os2/choice.cpp // Purpose: wxChoice // Author: David Webster // Modified by: @@ -12,84 +12,165 @@ // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" +#include "wx/defs.h" + +#if wxUSE_CHOICE + #ifndef WX_PRECOMP #include "wx/choice.h" #include "wx/utils.h" #include "wx/log.h" + #include "wx/settings.h" #endif #include "wx/os2/private.h" -#if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxChoice, wxControl) -#endif -bool wxChoice::Create(wxWindow *parent, - wxWindowID id, - const wxPoint& pos, - const wxSize& size, - int n, const wxString choices[], - long style, - const wxValidator& validator, - const wxString& name) +bool wxChoice::Create( + wxWindow* pParent +, wxWindowID vId +, const wxPoint& rPos +, const wxSize& rSize +, const wxArrayString& asChoices +, long lStyle +, const wxValidator& rValidator +, const wxString& rsName +) { - if ( !CreateControl(parent, id, pos, size, style, validator, name) ) - return FALSE; -// TODO: -/* - long msStyle = WS_CHILD | CBS_DROPDOWNLIST | WS_TABSTOP | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL; - if ( style & wxCB_SORT ) - msStyle |= CBS_SORT; - - // the experience shows that wxChoice vs. wxComboBox distinction confuses - // quite a few people - try to help them - wxASSERT_MSG( !(style & wxCB_DROPDOWN) && - !(style & wxCB_READONLY) && - !(style & wxCB_SIMPLE), + wxCArrayString chs(asChoices); + + return Create(pParent, vId, rPos, rSize, chs.GetCount(), chs.GetStrings(), + lStyle, rValidator, rsName); +} + +bool wxChoice::Create( + wxWindow* pParent +, wxWindowID vId +, const wxPoint& rPos +, const wxSize& rSize +, int n +, const wxString asChoices[] +, long lStyle +, const wxValidator& rValidator +, const wxString& rsName +) +{ + long lSstyle; + + if (!CreateControl( pParent + ,vId + ,rPos + ,rSize + ,lStyle + ,rValidator + ,rsName + )) + return false; + lSstyle = CBS_DROPDOWNLIST | + WS_TABSTOP | + WS_VISIBLE; + + if (lStyle & wxCLIP_SIBLINGS ) + lSstyle |= WS_CLIPSIBLINGS; + + wxASSERT_MSG( !(lStyle & wxCB_DROPDOWN) && + !(lStyle & wxCB_READONLY) && + !(lStyle & wxCB_SIMPLE), wxT("this style flag is ignored by wxChoice, you " "probably want to use a wxComboBox") ); - if ( !OS2CreateControl(wxT("COMBOBOX"), msStyle) ) - return FALSE; - - for ( int i = 0; i < n; i++ ) + if (!OS2CreateControl( wxT("COMBOBOX") + ,lSstyle + )) + return false; + + // + // A choice/combobox normally has a white background (or other, depending + // on global settings) rather than inheriting the parent's background colour. + // + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + for (int i = 0; i < n; i++) { - Append(choices[i]); + Append(asChoices[i]); } -*/ - SetSize(pos.x, pos.y, size.x, size.y); - - return TRUE; -} + wxFont* pTextFont = new wxFont( 10 + ,wxMODERN + ,wxNORMAL + ,wxNORMAL + ); + SetFont(*pTextFont); + SetSize( rPos.x + ,rPos.y + ,rSize.x + ,rSize.y + ); + delete pTextFont; + return true; +} // end of wxChoice::Create // ---------------------------------------------------------------------------- // adding/deleting items to/from the list // ---------------------------------------------------------------------------- -int wxChoice::DoAppend(const wxString& item) +int wxChoice::DoAppend( + const wxString& rsItem +) { - // TODO: - /* - int n = (int)SendMessage(GetHwnd(), CB_ADDSTRING, 0, (LONG)item.c_str()); - if ( n == CB_ERR ) - { - wxLogLastError("SendMessage(CB_ADDSTRING)"); - } - */ - return 0; //n -} - -void wxChoice::Delete(int n) + int nIndex; + LONG nIndexType = 0; + + if (m_windowStyle & wxLB_SORT) + nIndexType = LIT_SORTASCENDING; + else + nIndexType = LIT_END; + nIndex = (int)::WinSendMsg( GetHwnd() + ,LM_INSERTITEM + ,(MPARAM)nIndexType + ,(MPARAM)rsItem.c_str() + ); + return nIndex; +} // end of wxChoice::DoAppend + +int wxChoice::DoInsert( + const wxString& rsItem, + int pos +) +{ + wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT), -1, wxT("can't insert into sorted list")); + wxCHECK_MSG((pos>=0) && (pos<=GetCount()), -1, wxT("invalid index")); + + if (pos == GetCount()) + return DoAppend(rsItem); + + int nIndex; + LONG nIndexType = 0; + + if (m_windowStyle & wxLB_SORT) + nIndexType = LIT_SORTASCENDING; + else + nIndexType = pos; + nIndex = (int)::WinSendMsg( GetHwnd() + ,LM_INSERTITEM + ,(MPARAM)nIndexType + ,(MPARAM)rsItem.c_str() + ); + return nIndex; +} // end of wxChoice::DoInsert + +void wxChoice::Delete( + int n +) { wxCHECK_RET( n < GetCount(), wxT("invalid item index in wxChoice::Delete") ); - -// TODO: SendMessage(GetHwnd(), CB_DELETESTRING, n, 0); -} + ::WinSendMsg(GetHwnd(), LM_DELETEITEM, (MPARAM)n, (MPARAM)0); +} // end of wxChoice::Delete void wxChoice::Clear() { - // TODO: SendMessage(GetHwnd(), CB_RESETCONTENT, 0, 0); -} + Free(); + ::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0); +} // end of wxChoice::Clear // ---------------------------------------------------------------------------- // selection @@ -97,14 +178,19 @@ void wxChoice::Clear() int wxChoice::GetSelection() const { - // TODO: return (int)SendMessage(GetHwnd(), CB_GETCURSEL, 0, 0); - return 0; -} + return((int)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0))); +} // end of wxChoice::GetSelection -void wxChoice::SetSelection(int n) +void wxChoice::SetSelection( + int n +) { - // TODO: SendMessage(GetHwnd(), CB_SETCURSEL, n, 0); -} + ::WinSendMsg( GetHwnd() + ,LM_SELECTITEM + ,(MPARAM)n + ,(MPARAM)TRUE + ); +} // end of wxChoice::SetSelection // ---------------------------------------------------------------------------- // string list functions @@ -112,178 +198,233 @@ void wxChoice::SetSelection(int n) int wxChoice::GetCount() const { - // TODO: return (int)SendMessage(GetHwnd(), CB_GETCOUNT, 0, 0); - return 0; -} + return((int)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMCOUNT, (MPARAM)0, (MPARAM)0))); +} // end of wxChoice::GetCount -int wxChoice::FindString(const wxString& s) const +void wxChoice::SetString( int n, const wxString& rsStr ) { - // TODO: - /* - int pos = (int)SendMessage(GetHwnd(), CB_FINDSTRINGEXACT, - (WPARAM)-1, (LPARAM)s.c_str()); - - return pos == LB_ERR ? wxNOT_FOUND : pos; - */ - return 0; -} + LONG nIndexType = 0; + void* pData; -void wxChoice::SetString(int n, const wxString& s) -{ - wxFAIL_MSG(wxT("not implemented")); + if ( m_clientDataItemsType != wxClientData_None ) + { + pData = DoGetItemClientData(n); + } + else // no client data + { + pData = NULL; + } -#if 0 // should do this, but no Insert() so far - Delete(n); - Insert(n + 1, s); -#endif -} + ::WinSendMsg(GetHwnd(), LM_DELETEITEM, (MPARAM)n, 0); + + if (m_windowStyle & wxLB_SORT) + nIndexType = LIT_SORTASCENDING; + else + nIndexType = LIT_END; + ::WinSendMsg( GetHwnd() + ,LM_INSERTITEM + ,(MPARAM)nIndexType + ,(MPARAM)rsStr.c_str() + ); + + if (pData) + { + DoSetItemClientData( n + ,pData + ); + } +} // end of wxChoice::SetString wxString wxChoice::GetString(int n) const { - size_t len = 0; // TODO: (size_t)::SendMessage(GetHwnd(), CB_GETLBTEXTLEN, n, 0); - wxString str = ""; - // TODO: - /* - if (len) { - if ( ::SendMessage(GetHwnd(), CB_GETLBTEXT, n, - (LPARAM)str.GetWriteBuf(len)) == CB_ERR ) { - wxLogLastError("SendMessage(CB_GETLBTEXT)"); - } - str.UngetWriteBuf(); + int nLen = 0; + wxString sStr = wxEmptyString; + wxChar* zBuf; + + nLen = (size_t)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH, (MPARAM)n, (MPARAM)0)); + if (nLen != LIT_ERROR && nLen > 0) + { + zBuf = new wxChar[nLen + 1]; + ::WinSendMsg( GetHwnd() + ,LM_QUERYITEMTEXT + ,MPFROM2SHORT((SHORT)n, (SHORT)nLen) + ,(MPARAM)zBuf + ); + sStr = zBuf; + delete [] zBuf; } - */ - return str; -} + return sStr; +} // end of wxChoice::GetString // ---------------------------------------------------------------------------- // client data // ---------------------------------------------------------------------------- -void wxChoice::DoSetItemClientData( int n, void* clientData ) +void wxChoice::DoSetItemClientData( + int n +, void* pClientData +) { - // TODO: - /* - if ( SendMessage(GetHwnd(), CB_SETITEMDATA, n, (LPARAM)clientData) == CB_ERR ) - { - wxLogLastError(wxT("CB_SETITEMDATA")); - } - */ -} + ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, (MPARAM)n, MPFROMP(pClientData)); +} // end of wxChoice::DoSetItemClientData void* wxChoice::DoGetItemClientData( int n ) const { - // TODO: - /* - LPARAM rc = SendMessage(GetHwnd(), CB_GETITEMDATA, n, 0); - if ( rc == CB_ERR ) - { - wxLogLastError(wxT("CB_GETITEMDATA")); + MRESULT rc = 0L; - // unfortunately, there is no way to return an error code to the user - rc = (LPARAM) NULL; - } + rc = ::WinSendMsg(GetHwnd(), LM_QUERYITEMHANDLE, (MPARAM)n, (MPARAM)0); + return((void*)rc); +} // end of wxChoice::DoSetItemClientData - return (void *)rc; - */ - return NULL; -} - -void wxChoice::DoSetItemClientObject( int n, wxClientData* clientData ) +void wxChoice::DoSetItemClientObject( + int n +, wxClientData* pClientData +) { - DoSetClientData(n, clientData); -} - -wxClientData* wxChoice::DoGetItemClientObject( int n ) const + DoSetItemClientData( n + ,pClientData + ); +} // end of wxChoice::DoSetItemClientObject + +wxClientData* wxChoice::DoGetItemClientObject( + int n +) const { - // TODO: return (wxClientData *)DoGetClientData(n); - return NULL; -} + return (wxClientData *)DoGetItemClientData(n); +} // end of wxChoice::DoGetItemClientObject // ---------------------------------------------------------------------------- // wxOS2 specific helpers // ---------------------------------------------------------------------------- -void wxChoice::DoSetSize(int x, int y, - int width, int height, - int sizeFlags) +void wxChoice::DoSetSize(int nX, + int nY, + int nWidth, + int WXUNUSED(nHeight), + int nSizeFlags) { + // // Ignore height parameter because height doesn't mean 'initially // displayed' height, it refers to the drop-down menu as well. The - // wxWindows interpretation is different; also, getting the size returns + // wxWidgets interpretation is different; also, getting the size returns // the _displayed_ size (NOT the drop down menu size) so // setting-getting-setting size would not work. - wxControl::DoSetSize(x, y, width, -1, sizeFlags); -} - -wxSize wxChoice::DoGetBestSize() + // + wxControl::DoSetSize( nX + ,nY + ,nWidth + ,wxDefaultCoord + ,nSizeFlags + ); +} // end of wxChoice::DoSetSize + +wxSize wxChoice::DoGetBestSize() const { - // find the widest string - int wLine; - int wChoice = 0; - int nItems = GetCount(); - for ( int i = 0; i < nItems; i++ ) + // + // Find the widest string + // + int nLineWidth; + int nChoiceWidth = 0; + int nItems = GetCount(); + int nCx; + int nCy; + wxFont vFont = (wxFont)GetFont(); + + for (int i = 0; i < nItems; i++) { - wxString str(GetString(i)); - GetTextExtent(str, &wLine, NULL); - if ( wLine > wChoice ) - wChoice = wLine; + wxString sStr(GetString(i)); + + GetTextExtent( sStr + ,&nLineWidth + ,NULL + ); + if (nLineWidth > nChoiceWidth) + nChoiceWidth = nLineWidth; } - // give it some reasonable default value if there are no strings in the + // + // Give it some reasonable default value if there are no strings in the // list - if ( wChoice == 0 ) - wChoice = 100; - - // the combobox should be larger than the widest string - int cx, cy; - wxGetCharSize(GetHWND(), &cx, &cy, &GetFont()); - - wChoice += 5*cx; - + // + if (nChoiceWidth == 0L) + nChoiceWidth = 100L; + + // + // The combobox should be larger than the widest string + // + wxGetCharSize( GetHWND() + ,&nCx + ,&nCy + ,&vFont + ); + nChoiceWidth += 5 * nCx; + + // // Choice drop-down list depends on number of items (limited to 10) - size_t nStrings = nItems == 0 ? 10 : wxMin(10, nItems) + 1; - int hChoice = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy)*nStrings; - - return wxSize(wChoice, hChoice); -} - -MRESULT wxChoice::OS2WindowProc(HWND hwnd, WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) + // + size_t nStrings = nItems == 0 ? 10 : wxMin(10, nItems) + 1; + int nChoiceHeight = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy) * nStrings; + + return wxSize( nChoiceWidth + ,nChoiceHeight + ); +} // end of wxChoice::DoGetBestSize + +MRESULT wxChoice::OS2WindowProc( + WXUINT uMsg +, WXWPARAM wParam +, WXLPARAM lParam +) { - // TODO: - /* - if ( nMsg == WM_LBUTTONUP ) + return wxWindow::OS2WindowProc( uMsg + ,wParam + ,lParam + ); +} // end of wxChoice::OS2WindowProc + +bool wxChoice::OS2Command( + WXUINT uParam +, WXWORD WXUNUSED(wId) +) +{ + if (uParam != LN_SELECT) { - int x = (int)LOWORD(lParam); - int y = (int)HIWORD(lParam); - - // Ok, this is truly weird, but if a panel with a wxChoice loses the - // focus, then you get a *fake* WM_LBUTTONUP message with x = 65535 and - // y = 65535. Filter out this nonsense. // - // VZ: I'd like to know how to reproduce this please... - if ( x == 65535 && y == 65535 ) - return 0; + // "selection changed" is the only event we're after + // + return false; } - */ - return wxWindow::OS2WindowProc(hwnd, nMsg, wParam, lParam); -} + int n = GetSelection(); + + if (n > -1) + { + wxCommandEvent vEvent( wxEVT_COMMAND_CHOICE_SELECTED + ,m_windowId + ); + + vEvent.SetInt(n); + vEvent.SetEventObject(this); + vEvent.SetString(GetStringSelection()); + if (HasClientObjectData()) + vEvent.SetClientObject(GetClientObject(n)); + else if (HasClientUntypedData()) + vEvent.SetClientData(GetClientData(n)); + ProcessCommand(vEvent); + } + return true; +} // end of wxChoice::OS2Command -bool wxChoice::OS2Command(WXUINT param, WXWORD WXUNUSED(id)) +void wxChoice::Free() { - // TODO: - /* - if ( param != CBN_SELCHANGE) + if (HasClientObjectData()) { - // "selection changed" is the only event we're after - return FALSE; + size_t nCount = GetCount(); + + for (size_t n = 0; n < nCount; n++) + { + delete GetClientObject(n); + } } - */ - wxCommandEvent event(wxEVT_COMMAND_CHOICE_SELECTED, m_windowId); - event.SetInt(GetSelection()); - event.SetEventObject(this); -// TODO: event.SetString(GetStringSelection()); - ProcessCommand(event); - - return TRUE; -} +} // end of wxChoice::Free +#endif // wxUSE_CHOICE