home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / src / os2 / combobox.cpp < prev    next >
C/C++ Source or Header  |  2002-09-04  |  14KB  |  471 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        combobox.cpp
  3. // Purpose:     wxComboBox class
  4. // Author:      David Webster
  5. // Modified by:
  6. // Created:     10/13/99
  7. // RCS-ID:      $Id: COMBOBOX.CPP,v 1.17 2002/09/03 04:47:39 DW Exp $
  8. // Copyright:   (c) David Webster
  9. // Licence:     wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. #include "wx/combobox.h"
  13.  
  14. // For compilers that support precompilation, includes "wx.h".
  15. #include "wx/wxprec.h"
  16.  
  17. #ifndef WX_PRECOMP
  18.     #include "wx/setup.h"
  19.     #include "wx/settings.h"
  20. #endif
  21.  
  22. #if wxUSE_COMBOBOX
  23.  
  24. #include "wx/combobox.h"
  25. #include "wx/clipbrd.h"
  26. #include "wx/os2/private.h"
  27.  
  28. #define OWNER_DRAWN_LISTBOX_EXTRA_SPACE    (1)
  29.  
  30. MRESULT EXPENTRY wxComboEditWndProc( HWND   hWnd
  31.                                     ,UINT   uMessage
  32.                                     ,MPARAM wParam
  33.                                     ,MPARAM lParam
  34.                                    );
  35. //
  36. // The pointer to standard wnd proc
  37. //
  38. static WXFARPROC gfnWndprocEdit     = (WXFARPROC)NULL;
  39.  
  40. IMPLEMENT_DYNAMIC_CLASS(wxComboBox, wxControl)
  41.  
  42. bool wxComboBox::OS2Command(
  43.   WXUINT                            uParam
  44. , WXWORD                            WXUNUSED(wId)
  45. )
  46. {
  47.     long                            lSel = -1L;
  48.     wxString                        sValue;
  49.  
  50.     switch (uParam)
  51.     {
  52.         case CBN_LBSELECT:
  53.             if (GetSelection() > -1)
  54.             {
  55.                 wxCommandEvent      vEvent( wxEVT_COMMAND_COMBOBOX_SELECTED
  56.                                            ,GetId()
  57.                                           );
  58.  
  59.                 vEvent.SetInt(GetSelection());
  60.                 vEvent.SetEventObject(this);
  61.                 vEvent.SetString((char*)GetStringSelection().c_str());
  62.                 ProcessCommand(vEvent);
  63.             }
  64.             break;
  65.  
  66.         case CBN_EFCHANGE:
  67.             {
  68.                 wxCommandEvent      vEvent( wxEVT_COMMAND_TEXT_UPDATED
  69.                                            ,GetId()
  70.                                           );
  71.  
  72.                 if (lSel == -1L)
  73.                     sValue = GetValue();
  74.                 else
  75.                     SetValue(sValue);
  76.                 vEvent.SetString((char*)GetValue().c_str());
  77.                 vEvent.SetEventObject(this);
  78.                 ProcessCommand(vEvent);
  79.             }
  80.             break;
  81.     }
  82.     //
  83.     // There is no return value for the CBN_ notifications, so always return
  84.     // FALSE from here to pass the message to DefWindowProc()
  85.     //
  86.     return FALSE;
  87. } // end of wxComboBox::OS2Command
  88.  
  89. bool wxComboBox::Create(
  90.   wxWindow*                         pParent
  91. , wxWindowID                        vId
  92. , const wxString&                   rsValue
  93. , const wxPoint&                    rPos
  94. , const wxSize&                     rSize
  95. , int                               n
  96. , const wxString                    asChoices[]
  97. , long                              lStyle
  98. #if wxUSE_VALIDATORS
  99. , const wxValidator&                rValidator
  100. #endif
  101. , const wxString&                   rsName
  102. )
  103. {
  104.     m_isShown = FALSE;
  105.  
  106.     if (!CreateControl( pParent
  107.                        ,vId
  108.                        ,rPos
  109.                        ,rSize
  110.                        ,lStyle
  111. #if wxUSE_VALIDATORS
  112.                        ,rValidator
  113. #endif
  114.                        ,rsName
  115.                       ))
  116.         return FALSE;
  117.  
  118.     //
  119.     // Get the right style
  120.     //
  121.     long                            lSstyle = 0L;
  122.  
  123.     lSstyle = WS_TABSTOP   |
  124.               WS_VISIBLE;
  125.  
  126.     if (lStyle & wxCLIP_SIBLINGS )
  127.         lSstyle |= WS_CLIPSIBLINGS;
  128.     if (lStyle & wxCB_READONLY)
  129.         lSstyle |= CBS_DROPDOWNLIST;
  130.     else if (lStyle & wxCB_SIMPLE)
  131.         lSstyle |= CBS_SIMPLE; // A list (shown always) and edit control
  132.     else
  133.         lSstyle |= CBS_DROPDOWN;
  134.  
  135.  
  136.     if (!OS2CreateControl( "COMBOBOX"
  137.                           ,lSstyle
  138.                          ))
  139.         return FALSE;
  140.  
  141.     //
  142.     // A choice/combobox normally has a white background (or other, depending
  143.     // on global settings) rather than inheriting the parent's background colour.
  144.     //
  145.     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
  146.  
  147.     SetFont(*wxSMALL_FONT);
  148.  
  149.     int                             i;
  150.     for (i = 0; i < n; i++)
  151.     {
  152.         Append(asChoices[i]);
  153.     }
  154.  
  155.     SetSize( rPos.x
  156.             ,rPos.y
  157.             ,rSize.x
  158.             ,rSize.y
  159.            );
  160.     if (!rsValue.IsEmpty())
  161.     {
  162.         SetValue(rsValue);
  163.     }
  164.     gfnWndprocEdit = (WXFARPROC)::WinSubclassWindow( (HWND)GetHwnd()
  165.                                                     ,(PFNWP)wxComboEditWndProc
  166.                                                    );
  167.     ::WinSetWindowULong(GetHwnd(), QWL_USER, (ULONG)this);
  168.     Show(TRUE);
  169.     return TRUE;
  170. } // end of wxComboBox::Create
  171.  
  172. void wxComboBox::SetValue(
  173.   const wxString&                   rsValue
  174. )
  175. {
  176.     //
  177.     // If newlines are denoted by just 10, must stick 13 in front.
  178.     //
  179.     int                             nSingletons = 0;
  180.     int                             nLen = rsValue.Length();
  181.     int                             i;
  182.  
  183.     for (i = 0; i < nLen; i ++)
  184.     {
  185.         if ((i > 0) && (rsValue[i] == 10) && (rsValue[i - 1] != 13))
  186.             nSingletons ++;
  187.     }
  188.     if (nSingletons > 0)
  189.     {
  190.         wxChar*                     zTmp = new wxChar[nLen + nSingletons + 1];
  191.         int                         j = 0;
  192.  
  193.         for (i = 0; i < nLen; i ++)
  194.         {
  195.             if ((i > 0) && (rsValue[i] == 10) && (rsValue[i - 1] != 13))
  196.             {
  197.                 zTmp[j] = 13;
  198.                 j++;
  199.             }
  200.             zTmp[j] = rsValue[i];
  201.             j++;
  202.         }
  203.         zTmp[j] = 0;
  204.         ::WinSetWindowText(GetHwnd(), zTmp);
  205.         delete[] zTmp;
  206.     }
  207.     else
  208.         ::WinSetWindowText(GetHwnd(), rsValue.c_str());
  209. } // end of wxComboBox::SetValue
  210.  
  211. //
  212. // Clipboard operations
  213. //
  214. void wxComboBox::Copy()
  215. {
  216.     HWND                            hWnd = GetHwnd();
  217.  
  218.     ::WinSendMsg(hWnd, EM_COPY, (MPARAM)0, (MPARAM)0);
  219. } // end of wxComboBox::Copy
  220.  
  221. void wxComboBox::Cut()
  222. {
  223.     HWND                            hWnd = GetHwnd();
  224.  
  225.     ::WinSendMsg(hWnd, EM_CUT, (MPARAM)0, (MPARAM)0);
  226. } // end of wxComboBox::Cut
  227.  
  228. void wxComboBox::Paste()
  229. {
  230.     HWND                            hWnd = GetHwnd();
  231.  
  232.     ::WinSendMsg(hWnd, EM_PASTE, (MPARAM)0, (MPARAM)0);
  233. } // end of wxComboBox::Paste
  234.  
  235. void wxComboBox::SetEditable(
  236.   bool                              bEditable
  237. )
  238. {
  239.     HWND                            hWnd = GetHwnd();
  240.  
  241.     ::WinSendMsg(hWnd, EM_SETREADONLY, (MPARAM)!bEditable, (MPARAM)0L);
  242. } // end of wxComboBox::SetEditable
  243.  
  244. void wxComboBox::SetInsertionPoint(
  245.   long                              lPos
  246. )
  247. {
  248.     HWND                            hWnd = GetHwnd();
  249.  
  250.     ::WinSendMsg(hWnd, EM_SETFIRSTCHAR, MPFROMLONG(lPos), (MPARAM)0);
  251. } // end of wxComboBox::SetInsertionPoint
  252.  
  253. void wxComboBox::SetInsertionPointEnd()
  254. {
  255.     long                            lPos = GetLastPosition();
  256.  
  257.     SetInsertionPoint(lPos);
  258. } // end of wxComboBox::SetInsertionPointEnd
  259.  
  260. long wxComboBox::GetInsertionPoint() const
  261. {
  262.     long                            lPos = LONGFROMMR(::WinSendMsg( GetHwnd()
  263.                                                                    ,LM_QUERYSELECTION
  264.                                                                    ,(MPARAM)0
  265.                                                                    ,(MPARAM)0
  266.                                                                   ));
  267.    if (lPos == LIT_NONE)
  268.         return wxNOT_FOUND;
  269.    return lPos;
  270. } // end of wxComboBox::GetInsertionPoint
  271.  
  272. long wxComboBox::GetLastPosition() const
  273. {
  274.     HWND                            hEditWnd = GetHwnd();
  275.     long                            lLineLength = 0L;
  276.     WNDPARAMS                       vParams;
  277.  
  278.     //
  279.     // Get number of characters in the last (only) line. We'll add this to the character
  280.     // index for the last line, 1st position.
  281.     //
  282.  
  283.  
  284.     vParams.fsStatus = WPM_CCHTEXT;
  285.     if (::WinSendMsg( GetHwnd()
  286.                      ,WM_QUERYWINDOWPARAMS
  287.                      ,&vParams
  288.                      ,0
  289.                     ))
  290.     {
  291.         lLineLength = (long)vParams.cchText;
  292.     }
  293.     else
  294.         lLineLength = 0L;
  295.     return lLineLength;
  296. } // end of wxComboBox::GetLastPosition
  297.  
  298. void wxComboBox::Replace(
  299.   long                              lFrom
  300. , long                              lTo
  301. , const wxString&                   rsValue
  302. )
  303. {
  304. #if wxUSE_CLIPBOARD
  305.     HWND                            hWnd = GetHwnd();
  306.     long                            lFromChar = lFrom;
  307.     long                            lToChar = lTo;
  308.  
  309.     //
  310.     // Set selection and remove it
  311.     //
  312.     ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lFrom, (USHORT)lTo), 0);
  313.     ::WinSendMsg(hWnd, EM_CUT, (MPARAM)0, (MPARAM)0);
  314.  
  315.     //
  316.     // Now replace with 'value', by pasting.
  317.     //
  318.     wxSetClipboardData( wxDF_TEXT
  319.                        ,(wxObject *)rsValue.c_str()
  320.                        ,0
  321.                        ,0
  322.                       );
  323.  
  324.     //
  325.     // Paste into edit control
  326.     //
  327.     ::WinSendMsg(hWnd, EM_PASTE, (MPARAM)0, (MPARAM)0L);
  328. #endif
  329. } // end of wxComboBox::Replace
  330.  
  331. void wxComboBox::Remove(
  332.   long                              lFrom
  333. , long                              lTo
  334. )
  335. {
  336. #if wxUSE_CLIPBOARD
  337.     HWND                            hWnd = GetHwnd();
  338.     long                            lFromChar = lFrom;
  339.     long                            lToChar = lTo;
  340.  
  341.     ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lFrom, (USHORT)lTo), 0);
  342.     ::WinSendMsg(hWnd, EM_CUT, (MPARAM)0, (MPARAM)0);
  343. #endif
  344. } // end of wxComboBox::Remove
  345.  
  346. void wxComboBox::SetSelection(
  347.   long                              lFrom
  348. , long                              lTo
  349. )
  350. {
  351.     HWND                            hWnd = GetHwnd();
  352.     long                            lFromChar = lFrom;
  353.     long                            lToChar = lTo;
  354.  
  355.     //
  356.     // If from and to are both -1, it means
  357.     // (in wxWindows) that all text should be selected.
  358.     // This translates into Windows convention
  359.     //
  360.     if ((lFrom == -1L) && (lTo == -1L))
  361.     {
  362.         lFromChar = 0;
  363.         lToChar = -1;
  364.     }
  365.  
  366.     ::WinSendMsg( hWnd
  367.                  ,EM_SETSEL
  368.                  ,MPFROM2SHORT((USHORT)lFromChar, (USHORT)lToChar)
  369.                  ,(MPARAM)0
  370.                 );
  371. } // end of wxComboBox::SetSelection
  372.  
  373. void wxComboBox::DoSetSize(
  374.   int                               nX
  375. , int                               nY
  376. , int                               nWidth
  377. , int                               nHeight
  378. , int                               nSizeFlags
  379. )
  380. {
  381.     wxControl::DoSetSize( nX
  382.                          ,nY
  383.                          ,nWidth
  384.                          ,nHeight
  385.                          ,nSizeFlags
  386.                         );
  387. } // end of wxComboBox::DoSetSize
  388.  
  389. bool wxComboBox::ProcessEditMsg(
  390.   WXUINT                            uMsg
  391. , WXWPARAM                          wParam
  392. , WXLPARAM                          lParam)
  393. {
  394.     SHORT                           vFlag;
  395.     switch (uMsg)
  396.     {
  397.         case WM_CHAR:
  398.             vFlag = SHORT1FROMMP(wParam);
  399.             switch(vFlag)
  400.             {
  401.                 case KC_CHAR:
  402.                     return (HandleChar( wParam
  403.                                        ,lParam
  404.                                        ,TRUE /* isASCII */
  405.                                       ));
  406.  
  407.                 case KC_PREVDOWN:
  408.                     return (HandleKeyDown( wParam
  409.                                           ,lParam
  410.                                          ));
  411.  
  412.                 case KC_KEYUP:
  413.                     return (HandleKeyUp( wParam
  414.                                         ,lParam
  415.                                        ));
  416.             }
  417.             break;
  418.  
  419.         case WM_SETFOCUS:
  420.             if (SHORT1FROMMP((MPARAM)lParam) == TRUE)
  421.                 return(HandleSetFocus((WXHWND)(HWND)wParam));
  422.             else
  423.                 return(HandleKillFocus((WXHWND)(HWND)wParam));
  424.             break;
  425.     }
  426.     return FALSE;
  427. } // end of WinGuiBase_CComboBox::ProcessEditMsg
  428.  
  429. MRESULT EXPENTRY wxComboEditWndProc(
  430.   HWND                              hWnd
  431. , UINT                              uMessage
  432. , MPARAM                            wParam
  433. , MPARAM                            lParam
  434. )
  435. {
  436.     HWND                            hWndCombo;
  437.     wxWindow*                       pWin = NULL;
  438.  
  439.     hWndCombo = ::WinQueryWindow(hWnd, QW_PARENT);
  440.     pWin = (wxWindow*)wxFindWinFromHandle((WXHWND)hWndCombo);
  441.     switch (uMessage)
  442.     {
  443.         //
  444.         // Forward some messages to the combobox
  445.         //
  446.         case WM_SETFOCUS:
  447.         case WM_CHAR:
  448.             {
  449.                 wxComboBox*         pCombo = wxDynamicCast( pWin
  450.                                                            ,wxComboBox
  451.                                                           );
  452.  
  453.                 if (pCombo->ProcessEditMsg( uMessage
  454.                                            ,wParam
  455.                                            ,lParam
  456.                                           ))
  457.                     return ((MRESULT)0);
  458.             }
  459.             break;
  460.  
  461.         //
  462.         // TODO: Deal with tooltips here
  463.         //
  464.     }
  465.     return (gfnWndprocEdit(hWnd, (ULONG)uMessage, (MPARAM)wParam, (MPARAM)lParam));
  466. } // end of wxComboEditWndProc
  467.  
  468. #endif
  469.  // wxUSE_COMBOBOX
  470.  
  471.