Click here to Skip to main content
15,886,689 members
Articles / Programming Languages / C#

Subclassing TextBox Using Native Callbacks

Rate me:
Please Sign up or sign in to vote.
4.76/5 (14 votes)
3 Jan 2008CPOL4 min read 47.8K   918   18  
Adding Click Event on a Textbox by Subclassing using Native Callbacks
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace ClickableTextBox
{
    
    public partial class ClickableTextBox : TextBox
    {
        public delegate void onClick(object sender, EventArgs e);
        public event onClick Clicked;

        public ClickableTextBox()
        {
            InitializeComponent();
            WndProcHooker.HookWndProc(this,
                new WndProcHooker.WndProcCallback(this.WM_LButtonDown_Handler),
                Win32.WM_LBUTTONDOWN);
            WndProcHooker.HookWndProc(this,
                new WndProcHooker.WndProcCallback(this.WM_LButtonUp_Handler),
                Win32.WM_LBUTTONUP);
        }

        #region OnClick

        /// <summary>
        /// The method that gets called when a WM_NOTIFY message is received by the
        /// TextBox's parent.
        /// </summary>
        /// <param name="hwnd">The handle of the window that received the message</param>
        /// <param name="msg">The message received</param>
        /// <param name="wParam">The wParam arguments for the message</param>
        /// <param name="lParam">The lParam arguments for the message</param>
        /// <param name="handled">Set to true to indicate that this message was handled</param>
        /// <returns>An appropriate returen code for the message handled (see MSDN)</returns>
        int WM_Notify_Handler(
        IntPtr hwnd, uint msg, uint wParam, int lParam,
        ref bool handled)
        {
            Win32.NMHDR nmHdr = new Win32.NMHDR();
            System.Runtime.InteropServices.Marshal.PtrToStructure((IntPtr)lParam, nmHdr);
            switch (nmHdr.code)
            {
                case Win32.WM_LBUTTONDOWN:
                case Win32.WM_LBUTTONUP:
                    // get the cursor coordinates on the client
                    Point msgPos = Win32.LParamToPoint((int)Win32.GetMessagePos());
                    msgPos = this.PointToClient(msgPos);
                        RaiseMouseClickEvent(MouseButtons.Left, msgPos);
                    break;
                default:
                    break;
            }
            return 0;
        }
        public void OnMouseClick(MouseEventArgs e)
        {
            this.OnClick(new EventArgs());
        }

        protected override void OnClick(EventArgs e)
        {
            base.OnClick(e);
        }


        /// <summary>
        /// Raises the MouseClick event with the specified handle.
        /// </summary>
        /// <param name="hNode">The handle of the node for which the event is raised</param>
        /// <param name="button">The [mouse] buttons that were pressed to raise the event</param>
        /// <param name="coords">The [client] cursor coordinates at the time of the event</param>
        public void RaiseMouseClickEvent(MouseButtons button, Point coords)
        {

            MouseEventArgs e = new MouseEventArgs(button,1, coords.X, coords.Y, 0);

            OnMouseClick(e);
        }

        // The callback called when the window receives a WM_LBUTTONDOWN
        // message. We capture the mouse and draw the button in the "pushed"
        // state.
        // hwnd - The handle to the window that received the
        // message.
        // wParam - Indicates whether various virtual keys are
        // down.
        // lParam - The coordinates of the cursor.
        // handled - Set to true if we don't want to pass this
        // message on to the original window procedure.
        // Returns zero if we process this message.
        int WM_LButtonDown_Handler(
            IntPtr hwnd, uint msg, uint wParam, int lParam,
            ref bool handled)
        {
            // Start capturing the mouse input.
            this.Capture = true;
            // someone clicked on us so grab the focus
            this.Focus();

            // We have handled this windows message and we don't want the
            // sub-classed window to do anything else.
            handled = true;
            return 0;
        }
        // The callback called when the window receives a WM_LBUTTONUP
        // message. We release capture on the mouse, draw the button in the
        // "un-pushed" state and fire the  OnMouseUp event if the cursor was
        // let go of inside our client area.
        // hwnd - The handle to the window that received the
        // message
        // wParam - Indicates whether various virtual keys are
        // down.
        // lParam - The coordinates of the cursor
        // handled - Set to true if we don't want to pass this
        // message
        // on to the original window procedure
        // Returns zero if we process this message.
        int WM_LButtonUp_Handler(
            IntPtr hwnd, uint msg, uint wParam, int lParam,
            ref bool handled)
        {
            this.Capture = false;
            // TODO : implement your login on mouse key up event
            
                Clicked(this, null);

            handled = true;
            return 0;
        }
        #endregion
    }


}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Adaptive solutions Inc.
Pakistan Pakistan
BS(CS) From SZABIST (Pakistan)
I have been working as
"Web Application Developer"
with Adaptive Solutions Inc.


Comments and Discussions