/// <summary>
 /// Closes the tooltip
 /// </summary>
 private void CloseToolTip()
 {
     WINAPI.TOOLINFO ti = new WINAPI.TOOLINFO();
     ti.cbSize = Marshal.SizeOf(ti.GetType());
     ti.hwnd = GetHandler(moNotifyIcon);
     WINAPI.SendMessage(moNativeWindow.Handle, WINAPI.TTM_DELTOOL, 0, ref ti);
     OnBalloonTipClosed(this, EventArgs.Empty);
     moNativeWindow = new NativeWindow();
 }
        /// <summary>
        /// Tooltip window proc
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="iMsg"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        protected int WindowProc(IntPtr hWnd, UInt32 iMsg, IntPtr wParam, IntPtr lParam)
        {
            int height = 0;
            int width = 0;

            IntPtr nativeProc = WINAPI.GetProp(hWnd, "NATIVEPROC");

            if (iMsg == WINAPI.WM_PAINT)
            {
                // Drow the original tooltip
                int liWinProcResult = WINAPI.CallWindowProc(nativeProc, hWnd, iMsg, wParam, lParam);

                WINAPI.TOOLINFO ti = new WINAPI.TOOLINFO();
                ti.cbSize = Marshal.SizeOf(ti.GetType());
                ti.hwnd = GetHandler(moNotifyIcon);

                if (ti.hwnd != IntPtr.Zero)
                {
                    // Create graphics object for the tooltip
                    Graphics loGraphics = Graphics.FromHwnd(hWnd);

                    WINAPI.RECT rect = new WINAPI.RECT();
                    WINAPI.RECT rect1 = new WINAPI.RECT();

                    WINAPI.GetWindowRect(hWnd, ref rect);

                    // In rect1 - tooltip rectangle
                    // Calculate text display rectangle to rect
                    rect1 = rect;
                    WINAPI.SendMessage(hWnd, WINAPI.TTM_ADJUSTRECT, 0, out rect);

                    // Width and heigth of the text area
                    width = rect.right - rect.left;
                    height = rect.bottom - rect.top;

                    //Calculate iner rectangle of the text area
                    rect.left = rect.left - rect1.left;
                    rect.top = rect.top - rect1.top;
                    rect.right = rect.left + width;
                    rect.bottom = rect.top + height;

                    //Clear text area: 16 pixs - header, 30 pixs from bottom
                    loGraphics.FillRectangle(new SolidBrush(Color.LightYellow), new Rectangle(rect.left, rect.top + 16, width, height-30));

                    //Add close button and click handler
                    // 16 pixs for the button control
                    moCloseButton.Location = new System.Drawing.Point(rect.right - 16, rect.top);
                    moCloseButton.AutoSize = false;
                    moCloseButton.Click += CloseButtonClick;

                    WINAPI.SetParent(moCloseButton.Handle, hWnd);

                    //Adding panel to the tooltip below the header
                    moPanel.Location = new Point(rect.left, rect.top + 16);
                    WINAPI.SetParent(moPanel.Handle, hWnd);

                    loGraphics = null;

                }

                return liWinProcResult;
            }


            return WINAPI.CallWindowProc(nativeProc, hWnd, iMsg, wParam, lParam);
        }
        /// <summary>
        /// Shows the ballon tooltip
        /// </summary>
        /// <param name="timeout"></param>
        public void ShowBalloonTip(int timeout)
        {

            //Check if a balloon already is shown or no user control was defined
            if (moNativeWindow.Handle != IntPtr.Zero || moPanel == null)
                return;

            //Get a handle for the notify icon
            IntPtr loNotifyIconHandle = GetHandler(moNotifyIcon);

            if (loNotifyIconHandle == IntPtr.Zero)
                return;

            //Trying to find notify icon rectangle on a desktop
            if (!GetNotifyIconScreenRect(loNotifyIconHandle))
                return;

            //Create parameters for a new tooltip window
            System.Windows.Forms.CreateParams moCreateParams = new System.Windows.Forms.CreateParams();

            // New window is a tooltip and a balloon
            moCreateParams.ClassName = WINAPI.TOOLTIPS_CLASS;
            moCreateParams.Style = WINAPI.WS_POPUP | WINAPI.TTS_NOPREFIX | WINAPI.TTS_ALWAYSTIP | WINAPI.TTS_BALLOON;
            moCreateParams.Parent = loNotifyIconHandle;

            // Create the tooltip window
            moNativeWindow.CreateHandle(moCreateParams);

            //We save old window proc to be used later and replac it our own
            IntPtr loNativeProc = WINAPI.SetWindowLong(moNativeWindow.Handle, WINAPI.GWL_WNDPROC, wpcallback);

            if (loNativeProc == IntPtr.Zero)
                return;

            if (WINAPI.SetProp(moNativeWindow.Handle, "NATIVEPROC", loNativeProc) == 0)
                return;

            // Make tooltip  the top level window
            if (!WINAPI.SetWindowPos(moNativeWindow.Handle, WINAPI.HWND_TOPMOST, 0, 0, 0, 0, WINAPI.SWP_NOACTIVATE | WINAPI.SWP_NOSIZE))
                return;

            // Tool tip info. Set a TRACK flag to show it in specified position
            WINAPI.TOOLINFO ti = new WINAPI.TOOLINFO();
            ti.cbSize = Marshal.SizeOf(ti);
            ti.uFlags = WINAPI.TTF_TRACK;
            ti.hwnd = loNotifyIconHandle;


            //Approximating window size by use of char size
            WINAPI.SIZE size = new WINAPI.SIZE();
            IntPtr hDC = WINAPI.GetDC(moNativeWindow.Handle);

            if (hDC == IntPtr.Zero)
                return;

            if (WINAPI.GetTextExtentPoint32(hDC, ".", 1, ref size) == 0)
                return;

            int lines = 1 + moPanel.Height / size.cy;
            int cols = moPanel.Width / size.cx;

            ti.lpszText = ".";
            for (int i = 0; i < lines; i++)
            {
                for (int j = 0; j < cols; j++)
                    ti.lpszText += ".";
                ti.lpszText += "\r\n";
            }


            //Add tool to the notify icon
            if (WINAPI.SendMessage(moNativeWindow.Handle, WINAPI.TTM_ADDTOOL, 0, ref ti) == 0)
                return;

            WINAPI.SendMessage(moNativeWindow.Handle, WINAPI.TTM_SETTIPBKCOLOR,
                ColorTranslator.ToWin32(Color.LightYellow), ref ti);

            WINAPI.SendMessage(moNativeWindow.Handle, WINAPI.TTM_SETTIPTEXTCOLOR,
                ColorTranslator.ToWin32(Color.Black), ref ti);

            WINAPI.SendMessage(moNativeWindow.Handle, WINAPI.TTM_SETDELAYTIME, Duration.AutoPop, 1000);
            WINAPI.SendMessage(moNativeWindow.Handle, WINAPI.TTM_TRACKPOSITION, 0, (moPosition.Y << 16) + moPosition.X);
            WINAPI.SendMessage(moNativeWindow.Handle, WINAPI.TTM_SETTITLE, (int)BalloonTipIcon, BalloonTipTitle);
            WINAPI.SendMessage(moNativeWindow.Handle, WINAPI.TTM_TRACKACTIVATE, 1, ref ti);

            // Raise shown event
            OnBalloonTipShown(this, EventArgs.Empty);

            // Timeout for the tooltip
            moTimer.Interval = timeout;
            moTimer.Start();
        }