Announcement

Collapse
No announcement yet.

Textbox with "X" to clear content

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Textbox with "X" to clear content

    Is there a way to display a label or icon inside/on top of a textbox?

    Click image for larger version

Name:	xsample.png
Views:	127
Size:	3.6 KB
ID:	783900
    I would like to create a input control that works like on a webpage using HTML5 <input type='search'>
    HTML example at: www.timpex.se/pbsample.html

    Below is what I have as a starting point, but as you see it is far from something that works.
    /Mikael

    Code:
    #COMPILE EXE
    #DIM ALL
    #INCLUDE "win32api.inc"
    
    %IDtbox = 1000
    %IDtext = 1001
    
    FUNCTION PBMAIN() AS LONG
       LOCAL hDlg AS DWORD
       DIALOG DEFAULT FONT "Segoe UI", 9, 0, %DEFAULT_CHARSET
       DIALOG NEW PIXELS, 0, "Hover test",400,300,200,100, %WS_OVERLAPPEDWINDOW TO hDlg
       CONTROL ADD TEXTBOX, hDlg, %IDtbox, "Some text",  10 ,10,100,20, %SS_NOTIFY OR %WS_BORDER
       CONTROL ADD LABEL, hDlg  , %IDtext, "X", 110,10, 10,20, %SS_NOTIFY OR %SS_CENTER OR %SS_CENTERIMAGE
       CONTROL HIDE hDlg, %IDtext
       DIALOG SHOW MODAL hDlg CALL DlgProc
    END FUNCTION
    
    CALLBACK FUNCTION DlgProc() AS LONG
      LOCAL MouseOver AS DWORD
      STATIC Tracker AS BYTE
       SELECT CASE CB.MSG
          CASE %WM_SETCURSOR
             MouseOver = GetDlgCtrlId(CB.WPARAM)
             SELECT CASE MouseOver
               CASE %IDtbox
                IF Tracker = 0 THEN             'To be added later, check if textbox empty
                  Tracker = 1
                  CONTROL NORMALIZE CB.HNDL, %IDtext
                END IF
               CASE ELSE
                IF Tracker = 1 THEN
                  Tracker = 0
                  CONTROL HIDE CB.HNDL, %IDtext
                END IF
             END SELECT
          CASE %WM_COMMAND
    '         'If I could get the "X" accessible inside the textbox, clears checkbox
    '         IF CB.CTL = %IDtext AND CB.CTLMSG = %STN_CLICKED THEN CONTROL SET TEXT CB.HNDL, %IDtbox, ""
       END SELECT
    END FUNCTION

  • #2
    No mouseover to make "X" appear, but try this:
    Code:
    #compile exe
    #dim all
    #include "win32api.inc"
    
    %IDtbox = 1000
    %IDtext = 1001
    %ID_ClearBtn = 1002
    function pbmain() as long
       local hDlg as dword
       dialog default font "Segoe UI", 9, 0, %DEFAULT_CHARSET
       dialog new pixels, 0, "Hover test",400,300,200,100, %ws_overlappedwindow to hDlg
       control add textbox, hDlg, %IDtbox, "Some text",  10 ,10,100,20 'SS_NOTIFY not a
                                               'textbox style, it equals %ES_NOHIDESEL
      ' CONTROL ADD LABEL, hDlg  , %IDtext, "X", 110,10, 10,20, %SS_NOTIFY OR %SS_CENTER OR %SS_CENTERIMAGE
      ' CONTROL HIDE hDlg, %IDtext
      control add button, hDlg, %ID_ClearBtn, "X", 110, 11, 18, 18, %bs_center or %bs_flat or _
         %bs_vcenter, %ws_ex_left
       dialog show modal hDlg call DlgProc
    end function
    
    callback function DlgProc() as long
      local MouseOver as dword
      static Tracker as byte
       select case cb.msg
          case %WM_SETCURSOR
             MouseOver = GetDlgCtrlId(cb.wparam)
             select case MouseOver
               case %IDtbox
                if Tracker = 0 then             'To be added later, check if textbox empty
                  Tracker = 1
                  control normalize cb.hndl, %IDtext
                end if
               case else
                if Tracker = 1 then
                  Tracker = 0
                  control hide cb.hndl, %IDtext
                end if
             end select
          case %wm_command
            if cb.ctl = %ID_ClearBtn and cb.ctlmsg = %bn_clicked then
              control set text cb.hndl, %IDtbox, ""
            end if
            'Z order can hide the "X" when inside the textbox. <<==========
    '         'If I could get the "X" accessible inside the textbox, clears checkbox
    '         IF CB.CTL = %IDtext AND CB.CTLMSG = %STN_CLICKED THEN CONTROL SET TEXT CB.HNDL, %IDtbox, ""
       end select
    end function
    Cheers,

    added - or maybe the mouseover to unhide button?
    Dale

    Comment


    • #3
      Use a simple trick:

      Create a Label control with the text (just "X") right adjusted so it appears on right side. Crate it with a border to. make sure it has the styles so it can be clicked and respond to a click. Define the text color as Red.

      Now create your edit control on top of the label, but just slightly smaller so it fits inside and you can see the Labels border. Make sure it is not as wide so the label's X is still visible.

      Now using 2 controls, you create what appears to be just one.
      Chris Boss
      Computer Workshop
      Developer of "EZGUI"
      http://cwsof.com
      http://twitter.com/EZGUIProGuy

      Comment


      • #4
        A very old post but most likely still very relevant: http://www.catch22.net/tuts/win32/20...edit-control/#
        Paul Squires
        FireFly Visual Designer (for PowerBASIC Windows 10+)
        Version 3 now available.
        http://www.planetsquires.com

        Comment


        • #5
          To explore Chris' excellent advice, using your original code and just for fun - here a small example that resizes textbox and shows/hides the X label depending on if text exist. Result on mouse over:
          Click image for larger version  Name:	HooverTest.jpg Views:	0 Size:	5.5 KB ID:	783939
          Code:
          #COMPILE EXE
          #DIM ALL
          #INCLUDE "win32api.inc"
          
          %IDtbox = 1000
          %IDtext = 1001
          GLOBAL hEdit AS DWORD
          
          FUNCTION PBMAIN() AS LONG
             LOCAL hDlg AS DWORD
             DIALOG DEFAULT FONT "Segoe UI", 9, 0, %DEFAULT_CHARSET
             DIALOG NEW PIXELS, 0, "Hover test",400,300,200,100, %WS_OVERLAPPEDWINDOW TO hDlg
          
             CONTROL ADD LABEL,   hDlg, %IDtext, "X ",        108, 10, 20, 20, _
                                  %SS_NOTIFY OR %SS_RIGHT OR %SS_CENTERIMAGE, %WS_EX_CLIENTEDGE
             CONTROL SET COLOR hDlg, %IDtext, %RED, GetSysColor(%COLOR_WINDOW)
             CONTROL HIDE hDlg, %IDtext
          
             CONTROL ADD TEXTBOX, hDlg, %IDtbox, "Some text", 10 ,10, 118, 20, %WS_CLIPSIBLINGS, %WS_EX_CLIENTEDGE
          
             DIALOG SHOW MODAL hDlg CALL DlgProc
          END FUNCTION
          
          
          CALLBACK FUNCTION DlgProc() AS LONG
            LOCAL MouseOver AS DWORD, sBuf AS STRING
            STATIC Tracker AS BYTE
          
            SELECT CASE CB.MSG
                CASE %WM_SETCURSOR
                   MouseOver = GetDlgCtrlId(CB.WPARAM)
                   CONTROL GET TEXT CB.HNDL, %IDtbox TO sBuf
                   SELECT CASE MouseOver
                     CASE %IDtbox, %IDtext
                      IF Tracker = 0 THEN
                        Tracker = 1
                        CONTROL NORMALIZE CB.HNDL, %IDtext
                        CONTROL SET SIZE CB.HNDL, %IDtbox, 100, 20
                      END IF
                     CASE ELSE
                      IF Tracker = 1 AND LEN(sBuf) THEN ' only show X if text exists
                        Tracker = 0
                        CONTROL HIDE CB.HNDL, %IDtext
                        CONTROL SET SIZE CB.HNDL, %IDtbox, 118, 20
                      END IF
                   END SELECT
          
                CASE %WM_COMMAND
                   IF CB.CTL = %IDtext AND CB.CTLMSG = %STN_CLICKED THEN
                       CONTROL SET TEXT CB.HNDL, %IDtbox, ""
                       CONTROL HIDE CB.HNDL, %IDtext
                       CONTROL SET SIZE CB.HNDL, %IDtbox, 118, 20
                       CONTROL SET FOCUS CB.HNDL, %IDtbox
                   END IF
          
             END SELECT
          END FUNCTION

          Comment


          • #6
            Brilliant Borje

            Comment


            • #7
              and with a slightly different look...

              Code:
              #compile exe
              #dim all
              #include "win32api.inc"
              
              %ID_Edit = 1000
              %ID_Label = 1001
              
              function pbmain() as long                                                          
                 local hDlg as dword       
                 dialog default font "Segoe UI", 9, 0, %DEFAULT_CHARSET
                 dialog new pixels, 0, "Hover test",400,300,200,100, %WS_OVERLAPPEDWINDOW to hDlg
                 CONTROL ADD LABEL, hDlg  , %ID_Label, "X", 10,10, 110,20, %SS_NOTIFY OR %SS_right
                 control add textbox, hDlg, %ID_Edit, "Some text",  10 ,10,100,20
                 control hide hDlg, %ID_Label
                 dialog show modal hDlg call DlgProc
              end function
              
              callback function DlgProc() as long
                 local MouseOver as long
                 local sBuf as string 
                 local pt as pointapi
                 STATIC Tracker AS BYTE
                 select case cb.msg                                                    
                    CASE %WM_SETCURSOR
                       MouseOver = GetDlgCtrlId(CB.WPARAM)
                       CONTROL GET TEXT CB.HNDL, %ID_Edit TO sBuf
                       SELECT CASE MouseOver
                         CASE %ID_Edit, %ID_Label
                            IF Tracker = 0 THEN
                               Tracker = 1
                               CONTROL NORMALIZE CB.HNDL, %ID_Label                             
                               CONTROL SET SIZE CB.HNDL, %ID_Edit, 100, 20
                            END IF
                         CASE ELSE
                            IF Tracker = 1 AND LEN(sBuf) THEN ' only show X if text exists
                               Tracker = 0
                               CONTROL HIDE CB.HNDL, %ID_Label
                               CONTROL SET SIZE CB.HNDL, %ID_Edit, 100, 20
                            END IF
                       END SELECT
                    case %wm_command 
                      if cb.ctl = %ID_Label and cb.ctlmsg = %STN_CLICKED then
                         GetCursorPos pt
                         if pt.x > 520 then 
                            control set text cb.hndl, %ID_Edit, ""
                            control hide cb.hndl, %ID_Label
                         else
                            control send cb.hndl, %ID_Edit, %EM_SETSEL, -1, 0  
                         end if
                      end if
                 end select
              end function

              Comment


              • #8
                Finally after a lot of testing and reading, I got something close enough to that I wanted.
                It even looks ok if you use XPTheme and it should not be hard to modify it to show a eye icon in password boxes.

                Thank you all for the inspirational suggestions. /Mikael

                Code:
                #COMPILE EXE
                #DIM ALL
                #INCLUDE "win32api.inc"
                '#RESOURCE MANIFEST, 1, "XPTheme.xml"
                
                %IDtbox = 1000
                %IDtext = 1001
                
                FUNCTION PBMAIN() AS LONG
                  LOCAL hDlg AS DWORD
                  DIALOG DEFAULT FONT "Segoe UI", 9, 0, %DEFAULT_CHARSET
                  DIALOG NEW PIXELS, 0, "Hover test",400,300,200,100, %WS_OVERLAPPEDWINDOW TO hDlg
                
                  CONTROL ADD TEXTBOX, hDlg, %IDtbox, "Some text", 10, 10, 130, 20, %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %ES_LEFT, %WS_EX_CLIENTEDGE
                  CONTROL ADD LABEL,hDlg, %IDtext, "X", 126, 14, 10, 12, %SS_NOTIFY OR %SS_RIGHT OR %SS_CENTERIMAGE
                  CONTROL SET COLOR hDlg, %IDtext, %RED, GetSysColor(%COLOR_WINDOW)
                  CONTROL HIDE hDlg, %IDtext
                
                  CONTROL ADD TEXTBOX, hDlg, 2000, "Standard textbox", 10, 60, 130, 20, %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %ES_LEFT, %WS_EX_CLIENTEDGE
                
                  DIALOG SHOW MODAL hDlg CALL DlgProc
                END FUNCTION
                
                CALLBACK FUNCTION DlgProc() AS LONG
                  LOCAL hSub, oldProc AS DWORD, sBuf AS STRING
                
                  SELECT CASE CB.MSG
                    CASE %WM_INITDIALOG
                      CONTROL HANDLE CB.HNDL, %IDtbox TO hSub                 '- Setup subclass
                      oldProc = SetWindowLong(hSub, %GWL_WNDPROC, CODEPTR(SubClassProc))
                      DIALOG SET USER CB.HNDL, 1, oldProc
                
                    CASE %WM_SETCURSOR
                      SELECT CASE GetDlgCtrlId(CB.WPARAM)
                        CASE %IDtbox                                          '- Mouse in
                          CONTROL GET TEXT CB.HNDL, %IDtbox TO sBuf
                          IF LEN(sBuf) THEN                                   '- Only show "X" if text exists
                            CONTROL NORMALIZE CB.HNDL, %IDtext
                          END IF
                        CASE ELSE                                             '- Mouse out
                          CONTROL HIDE CB.HNDL, %IDtext
                      END SELECT
                
                    CASE %WM_DESTROY                                          '- Dialog ends
                      DIALOG GET USER CB.HNDL, 1 TO oldProc
                      IF oldProc THEN                                         '- Remove subclass
                        CONTROL HANDLE CB.HNDL, %IDtbox TO hSub
                        SetWindowLong hSub, %GWL_WNDPROC, oldProc
                      END IF
                  END SELECT
                END FUNCTION
                
                '- %IDtbox SubClass procedure -
                FUNCTION SubClassProc(BYVAL hWnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
                  LOCAL oldProc, hDlg AS DWORD, pt AS POINT, sBuf AS STRING
                
                  hDlg = GetParent(hWnd)                                      '- Get window handle
                  DIALOG GET USER hDlg, 1 TO oldProc
                  IF oldProc = 0 THEN EXIT FUNCTION
                
                  SELECT CASE AS LONG wMsg
                    CASE %WM_LBUTTONDOWN
                      GetCursorPos pt
                      ScreenToClient hDlg, pt
                      IF pt.x > 126 THEN                                      '- Clear textbox if "X" is clicked
                        CONTROL SET TEXT hDlg, %IDtbox, ""
                        CONTROL HIDE hDlg, %IDtext
                      END IF
                
                    CASE %WM_SETCURSOR                                        '- For better look and behaviour
                      GetCursorPos pt
                      ScreenToClient hDlg, pt
                      IF pt.x > 126 THEN
                        CONTROL GET TEXT hDlg, %IDtbox TO sBuf
                        IF LEN(sBuf) THEN                                     '- Mouse in on "X"
                          CONTROL NORMALIZE hDlg, %IDtext                     '- Only show "X" if text exists
                        END IF
                        MOUSEPTR 1                                            '- "X" hover, change mouse pointer
                        EXIT FUNCTION                                         '- and exit.
                      END IF
                  END SELECT
                
                  FUNCTION = CallWindowProc(oldProc, hWnd, wMsg, wParam, lParam)
                END FUNCTION

                Comment

                Working...
                X