Showing posts with label Controls. Show all posts
Showing posts with label Controls. Show all posts

6.17.2011

Textual Cue For TextBox Control

In this article, every thing is based on this : EM_SETCUEBANNER

this is a Windows Message that we can send to an edit control such as a textbox, so we can have something like this :
 
this tip "Enter your full name here" on the textbox is usally useful to the user and avoid some confusion.
All we need to do, is to send this message to the handle of the control, via SendMessage Api.

Declare Unicode Function SendMessageW Lib "User32.dll" (ByVal Hwnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Boolean, ByVal lParam As String) As Boolean
    Const EM_SETCUEBANNER = 5377
    Function SetCueText(ByRef Textbox1 As TextBox, ByVal CueText As String, Optional ByVal ShowOnFocus As Boolean = False) As Boolean
        Return SendMessageW(Textbox1.Handle, EM_SETCUEBANNER, ShowOnFocus, CueText)
    End Function

Usage :
Call SetCueText wih these parameters: :
Textbox1 : the textbox control that you want to add a cue text to it. (Textbox)
CueText : The Tip that will show on the textbox (String)
ShowOnFocus : Set to true if you want the cue text visible even if the textbox has the focus (boolean)
Return value : returns true if it succeeds, otherwise it returns false.
Even Better, we can extend the textbox control, and add a property Called "CueText", just like this :

Imports System.Windows.Forms

Public Class mTextBox
    Inherits TextBox
    Declare Unicode Function SendMessageW Lib "User32.dll" (ByVal Hwnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Boolean, ByVal lParam As String) As Boolean
    Const EM_SETCUEBANNER = 5377
    Private _CueText As String
    Private _CueFocus As Boolean
    Public Property CueText() As String
        Get
            Return _CueText
        End Get
        Set(ByVal value As String)
            _CueText = value
            If Me.Handle <> IntPtr.Zero Then SendMessageW(Me.Handle, EM_SETCUEBANNER, New IntPtr(CInt(_CueFocus)), _CueText)
        End Set
    End Property
    Property CueTextFocus() As Boolean
        Get
            Return _CueFocus
        End Get
        Set(ByVal value As Boolean)
            _CueFocus = value
            CueText = CueText
        End Set
    End Property
End Class

What we did, we created a control that inherits from the usual textbox, and added two properties that allow us to get and set the cue text, and also whether to show on focus or not.

OpenIconDialog

If you noticed in your tool box, you've got your OpenFileDialog, SaveFileDialog, ColorDialog, ect...
But There Is No OpenIconDialog.
What we are going to do, is to use the PickIconDlg Api to show a dialog to choose an embedded icon in a file,it will return the index of the selected icon in the file, and then we use the ExtractIconEx Api to load the icon of that index to memory, get its handle and return a variable of type System.Drawing.Icon.
So basically, we made an OpenIconDialog.

Declare Unicode Function PickIconDlg Lib "shell32.dll" (ByVal hwnd As IntPtr, ByVal pszIconPath As StringBuilder, ByVal cchIconPath As Integer, ByRef piIconIndex As Integer) As Integer
    <DllImport("shell32.dll", CharSet:=CharSet.Auto)> _
    Private Shared Function ExtractIconEx(ByVal stExeFileName As String, ByVal nIconIndex As Integer, ByVal phiconLarge As IntPtr(), ByVal phiconSmall As IntPtr(), ByVal nIcons As Integer) As Integer
    End Function
    Function OpenIconDialog(Optional ByVal IcoPath As String = "Shell32.dll") As Icon
        Dim buff As New StringBuilder(IcoPath, 500)
        Dim ind As Integer
        If PickIconDlg(Nothing, buff, buff.Capacity, ind) = 1 Then
            Dim bitm As New Bitmap(1, 1)
            Dim hIcon() As IntPtr = New IntPtr(0) {}
            If (ExtractIconEx(buff.ToString, ind, hIcon, Nothing, 1) = 1) AndAlso hIcon(0) <> IntPtr.Zero Then
                Return Icon.FromHandle(hIcon(0))
            End If
        End If
        Return Nothing
    End Function
It would look something like this :

Msdn recommends that we call DestroyIcon api after finishing of using the icon, but we don't need to add that api declaration to our code since the type System.Drawing.Icon has a method called Dispose, that will eventually cleanup and call the DestroyIcon api.