Exetools

Exetools (https://forum.exetools.com/index.php)
-   Developer Section (https://forum.exetools.com/forumdisplay.php?f=48)
-   -   Code timing snippet (https://forum.exetools.com/showthread.php?t=16842)

Git 05-17-2015 19:13

Code timing snippet
 
Is it ok to post small pieces of code here that could be useful for people to include in programs?. If not, please delete or move the message.

Here is a trivial snippet of C source that will measure the time between two calls to _ftime_s() and return the number of seconds in a double, accurate to 1millisecond. It's useful for measuring run times of functions, bruteforce loops, etc, on the fly. I've used it lot, please help yourself if useful to you or ignore otherwise.

Git

Code:

#include <stdio.h>
#include <stdlib.h>
#include <sys/timeb.h>
#include <time.h>

int main(int argc, char * argv[])
{
        struct _timeb startTime, endTime;
        double        diftim;
       
        _ftime_s(&startTime);
        ...
        ...
        do things
        ...
        ...
        _ftime_s(&endTime);
        diftim = timediff(&startTime, &endTime);
        printf("\nProcessing time %8.3f seconds\n", diftim);
}


double timediff(struct _timeb *timstart, struct _timeb *timend)
{
        __int64        sTime, eTime;

        eTime = timend->millitm + 1000 * timend->time;
        sTime = timstart->millitm + 1000 * timstart->time;

        return (eTime - sTime) / 1000.0;
}

// The  _ftime_s(&endTime) statement could go in the timediff() function
// if the calling time of timediff() is insignificant.


mr.exodia 05-17-2015 19:47

Yea, I think this section would fit, since it is your code. There is also the 'Source Code' forum but that one looks mainly like links to other people their source code.

NimDa2k 08-01-2015 12:18

Create global HotKeys VB.NET
 
Code:

#Region " Usage Examples "

'Public Class Form1

'    ''' <summary>
'    ''' Define the system-wide hotkey object.
'    ''' </summary>
'    Private WithEvents Hotkey As GlobalHotkey = Nothing

'    ''' <summary>
'    ''' Initializes a new instance of this class.
'    ''' </summary>
'    Public Sub New()

'        InitializeComponent()

'        ' Registers a new global hotkey on the system. (Alt + Ctrl + A)
'        Hotkey = New GlobalHotkey(GlobalHotkey.KeyModifier.Alt Or GlobalHotkey.KeyModifier.Ctrl, Keys.A)

'        ' Replaces the current registered hotkey with a new one. (Alt + Escape)
'        Hotkey = New GlobalHotkey([Enum].Parse(GetType(GlobalHotkey.KeyModifier), "Alt", True),
'                                  [Enum].Parse(GetType(Keys), "Escape", True))

'        ' Set the tag property.
'        Hotkey.Tag = "I'm an example tag"

'    End Sub

'    ''' <summary>
'    ''' Handles the Press event of the HotKey object.
'    ''' </summary>
'    Private Sub HotKey_Press(ByVal sender As GlobalHotkey, ByVal e As GlobalHotkey.HotKeyEventArgs) _
'    Handles Hotkey.Press

'        MsgBox(e.Count) ' The times that the hotkey was pressed.
'        MsgBox(e.ID) ' The unique hotkey identifier.
'        MsgBox(e.Key.ToString) ' The assigned key.
'        MsgBox(e.Modifier.ToString) ' The assigned key-modifier.

'        MsgBox(sender.Tag) ' The hotkey tag object.

'        ' Unregister the hotkey.
'        Hotkey.Unregister()

'        ' Register it again.
'        Hotkey.Register()

'        ' Is Registered?
'        MsgBox(Hotkey.IsRegistered)

'    End Sub

'End Class

#End Region

#Region " Imports "

Imports System.ComponentModel
Imports System.Runtime.InteropServices

#End Region

#Region " Global Hotkey "

''' <summary>
''' Class to perform system-wide hotkey operations.
''' </summary>
Friend NotInheritable Class GlobalHotkey : Inherits NativeWindow : Implements IDisposable

#Region " API "

    ''' <summary>
    ''' Native API Methods.
    ''' </summary>
    Private Class NativeMethods

        ''' <summary>
        ''' Defines a system-wide hotkey.
        ''' </summary>
        ''' <param name="hWnd">The hWND.</param>
        ''' <param name="id">The identifier of the hotkey.
        ''' If the hWnd parameter is NULL, then the hotkey is associated with the current thread rather than with a particular window.
        ''' If a hotkey already exists with the same hWnd and id parameters.</param>
        ''' <param name="fsModifiers">The keys that must be pressed in combination with the key specified by the uVirtKey parameter
        ''' in order to generate the WM_HOTKEY message.
        ''' The fsModifiers parameter can be a combination of the following values.</param>
        ''' <param name="vk">The virtual-key code of the hotkey.</param>
        ''' <returns>
        ''' <c>true</c> if the function succeeds, otherwise <c>false</c>
        ''' </returns>
        <DllImport("user32.dll", SetLastError:=True)>
        Public Shared Function RegisterHotKey(
                      ByVal hWnd As IntPtr,
                      ByVal id As Integer,
                      ByVal fsModifiers As UInteger,
                      ByVal vk As UInteger
        ) As <MarshalAs(UnmanagedType.Bool)> Boolean
        End Function

        ''' <summary>
        ''' Unregisters a hotkey previously registered.
        ''' </summary>
        ''' <param name="hWnd">The hWND.</param>
        ''' <param name="id">The identifier of the hotkey to be unregistered.</param>
        ''' <returns>
        ''' <c>true</c> if the function succeeds, otherwise <c>false</c>
        ''' </returns>
        <DllImport("user32.dll", SetLastError:=True)>
        Public Shared Function UnregisterHotKey(
                      ByVal hWnd As IntPtr,
                      ByVal id As Integer
        ) As <MarshalAs(UnmanagedType.Bool)> Boolean
        End Function

    End Class

#End Region

#Region " Members "

#Region " Properties "

    ''' <summary>
    ''' Indicates the key assigned to the hotkey.
    ''' </summary>
    Public ReadOnly Property Key As Keys
        Get
            Return Me.PressEventArgs.Key
        End Get
    End Property

    ''' <summary>
    ''' Indicates the Key-Modifier assigned to the hotkey.
    ''' </summary>
    Public ReadOnly Property Modifier As KeyModifier
        Get
            Return Me.PressEventArgs.Modifier
        End Get
    End Property

    ''' <summary>
    ''' Indicates the unique identifier assigned to the hotkey.
    ''' </summary>
    Public ReadOnly Property ID As Integer
        Get
            Return Me.PressEventArgs.ID
        End Get
    End Property

    ''' <summary>
    ''' Indicates user-defined data associated with this object.
    ''' </summary>
    Public Property Tag As Object = Nothing

    ''' <summary>
    ''' Indicates how many times was pressed the hotkey.
    ''' </summary>
    Public ReadOnly Property Count As Integer
        Get
            Return _Count
        End Get
    End Property

#End Region

#Region " Enumerations "

    ''' <summary>
    ''' Key-modifiers to assign to a hotkey.
    ''' </summary>
    <Flags>
    Public Enum KeyModifier As Integer

        ''' <summary>
        ''' Any modifier.
        ''' </summary>
        None = &H0

        ''' <summary>
        ''' The Alt key.
        ''' </summary>
        Alt = &H1

        ''' <summary>
        ''' The Control key.
        ''' </summary>
        Ctrl = &H2

        ''' <summary>
        ''' The Shift key.
        ''' </summary>
        Shift = &H4

        ''' <summary>
        ''' The Windows key.
        ''' </summary>
        Win = &H8

    End Enum

    ''' <summary>
    ''' Known Windows Message Identifiers.
    ''' </summary>
    <Description("Messages to process in WndProc")>
    Public Enum KnownMessages As Integer

        ''' <summary>
        ''' Posted when the user presses a hot key registered by the RegisterHotKey function.
        ''' The message is placed at the top of the message queue associated with the thread that registered the hot key.
        ''' <paramref name="WParam"/>
        ''' The identifier of the hot key that generated the message.
        ''' If the message was generated by a system-defined hot key.
        ''' <paramref name="LParam"/>
        ''' The low-order word specifies the keys that were to be pressed in
        ''' combination with the key specified by the high-order word to generate the WM_HOTKEY message.
        ''' </summary>
        WM_HOTKEY = &H312

    End Enum

#End Region

#Region " Events "

    ''' <summary>
    ''' Event that is raised when a hotkey is pressed.
    ''' </summary>
    Public Event Press As EventHandler(Of HotKeyEventArgs)

    ''' <summary>
    ''' Event arguments for the Press event.
    ''' </summary>
    Public Class HotKeyEventArgs : Inherits EventArgs

        ''' <summary>
        ''' Indicates the Key assigned to the hotkey.
        ''' </summary>
        ''' <value>The key.</value>
        Friend Property Key As Keys

        ''' <summary>
        ''' Indicates the Key-Modifier assigned to the hotkey.
        ''' </summary>
        ''' <value>The modifier.</value>
        Friend Property Modifier As KeyModifier

        ''' <summary>
        ''' Indicates the unique identifier assigned to the hotkey.
        ''' </summary>
        ''' <value>The identifier.</value>
        Friend Property ID As Integer

        ''' <summary>
        ''' Indicates how many times was pressed the hotkey.
        ''' </summary>
        Friend Property Count As Integer

    End Class

#End Region

#Region " Exceptions "

    ''' <summary>
    ''' Exception that is thrown when a hotkey tries to register but is already registered.
    ''' </summary>
    <Serializable>
    Private Class IsRegisteredException : Inherits Exception

        ''' <summary>
        ''' Initializes a new instance of the <see cref="IsRegisteredException"/> class.
        ''' </summary>
        Sub New()
            MyBase.New("Unable to register. Hotkey is already registered.")
        End Sub

    End Class

    ''' <summary>
    ''' Exception that is thrown when a hotkey tries to unregister but is not registered.
    ''' </summary>
    <Serializable>
    Private Class IsNotRegisteredException : Inherits Exception

        ''' <summary>
        ''' Initializes a new instance of the <see cref="IsNotRegisteredException"/> class.
        ''' </summary>
        Sub New()
            MyBase.New("Unable to unregister. Hotkey is not registered.")
        End Sub

    End Class

#End Region

#Region " Other "

    ''' <summary>
    ''' Stores an counter indicating how many times was pressed the hotkey.
    ''' </summary>
    Private _Count As Integer = 0

    ''' <summary>
    ''' Stores the Press Event Arguments.
    ''' </summary>
    Protected PressEventArgs As New HotKeyEventArgs

#End Region

#End Region

#Region " Constructor "

    ''' <summary>
    ''' Creates a new system-wide hotkey.
    ''' </summary>
    ''' <param name="Modifier">
    ''' Indicates the key-modifier to assign to the hotkey.
    ''' ( Can use one or more modifiers )
    ''' </param>
    ''' <param name="Key">
    ''' Indicates the key to assign to the hotkey.
    ''' </param>
    ''' <exception cref="IsRegisteredException"></exception>
    <DebuggerStepperBoundary()>
    Public Sub New(ByVal Modifier As KeyModifier, ByVal Key As Keys)

        MyBase.CreateHandle(New CreateParams)

        Me.PressEventArgs.ID = MyBase.GetHashCode()
        Me.PressEventArgs.Key = Key
        Me.PressEventArgs.Modifier = Modifier
        Me.PressEventArgs.Count = 0

        If Not NativeMethods.RegisterHotKey(MyBase.Handle,
                                            Me.ID,
                                            Me.Modifier,
                                            Me.Key) Then

            Throw New IsRegisteredException

        End If

    End Sub

#End Region

#Region " Event Handlers "

    ''' <summary>
    ''' Occurs when a hotkey is pressed.
    ''' </summary>
    Private Sub OnHotkeyPress() Handles Me.Press
        _Count += 1
    End Sub

#End Region

#Region "Public Methods "

    ''' <summary>
    ''' Determines whether this hotkey is registered on the system.
    ''' </summary>
    ''' <returns>
    ''' <c>true</c> if this hotkey is registered; otherwise, <c>false</c>.
    ''' </returns>
    Public Function IsRegistered() As Boolean

        DisposedCheck()

        ' Try to unregister the hotkey.
        Select Case NativeMethods.UnregisterHotKey(MyBase.Handle, Me.ID)

            Case False ' Unregistration failed.
                Return False ' Hotkey is not registered.

            Case Else ' Unregistration succeeds.
                Register() ' Re-Register the hotkey before return.
                Return True ' Hotkey is registeres.

        End Select

    End Function

    ''' <summary>
    ''' Registers this hotkey on the system.
    ''' </summary>
    ''' <exception cref="IsRegisteredException"></exception>
    Public Sub Register()

        DisposedCheck()

        If Not NativeMethods.RegisterHotKey(MyBase.Handle,
                                            Me.ID,
                                            Me.Modifier,
                                            Me.Key) Then

            Throw New IsRegisteredException

        End If

    End Sub

    ''' <summary>
    ''' Unregisters this hotkey from the system.
    ''' After calling this method the hotkey turns unavaliable.
    ''' </summary>
    Public Sub Unregister()

        DisposedCheck()

        If Not NativeMethods.UnregisterHotKey(MyBase.Handle, Me.ID) Then

            Throw New IsNotRegisteredException

        End If

    End Sub

#End Region

#Region " Hidden methods "

    ' These methods and properties are purposely hidden from Intellisense just to look better without unneeded methods.
    ' NOTE: The methods can be re-enabled at any-time if needed.

    ''' <summary>
    ''' Assigns the handle.
    ''' </summary>
    <EditorBrowsable(EditorBrowsableState.Never)>
    Public Shadows Sub AssignHandle()
    End Sub

    ''' <summary>
    ''' Creates the handle.
    ''' </summary>
    <EditorBrowsable(EditorBrowsableState.Never)>
    Public Shadows Sub CreateHandle()
    End Sub

    ''' <summary>
    ''' Creates the object reference.
    ''' </summary>
    <EditorBrowsable(EditorBrowsableState.Never)>
    Public Shadows Sub CreateObjRef()
    End Sub

    ''' <summary>
    ''' Definitions the WND proc.
    ''' </summary>
    <EditorBrowsable(EditorBrowsableState.Never)>
    Public Shadows Sub DefWndProc()
    End Sub

    ''' <summary>
    ''' Destroys the window and its handle.
    ''' </summary>
    <EditorBrowsable(EditorBrowsableState.Never)>
    Public Shadows Sub DestroyHandle()
    End Sub

    ''' <summary>
    ''' Equalses this instance.
    ''' </summary>
    <EditorBrowsable(EditorBrowsableState.Never)>
    Public Shadows Sub Equals()
    End Sub

    ''' <summary>
    ''' Gets the hash code.
    ''' </summary>
    <EditorBrowsable(EditorBrowsableState.Never)>
    Public Shadows Sub GetHashCode()
    End Sub

    ''' <summary>
    ''' Gets the lifetime service.
    ''' </summary>
    <EditorBrowsable(EditorBrowsableState.Never)>
    Public Shadows Sub GetLifetimeService()
    End Sub

    ''' <summary>
    ''' Initializes the lifetime service.
    ''' </summary>
    <EditorBrowsable(EditorBrowsableState.Never)>
    Public Shadows Sub InitializeLifetimeService()
    End Sub

    ''' <summary>
    ''' Releases the handle associated with this window.
    ''' </summary>
    <EditorBrowsable(EditorBrowsableState.Never)>
    Public Shadows Sub ReleaseHandle()
    End Sub

    ''' <summary>
    ''' Gets the handle for this window.
    ''' </summary>
    <EditorBrowsable(EditorBrowsableState.Never)>
    Public Shadows Property Handle()

#End Region

#Region " WndProc "

    ''' <summary>
    ''' Invokes the default window procedure associated with this window to process messages for this Window.
    ''' </summary>
    ''' <param name="m">
    ''' A <see cref="T:System.Windows.Forms.Message" /> that is associated with the current Windows message.
    ''' </param>
    Protected Overrides Sub WndProc(ByRef m As Message)

        Select Case m.Msg

            Case KnownMessages.WM_HOTKEY  ' A hotkey is pressed.

                ' Update the pressed counter.
                Me.PressEventArgs.Count += 1

                ' Raise the Event
                RaiseEvent Press(Me, Me.PressEventArgs)

            Case Else
                MyBase.WndProc(m)

        End Select

    End Sub

#End Region

#Region " IDisposable "

    ''' <summary>
    ''' To detect redundant calls when disposing.
    ''' </summary>
    Private IsDisposed As Boolean = False

    ''' <summary>
    ''' Prevent calls to methods after disposing.
    ''' </summary>
    ''' <exception cref="System.ObjectDisposedException"></exception>
    Private Sub DisposedCheck()

        If Me.IsDisposed Then
            Throw New ObjectDisposedException(Me.GetType().FullName)
        End If

    End Sub

    ''' <summary>
    ''' Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
    ''' </summary>
    Public Sub Dispose() Implements IDisposable.Dispose
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub

    ''' <summary>
    ''' Releases unmanaged and - optionally - managed resources.
    ''' </summary>
    ''' <param name="IsDisposing">
    ''' <c>true</c> to release both managed and unmanaged resources;
    ''' <c>false</c> to release only unmanaged resources.
    ''' </param>
    Protected Sub Dispose(Byval IsDisposing As Boolean)

        If Not Me.IsDisposed Then

            If IsDisposing Then
                NativeMethods.UnregisterHotKey(MyBase.Handle, Me.ID)
            End If

        End If

        Me.IsDisposed = True

    End Sub

#End Region

End Class

#End Region


rasta 12-31-2017 17:35

It would be much better if code snippets are 1 post for each, else if someone searches for global hotkeys will never search under code timing.

Btw Git, nice approach to detect beeing debugged.

chants 01-03-2018 17:34

That C code has become a bit prehistoric these days. I am not sure if timeb is portable either (though certainly with conditional compilation the prior snippet can be made to port on Windows and Linux for low 1ms resolution timer).

Here is STL C++ code for high resolution and portable code, requires no coding and mostly just ugly namespace declaration and templates.

Quote:

#include <chrono>
std::chrono::time_point<std::chrono::high_resolution_clock> start = std::chrono::high_resolution_clock::now();
//do things
std::chrono::duration<double, std::milli> elapsed = std::chrono::high_resolution_clock::now() - start;
printf("\nProcessing time %8.3f seconds\n", elapsed.count());

Git 01-05-2018 02:05

I'll stick to plain old C which is readable and understandable thanks :)

Git


All times are GMT +8. The time now is 16:41.

Powered by vBulletin® Version 3.8.8
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX