Announcement

Collapse
No announcement yet.

Textbox Drawing

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

  • Dominic Mitchell
    replied
    Is there any way to pull off the same effect for a combobox
    No. The combo box is a unique beast in the land of Windows.
    You can use your suggestion or roll your own combo box.

    Leave a comment:


  • John Thompson
    replied
    Wow. That is awesome and exactly what I was hoping for. I wasn't aware of the WM_NC* messages before. I've tried this with other controls (datetimepicker, richedit, textbox, listbox) and it works great, but when I try it with a combobox it doesn't work. I was guessing this was due to the fixed height so I tried to set it up to display the text on the left, but it had some weird effects. I was reading that you can do ownerdrawn stuff with comboboxes, but it looks like it only applies to the dropdown list. Is there any way to pull off the same effect for a combobox or would I probably have to draw the name into the top row on the dropdown list or something?

    Thanks!

    -John

    Leave a comment:


  • Dominic Mitchell
    replied
    Here is a quick sample.

    Code:
    '###############################################################################
    '                             Phoenix Visual Designer
    '                              Generated source code
    '###############################################################################
    
    '                                Acknowledgements
    ' José Roca:
    ' For his ground breaking work which interfaces low-level COM and
    ' PowerBASIC-COM automation.
    '
    ' Jeffrey Richter:
    ' For his original implementation of a layout algorithm which positions
    ' controls in a window based on a set of rules.
    
    #DIM ALL
    #REGISTER NONE
    #COMPILE EXE
    #OPTION VERSION4
    
    #INCLUDE "WIN32API.INC"
    
    '=========================== [ Control Identifiers ] ===========================
    
    ' Form1
    %IDD_FORM1                                  = 100
    %IDC_FORM1_EDIT1                            = 101
    
    '====================== [ Global Variable Declarations ] =======================
    
    GLOBAL  ghInstance    AS DWORD    ' handle of the application instance
    
    '-------------------------------------------------------------------------------
    '
    ' PROCEDURE: WinMain
    ' PURPOSE:   Program entry point, calls initialization function, processes
    '            message loop.
    '
    '-------------------------------------------------------------------------------
    
    FUNCTION WINMAIN _
      ( _
      BYVAL hInstance     AS DWORD, _       ' handle of current instance
      BYVAL hPrevInstance AS DWORD, _       ' handle of previous instance(not used in Win32)
      BYVAL pszCmdLine    AS ASCIIZ PTR, _  ' address of command line
      BYVAL nCmdShow      AS LONG _         ' show state of window
      ) AS LONG
    
      LOCAL szClassName     AS ASCIIZ * %MAX_PATH   ' class name
      LOCAL twcx            AS WNDCLASSEX           ' class information
      LOCAL tmsg            AS tagMsg               ' message information
      LOCAL hWnd            AS DWORD                ' handle of main window
      LOCAL hWndModeless    AS DWORD                ' handle of the current active window
    
      ' Save the handle of the application instance
      ghInstance = hInstance
    
      ' Register the Form1 window
      szClassName        = "Form1_Class"
      twcx.cbSize        = SIZEOF(twcx)                               ' size of WNDCLASSEX structure
      twcx.style         = %CS_DBLCLKS                                ' class styles
      twcx.lpfnWndProc   = CODEPTR(Form1_WndProc)                     ' address of window procedure used by class
      twcx.cbClsExtra    = 0                                          ' extra class bytes
      twcx.cbWndExtra    = 0                                          ' extra window bytes
      twcx.hInstance     = ghInstance                                 ' instance of the process that is registering the window
      twcx.hIcon         = LoadIcon(%NULL, BYVAL %IDI_APPLICATION)    ' handle of class icon
      twcx.hCursor       = LoadCursor(%NULL, BYVAL %IDC_ARROW)        ' handle of class cursor
      twcx.hbrBackground = %COLOR_BTNFACE + 1                         ' brush used to fill background of window's client area
      twcx.lpszMenuName  = %NULL                                      ' resource identifier of the class menu
      twcx.lpszClassName = VARPTR(szClassName)                        ' class name
      twcx.hIconSm       = %NULL                                      ' handle of small icon shown in caption/system Taskbar
      IF ISFALSE RegisterClassEx(twcx) THEN
        FUNCTION = %TRUE
        EXIT FUNCTION
      END IF
    
      ' Create the Form1 window
      hWnd = CreateWindowEx(%WS_EX_WINDOWEDGE, _                                          ' extended styles
                            "Form1_Class", _                                              ' class name
                            "Text box drawing", _                                         ' caption
                            %WS_OVERLAPPEDWINDOW OR %WS_VISIBLE, _                        ' window styles
                            139, 131, _                                                   ' left, top
                            360, 374, _                                                   ' width, height
                            %NULL, %NULL, _                                               ' handle of owner, menu handle
                            ghInstance, BYVAL %NULL)                                      ' handle of instance, creation parameters
      ' If window could not be created, return "failure"
      IF ISFALSE hWnd THEN
        FUNCTION = %FALSE
        EXIT FUNCTION
      END IF
    
      ' Make the window visible; update its client area
      ShowWindow hWnd, nCmdShow
      UpdateWindow hWnd
    
      ' Main message loop of program.
      ' Acquire and dispatch messages until a WM_QUIT message is received.
      WHILE ISTRUE GetMessage(tmsg, BYVAL %NULL, 0, 0)
        hWndModeless = phnxGetFormHandle(GetFocus())
        IF (ISFALSE hWndModeless) OR (ISFALSE IsDialogMessage(hWndModeless, tmsg)) THEN
          TranslateMessage tmsg
          DispatchMessage tmsg
        END IF
      WEND
    
      FUNCTION = tmsg.wParam
    
    END FUNCTION
    
    '-------------------------------------------------------------------------------
    '
    ' PROCEDURE: Form1_WndProc
    ' PURPOSE:   Processes messages for the Form1 window.
    '
    '-------------------------------------------------------------------------------
    
    FUNCTION Form1_WndProc _
      ( _
      BYVAL hWnd    AS DWORD, _ ' window handle
      BYVAL uMsg    AS DWORD, _ ' type of message
      BYVAL wParam  AS DWORD, _ ' first message parameter
      BYVAL lParam  AS LONG _   ' second message parameter
      ) EXPORT AS LONG
    
      LOCAL hWndChild   AS DWORD    ' handle of child window
      LOCAL hFont       AS DWORD    ' handle of font used by form
    
      SELECT CASE uMsg
        CASE %WM_COMMAND
    
          SELECT CASE LOWRD(wParam)
            CASE %IDC_FORM1_EDIT1
              IF HIWRD(wParam) = %EN_CHANGE THEN
              END IF
    
            CASE %IDCLOSE
              IF HIWRD(wParam) = %BN_CLICKED THEN
                PostMessage hWnd, %WM_CLOSE, 0, 0
              END IF
          END SELECT
    
        CASE %WM_SETFOCUS
          ' Set the keyboard focus to the first control that is
          ' visible, not disabled, and has the WS_TABSTOP style
          SetFocus GetNextDlgTabItem(hWnd, %NULL, %FALSE)
    
        CASE %WM_DESTROY
          PostQuitMessage 0
          FUNCTION = %FALSE
          EXIT FUNCTION
    
        CASE %WM_CREATE
          ' Create font used by container
          hFont = GetStockObject(%DEFAULT_GUI_FONT)
    
          ' Create the Edit1 edit control
          hWndChild = CreateWindowEx(%WS_EX_CLIENTEDGE, _                                 ' extended styles
                                     "Edit", _                                            ' class name
                                     "Once upon a time", _                                ' caption
                                     %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR _         ' window styles
                                     %ES_LEFT OR %ES_AUTOHSCROLL, _                       ' class styles
                                     55, 50, _                                            ' left, top
                                     211, 36, _                                           ' width, height
                                     hWnd, %IDC_FORM1_EDIT1, _                            ' handle of parent, control ID
                                     ghInstance, BYVAL %NULL)                             ' handle of instance, creation parameters
          ' Subclass the control
          SetProp hWndChild, "OLDWNDPROC", SetWindowLong(hWndChild, %GWL_WNDPROC, CODEPTR(Form1_Edit1_SubclassProc))
          SendMessage hWndChild, %WM_SETFONT, hFont, %TRUE
    
          ' Create the Close text button
          hWndChild = CreateWindowEx(%NULL, _                                             ' extended styles
                                     "Button", _                                          ' class name
                                     "Close", _                                           ' caption
                                     %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR _         ' window styles
                                     %BS_PUSHBUTTON OR %BS_CENTER OR %BS_VCENTER, _       ' class styles
                                     130, 295, _                                          ' left, top
                                     76, 26, _                                            ' width, height
                                     hWnd, %IDCLOSE, _                                    ' handle of parent, control ID
                                     ghInstance, BYVAL %NULL)                             ' handle of instance, creation parameters
          SendMessage hWndChild, %WM_SETFONT, hFont, %TRUE
    
          FUNCTION = %FALSE
          EXIT FUNCTION
      END SELECT
    
      FUNCTION = DefWindowProc(hWnd, uMsg, wParam, lParam)
    
    END FUNCTION
    
    '-------------------------------------------------------------------------------
    '
    ' PROCEDURE: Form1_Edit1_SubclassProc
    ' PURPOSE:   Processes messages for the subclassed Edit window.
    '
    '-------------------------------------------------------------------------------
    
    FUNCTION Form1_Edit1_SubclassProc _
      ( _
      BYVAL hWnd    AS DWORD, _ ' control handle
      BYVAL uMsg    AS DWORD, _ ' type of message
      BYVAL wParam  AS DWORD, _ ' first message parameter
      BYVAL lParam  AS LONG _   ' second message parameter
      ) EXPORT AS LONG
    
      LOCAL trc             AS RECT
      LOCAL trcWin          AS RECT
      LOCAL ptnccsp         AS NCCALCSIZE_PARAMS PTR
      LOCAL lpOldWndProc    AS DWORD    ' address of original window procedure
      LOCAL hDC             AS DWORD
      LOCAL hFontOld        AS DWORD
      LOCAL dwBkModeOld     AS DWORD
      LOCAL cyEdge          AS LONG
      LOCAL lMsgResult      AS LONG
    
      lpOldWndProc = GetProp(hWnd, "OLDWNDPROC")
    
      SELECT CASE uMsg
        CASE %WM_DESTROY
          ' Remove control subclassing
          SetWindowLong hWnd, %GWL_WNDPROC, RemoveProp(hWnd, "OLDWNDPROC")
    
        CASE %WM_NCCALCSIZE
          ptnccsp = lParam
          ' We will create space for the label area by increasing the
          ' height of the frame on the bottom side
          GetWindowRect hWnd, trc
          lMsgResult = DefWindowProc(hWnd, %WM_NCCALCSIZE, wParam, lParam)
          @ptnccsp.rgrc(0).nBottom  = @ptnccsp.rgrc(0).nBottom - (trc.nBottom - trc.nTop) / 3
          FUNCTION = lMsgResult
          EXIT FUNCTION
    
        CASE %WM_NCPAINT
          hDC = GetWindowDC(hWnd)
          ' Calculate the bounding rectangle of the label area
          ' adjusted to the coordinate space of the window dc
          GetWindowRect hWnd, trcWin
          GetClientRect hWnd, trc
          MapWindowPoints hWnd, %NULL, BYVAL VARPTR(trc), 2
          cyEdge = trc.nTop - trcWin.nTop
          trc.nTop    = trc.nBottom
          trc.nBottom = trcWin.nBottom - cyEdge
          OffsetRect trc, -trcWin.nLeft, -trcWin.nTop
    
          ' Brush the background
          FillRect hDC, trc, %COLOR_3DSHADOW + 1
    
          hFontOld    = SelectObject(hDC, SendMessage(hWnd, %WM_GETFONT, 0, 0))
          dwBkModeOld = SetBkMode(hDC, %TRANSPARENT)
          DrawText hDC, "Hello", -1, trc, %DT_CENTER OR %DT_VCENTER
    
          SetBkMode hDC, dwBkModeOld
          SelectObject hDC, hFontOld
          ReleaseDC hWnd, hDC
          ' Let Windows paint the rest of the frame
    
        CASE %WM_SETFONT
          lMsgResult = CallWindowProc(lpOldWndProc, hWnd, %WM_SETFONT, wParam, lParam)
          ' Force a WM_NCCALCSIZE message to be sent to the window
          SetWindowPos hWnd, %NULL, 0, 0, 0, 0, %SWP_NOZORDER OR %SWP_NOMOVE OR %SWP_NOSIZE OR %SWP_FRAMECHANGED
          FUNCTION = lMsgResult
          EXIT FUNCTION
      END SELECT
    
      FUNCTION = CallWindowProc(lpOldWndProc, hWnd, uMsg, wParam, lParam)
    
    END FUNCTION

    Leave a comment:


  • Dominic Mitchell
    replied
    It is possible.

    Leave a comment:


  • Michael Mattias
    replied
    >a label for each textbox inside the textbox (on the bottom

    Why not just put an edit (textbox) control immediately above a static (label) control?

    You can paint the label control's background to match the textbox's background (see WM_CTLCOLORSTATIC notification message, return GetStockOject (%WHITE_BRUSH) )and no one will ever know your 'one' control is actually 'two' controls.

    ???

    Of course, the listview is not a bad idea, Either. you only allow editing on rows 0,2,4... and reserve rows 1,3,5... for the the label.

    Leave a comment:


  • John Thompson
    started a topic Textbox Drawing

    Textbox Drawing

    Is it possible to draw on a textbox? I've got an application I'm designing for user input. It has a lot of textboxes, and I'd like to be able to draw a label for each textbox inside the textbox (on the bottom). I started doing this with a custom control, and while I'm really happy with the drawing portion, it's taking a lot of work to handle everything the textbox control already does.

    What I want to do is just take the bottom 1/3rd of a textbox, use it for drawing only, draw the label name, restrict the textbox from displaying its text there, and restrict the caret from displaying in this bottom 1/3rd section.

    Code:
    /--------------------\
    |                            |
    |                            |
    | name                    |
    \--------------------/
    I've searched textbox draw on here and Google, but am not finding a whole lot. I think I'm thinking of listviews or something, but I was hoping I can do this with textboxes also. Does anyone know if this is possible and what I need to research to make it happen?

    Thanks!

    -John
Working...
X