none
設定MessageBox在若干時間之後自動關閉 for C# RRS feed

  • 問題

  • 各位先進前輩 請問,
    我想要
    MessageBox在X秒後自動消失,
    該如何用FindWindow找到MessageBox,
    用SendMessage關閉它呢?

    備註:
    使用VS2005 C#語言
    智慧型裝置OS為Mobile5.0


    程式碼區塊

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    using System.Threading;
    //using Microsoft.Win32;

    namespace Msg
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }

            #region Dll Import
            [DllImport("user32", EntryPoint="FindWindow")]
            public static extern int FindWindowA(string lpClassName, string lpWindowName);
            [DllImport("user32.dll", EntryPoint = "FindWindowEx")]
            private static extern IntPtr FindWindowEx(IntPtr hwndParent,IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
            [DllImport("User32.dll", EntryPoint = "SendMessage")]
            private static extern int SendMessage(IntPtr hWnd,int Msg, IntPtr wParam, string lParam);
            [DllImport("user32", EntryPoint = "SendMessageTimeout")]
            public static extern int SendMessageTimeoutA(int hwnd, int MSG, int wParam, int lParam, int fuFlags, int uTimeout, ref int lpdwResult);
            #endregion

            public const int WM_CLOSE = 0x10;
            public const string MsgTitle = "Test Message";

            private void button1_Click(object sender, EventArgs e)
            {
               timer1.Interval = 3000;
               timer1.Enabled = true;
               MessageBox.Show("若不回應的話,X秒後此 MsgBox 會自動關閉", MsgTitle);
               timer1.Enabled = false;
            }

            private void timer1_Tick(object sender, EventArgs e)
            {
                int hWnd;
                string lpClassName;
                hWnd = FindWindow(lpClassName, MsgTitle);
                //FindWindow(button1_Click, MsgTitle);
                SendMessage(hWnd);
            }
        }
    }


    2007年12月3日 下午 12:29

解答

所有回覆

  • HI,

     

    您可以直接在C#程式中以P/Invoke技巧呼叫MessageBoxTimeout API:

     

    http://www.codeproject.com/KB/cpp/MessageBoxTimeout.aspx

     

    tihs

    2007年12月4日 上午 03:00

  • 謝謝兩位前輩的指導,
    我再慢慢研究研究。
    2007年12月6日 上午 03:33
  • 試試看...

     

    程式碼區塊

    using System;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;

     

    namespace WindowsApplication1
    {
      public partial class Form1 : Form
      {


        public Form1()
        {
          InitializeComponent();
        }

     

        private void Form1_Load(object sender, EventArgs e)
        {
          MessageBoxTimeout.Show("It will be closed automatically in 5 seconds", "MessageBox With Timeout", 5000);
        }


      }

     

      public class MessageBoxTimeout
      {
        [DllImport("kernel32.dll")]
        private static extern uint GetCurrentThreadId();

        private delegate int EnumWindowsProc(IntPtr hWnd, IntPtr lParam);

     

        [DllImport("user32.dll")]
        private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);

     

        [DllImport("user32.dll", SetLastError = true)]
        private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

     

        [DllImport("user32.dll")]
        private static extern int GetClassName(IntPtr hWnd, [Out] StringBuilder lpClassName, int nMaxCount);

     

        [DllImport("user32.dll")]
        private static extern bool IsWindowEnabled(IntPtr hWnd);

     

        [DllImport("user32.dll", SetLastError = true)]
        [return : MarshalAs(UnmanagedType.Bool)]
        private static extern bool PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

     

        private class TimerThread
        {


          private readonly DateTime timeoutTime;
          private readonly uint currentThreadId;
          private bool terminateFlag;
          private readonly Thread thread;

     

          public TimerThread(int timeoutMillisec)
          {
            timeoutTime = DateTime.Now.AddMilliseconds(timeoutMillisec);
            currentThreadId = GetCurrentThreadId();
            terminateFlag = false;
            thread = new Thread(ThreadProc);
            thread.Start();
          }

     

          private void ThreadProc()
          {
            while (!terminateFlag)
            {
              Thread.Sleep(100);


              if (DateTime.Now > timeoutTime)
              {
                EnumWindows(EnumWindowsProc, new IntPtr(0));
                return;
              }
            }
          }

     

          private int EnumWindowsProc(IntPtr hWnd, IntPtr lParam)
          {
            uint processId;
            uint threadId;
            threadId = GetWindowThreadProcessId(hWnd, out processId);


            if (threadId == currentThreadId)
            {
              StringBuilder className = new StringBuilder("", 256);
              GetClassName(hWnd, className, 256);
              if (className.ToString() == "#32770" && IsWindowEnabled(hWnd))
              {
                const int WM_COMMAND = 0x111;
                PostMessage(hWnd, WM_COMMAND, new IntPtr(2), new IntPtr(0));
                return 0;
              }
            }


            return 1;
          }

     

          public void Terminate()
          {
            terminateFlag = true;
            thread.Join();
          }
        }

     

        public static DialogResult Show(string text, int timeoutMillsec)
        {
          TimerThread tt = new TimerThread(timeoutMillsec);


          try
          {
            return MessageBox.Show(text);
          }
          finally
          {
            tt.Terminate();
          }
        }

     

        public static DialogResult Show(string text, string caption, int timeoutMillsec)
        {
          TimerThread tt = new TimerThread(timeoutMillsec);


          try
          {
            return MessageBox.Show(text, caption);
          }
          finally
          {
            tt.Terminate();
          }
        }
      }
    }

     

     

     

     

    2007年12月6日 上午 05:08