home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / os2 / combobox.cpp < prev    next >
C/C++ Source or Header  |  2002-12-27  |  13KB  |  438 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.2.2 2002/12/27 14:49:34 JS 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. , const wxValidator&                rValidator
  99. , const wxString&                   rsName
  100. )
  101. {
  102.     m_isShown = FALSE;
  103.  
  104.     if (!CreateControl( pParent
  105.                        ,vId
  106.                        ,rPos
  107.                        ,rSize
  108.                        ,lStyle
  109.                        ,rValidator
  110.                        ,rsName
  111.                       ))
  112.         return FALSE;
  113.  
  114.     //
  115.     // Get the right style
  116.     //
  117.     long                            lSstyle = 0L;
  118.  
  119.     lSstyle = WS_TABSTOP   |
  120.               WS_VISIBLE;
  121.  
  122.     if (lStyle & wxCLIP_SIBLINGS )
  123.         lSstyle |= WS_CLIPSIBLINGS;
  124.     if (lStyle & wxCB_READONLY)
  125.         lSstyle |= CBS_DROPDOWNLIST;
  126.     else if (lStyle & wxCB_SIMPLE)
  127.         lSstyle |= CBS_SIMPLE; // A list (shown always) and edit control
  128.     else
  129.         lSstyle |= CBS_DROPDOWN;
  130.  
  131.  
  132.     if (!OS2CreateControl( "COMBOBOX"
  133.                           ,lSstyle
  134.                          ))
  135.         return FALSE;
  136.  
  137.     //
  138.     // A choice/combobox normally has a white background (or other, depending
  139.     // on global settings) rather than inheriting the parent's background colour.
  140.     //
  141.     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
  142.  
  143.     SetFont(*wxSMALL_FONT);
  144.  
  145.     int                             i;
  146.     for (i = 0; i < n; i++)
  147.     {
  148.         Append(asChoices[i]);
  149.     }
  150.  
  151.     SetSize( rPos.x
  152.             ,rPos.y
  153.             ,rSize.x
  154.             ,rSize.y
  155.            );
  156.     if (!rsValue.IsEmpty())
  157.     {
  158.         SetValue(rsValue);
  159.     }
  160.     gfnWndprocEdit = (WXFARPROC)::WinSubclassWindow( (HWND)GetHwnd()
  161.                                                     ,(PFNWP)wxComboEditWndProc
  162.                                                    );
  163.     ::WinSetWindowULong(GetHwnd(), QWL_USER, (ULONG)this);
  164.     Show(TRUE);
  165.     return TRUE;
  166. } // end of wxComboBox::Create
  167.  
  168. void wxComboBox::SetValue(
  169.   const wxString&                   rsValue
  170. )
  171. {
  172.     if ( HasFlag(wxCB_READONLY) )
  173.         SetStringSelection(rsValue);
  174.     else
  175.         ::WinSetWindowText(GetHwnd(), rsValue.c_str());
  176. } // end of wxComboBox::SetValue
  177.  
  178. //
  179. // Clipboard operations
  180. //
  181. void wxComboBox::Copy()
  182. {
  183.     HWND                            hWnd = GetHwnd();
  184.  
  185.     ::WinSendMsg(hWnd, EM_COPY, (MPARAM)0, (MPARAM)0);
  186. } // end of wxComboBox::Copy
  187.  
  188. void wxComboBox::Cut()
  189. {
  190.     HWND                            hWnd = GetHwnd();
  191.  
  192.     ::WinSendMsg(hWnd, EM_CUT, (MPARAM)0, (MPARAM)0);
  193. } // end of wxComboBox::Cut
  194.  
  195. void wxComboBox::Paste()
  196. {
  197.     HWND                            hWnd = GetHwnd();
  198.  
  199.     ::WinSendMsg(hWnd, EM_PASTE, (MPARAM)0, (MPARAM)0);
  200. } // end of wxComboBox::Paste
  201.  
  202. void wxComboBox::SetEditable(
  203.   bool                              bEditable
  204. )
  205. {
  206.     HWND                            hWnd = GetHwnd();
  207.  
  208.     ::WinSendMsg(hWnd, EM_SETREADONLY, (MPARAM)!bEditable, (MPARAM)0L);
  209. } // end of wxComboBox::SetEditable
  210.  
  211. void wxComboBox::SetInsertionPoint(
  212.   long                              lPos
  213. )
  214. {
  215.     HWND                            hWnd = GetHwnd();
  216.  
  217.     ::WinSendMsg(hWnd, EM_SETFIRSTCHAR, MPFROMLONG(lPos), (MPARAM)0);
  218. } // end of wxComboBox::SetInsertionPoint
  219.  
  220. void wxComboBox::SetInsertionPointEnd()
  221. {
  222.     long                            lPos = GetLastPosition();
  223.  
  224.     SetInsertionPoint(lPos);
  225. } // end of wxComboBox::SetInsertionPointEnd
  226.  
  227. long wxComboBox::GetInsertionPoint() const
  228. {
  229.     long                            lPos = LONGFROMMR(::WinSendMsg( GetHwnd()
  230.                                                                    ,LM_QUERYSELECTION
  231.                                                                    ,(MPARAM)0
  232.                                                                    ,(MPARAM)0
  233.                                                                   ));
  234.    if (lPos == LIT_NONE)
  235.         return wxNOT_FOUND;
  236.    return lPos;
  237. } // end of wxComboBox::GetInsertionPoint
  238.  
  239. long wxComboBox::GetLastPosition() const
  240. {
  241.     HWND                            hEditWnd = GetHwnd();
  242.     long                            lLineLength = 0L;
  243.     WNDPARAMS                       vParams;
  244.  
  245.     //
  246.     // Get number of characters in the last (only) line. We'll add this to the character
  247.     // index for the last line, 1st position.
  248.     //
  249.  
  250.  
  251.     vParams.fsStatus = WPM_CCHTEXT;
  252.     if (::WinSendMsg( GetHwnd()
  253.                      ,WM_QUERYWINDOWPARAMS
  254.                      ,&vParams
  255.                      ,0
  256.                     ))
  257.     {
  258.         lLineLength = (long)vParams.cchText;
  259.     }
  260.     else
  261.         lLineLength = 0L;
  262.     return lLineLength;
  263. } // end of wxComboBox::GetLastPosition
  264.  
  265. void wxComboBox::Replace(
  266.   long                              lFrom
  267. , long                              lTo
  268. , const wxString&                   rsValue
  269. )
  270. {
  271. #if wxUSE_CLIPBOARD
  272.     HWND                            hWnd = GetHwnd();
  273.     long                            lFromChar = lFrom;
  274.     long                            lToChar = lTo;
  275.  
  276.     //
  277.     // Set selection and remove it
  278.     //
  279.     ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lFrom, (USHORT)lTo), 0);
  280.     ::WinSendMsg(hWnd, EM_CUT, (MPARAM)0, (MPARAM)0);
  281.  
  282.     //
  283.     // Now replace with 'value', by pasting.
  284.     //
  285.     wxSetClipboardData( wxDF_TEXT
  286.                        ,(wxObject *)rsValue.c_str()
  287.                        ,0
  288.                        ,0
  289.                       );
  290.  
  291.     //
  292.     // Paste into edit control
  293.     //
  294.     ::WinSendMsg(hWnd, EM_PASTE, (MPARAM)0, (MPARAM)0L);
  295. #endif
  296. } // end of wxComboBox::Replace
  297.  
  298. void wxComboBox::Remove(
  299.   long                              lFrom
  300. , long                              lTo
  301. )
  302. {
  303. #if wxUSE_CLIPBOARD
  304.     HWND                            hWnd = GetHwnd();
  305.     long                            lFromChar = lFrom;
  306.     long                            lToChar = lTo;
  307.  
  308.     ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lFrom, (USHORT)lTo), 0);
  309.     ::WinSendMsg(hWnd, EM_CUT, (MPARAM)0, (MPARAM)0);
  310. #endif
  311. } // end of wxComboBox::Remove
  312.  
  313. void wxComboBox::SetSelection(
  314.   long                              lFrom
  315. , long                              lTo
  316. )
  317. {
  318.     HWND                            hWnd = GetHwnd();
  319.     long                            lFromChar = lFrom;
  320.     long                            lToChar = lTo;
  321.  
  322.     //
  323.     // If from and to are both -1, it means
  324.     // (in wxWindows) that all text should be selected.
  325.     // This translates into Windows convention
  326.     //
  327.     if ((lFrom == -1L) && (lTo == -1L))
  328.     {
  329.         lFromChar = 0;
  330.         lToChar = -1;
  331.     }
  332.  
  333.     ::WinSendMsg( hWnd
  334.                  ,EM_SETSEL
  335.                  ,MPFROM2SHORT((USHORT)lFromChar, (USHORT)lToChar)
  336.                  ,(MPARAM)0
  337.                 );
  338. } // end of wxComboBox::SetSelection
  339.  
  340. void wxComboBox::DoSetSize(
  341.   int                               nX
  342. , int                               nY
  343. , int                               nWidth
  344. , int                               nHeight
  345. , int                               nSizeFlags
  346. )
  347. {
  348.     wxControl::DoSetSize( nX
  349.                          ,nY
  350.                          ,nWidth
  351.                          ,nHeight
  352.                          ,nSizeFlags
  353.                         );
  354. } // end of wxComboBox::DoSetSize
  355.  
  356. bool wxComboBox::ProcessEditMsg(
  357.   WXUINT                            uMsg
  358. , WXWPARAM                          wParam
  359. , WXLPARAM                          lParam)
  360. {
  361.     SHORT                           vFlag;
  362.     switch (uMsg)
  363.     {
  364.         case WM_CHAR:
  365.             vFlag = SHORT1FROMMP(wParam);
  366.             switch(vFlag)
  367.             {
  368.                 case KC_CHAR:
  369.                     return (HandleChar( wParam
  370.                                        ,lParam
  371.                                        ,TRUE /* isASCII */
  372.                                       ));
  373.  
  374.                 case KC_PREVDOWN:
  375.                     return (HandleKeyDown( wParam
  376.                                           ,lParam
  377.                                          ));
  378.  
  379.                 case KC_KEYUP:
  380.                     return (HandleKeyUp( wParam
  381.                                         ,lParam
  382.                                        ));
  383.             }
  384.             break;
  385.  
  386.         case WM_SETFOCUS:
  387.             if (SHORT1FROMMP((MPARAM)lParam) == TRUE)
  388.                 return(HandleSetFocus((WXHWND)(HWND)wParam));
  389.             else
  390.                 return(HandleKillFocus((WXHWND)(HWND)wParam));
  391.             break;
  392.     }
  393.     return FALSE;
  394. } // end of WinGuiBase_CComboBox::ProcessEditMsg
  395.  
  396. MRESULT EXPENTRY wxComboEditWndProc(
  397.   HWND                              hWnd
  398. , UINT                              uMessage
  399. , MPARAM                            wParam
  400. , MPARAM                            lParam
  401. )
  402. {
  403.     HWND                            hWndCombo;
  404.     wxWindow*                       pWin = NULL;
  405.  
  406.     hWndCombo = ::WinQueryWindow(hWnd, QW_PARENT);
  407.     pWin = (wxWindow*)wxFindWinFromHandle((WXHWND)hWndCombo);
  408.     switch (uMessage)
  409.     {
  410.         //
  411.         // Forward some messages to the combobox
  412.         //
  413.         case WM_SETFOCUS:
  414.         case WM_CHAR:
  415.             {
  416.                 wxComboBox*         pCombo = wxDynamicCast( pWin
  417.                                                            ,wxComboBox
  418.                                                           );
  419.  
  420.                 if (pCombo->ProcessEditMsg( uMessage
  421.                                            ,wParam
  422.                                            ,lParam
  423.                                           ))
  424.                     return ((MRESULT)0);
  425.             }
  426.             break;
  427.  
  428.         //
  429.         // TODO: Deal with tooltips here
  430.         //
  431.     }
  432.     return (gfnWndprocEdit(hWnd, (ULONG)uMessage, (MPARAM)wParam, (MPARAM)lParam));
  433. } // end of wxComboEditWndProc
  434.  
  435. #endif
  436.  // wxUSE_COMBOBOX
  437.  
  438.