The full article is <a href="http://asp.net/AJAX/Documentation/Live/tutorials/CreatingCustomClientControlsTutorial.aspx">here</a>, The summary is bellow.

        <ul>
        <li>You need to write a js file to define the control</li>
        <li>You need to write script in the page the hookup the relation ship</li>
        </ul>


        <p>Here is the js file</p>

        <pre data-sub="prettyprint:_">
        Type.registerNamespace("Demo");

        // Constructor
        Demo.HoverButton = function(element) {

        Demo.HoverButton.initializeBase(this, [element]);

        this._clickDelegate = null;
        this._hoverDelegate = null;
        this._unhoverDelegate = null;
        }
        Demo.HoverButton.prototype = {

        // text property accessors.
        get_text: function() {
        return this.get_element().innerHTML;
        },
        set_text: function(value) {
        this.get_element().innerHTML = value;
        },

        // Bind and unbind to click event.
        add_click: function(handler) {
        this.get_events().addHandler('click', handler);
        },
        remove_click: function(handler) {
        this.get_events().removeHandler('click', handler);
        },

        // Bind and unbind to hover event.
        add_hover: function(handler) {
        this.get_events().addHandler('hover', handler);
        },
        remove_hover: function(handler) {
        this.get_events().removeHandler('hover', handler);
        },

        // Bind and unbind to unhover event.
        add_unhover: function(handler) {
        this.get_events().addHandler('unhover', handler);
        },
        remove_unhover: function(handler) {
        this.get_events().removeHandler('unhover', handler);
        },

        // Release resources before control is disposed.
        dispose: function() {

        var element = this.get_element();

        if (this._clickDelegate) {
        Sys.UI.DomEvent.removeHandler(element, 'click', this._clickDelegate);
        delete this._clickDelegate;
        }

        if (this._hoverDelegate) {
        Sys.UI.DomEvent.removeHandler(element, 'focus', this._hoverDelegate);
        Sys.UI.DomEvent.removeHandler(element, 'mouseover', this._hoverDelegate);
        delete this._hoverDelegate;
        }

        if (this._unhoverDelegate) {
        Sys.UI.DomEvent.removeHandler(element, 'blur', this._unhoverDelegate);
        Sys.UI.DomEvent.removeHandler(element, 'mouseout', this._unhoverDelegate);
        delete this._unhoverDelegate;
        }
        Demo.HoverButton.callBaseMethod(this, 'dispose');
        },

        initialize: function() {

        var element = this.get_element();

        if (!element.tabIndex) element.tabIndex = 0;

        if (this._clickDelegate === null) {
        this._clickDelegate = Function.createDelegate(this, this._clickHandler);
        }
        Sys.UI.DomEvent.addHandler(element, 'click', this._clickDelegate);

        if (this._hoverDelegate === null) {
        this._hoverDelegate = Function.createDelegate(this, this._hoverHandler);
        }
        Sys.UI.DomEvent.addHandler(element, 'mouseover', this._hoverDelegate);
        Sys.UI.DomEvent.addHandler(element, 'focus', this._hoverDelegate);

        if (this._unhoverDelegate === null) {
        this._unhoverDelegate = Function.createDelegate(this, this._unhoverHandler);
        }
        Sys.UI.DomEvent.addHandler(element, 'mouseout', this._unhoverDelegate);
        Sys.UI.DomEvent.addHandler(element, 'blur', this._unhoverDelegate);

        Demo.HoverButton.callBaseMethod(this, 'initialize');

        },
        _clickHandler: function(event) {
        var h = this.get_events().getHandler('click');
        if (h) h(this, Sys.EventArgs.Empty);
        },
        _hoverHandler: function(event) {
        var h = this.get_events().getHandler('hover');
        if (h) h(this, Sys.EventArgs.Empty);
        },
        _unhoverHandler: function(event) {
        var h = this.get_events().getHandler('unhover');
        if (h) h(this, Sys.EventArgs.Empty);
        }
        }

        Demo.HoverButton.registerClass('Demo.HoverButton', Sys.UI.Control);

        // Since this script is not loaded by System.Web.Handlers.ScriptResourceHandler
        // invoke Sys.Application.notifyScriptLoaded to notify ScriptManager
        // that this is the end of the script.
        if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

        </pre>


        <p>Here the hookup code</p>

        <pre data-sub="prettyprint:_">
        var app = Sys.Application;
        app.add_load(applicationLoadHandler);

        function applicationLoadHandler(sender, args) {
        $create(
        Demo.HoverButton, //The component type.
        {text: 'A HoverButton Control',element: {style: {fontWeight: "bold", borderWidth: "2px"}}}, //A JSON object that contains a component ID value and optionally any initial property name/value pairs.
        {click: start, hover: doSomethingOnHover, unhover: doSomethingOnUnHover}, //An optional JSON object that contains event name and event/handler binding pairs.
        null, //An optional JSON object that contains references to associated components, passed as component name/ID pairs.
        $get('Button1') //clientside control
        );
        }

        function doSomethingOnHover(sender, args) {
        hoverMessage = "The mouse is over the button."
        $get('HoverLabel').innerHTML = hoverMessage;
        }

        function doSomethingOnUnHover(sender, args) {
        $get('HoverLabel').innerHTML = "";
        }

        function start(sender, args) {
        alert("The start function handled the HoverButton click event.");
        }
        </pre>