X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/37f214d588b02079a3ddf64c2e46585ca1657c1b..abd474ea63667f727940a009cc3e0b23ba9f418f:/src/os2/combobox.cpp diff --git a/src/os2/combobox.cpp b/src/os2/combobox.cpp index 6e4dc8074d..81590e0f99 100644 --- a/src/os2/combobox.cpp +++ b/src/os2/combobox.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: combobox.cpp +// Name: src/os2/combobox.cpp // Purpose: wxComboBox class // Author: David Webster // Modified by: @@ -9,293 +9,274 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#include "wx/combobox.h" - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" -#ifndef WX_PRECOMP -#include "wx/setup.h" -#endif - #if wxUSE_COMBOBOX #include "wx/combobox.h" + +#ifndef WX_PRECOMP + #include "wx/settings.h" +#endif + #include "wx/clipbrd.h" #include "wx/os2/private.h" -#if !USE_SHARED_LIBRARY -IMPLEMENT_DYNAMIC_CLASS(wxComboBox, wxControl) -#endif +#define OWNER_DRAWN_LISTBOX_EXTRA_SPACE (1) -bool wxComboBox::OS2Command(WXUINT param, WXWORD WXUNUSED(id)) -{ - // TODO: - /* - if (param == CBN_SELCHANGE) - { - wxCommandEvent event(wxEVT_COMMAND_COMBOBOX_SELECTED, m_windowId); - event.SetInt(GetSelection()); - event.SetEventObject(this); - event.SetString(GetStringSelection()); - ProcessCommand(event); - - return TRUE; - } - else if (param == CBN_EDITCHANGE) - { - wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId); - event.SetString(GetValue()); - event.SetEventObject(this); - ProcessCommand(event); - - return TRUE; - } - else - return FALSE; -*/ - return FALSE; -} +MRESULT EXPENTRY wxComboEditWndProc( HWND hWnd + ,UINT uMessage + ,MPARAM wParam + ,MPARAM lParam + ); +// +// The pointer to standard wnd proc +// +static WXFARPROC gfnWndprocEdit = (WXFARPROC)NULL; -bool wxComboBox::Create(wxWindow *parent, wxWindowID id, - const wxString& value, - const wxPoint& pos, - const wxSize& size, - int n, const wxString choices[], - long style, - const wxValidator& validator, - const wxString& name) +bool wxComboBox::OS2Command( WXUINT uParam, WXWORD WXUNUSED(wId) ) { - SetName(name); - SetValidator(validator); - if (parent) parent->AddChild(this); - SetBackgroundColour(parent->GetBackgroundColour()) ; - SetForegroundColour(parent->GetForegroundColour()) ; - - m_windowStyle = style; - - if ( id == -1 ) - m_windowId = (int)NewControlId(); - else - m_windowId = id; - - int x = pos.x; - int y = pos.y; - int width = size.x; - int height = size.y; -// TODO: -/* - long msStyle = WS_CHILD | WS_TABSTOP | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | - CBS_NOINTEGRALHEIGHT; - - if (m_windowStyle & wxCB_READONLY) - msStyle |= CBS_DROPDOWNLIST; - else if (m_windowStyle & wxCB_SIMPLE) - msStyle |= CBS_SIMPLE; // A list (shown always) and edit control - else - msStyle |= CBS_DROPDOWN; - - if (m_windowStyle & wxCB_SORT) - msStyle |= CBS_SORT; - - bool want3D; - WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D) ; - - // Even with extended styles, need to combine with WS_BORDER - // for them to look right. - if ( want3D || wxStyleHasBorder(m_windowStyle) ) - msStyle |= WS_BORDER; - - m_hWnd = (WXHWND)::CreateWindowEx(exStyle, wxT("COMBOBOX"), NULL, - msStyle, - 0, 0, 0, 0, (HWND) parent->GetHWND(), (HMENU)m_windowId, - wxGetInstance(), NULL); - - wxCHECK_MSG( m_hWnd, FALSE, wxT("Failed to create combobox") ); - - // Subclass again for purposes of dialog editing mode - SubclassWin(m_hWnd); - - SetFont(parent->GetFont()); - int i; - for (i = 0; i < n; i++) - { - Append(choices[i]); - } - - SetSelection(i); - - SetSize(x, y, width, height); - if ( !value.IsEmpty() ) - { - SetValue(value); - } -*/ - return TRUE; -} + long lSel = GetSelection(); + wxString sValue; -void wxComboBox::SetValue(const wxString& value) -{ - // If newlines are denoted by just 10, must stick 13 in front. - int singletons = 0; - int len = value.Length(); - int i; - for (i = 0; i < len; i ++) - { - if ((i > 0) && (value[i] == 10) && (value[i-1] != 13)) - singletons ++; - } - if (singletons > 0) - { - wxChar *tmp = new wxChar[len + singletons + 1]; - int j = 0; - for (i = 0; i < len; i ++) + switch (uParam) { - if ((i > 0) && (value[i] == 10) && (value[i-1] != 13)) - { - tmp[j] = 13; - j ++; - } - tmp[j] = value[i]; - j ++; + case CBN_LBSELECT: + if (lSel > -1) + { + wxCommandEvent vEvent( wxEVT_COMMAND_COMBOBOX_SELECTED, GetId() ); + + vEvent.SetInt(lSel); + vEvent.SetEventObject(this); + vEvent.SetString(GetStringSelection()); + + ProcessCommand(vEvent); + } + break; + + case CBN_EFCHANGE: + { + wxCommandEvent vEvent( wxEVT_COMMAND_TEXT_UPDATED, GetId() ); + + if (lSel == -1L) + sValue = GetValue(); + else + sValue = GetStringSelection(); + vEvent.SetString(sValue); + vEvent.SetEventObject(this); + ProcessCommand(vEvent); + } + break; } - tmp[j] = 0; -// SetWindowText(GetHwnd(), tmp); - delete[] tmp; - } -// else -// SetWindowText(GetHwnd(), value); -} - -// Clipboard operations -void wxComboBox::Copy() -{ - HWND hWnd = GetHwnd(); -// SendMessage(hWnd, WM_COPY, 0, 0L); -} - -void wxComboBox::Cut() + // + // There is no return value for the CBN_ notifications, so always return + // false from here to pass the message to DefWindowProc() + // + return false; +} // end of wxComboBox::OS2Command + +bool wxComboBox::Create( + wxWindow* pParent +, wxWindowID vId +, const wxString& rsValue +, const wxPoint& rPos +, const wxSize& rSize +, const wxArrayString& asChoices +, long lStyle +, const wxValidator& rValidator +, const wxString& rsName +) { - HWND hWnd = GetHwnd(); -// SendMessage(hWnd, WM_CUT, 0, 0L); -} + wxCArrayString chs(asChoices); -void wxComboBox::Paste() -{ - HWND hWnd = GetHwnd(); -// SendMessage(hWnd, WM_PASTE, 0, 0L); + return Create(pParent, vId, rsValue, rPos, rSize, chs.GetCount(), + chs.GetStrings(), lStyle, rValidator, rsName); } -void wxComboBox::SetEditable(bool editable) +bool wxComboBox::Create( + wxWindow* pParent +, wxWindowID vId +, const wxString& rsValue +, const wxPoint& rPos +, const wxSize& rSize +, int n +, const wxString asChoices[] +, long lStyle +, const wxValidator& rValidator +, const wxString& rsName +) { - // Can't implement in MSW? -// HWND hWnd = GetHwnd(); -// SendMessage(hWnd, EM_SETREADONLY, (WPARAM)!editable, (LPARAM)0L); -} + m_isShown = false; + + if (!CreateControl( pParent + ,vId + ,rPos + ,rSize + ,lStyle + ,rValidator + ,rsName + )) + return false; + + // + // Get the right style + // + long lSstyle = 0L; + + lSstyle = WS_TABSTOP | + WS_VISIBLE; + + // clipping siblings does not yet work + // if (lStyle & wxCLIP_SIBLINGS ) + // lSstyle |= WS_CLIPSIBLINGS; + if (lStyle & wxCB_READONLY) + lSstyle |= CBS_DROPDOWNLIST; + else if (lStyle & wxCB_SIMPLE) + lSstyle |= CBS_SIMPLE; // A list (shown always) and edit control + else + lSstyle |= CBS_DROPDOWN; + + + 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(asChoices[i]); + } -void wxComboBox::SetInsertionPoint(long pos) -{ -/* - HWND hWnd = GetHwnd(); - SendMessage(hWnd, EM_SETSEL, pos, pos); - SendMessage(hWnd, EM_SCROLLCARET, (WPARAM)0, (LPARAM)0); - char *nothing = ""; - SendMessage(hWnd, EM_REPLACESEL, 0, (LPARAM)nothing); -*/ -} + SetSize( rPos.x + ,rPos.y + ,rSize.x + ,rSize.y + ); -void wxComboBox::SetInsertionPointEnd() -{ -/* - long pos = GetLastPosition(); - SetInsertionPoint(pos); -*/ -} + // Set height to use with sizers i.e. without the dropdown listbox + wxFont vFont = GetFont(); + int nEditHeight; + wxGetCharSize( GetHWND(), NULL, &nEditHeight, &vFont ); + nEditHeight = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nEditHeight); + SetInitialSize(wxSize(-1,nEditHeight+4)); // +2x2 for the border -long wxComboBox::GetInsertionPoint() const + if (!rsValue.empty()) + { + SetValue(rsValue); + } + gfnWndprocEdit = (WXFARPROC)::WinSubclassWindow( (HWND)GetHwnd() + ,(PFNWP)wxComboEditWndProc + ); + ::WinSetWindowULong(GetHwnd(), QWL_USER, (ULONG)this); + Show(true); + return true; +} // end of wxComboBox::Create + +wxString wxComboBox::GetValue() const { -/* - DWORD Pos=(DWORD)SendMessage(GetHwnd(), EM_GETSEL, 0, 0L); - return Pos&0xFFFF; -*/ - return 0; + return HasFlag(wxCB_READONLY) ? GetStringSelection() + : wxTextEntry::GetValue(); } -long wxComboBox::GetLastPosition() const +void wxComboBox::SetValue(const wxString& value) { -/* - HWND hWnd = GetHwnd(); - - // Will always return a number > 0 (according to docs) - int noLines = (int)SendMessage(hWnd, EM_GETLINECOUNT, (WPARAM)0, (LPARAM)0L); - - // This gets the char index for the _beginning_ of the last line - int charIndex = (int)SendMessage(hWnd, EM_LINEINDEX, (WPARAM)(noLines-1), (LPARAM)0L); - - // Get number of characters in the last line. We'll add this to the character - // index for the last line, 1st position. - int lineLength = (int)SendMessage(hWnd, EM_LINELENGTH, (WPARAM)charIndex, (LPARAM)0L); - - return (long)(charIndex + lineLength); -*/ - return 0; + if ( HasFlag(wxCB_READONLY) ) + SetStringSelection(value); + else + wxTextEntry::SetValue(value); } -void wxComboBox::Replace(long from, long to, const wxString& value) +void wxComboBox::Clear() { -#if wxUSE_CLIPBOARD - HWND hWnd = GetHwnd(); - long fromChar = from; - long toChar = to; - - // Set selection and remove it -// SendMessage(hWnd, CB_SETEDITSEL, fromChar, toChar); -// SendMessage(hWnd, WM_CUT, (WPARAM)0, (LPARAM)0); - - // Now replace with 'value', by pasting. - wxSetClipboardData(wxDF_TEXT, (wxObject *)(const wxChar *)value, 0, 0); - - // Paste into edit control -// SendMessage(hWnd, WM_PASTE, (WPARAM)0, (LPARAM)0L); -#endif + wxChoice::Clear(); + if ( !HasFlag(wxCB_READONLY) ) + wxTextEntry::Clear(); } -void wxComboBox::Remove(long from, long to) +bool wxComboBox::IsEditable() const { - HWND hWnd = GetHwnd(); - long fromChar = from; - long toChar = to; - - // Cut all selected text -// SendMessage(hWnd, CB_SETEDITSEL, fromChar, toChar); -// SendMessage(hWnd, WM_CUT, (WPARAM)0, (LPARAM)0); + return !HasFlag(wxCB_READONLY) && wxTextEntry::IsEditable(); } -void wxComboBox::SetSelection(long from, long to) +bool wxComboBox::ProcessEditMsg( + WXUINT uMsg +, WXWPARAM wParam +, WXLPARAM lParam) { - HWND hWnd = GetHwnd(); - long fromChar = from; - long toChar = to; - // if from and to are both -1, it means - // (in wxWindows) that all text should be selected. - // This translates into Windows convention - if ((from == -1) && (to == -1)) + SHORT vFlag; + switch (uMsg) { - fromChar = 0; - toChar = -1; + case WM_CHAR: + vFlag = SHORT1FROMMP(wParam); + switch(vFlag) + { + case KC_CHAR: + return (HandleChar( wParam + ,lParam + ,true /* isASCII */ + )); + + case KC_PREVDOWN: + return (HandleKeyDown( wParam + ,lParam + )); + + case KC_KEYUP: + return (HandleKeyUp( wParam + ,lParam + )); + } + break; + + case WM_SETFOCUS: + if (SHORT1FROMMP((MPARAM)lParam) == TRUE) + return(HandleSetFocus((WXHWND)(HWND)wParam)); + else + return(HandleKillFocus((WXHWND)(HWND)wParam)); } - -// SendMessage(hWnd, CB_SETEDITSEL, (WPARAM)fromChar, (LPARAM)toChar); -// SendMessage(hWnd, EM_SCROLLCARET, (WPARAM)0, (LPARAM)0); -} - -void wxComboBox::DoSetSize(int x, int y, - int width, int height, - int sizeFlags) + return false; +} // end of wxComboBox::ProcessEditMsg + +MRESULT EXPENTRY wxComboEditWndProc( + HWND hWnd +, UINT uMessage +, MPARAM wParam +, MPARAM lParam +) { - wxControl::DoSetSize(x, y, width, height, sizeFlags); -} + switch (uMessage) + { + // + // Forward some messages to the combobox + // + case WM_SETFOCUS: + case WM_CHAR: + { + wxComboBox* pCombo = (wxComboBox *)::WinQueryWindowULong( hWnd + ,QWL_USER + ); + + if (pCombo->ProcessEditMsg( uMessage + ,wParam + ,lParam + )) + return ((MRESULT)0); + } + break; + + // + // TODO: Deal with tooltips here + // + } + return (gfnWndprocEdit(hWnd, (ULONG)uMessage, (MPARAM)wParam, (MPARAM)lParam)); +} // end of wxComboEditWndProc #endif // wxUSE_COMBOBOX -