Excerpted from ahbian BLOG - a MessageBox with a timed closing function

xiaoxiao2021-03-06  75

With Windows Hook and some other Win32 APIs, you can use the system.windows.forms.MessageBox to use to achieve some cool results. This example implements how to add a timer to System.Windows.Forms.MessageBox. The development impulse of this example comes from Lianzhong Flying Chess. Many friends think it is not easier to use System.Windows.Forms.form multi-threaded, unfortunately - my point of view is the opposite. Developing advanced WinForm applications on .NET, (at least until now) Traditional Win32 API is unavoidable, many advanced applications and techniques must be used to use Win32 API. It is better to face with it, it is better to face it. This article does not introduce the principles and C # implementation of Windows Hook, please refer to: http://msdn.microsoft.com/msdnmag/issues/02/10/cuttingEDGE/ (About Windows Hook details, this example uses Class) http://msdn.microsoft.com/msdnmag/issues/02/11/CuttingEDGE/ (About MessageBox other surgery improvements) Before reading this text, please read the above two. This article does not introduce the principle about the C # call of Win32 API. Some Win32 enumerations referred to in the text and a large number of Win32 API come from my personal standard Win32 library (especially WindowsAPI tool class). Most methods and enumeration names are consistent with the name of MSDN, which can be said to be an eye. The specific implementation code is as follows, and the technical details of the implementation are inclusions between the code, and there is no more expensive tongue here. Finally, it is necessary to declare that this example has just been released, so it has not been tested on Windows 98. Using system.drawing; using system.windows.forms ;. USING SYSTEM.WINDOWING;

Using XXXX.COMMON.WIN32;

Namespace xxxx.library.Forms {///

/// Message box with timer function /// /// /// /// //// TIMABLEMESSAGEBOX TMMSGBOX = New TimableMessageBox (); /// TMMSGBOX.DELAYSECONDS = 15; // The default is 10 second SECONDS. /// // TMMSGBOX.CUSOTMICON = YOURICON / / can set the custom icon here. /// DialogResult DR; /// DR = TMMSGBOX.SHOW (DialogResult.no, // After the default result /// "Your message text", /// "Your Title", ////////////////////////////////////////////////////////////////////// /// MessageBoxicon.question; /// // IF (DR == DialogResult.no) /// Return; /// else //// DO Your process ... ///// < / code> /// public class timableMessageBox {// A default clock icon (shown in the diagram) // A icon from this assembly is subject to an icon // will not introduce how to set up and read embedded resources private static Icon DefaultIcon = Resources.icoTimer01; // define a static text control style private const int StaticTextControlStyle = (int) StaticStyles.SS_CENTER | (int) WindowStyles.WS_CHILD | (int) WindowStyles.WS_VISIBLE; // Win32 constant private const int ID_ICONWINDOW = 0x0014; private const int STM_SETICON = 0x0170; // variable domain protected LocalCbtHook m_cbt; protected IntPtr m_hwnd = IntPtr.Zero; protected IntPtr m_hwndStatic = IntPtr.Zero; protected IntPtr m_closeButton = IntPtr.Zero; protected bool m_bInited = false; protected bool m_btimeout = false; protected bool m_iscustom = false; Protected bool m_needenumchild = false; protected bool m_needreplaceicon = false; protected iCON m_custom; private int m_timercount = 0; private int m_delaysecond = 10;

///

/// Default constructor /// public timableMessageBox () {m_cbt = new localcbthook (); // This class is taken from MSDN Magzine, but it has been transferred to my Win32 library. M_cbt.windowcreated = new cbteventhandler (WNDCREATED); m_cbt.windowactivated = new cbteventhandler (wndactivated);} /// /// Get and sets the custom icon. /// public icon custom {get {return m_customicon;} set {m_customicon = value;}}

///

/// Get and sets the time that can stay in seconds. /// public int delayseconds {get {return m_delaysecond;} set {m_delaysecond = value;}}

Private void WNDCREATED (Object sender, cbteventargs e) {if (e.Isdialogwindow) {m_binited = false; m_hwnd = E.handle;}}

Private Void Wndactivated (Object Sender, CBTEventArgs E) {// is not the same window does not process if (m_hwnd! = E.handle) return;

// Whether it has been initialized, the subsequent changes are required only when the message frame is activated. if (m_bInited) return; else m_bInited = true; // replacement icon if (m_needReplaceIcon) {IntPtr hwndIcon1 = WindowsAPI.GetDlgItem (m_hwnd, ID_ICONWINDOW); IntPtr hIcon; if (m_isCustom) {hIcon = m_customIcon.Handle;} else {hIcon = Defaulticon.handle;} Windowsapi.sendMessage (HWndicon1, STM_SETICON, HICON, INTPTR.ZERO);}

#Region Add a static text control

/ / Get the font that can be used by static text controls. IntPtr hFont; IntPtr hwndText = WindowsAPI.GetDlgItem (m_hwnd, 0xFFFF); if (! HwndText = IntPtr.Zero) hFont = new IntPtr (WindowsAPI.SendMessage (hwndText, (int) Msg.WM_GETFONT, IntPtr.Zero, IntPtr.Zero) ); Else hfont = new intptr (windowsapi.sendMessage (m_hWnd, (int) msg.wm_getfont, intptr.zero, intptr.zero); font fcur = font.fromhfont (hfont); // Get x X of a static text control location And Y coordinate value int x = 0, y = 0; INTPTR hWndicon = Windowsapi.getdlgitem (m_hwnd, id_iconwindow); Rect RCICON = new Rect (); Windowsapi.GetWindower; Point Pt = New Point () Pt.x = rcicon.top; pt.y = rcicon.top; windowsapi.screenToclient (m_hwnd, ref pt); x = pt.x; y = pt.y rCICION.BOTTOM - RCICON.TOP 2;

// Create a static text control and add to the message box m_hwndstatic = Windowsapi.createWindowex (0, "static", "0", statictextcontrolstyle, x, y, rCICON.RIGHT - RCICON.LEFT, (int) fcur.getHeight () , M_HWND, INTPTR.ZERO, INTPTR.ZERO, INTPTR.ZERO;

/ / Update the required font windowsapi.sendMessage (m_hWndStatic, (int) msg.wm_setfont, hfont, new intptr (1)); // find the button IF on a message box if (m_needenumchild) Windowsapi.EnumChildWindows (this.m_hwnd, New Windowsapi.enumChildProc (this.enumchildWindowsProc), 0);

// Remove hook m_cbt.uninstall (); #ndregion}

/ / Time information Update Timer's Process Routor Private Void TimerupdateElapseHandler (INTPTR HWND, UINT UIMSG, UINT IDEVENT, INT DWTIME) {IF (this.m_hwndstatic == INTPTR.ZERO) Return;

// Display Time Message Text Windowsapi.SetWindowText (this.m_hwndstatic, ( m_timercount) .tostring ());}

// Close message box timer processing routine private void TimerCloseElapseHandler (IntPtr hWnd, uint uiMsg, uint idEvent, int dwTime) {// need to simulate a click operation if (m_closeButton! = IntPtr.Zero) {int buttonCommand = WindowsAPI .GetDlgCtrlID (m_closeButton); // Console.WriteLine:; // send a command message WindowsAPI.SendMessage (m_hwnd, (int) Msg.WM_COMMAND, buttonCommand, m_closeButton);} else {// sent directly ( "command" buttonCommand) Close window message Windowsapi.sendMessage (m_hwnd, (uint) msg.wm_close, 0, 0);} // Setting the timeout tag m_btimeout = true;} // The process routine // is used to find a button. Private Bool EnumchildWindowsProc (intptr hwnd, int lpram) {// Gets the Windows Class name of the sub-window. StringBuffer Sb; int Lret = Windowsapi.getClassName (hwnd, out sb, 512); string sclassname = sb.sztext; //console.writeline(SClassName);

/ / Check if it is a button. IF (SclassName.toupper () == "Button") {m_closebutton = hwnd; return false; // Just start to stop enumeration} else {return true;}} #Region methods ///

/// The main method of the message box is displayed, and other overload methods are finally called this method. /// /// Dialog Box Results After the timeout /// Message text to display on the message box /// message box Title text /// button combination /// Icon style, if you set a custom icon, the icon style set here is meaningless. /// If set to MessageBoxicon.none, the built-in default icon will be used: a small clock. position /// Default button /// System.Windows.Forms.DialogResult public DialogResult Show (DialogResult timeoutDialogResult, string strMessageText String strmessageboxtitle, MessageBoxButtons Buttons, MessageBoxicon, MessageBoxDefaultButton DefaultButton) {// Is the custom icon // Custom icon priority is most preferred. M_iscustom = m_customicon! = Null && m_customicon! = Default; // When you need to replace the icon // Custom icon, you must replace the icon. / / In addition, when the custom icon is not set and no standard icon style is set, then the default icon is used, and the icon is also required. M_needReplaceicon = m_iscustom || icon == MessageBoxicon.none;

// If you do not specify an icon type, add a placeholder icon type. // As long as MessageBoxicon.none can, // But pay attention to Warning, Stop, Error will send a different sound. / / Make sure there is an icon, which is to display timing information below the icon. IF (icon == MessageBoxicon.none) {icon = messageboxicon.information;} // Reset each marker M_BTIMEOUT = false; m_timercount = 0; m_hwnd = INTPTR.ZERO; m_closebutton = INTPTR.ZERO; // Due to two The close button on the window title bar of the button style is disabled, // The sending WM_CLOSE message is sent to the message box at this time. // So use a roundabout method: first find any button on the message box, // In the event handling routine of the closing message frame timer, the button simulates a command operation, // to achieve the purpose of the closing window . As the button is not important, because the timeout returned // dialog assembly is the default value parameter set by the caller: TimeoutDialogresutl. M_needenumchild = (MessageBoxButtons.AbortRetryIgnore == Buttons || messageboxbuttons.yesno == Buttons);

// Create two timer // Close the timer INTPTR TIMERCOLSE = WindowsApi.SetTim (INTPTR.ZERO, 0, M_DELAYSECOND * 1000, New WindowsApi.TimerPSehandler); // Update Timer INTPTR Timerupdate = Windowsapi.Settimer (INTPTR.ZERO, 0, 1000, New Windowsapi.TimerProc (TimerUpdateElapseHandler);

/ / Set hook m_cbt.install ();

// Display message box DialogResult Dr = MessageBox.Show (StrMessageText, StrMessageboXtitle, Buttons, Icon, DefaultButton);

// Destroy Timer Windowsapi.killTimer (INTPTR.ZERO, TIMERCOLSE); Windowsapi.killTimer (INTPTR.ZERO, TIMERUPDATE);

/ / The corresponding result is returned to the corresponding result. If (m_btimeout) return timeoutdialogresult; // If you turn, return the value set by the parameter. ELSE RETURN DR; // If there is no timeout, the value of the user clicks is returned. }

public DialogResult Show (DialogResult timeoutDialogResult, string strMessageText, string strMessageBoxTitle, System.Windows.Forms.MessageBoxButtons buttons, MessageBoxIcon icon) {return Show (timeoutDialogResult, strMessageText, strMessageBoxTitle, buttons, icon, MessageBoxDefaultButton.Button1);} public DialogResult Show (DialogResult timeoutDialogResult, string strMessageText, string strMessageBoxTitle, System.Windows.Forms.MessageBoxButtons buttons) {return Show (timeoutDialogResult, strMessageText, strMessageBoxTitle, buttons, MessageBoxIcon.None);} public DialogResult Show (DialogResult timeoutDialogResult, string strMessageText, string strMessageBoxTitle) {return show (timeoutDialogResult, strMessageText, strMessageBoxTitle, System.Windows.Forms.MessageBoxButtons.OK);} public DialogResult show (DialogResult timeoutDialogResult, string strMessageText) {return show (timeoutDialogResult, strMessageText, "");}

#ndregion}}}

转载请注明原文地址:https://www.9cbs.com/read-109058.html

New Post(0)