שתף באמצעות


TextBox watermark (CueBanner) which goes away when user types in single line TextBox (not for RichTextBox).

Question

Sunday, July 24, 2016 3:37 AM | 3 votes

Just for info if anyone interested. Maybe code is already in this Forum but I've not seen it before.

Pic2 without TextBox2 password char set, Pic3 with TextBox2 password char set.

EM_SETCUEBANNER message

Option Strict On

Imports System.Runtime.InteropServices

Public Class Form1

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

    Const EM_SETCUEBANNER As Integer = &H1501

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.Location = New Point(CInt((Screen.PrimaryScreen.WorkingArea.Width / 2) - (Me.Width / 2)), CInt((Screen.PrimaryScreen.WorkingArea.Height / 2) - (Me.Height / 2)))
        'TextBox2.PasswordChar = CChar("*")
        SendMessage(TextBox1.Handle, EM_SETCUEBANNER, 1, "Username")
        SendMessage(TextBox2.Handle, EM_SETCUEBANNER, 1, "Password")
    End Sub

End Class

La vida loca

All replies (13)

Sunday, July 24, 2016 10:10 AM | 3 votes

 Hi John,

 For a TextBox,  you can also set the wParam to (1 or 0) indicating (True or False) to hide the cuebanner text as soon as the textbox gains focus or to keep it showing when the textbox gains focus and hide it only if the user enters a character.

 You can also do this with a ComboBox too.  The only difference with a combobox is that you can not set the wParam to (0 or 1) like you can with a TextBox.  If the combobox DropDownStyle is set to DropDown it will hide the text as soon as it gains focus.  If the DropDownStyle is set to DropDownList,  then it will hide the text as soon as an item is selected.

 I put an example on DIC for a TextBox a few months ago but,  i expanded that to include the ComboBox and will post it here in case you or others want to try it or keep an example.  I set it up in a small class with shared subs.  I figure it may be handy if you had several TextBoxes and/or ComboBoxes that you wanted set.   8)

Imports System.Runtime.InteropServices

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        TextBox1.Multiline = False
        TextBox2.Multiline = False
        ComboBox1.DropDownStyle = ComboBoxStyle.DropDown
        ComboBox2.DropDownStyle = ComboBoxStyle.DropDownList

        CueBannerSetter.SetCueBanner(TextBox1, "Enter Search Word...", False)
        CueBannerSetter.SetCueBanner(TextBox2, "Enter Search Word...", True)
        CueBannerSetter.SetCueBanner(ComboBox1, "Select or Type a name here...")
        CueBannerSetter.SetCueBanner(ComboBox2, "Select An Item...")
    End Sub
End Class

Public Class CueBannerSetter
    Private Const EM_SETCUEBANNER As Integer = &H1501
    Private Const CB_SETCUEBANNER As Integer = &H1703

    <DllImport("user32.dll", EntryPoint:="SendMessageW")>
    Private Shared Function SendMessageW(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As UInteger, <MarshalAs(UnmanagedType.LPTStr)> ByVal lParam As String) As Integer
    End Function

    ''' <summary>Shows grayed text in the combobox to indicate what the combobox is for.</summary>
    ''' <param name="CbBx">The combobox to set the cuebanner text in.</param>
    ''' <param name="QBannerText">The cuebanner text to show in the combobox.</param>
    Public Shared Sub SetCueBanner(ByVal CbBx As ComboBox, ByVal QBannerText As String)
        SendMessageW(CbBx.Handle, CB_SETCUEBANNER, 0, QBannerText)
    End Sub

    ''' <summary>Shows grayed text in the textbox to indicate what the textbox is for.</summary>
    ''' <param name="TxBx">The textbox to set the cuebanner text in.</param>
    ''' <param name="QBannerText">The cuebanner text to show in the textbox.</param>
    ''' <param name="Clearonfocus">True to clear the cuebanner text when the textbox receives focus, otherwise False.</param>
    Public Shared Sub SetCueBanner(ByVal TxBx As TextBox, ByVal QBannerText As String, ByVal Clearonfocus As Boolean)
        Dim showfocused As UInteger = 1
        If Clearonfocus Then showfocused = 0
        SendMessageW(TxBx.Handle, EM_SETCUEBANNER, showfocused, QBannerText)
    End Sub
End Class

If you say it can`t be done then i`ll try it


Sunday, July 24, 2016 2:33 PM | 1 vote

Nice as always Razerz (er...Ray)!

La vida loca


Sunday, July 24, 2016 3:20 PM | 2 votes

Thanks for sharing :-)

I did a library for this back several years located here on vbforums for VS2013, a revised VS2015 version is shown below.

In the version mentioned above I had functions, in the version below, language extension methods

Imports System.Runtime.InteropServices
Public Module CueBannerTextCode
    <DllImport("user32.dll", CharSet:=CharSet.Auto)> _
    Private 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
    Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (
            ByVal hWnd1 As IntPtr,
            ByVal hWnd2 As IntPtr,
            ByVal lpsz1 As String,
            ByVal lpsz2 As String) As IntPtr

    Private Const EM_SETCUEBANNER As Integer = &H1501
    ''' <summary>
    ''' Used to place shadow text into a TextBox or ComboBox when control does not have focus
    ''' </summary>
    ''' <param name="control">Name of control</param>
    ''' <param name="text">Shadow text to show when control does not have focus</param>
    ''' <remarks>
    ''' Some might call this a watermark affect
    ''' </remarks>
    <System.Diagnostics.DebuggerStepThrough()>
    <System.Runtime.CompilerServices.Extension()>
    Public Sub SetCueText(ByVal control As Control, ByVal text As String)

        If TypeOf control Is ComboBox Then
            Dim Edit_hWnd As IntPtr = FindWindowEx(control.Handle, IntPtr.Zero, "Edit", Nothing)
            If Not Edit_hWnd = IntPtr.Zero Then
                SendMessage(Edit_hWnd, EM_SETCUEBANNER, 0, text)
            End If
        ElseIf TypeOf control Is TextBox Then
            SendMessage(control.Handle, EM_SETCUEBANNER, 0, text)
        End If
    End Sub


End Module

Sample usage

Imports CueBannerLibrary
Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        txtFirstName.SetCueText("Please enter your first name")
        txtLastName.SetCueText("Please enter your last name")
        ComboBox1.SetCueText("Enter gender")
        ActiveControl = cmdSubmit
    End Sub
End Class

C# library

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Cue_BannerLibrary
{
    public static class CueBannerTextCode
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private extern static Int32 SendMessage(
            IntPtr hWnd, 
            int msg, 
            int wParam, [MarshalAs(UnmanagedType.LPWStr)]
        string lParam);

        [System.Runtime.InteropServices.DllImport("user32", 
            EntryPoint = "FindWindowExA", 
            ExactSpelling = true, 
            CharSet = CharSet.Ansi, SetLastError = true)]

        private static extern IntPtr FindWindowEx(IntPtr hWnd1, IntPtr hWnd2, string lpsz1, string lpsz2);
        private const int EM_SETCUEBANNER = 0x1501;
        /// <summary>
        /// Used to place shadow text into a TextBox or ComboBox when control does not have focus
        /// </summary>
        /// <param name="control">Name of control</param>
        /// <param name="text">Shadow text to show when control does not have focus</param>
        /// <remarks>
        /// Some might call this a watermark affect
        /// </remarks>
        public static void SetCueText(this Control control, string text)
        {

            if (control is ComboBox)
            {
                IntPtr Edit_hWnd = FindWindowEx(control.Handle, IntPtr.Zero, "Edit", null);
                if (!(Edit_hWnd == IntPtr.Zero))
                {
                    SendMessage(Edit_hWnd, EM_SETCUEBANNER, 0, text);
                }
            }
            else if (control is TextBox)
            {
                SendMessage(control.Handle, EM_SETCUEBANNER, 0, text);
            }
        }
    }
}

Usage (same as vb.net)

using Cue_BannerLibrary;
using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            txtFirstName.SetCueText("Please enter your first name");
            txtLastName.SetCueText("Please enter your last name");
            ComboBox1.SetCueText("Enter gender");
            ActiveControl = cmdSubmit;
        }
    }
}

VS2015 solution

Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
VB Forums - moderator


Sunday, July 24, 2016 3:55 PM | 2 votes

Maybe code is already in this Forum but I've not seen it before.

https://social.msdn.microsoft.com/Forums/en-US/a110cb06-87d6-4267-996c-26da01bedb84/how-to-make-text-box-like-this-in-vb-thank-u?forum=vbgeneral


Sunday, July 24, 2016 4:47 PM | 1 vote

@ Monkeyboy,

  Thanks.  You should have figured i posted this at some point in the last few years of learning VB.Net.  You know how i love using the Win32 Api`s.   8)

 

** @ Karen**,

  Hey now,  you better watch posting that C# code here in the VB.Net forum,  you might get your post reported as abusive doing that.  haha Just kidding.  8)

 

** @ Dave299**,

  I knew i had posted a few examples of using this somewhere.  You always seem to be the one that finds them too.  I say we vote for Dave299 to replace Google.  8)

If you say it can`t be done then i`ll try it


Sunday, July 24, 2016 5:10 PM | 2 votes

Maybe code is already in this Forum but I've not seen it before.

https://social.msdn.microsoft.com/Forums/en-US/a110cb06-87d6-4267-996c-26da01bedb84/how-to-make-text-box-like-this-in-vb-thank-u?forum=vbgeneral

Now that is classic Dave299!

La vida loca


Sunday, July 24, 2016 5:10 PM | 1 vote

@ Monkeyboy,

  Thanks.  You should have figured i posted this at some point in the last few years of learning VB.Net.  You know how i love using the Win32 Api`s.   8)

 

** @ Karen**,

  Hey now,  you better watch posting that C# code here in the VB.Net forum,  you might get your post reported as abusive doing that.  haha Just kidding.  8)

 

** @ Dave299**,

  I knew i had posted a few examples of using this somewhere.  You always seem to be the one that finds them too.  I say we vote for Dave299 to replace Google.  8)

If you say it can`t be done then i`ll try it

Hah...you did.

La vida loca


Sunday, July 24, 2016 5:53 PM

Hah...you did.

La vida loca

 This thread will be much easier to find than the others since this has "CueBanner" in the title and we can filter the forum search for Discussions only.  I am sure i will want to post a link or two for it sooner or later.  8)

If you say it can`t be done then i`ll try it


Sunday, July 24, 2016 9:36 PM | 3 votes

 

** @ Karen**,

  Hey now,  you better watch posting that C# code here in the VB.Net forum,  you might get your post reported as abusive doing that.  haha Just kidding.  8)

If you say it can`t be done then i`ll try it

Okay, since I may be flagged here is an addition I did in C# but will only show the VB.NET version :-)

Enums for custom TextBox

Public Module Enumerations
    Public Enum WaterMark
        ' Hide cue text when entering control
        Hide = 0
        ' Show cue text when entering control until user begins to type
        Show = 1
    End Enum
End Module

Custom cue/watermark textbox

Imports System.ComponentModel
Imports System.Runtime.InteropServices
Public Class CueTextBox
    Inherits TextBox

    <Category("WaterMark"), Description("Text to display for cue text"), Localizable(True)>
    Public Property Cue() As String
        Get
            Return mCue
        End Get
        Set(ByVal value As String)
            mCue = value
            updateCue()
        End Set
    End Property
    <Category("WaterMark"), Description("Cue text behavior")>
    Public Property WaterMarkOption() As WaterMark
        Get
            Return mWaterMark
        End Get
        Set(ByVal value As WaterMark)
            mWaterMark = value
            updateCue()
        End Set
    End Property
    Private Sub updateCue()
        If IsHandleCreated AndAlso mCue IsNot Nothing Then
            SendMessage(Me.Handle, &H1501, CType(WaterMarkOption, IntPtr), mCue)
        End If
    End Sub
    Protected Overrides Sub OnHandleCreated(ByVal e As EventArgs)
        MyBase.OnHandleCreated(e)
        updateCue()
    End Sub
    Private mCue As String = "Enter text"
    Private mWaterMark As WaterMark = WaterMark.Hide

    <DllImport("user32.dll", CharSet:=CharSet.Unicode)>
    Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wp As IntPtr, ByVal lp As String) As IntPtr
    End Function
End Class

WaterMarkOption, hide means to hide cue text on enter, show, enter control, cue text displays until user begins to type in something.

Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
VB Forums - moderator


Sunday, July 24, 2016 11:36 PM

@Kareninstructor

I think I saw that thread in C# in some other forum or something when I was researching this.

La vida loca


Monday, July 25, 2016 2:20 AM

@Kareninstructor

I think I saw that thread in C# in some other forum or something when I was researching this.

La vida loca

Yes but my version is better, compare and see :-)

Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
VB Forums - moderator


Wednesday, November 4, 2020 8:21 PM

Could you please do that without importing to a dll reference?


Wednesday, November 4, 2020 8:46 PM

Could you please do that without importing to a dll reference?

Hi

How about this maybe - no Imports

' Form1 with TextBoxes 1,2 and 3
Option Strict On
Option Explicit On
Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        SetCueText(TextBox1, "TextBox1 Cue Banner  ....")
        SetCueText(TextBox2, "TextBox2 Cue Banner  ....")

        ' this just so TB1 & 2 not selected
        TextBox3.Select()

    End Sub
End Class
Module CueBannerText
    <Runtime.InteropServices.DllImport("user32.dll", CharSet:=Runtime.InteropServices.CharSet.Auto)>
    Private Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As Integer, <Runtime.InteropServices.MarshalAs(Runtime.InteropServices.UnmanagedType.LPWStr)> ByVal lParam As String) As Int32
    End Function
    Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As IntPtr, ByVal hWnd2 As IntPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As IntPtr
    Private Const EM_SETCUEBANNER As Integer = &H1501
    Public Sub SetCueText(ByVal control As Control, ByVal text As String)
        SendMessage(control.Handle, EM_SETCUEBANNER, 0, text)
    End Sub
End Module

Regards Les, Livingston, Scotland