Sev09
Sev09

Reputation: 883

Create a textbox "hint" message for two different textboxes(watermark)

I was wondering how to create a "hint" for two different textboxes in a form?

Here is the code I have:

Imports System.Runtime.InteropServices

Form_Load Event:

SendMessage(Me.txtAmount.Handle, &H1501, 0, "$X.XX")
SendMessage(Me.txtMemo.Handle, &H1501, 0, "Enter a transaction memo.")

Shared Function:

<DllImport("user32.dll", CharSet:=CharSet.Auto)> _
    Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As Integer, <MarshalAs(UnmanagedType.LPWStr)> ByVal lParam As String) As Int32
    End Function

This code is only working for the txtAmount textbox. Any idea how to get two working in one form?

Thanks.

Upvotes: 1

Views: 5677

Answers (3)

Andrea De Filippo
Andrea De Filippo

Reputation: 1

Just came across this. In addition to user3311691 post, I suggest adding a couple of lines to enhance the quality of the text rendered:

Using g As Graphics = Me.CreateGraphics, oFmt As New StringFormat()
            oFmt.LineAlignment = StringAlignment.Near
            g.Clear(SystemColors.Window)
            g.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
            g.DrawString(CueBannerText, Me.Font, SystemBrushes.GrayText, Me.ClientRectangle, oFmt)
        End Using

Upvotes: 0

ElektroStudios
ElektroStudios

Reputation: 20474

You can reproduce a textbox Hint without API:

''' <summary>
''' Indicates the Textbox Hint.
''' </summary>
Private ReadOnly TextBoxHint As String = "I'm a control hint."

''' <summary>
''' Handles the Hint event of the TextBox control.
''' </summary>
''' <param name="sender">The source of the event.</param>
''' <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
Private Sub TextBox_Leave(ByVal sender As Object, ByVal e As EventArgs) Handles _
TextBox1.Leave, TextBox1.HandleCreated

    Select Case CStr(sender.Text)

        Case Is = TextBoxHint
            sender.text = String.Empty

        Case Is = String.Empty
            sender.text = TextBoxHint

    End Select

End Sub

''' <summary>
''' Handles the Enter event of the TextBox control.
''' </summary>
''' <param name="sender">The source of the event.</param>
''' <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
Private Sub TextBox_Enter(ByVal sender As Object, ByVal e As EventArgs) Handles _
TextBox1.Enter

    Select Case CStr(sender.Text)

        Case Is = TextBoxHint
            sender.text = String.Empty

    End Select

End Sub

Anyways, try this alternative, I've tested it on various textbox at the same time and worked nice:

' Set Control Hint
' ( By Elektro )
'
' Usage Examples:
' SetControlHint(TextBox1, "I'm a text hint.")

''' <summary>
''' Messages to send to an Edit control, such a TextBox.
''' </summary>
Private Enum EditControlMessages As Integer

    ''' <summary>
    ''' Sets the textual cue, or tip, that is displayed by the edit control to prompt the user for information.
    ''' http://msdn.microsoft.com/en-us/library/windows/desktop/bb761639%28v=vs.85%29.aspx
    ''' </summary>
    SetCueBanner = &H1501I

End Enum

''' <summary>
''' Sends the specified message to a window or windows. 
''' The SendMessage function calls the window procedure for the specified window 
''' and does not return until the window procedure has processed the message.
''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms644950%28v=vs.85%29.aspx
''' </summary>
''' <param name="hWnd">
''' A handle to the Control whose will receive the message.
''' </param>
''' <param name="msg">
''' The message to be sent.
''' </param>
''' <param name="wParam">
''' Additional message-specific information.
''' </param>
''' <param name="lParam">
''' Additional message-specific information.
''' </param>
''' <returns>
''' The return value specifies the result of the message processing; it depends on the message sent.
''' </returns>
<System.Runtime.InteropServices.DllImport("user32.dll",
EntryPoint:="SendMessage",
CharSet:=System.Runtime.InteropServices.CharSet.Auto)>
Private Shared Function SendEditMessage(
        ByVal hWnd As IntPtr,
        ByVal msg As EditControlMessages,
        ByVal wParam As IntPtr,
        <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)>
        ByVal lParam As String
) As UInteger
End Function

''' <summary>
''' Sets a text hint for an edit control such a TextBox.
''' </summary>
''' <param name="Control">Indicates the control.</param>
''' <param name="Hint">Indicates the text hint.</param>
''' <returns><c>true</c> if operation succeeds, <c>false</c> otherwise.</returns>
Private Function SetControlHint(ByVal [Control] As Control,
                                ByVal Hint As String) As Boolean

    Return SendEditMessage([Control].Handle, EditControlMessages.SetCueBanner, IntPtr.Zero, Hint)

End Function

Upvotes: 1

user3311691
user3311691

Reputation:

Create a class:

Public Class MultilineTextBoxWaterMark
Inherits TextBox

Private Const WM_PAINT = &HF

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    MyBase.WndProc(m)

    If m.Msg = WM_PAINT Then
        If Text.Length <> 0 Or Me.Focused Then
            Return
        End If
        Using g As Graphics = Me.CreateGraphics, format As New StringFormat()
            format.LineAlignment = StringAlignment.Near

            g.DrawString("Enter a transaction memo.", Me.Font, Brushes.LightGray, Me.ClientRectangle, format)
        End Using
    End If
End Sub

End Class

Then in your main form:

Private MltLnTxtBxWrMrk As New MultilineTextBoxWaterMark

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    MltLnTxtBxWrMrk.Location = New Point(100, 30) 'whatever you want
    MltLnTxtBxWrMrk.Width = 300 'whatever you want
    MltLnTxtBxWrMrk.Height = 100 'whatever you want
    MltLnTxtBxWrMrk.BorderStyle = BorderStyle.Fixed3D 'whatever you want
    MltLnTxtBxWrMrk.Multiline = True

    Me.Controls.Add(MltLnTxtBxWrMrk)
End Sub

I think it works. Thank you

Upvotes: 6

Related Questions