现在有个主窗体程序A,A执行到某一步的时候我想建立一个新Thread调用B,B是一段逻辑,b执行完毕以后会弹出一个浮动窗体告诉用户结果。
其实代码很简单,以下3行代码都是在A里面的
      HCheckIn_Out h = new HCheckIn_Out();
     Thread t = new Thread(new ThreadStart(h.HCheckIn));
     t.Start();
HCheckIn里执行了
      show浮动窗体();
但是以上程序的执行结果是浮动窗体没有出现,过了一段时间提示“内存不足”然后程序就崩溃了。
不知道应该如何改,期待各位解答,谢谢。

解决方案 »

  1.   

    在线程里是否循环调用Show(),产生很多窗体导致内存out.
      

  2.   

    这位任兄的主意不错
    我认为在线程里就没有触发Show(),而是在前面是否出现死循环?
      

  3.   

    多谢楼上各位。
    我后来做了下测试,线程B当中如果弹出的是一个普通的Dialog,那程序可以正常运行。
    但是如果改成我们现在的浮动窗口就无法显示了。我现在把TaskBarNotifier代码贴在下面,希望能找到原因。谢谢。// C# TaskbarNotifier Class v1.0
    // 11 january 2003 : Patrick Vanden Driessche <[email protected]> added a few enhancements
    //           Small Enhancements/Bugfix
    //           Small bugfix: When Content text measures larger than the corresponding ContentRectangle
    //                         the focus rectangle was not correctly drawn. This has been solved.
    //           Added KeepVisibleOnMouseOver
    //           Added ReShowOnMouseOver
    //           Added If the Title or Content are too long to fit in the corresponding Rectangles,
    //                 the text is truncateed and the ellipses are appended (StringTrimming).using System;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Drawing.Drawing2D;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;namespace Hiboard
    {
    /// <summary>
    /// TaskbarNotifier allows to display MSN style/Skinned instant messaging popups
    /// </summary>
    public class TaskbarNotifier : System.Windows.Forms.Form
    {
    #region TaskbarNotifier Protected Members
    protected Bitmap BackgroundBitmap = null;
    protected Bitmap CloseBitmap = null;
    protected Point CloseBitmapLocation;
    protected Size CloseBitmapSize;
    protected Rectangle RealTitleRectangle;
    protected Rectangle RealContentRectangle;
    protected Rectangle WorkAreaRectangle;
    protected Timer timer = new Timer();
    protected TaskbarStates taskbarState = TaskbarStates.hidden;
    protected string titleText;
    protected string contentText;
    protected Color normalTitleColor = Color.FromArgb(255,0,0);
    protected Color hoverTitleColor = Color.FromArgb(255,0,0);
    protected Color normalContentColor = Color.FromArgb(0,0,0);
    protected Color hoverContentColor = Color.FromArgb(0,0,0x66);
    protected Font normalTitleFont = new Font("Arial",12,FontStyle.Regular,GraphicsUnit.Pixel);
    protected Font hoverTitleFont = new Font("Arial",12,FontStyle.Bold,GraphicsUnit.Pixel);
    protected Font normalContentFont = new Font("Arial",11,FontStyle.Regular,GraphicsUnit.Pixel);
    protected Font hoverContentFont = new Font("Arial",11,FontStyle.Regular,GraphicsUnit.Pixel);
    protected int nShowEvents;
    protected int nHideEvents;
    protected int nVisibleEvents;
    protected int nIncrementShow;
    protected int nIncrementHide;
    protected bool bIsMouseOverPopup = false;
    protected bool bIsMouseOverClose = false;
    protected bool bIsMouseOverContent = false;
    protected bool bIsMouseOverTitle = false;
    protected bool bIsMouseDown = false;
    protected bool bKeepVisibleOnMouseOver = true; // Added Rev 002
    protected bool bReShowOnMouseOver = false; // Added Rev 002
    #endregion

    #region TaskbarNotifier Public Members
    public Rectangle TitleRectangle;
    public Rectangle ContentRectangle;
    public bool TitleClickable = false;
    public bool ContentClickable = true;
    public bool CloseClickable = true;
    public bool EnableSelectionRectangle = true;
    public event EventHandler CloseClick = null;
    public event EventHandler TitleClick = null;
    public event EventHandler ContentClick = null;
    #endregion

    #region TaskbarNotifier Enums
    /// <summary>
    /// List of the different popup animation status
    /// </summary>
    public enum TaskbarStates
    {
    hidden = 0,
    appearing = 1,
    visible = 2,
    disappearing = 3
    }
    #endregion #region TaskbarNotifier Constructor
    /// <summary>
    /// The Constructor for TaskbarNotifier
    /// </summary>
    public TaskbarNotifier()
    {
    // Window Style
    FormBorderStyle = FormBorderStyle.None;
    WindowState = FormWindowState.Minimized;
    base.Show();
    base.Hide();
    WindowState = FormWindowState.Normal;
    ShowInTaskbar = false;
    TopMost = true;
    MaximizeBox = false;
    MinimizeBox = false;
    ControlBox = false;

    timer.Enabled = true;
    timer.Tick += new EventHandler(OnTimer);
    }
    #endregion #region TaskbarNotifier Properties
    /// <summary>
    /// Get the current TaskbarState (hidden, showing, visible, hiding)
    /// </summary>
    public TaskbarStates TaskbarState
    {
    get
    {
    return taskbarState;
    }
    } /// <summary>
    /// Get/Set the popup Title Text
    /// </summary>
    public string TitleText
    {
    get
    {
    return titleText;
    }
    set
    {
    titleText=value;
    Refresh();
    }
    } /// <summary>
    /// Get/Set the popup Content Text
    /// </summary>
    public string ContentText
    {
    get
    {
    return contentText;
    }
    set
    {
    contentText=value;
    Refresh();
    }
    } /// <summary>
    /// Get/Set the Normal Title Color
    /// </summary>
    public Color NormalTitleColor
    {
    get
    {
    return normalTitleColor;
    }
    set
    {
    normalTitleColor = value;
    Refresh();
    }
    } /// <summary>
    /// Get/Set the Hover Title Color
    /// </summary>
    public Color HoverTitleColor
    {
    get
    {
    return hoverTitleColor;
    }
    set
    {
    hoverTitleColor = value;
    Refresh();
    }
    } /// <summary>
    /// Get/Set the Normal Content Color
    /// </summary>
    public Color NormalContentColor
    {
    get
    {
    return normalContentColor;
    }
    set
    {
    normalContentColor = value;
    Refresh();
    }
    } /// <summary>
    /// Get/Set the Hover Content Color
    /// </summary>
    public Color HoverContentColor
    {
    get
    {
    return hoverContentColor;
    }
    set
    {
    hoverContentColor = value;
    Refresh();
    }
    } /// <summary>
    /// Get/Set the Normal Title Font
    /// </summary>
    public Font NormalTitleFont
    {
    get
    {
    return normalTitleFont;
    }
    set
    {
    normalTitleFont = value;
    Refresh();
    }
    } /// <summary>
    /// Get/Set the Hover Title Font
    /// </summary>
    public Font HoverTitleFont
    {
    get
    {
    return hoverTitleFont;
    }
    set
    {
    hoverTitleFont = value;
    Refresh();
    }
    } /// <summary>
    /// Get/Set the Normal Content Font
    /// </summary>
    public Font NormalContentFont
    {
    get
    {
    return normalContentFont;
    }
    set
    {
    normalContentFont = value;
    Refresh();
    }
    } /// <summary>
    /// Get/Set the Hover Content Font
    /// </summary>
    public Font HoverContentFont
    {
    get
    {
    return hoverContentFont;
    }
    set
    {
    hoverContentFont = value;
    Refresh();
    }
    } /// <summary>
    /// Indicates if the popup should remain visible when the mouse pointer is over it.
    /// Added Rev 002
    /// </summary>
    public bool KeepVisibleOnMousOver
    {
    get
    {
    return bKeepVisibleOnMouseOver;
    }
    set
    {
    bKeepVisibleOnMouseOver=value;
    }
    } /// <summary>
    /// Indicates if the popup should appear again when mouse moves over it while it's disappearing.
    /// Added Rev 002
    /// </summary>
    public bool ReShowOnMouseOver
    {
    get
    {
    return bReShowOnMouseOver;
    }
    set
    {
    bReShowOnMouseOver=value;
    }
    } #endregion
      

  4.   


    #region TaskbarNotifier Public Methods
    [DllImport("user32.dll")]
    private static extern Boolean ShowWindow(IntPtr hWnd,Int32 nCmdShow);
    /// <summary>
    /// Displays the popup for a certain amount of time
    /// </summary>
    /// <param name="strTitle">The string which will be shown as the title of the popup</param>
    /// <param name="strContent">The string which will be shown as the content of the popup</param>
    /// <param name="nTimeToShow">Duration of the showing animation (in milliseconds)</param>
    /// <param name="nTimeToStay">Duration of the visible state before collapsing (in milliseconds)</param>
    /// <param name="nTimeToHide">Duration of the hiding animation (in milliseconds)</param>
    /// <returns>Nothing</returns>
    public void Show(string strTitle, string strContent, int nTimeToShow, int nTimeToStay, int nTimeToHide)
    {
    WorkAreaRectangle = Screen.GetWorkingArea(WorkAreaRectangle);
    titleText = strTitle;
    contentText = strContent;
    nVisibleEvents = nTimeToStay;
    CalculateMouseRectangles(); // We calculate the pixel increment and the timer value for the showing animation
    int nEvents;
    if (nTimeToShow > 10)
    {
    nEvents = Math.Min((nTimeToShow / 10), BackgroundBitmap.Height);
    nShowEvents = nTimeToShow / nEvents;
    nIncrementShow = BackgroundBitmap.Height / nEvents;
    }
    else
    {
    nShowEvents = 10;
    nIncrementShow = BackgroundBitmap.Height;
    } // We calculate the pixel increment and the timer value for the hiding animation
    if( nTimeToHide > 10)
    {
    nEvents = Math.Min((nTimeToHide / 10), BackgroundBitmap.Height);
    nHideEvents = nTimeToHide / nEvents;
    nIncrementHide = BackgroundBitmap.Height / nEvents;
    }
    else
    {
    nHideEvents = 10;
    nIncrementHide = BackgroundBitmap.Height;
    } switch (taskbarState)
    {
    case TaskbarStates.hidden:
    taskbarState = TaskbarStates.appearing;
    SetBounds(WorkAreaRectangle.Right-BackgroundBitmap.Width-17,
                            WorkAreaRectangle.Bottom-1, BackgroundBitmap.Width, 0);
    timer.Interval = nShowEvents;
    timer.Start();
    // We Show the popup without stealing focus
    ShowWindow(this.Handle, 4);
    break; case TaskbarStates.appearing:
    Refresh();
    break; case TaskbarStates.visible:
    timer.Stop();
    timer.Interval = nVisibleEvents;
    timer.Start();
    Refresh();
    break; case TaskbarStates.disappearing:
    timer.Stop();
    taskbarState = TaskbarStates.visible;
    SetBounds(WorkAreaRectangle.Right-BackgroundBitmap.Width-17, WorkAreaRectangle.Bottom-BackgroundBitmap.Height-1, BackgroundBitmap.Width, BackgroundBitmap.Height);
    timer.Interval = nVisibleEvents;
    timer.Start();
    Refresh();
    break;
    }
    } /// <summary>
    /// Hides the popup
    /// </summary>
    /// <returns>Nothing</returns>
    public new void Hide()
    {
    if (taskbarState != TaskbarStates.hidden)
    {
    timer.Stop();
    taskbarState = TaskbarStates.hidden;
    base.Hide();
    }
    } /// <summary>
    /// Sets the background bitmap and its transparency color
    /// </summary>
    /// <param name="strFilename">Path of the Background Bitmap on the disk</param>
    /// <param name="transparencyColor">Color of the Bitmap which won't be visible</param>
    /// <returns>Nothing</returns>
    public void SetBackgroundBitmap(string strFilename, Color transparencyColor)
    {
    BackgroundBitmap = new Bitmap(strFilename);
    Width = BackgroundBitmap.Width;
    Height = BackgroundBitmap.Height;
    Region = BitmapToRegion(BackgroundBitmap, transparencyColor);
    } /// <summary>
    /// Sets the background bitmap and its transparency color
    /// </summary>
    /// <param name="image">Image/Bitmap object which represents the Background Bitmap</param>
    /// <param name="transparencyColor">Color of the Bitmap which won't be visible</param>
    /// <returns>Nothing</returns>
    public void SetBackgroundBitmap(Image image, Color transparencyColor)
    {
    BackgroundBitmap = new Bitmap(image);
    Width = BackgroundBitmap.Width;
    Height = BackgroundBitmap.Height;
    Region = BitmapToRegion(BackgroundBitmap, transparencyColor);
    } /// <summary>
    /// Sets the 3-State Close Button bitmap, its transparency color and its coordinates
    /// </summary>
    /// <param name="strFilename">Path of the 3-state Close button Bitmap on the disk (width must a multiple of 3)</param>
    /// <param name="transparencyColor">Color of the Bitmap which won't be visible</param>
    /// <param name="position">Location of the close button on the popup</param>
    /// <returns>Nothing</returns>
    public void SetCloseBitmap(string strFilename, Color transparencyColor, Point position)
    {
    CloseBitmap = new Bitmap(strFilename);
    CloseBitmap.MakeTransparent(transparencyColor);
    CloseBitmapSize = new Size(CloseBitmap.Width/3, CloseBitmap.Height);
    CloseBitmapLocation = position;
    } /// <summary>
    /// Sets the 3-State Close Button bitmap, its transparency color and its coordinates
    /// </summary>
    /// <param name="image">Image/Bitmap object which represents the 3-state Close button Bitmap (width must be a multiple of 3)</param>
    /// <param name="transparencyColor">Color of the Bitmap which won't be visible</param>
    /// /// <param name="position">Location of the close button on the popup</param>
    /// <returns>Nothing</returns>
    public void SetCloseBitmap(Image image, Color transparencyColor, Point position)
    {
    CloseBitmap = new Bitmap(image);
    CloseBitmap.MakeTransparent(transparencyColor);
    CloseBitmapSize = new Size(CloseBitmap.Width/3, CloseBitmap.Height);
    CloseBitmapLocation = position;
    }
    #endregion #region TaskbarNotifier Protected Methods
    protected void DrawCloseButton(Graphics grfx)
    {
    if (CloseBitmap != null)
    {
    Rectangle rectDest = new Rectangle(CloseBitmapLocation, CloseBitmapSize);
    Rectangle rectSrc; if (bIsMouseOverClose)
    {
    if (bIsMouseDown)
    rectSrc = new Rectangle(new Point(CloseBitmapSize.Width*2, 0), CloseBitmapSize);
    else
    rectSrc = new Rectangle(new Point(CloseBitmapSize.Width, 0), CloseBitmapSize);
    }
    else
    rectSrc = new Rectangle(new Point(0, 0), CloseBitmapSize);
    grfx.DrawImage(CloseBitmap, rectDest, rectSrc, GraphicsUnit.Pixel);
    }
    } protected void DrawText(Graphics grfx)
    {
    if (titleText != null && titleText.Length != 0)
    {
    StringFormat sf = new StringFormat();
    sf.Alignment = StringAlignment.Near;
    sf.LineAlignment = StringAlignment.Center;
    sf.FormatFlags = StringFormatFlags.NoWrap;
    sf.Trimming = StringTrimming.EllipsisCharacter; // Added Rev 002
    if (bIsMouseOverTitle)
    grfx.DrawString(titleText, hoverTitleFont, new SolidBrush(hoverTitleColor), TitleRectangle, sf);
    else
    grfx.DrawString(titleText, normalTitleFont, new SolidBrush(normalTitleColor), TitleRectangle, sf);
    } if (contentText != null && contentText.Length != 0)
    {
    StringFormat sf = new StringFormat();
    sf.Alignment = StringAlignment.Center;
    sf.LineAlignment = StringAlignment.Center;
    sf.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;
    sf.Trimming = StringTrimming.Word; // Added Rev 002

    if (bIsMouseOverContent)
    {
    grfx.DrawString(contentText, hoverContentFont, new SolidBrush(hoverContentColor), ContentRectangle, sf);
    if (EnableSelectionRectangle)
    ControlPaint.DrawBorder3D(grfx, RealContentRectangle, Border3DStyle.Etched, Border3DSide.Top | Border3DSide.Bottom | Border3DSide.Left | Border3DSide.Right);

    }
    else
    grfx.DrawString(contentText, normalContentFont, new SolidBrush(normalContentColor), ContentRectangle, sf);
    }
    }
      

  5.   


    protected void CalculateMouseRectangles()
    {
    Graphics grfx = CreateGraphics();
    StringFormat sf = new StringFormat();
    sf.Alignment = StringAlignment.Center;
    sf.LineAlignment = StringAlignment.Center;
    sf.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;
    SizeF sizefTitle = grfx.MeasureString(titleText, hoverTitleFont, TitleRectangle.Width, sf);
    SizeF sizefContent = grfx.MeasureString(contentText, hoverContentFont, ContentRectangle.Width, sf);
    grfx.Dispose(); // Added Rev 002
            //We should check if the title size really fits inside the pre-defined title rectangle
    if (sizefTitle.Height > TitleRectangle.Height)
    {
    RealTitleRectangle = new Rectangle(TitleRectangle.Left, TitleRectangle.Top, TitleRectangle.Width , TitleRectangle.Height );

    else
    {
    RealTitleRectangle = new Rectangle(TitleRectangle.Left, TitleRectangle.Top, (int)sizefTitle.Width, (int)sizefTitle.Height);
    }
    RealTitleRectangle.Inflate(0,2); // Added Rev 002
    //We should check if the Content size really fits inside the pre-defined Content rectangle
    if (sizefContent.Height > ContentRectangle.Height)
    {
    RealContentRectangle = new Rectangle((ContentRectangle.Width-(int)sizefContent.Width)/2+ContentRectangle.Left, ContentRectangle.Top, (int)sizefContent.Width, ContentRectangle.Height );
    }
    else
    {
    RealContentRectangle = new Rectangle((ContentRectangle.Width-(int)sizefContent.Width)/2+ContentRectangle.Left, (ContentRectangle.Height-(int)sizefContent.Height)/2+ContentRectangle.Top, (int)sizefContent.Width, (int)sizefContent.Height);
    }
    RealContentRectangle.Inflate(0,2);
    } protected Region BitmapToRegion(Bitmap bitmap, Color transparencyColor)
    {
    if (bitmap == null)
    throw new ArgumentNullException("Bitmap", "Bitmap cannot be null!"); int height = bitmap.Height;
    int width = bitmap.Width; GraphicsPath path = new GraphicsPath(); for (int j=0; j<height; j++ )
    for (int i=0; i<width; i++)
    {
    if (bitmap.GetPixel(i, j) == transparencyColor)
    continue; int x0 = i; while ((i < width) && (bitmap.GetPixel(i, j) != transparencyColor))
    i++; path.AddRectangle(new Rectangle(x0, j, i-x0, 1));
    } Region region = new Region(path);
    path.Dispose();
    return region;
    }
    #endregion #region TaskbarNotifier Events Overrides
    protected void OnTimer(Object obj, EventArgs ea)
    {
    switch (taskbarState)
    {
    case TaskbarStates.appearing:
    if (Height < BackgroundBitmap.Height)
    SetBounds(Left, Top-nIncrementShow ,Width, Height + nIncrementShow);
    else
    {
    timer.Stop();
    Height = BackgroundBitmap.Height;
    timer.Interval = nVisibleEvents;
    taskbarState = TaskbarStates.visible;
    timer.Start();
    }
    break; case TaskbarStates.visible:
    timer.Stop();
    timer.Interval = nHideEvents;
    // Added Rev 002
    if ((bKeepVisibleOnMouseOver && !bIsMouseOverPopup ) || (!bKeepVisibleOnMouseOver))
    {
    taskbarState = TaskbarStates.disappearing;

    //taskbarState = TaskbarStates.disappearing; // Rev 002
    timer.Start();
    break; case TaskbarStates.disappearing:
    // Added Rev 002
    if (bReShowOnMouseOver && bIsMouseOverPopup) 
    {
    taskbarState = TaskbarStates.appearing;

    else 
    {
    if (Top < WorkAreaRectangle.Bottom)
    SetBounds(Left, Top + nIncrementHide, Width, Height - nIncrementHide);
    else
    Hide();
    }
    break;
    }

    } protected override void OnMouseEnter(EventArgs ea)
    {
    base.OnMouseEnter(ea);
    bIsMouseOverPopup = true;
    Refresh();
    } protected override void OnMouseLeave(EventArgs ea)
    {
    base.OnMouseLeave(ea);
    bIsMouseOverPopup = false;
    bIsMouseOverClose = false;
    bIsMouseOverTitle = false;
    bIsMouseOverContent = false;
    Refresh();
    } protected override void OnMouseMove(MouseEventArgs mea)
    {
    base.OnMouseMove(mea); bool bContentModified = false;

    if ( (mea.X > CloseBitmapLocation.X) && (mea.X < CloseBitmapLocation.X + CloseBitmapSize.Width) && (mea.Y > CloseBitmapLocation.Y) && (mea.Y < CloseBitmapLocation.Y + CloseBitmapSize.Height) && CloseClickable )
    {
    if (!bIsMouseOverClose)
    {
    bIsMouseOverClose = true;
    bIsMouseOverTitle = false;
    bIsMouseOverContent = false;
    Cursor = Cursors.Hand;
    bContentModified = true;
    }
    }
    else if (RealContentRectangle.Contains(new Point(mea.X, mea.Y)) && ContentClickable)
    {
    if (!bIsMouseOverContent)
    {
    bIsMouseOverClose = false;
    bIsMouseOverTitle = false;
    bIsMouseOverContent = true;
    Cursor = Cursors.Hand;
    bContentModified = true;
    }
    }
    else if (RealTitleRectangle.Contains(new Point(mea.X, mea.Y)) && TitleClickable)
    {
    if (!bIsMouseOverTitle)
    {
    bIsMouseOverClose = false;
    bIsMouseOverTitle = true;
    bIsMouseOverContent = false;
    Cursor = Cursors.Hand;
    bContentModified = true;
    }
    }
    else
    {
    if (bIsMouseOverClose || bIsMouseOverTitle || bIsMouseOverContent)
    bContentModified = true; bIsMouseOverClose = false;
    bIsMouseOverTitle = false;
    bIsMouseOverContent = false;
    Cursor = Cursors.Default;
    } if (bContentModified)
    Refresh();
    } protected override void OnMouseDown(MouseEventArgs mea)
    {
    base.OnMouseDown(mea);
    bIsMouseDown = true;

    if (bIsMouseOverClose)
    Refresh();
    } protected override void OnMouseUp(MouseEventArgs mea)
    {
    base.OnMouseUp(mea);
    bIsMouseDown = false; if (bIsMouseOverClose)
    {
    Hide();

    if (CloseClick != null)
    CloseClick(this, new EventArgs());
    }
    else if (bIsMouseOverTitle)
    {
    if (TitleClick != null)
    TitleClick(this, new EventArgs());
    }
    else if (bIsMouseOverContent)
    {
    if (ContentClick != null)
    ContentClick(this, new EventArgs());
    }
    } protected override void OnPaintBackground(PaintEventArgs pea)
    {
    Graphics grfx = pea.Graphics;
    grfx.PageUnit = GraphicsUnit.Pixel;

    Graphics offScreenGraphics;
    Bitmap offscreenBitmap;

    offscreenBitmap = new Bitmap(BackgroundBitmap.Width, BackgroundBitmap.Height);
    offScreenGraphics = Graphics.FromImage(offscreenBitmap);

    if (BackgroundBitmap != null)
    {
    offScreenGraphics.DrawImage(BackgroundBitmap, 0, 0, BackgroundBitmap.Width, BackgroundBitmap.Height);
    }

    DrawCloseButton(offScreenGraphics);
    DrawText(offScreenGraphics); grfx.DrawImage(offscreenBitmap, 0, 0);
    }
    #endregion
    }
    }