elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Entrar al Canal Oficial Telegram de elhacker.net


  Mostrar Mensajes
Páginas: 1 [2] 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ... 1236
11  Programación / .NET (C#, VB.NET, ASP) / Re: Librería de Snippets para VB.NET !! (Compartan aquí sus snippets) en: 19 Abril 2024, 18:16 pm
En esta ocasión comparto el código fuente de un control de tipo NumericUpDown para poder usarlo en una barra ToolStrip o StatusStrip, y también un control de tipo TrackBar con la misma finalidad.





ToolStripNumericUpDown.vb
Código
  1. ' ***********************************************************************
  2. ' Author   : ElektroStudios
  3. ' Modified : 19-April-2024
  4. ' ***********************************************************************
  5.  
  6. #Region " Option Statements "
  7.  
  8. Option Strict On
  9. Option Explicit On
  10. Option Infer Off
  11.  
  12. #End Region
  13.  
  14. #Region " Imports "
  15.  
  16. Imports System.ComponentModel
  17. Imports System.Drawing
  18. Imports System.Runtime.InteropServices
  19. Imports System.Windows.Forms
  20. Imports System.Windows.Forms.Design
  21.  
  22. #End Region
  23.  
  24. #Region " ToolStripNumericUpDown "
  25.  
  26. ' ReSharper disable once CheckNamespace
  27.  
  28. Namespace DevCase.UI.Components
  29.  
  30.    ''' <summary>
  31.    ''' Represents a selectable Windows spin box <see cref="ToolStripItem"/> that displays numeric values.
  32.    ''' </summary>
  33.    ''' <seealso cref="ToolStripControlHost"/>
  34.    <
  35.        ComVisible(True),
  36.        DebuggerStepThrough,
  37.        DefaultEvent(NameOf(ToolStripNumericUpDown.ValueChanged)),
  38.        DefaultProperty(NameOf(ToolStripNumericUpDown.Value)),
  39.        DefaultBindingProperty(NameOf(ToolStripNumericUpDown.Value)),
  40.        Description("Represents a selectable Windows spin box ToolStripItem that displays numeric values."),
  41.        Designer("System.Windows.Forms.Design.ToolStripItemDesigner, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"),
  42.        DesignerCategory(NameOf(DesignerCategoryAttribute.Generic)),
  43.        DesignTimeVisible(False),
  44.        DisplayName(NameOf(ToolStripNumericUpDown)),
  45.        Localizable(True),
  46.        ToolboxBitmap(GetType(NumericUpDown), "NumericUpDown.bmp"),
  47.        ToolboxItem(False),
  48.        ToolboxItemFilter("System.Windows.Forms", ToolboxItemFilterType.Allow),
  49.        ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ToolStrip Or ToolStripItemDesignerAvailability.StatusStrip)
  50.    >
  51.    Public Class ToolStripNumericUpDown : Inherits ToolStripControlHost
  52.  
  53. #Region " Properties "
  54.  
  55.        ''' <summary>
  56.        ''' Gets the <see cref="NumericUpDown"/> control that is hosted by this <see cref="ToolStripNumericUpDown"/>.
  57.        ''' </summary>
  58.        <
  59.            Browsable(True), EditorBrowsable(EditorBrowsableState.Advanced),
  60.            DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
  61.            Category("Components"), Description("The NumericUpDown control that is hosted by this control.")
  62.        >
  63.        Public Shadows ReadOnly Property Control As NumericUpDown
  64.            Get
  65.                Return DirectCast(MyBase.Control, NumericUpDown)
  66.            End Get
  67.        End Property
  68.  
  69.        ''' <summary>
  70.        ''' Gets or sets the numeric value assigned to this <see cref="ToolStripNumericUpDown"/>.
  71.        ''' </summary>
  72.        '''
  73.        ''' <value>
  74.        ''' The numeric value assigned to this <see cref="ToolStripNumericUpDown"/>.
  75.        ''' </value>
  76.        <
  77.            Bindable(True),
  78.            DefaultValue(0D),
  79.            Category("Appearance"), Description("The numeric value assigned to this control.")
  80.        >
  81.        Public Property Value As Decimal
  82.            Get
  83.                Return Me.Control.Value
  84.            End Get
  85.            Set(value As Decimal)
  86.                Me.Control.Value = value
  87.            End Set
  88.        End Property
  89.  
  90.        ''' <summary>
  91.        ''' Gets or sets the text to be displayed in this <see cref="ToolStripNumericUpDown"/>.
  92.        ''' </summary>
  93.        '''
  94.        ''' <value>
  95.        ''' The text to be displayed in this <see cref="ToolStripNumericUpDown"/>.
  96.        ''' </value>
  97.        <
  98.            Browsable(False), EditorBrowsable(EditorBrowsableState.Never),
  99.            Bindable(False),
  100.            DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
  101.            Category("Behavior"), Description("The text to be displayed in this control.")
  102.        >
  103.        Public Overrides Property Text As String
  104.            Get
  105.                Return Me.Control.Text
  106.            End Get
  107.            Set(value As String)
  108.                Me.Control.Text = value
  109.            End Set
  110.        End Property
  111.  
  112.        ''' <summary>
  113.        ''' This property is not applicable for this control.
  114.        ''' </summary>
  115.        <
  116.            Browsable(False), EditorBrowsable(EditorBrowsableState.Never),
  117.            Category("Not Applicable"), Description("This property is not applicable for this control.")
  118.        >
  119.        Public Overrides Property BackgroundImage As Image
  120.            Get
  121.                Return Nothing
  122.            End Get
  123.            Set(value As Image)
  124.                MyBase.BackgroundImage = Nothing
  125.            End Set
  126.        End Property
  127.  
  128.        ''' <summary>
  129.        ''' This property is not applicable for this control.
  130.        ''' </summary>
  131.        <
  132.            Browsable(False), EditorBrowsable(EditorBrowsableState.Never),
  133.            Category("Not Applicable"), Description("This property is not applicable for this control.")
  134.        >
  135.        Public Overrides Property BackgroundImageLayout As ImageLayout
  136.            Get
  137.                Return MyBase.BackgroundImageLayout
  138.            End Get
  139.            Set(value As ImageLayout)
  140.                MyBase.BackgroundImageLayout = value
  141.            End Set
  142.        End Property
  143.  
  144.        ''' <summary>
  145.        ''' This property is not applicable for this control.
  146.        ''' </summary>
  147.        <
  148.            Browsable(False), EditorBrowsable(EditorBrowsableState.Never),
  149.            Category("Not Applicable"), Description("This property is not applicable for this control.")
  150.        >
  151.        Public Overrides Property Image As Image
  152.            Get
  153.                Return Nothing
  154.            End Get
  155.            Set(value As Image)
  156.                MyBase.Image = Nothing
  157.            End Set
  158.        End Property
  159.  
  160. #End Region
  161.  
  162. #Region " Events "
  163.  
  164.        ''' <summary>
  165.        ''' Occurs whenever the <see cref="ToolStripNumericUpDown.Value"/> property is changed.
  166.        ''' </summary>
  167.        <
  168.            Category("Action"), Description("Occurs whenever the Value property is changed.")
  169.        >
  170.        Public Event ValueChanged As EventHandler
  171.  
  172. #End Region
  173.  
  174. #Region " Constructors "
  175.  
  176.        ''' <summary>
  177.        ''' Initializes a new instance of the <see cref="ToolStripNumericUpDown"/> class.
  178.        ''' </summary>
  179.        Public Sub New()
  180.            MyBase.New(ToolStripNumericUpDown.CreateControlInstance())
  181.        End Sub
  182.  
  183. #End Region
  184.  
  185. #Region " Event Invocators "
  186.  
  187.        ''' <summary>
  188.        ''' Raises the <see cref="ToolStripNumericUpDown.ValueChanged"/> event.
  189.        ''' </summary>
  190.        '''
  191.        ''' <param name="sender">
  192.        ''' The source of the event.
  193.        ''' </param>
  194.        '''
  195.        ''' <param name="e">
  196.        ''' The <see cref="EventArgs"/> instance containing the event data.
  197.        ''' </param>
  198.        Private Sub OnValueChanged(sender As Object, e As EventArgs)
  199.            If Me.ValueChangedEvent IsNot Nothing Then
  200.                RaiseEvent ValueChanged(Me, e)
  201.            End If
  202.        End Sub
  203.  
  204. #End Region
  205.  
  206. #Region " Event Invocators (Overriden) "
  207.  
  208.        ''' <summary>
  209.        ''' Subscribes events from the hosted control
  210.        ''' </summary>
  211.        '''
  212.        ''' <param name="control">
  213.        ''' The control from which to subscribe events.
  214.        ''' </param>
  215.        Protected Overrides Sub OnSubscribeControlEvents(control As Control)
  216.            MyBase.OnSubscribeControlEvents(control)
  217.  
  218.            AddHandler DirectCast(control, NumericUpDown).ValueChanged, AddressOf Me.OnValueChanged
  219.        End Sub
  220.  
  221.        ''' <summary>
  222.        ''' Unsubscribes events from the hosted control
  223.        ''' </summary>
  224.        '''
  225.        ''' <param name="control">
  226.        ''' The control from which to unsubscribe events.
  227.        ''' </param>
  228.        Protected Overrides Sub OnUnsubscribeControlEvents(control As Control)
  229.            MyBase.OnUnsubscribeControlEvents(control)
  230.  
  231.            RemoveHandler DirectCast(control, NumericUpDown).ValueChanged, AddressOf Me.OnValueChanged
  232.        End Sub
  233.  
  234. #End Region
  235.  
  236. #Region " Private Methods "
  237.  
  238.        ''' <summary>
  239.        ''' Creates the control instance.
  240.        ''' </summary>
  241.        '''
  242.        ''' <returns>
  243.        ''' The control.
  244.        ''' </returns>
  245.        Private Shared Function CreateControlInstance() As Control
  246.            Return New NumericUpDown() With {.AutoSize = True}
  247.        End Function
  248.  
  249. #End Region
  250.  
  251.    End Class
  252.  
  253. End Namespace
  254.  
  255. #End Region
  256.  




ToolStripTrackBar.vb
Código
  1. ' ***********************************************************************
  2. ' Author   : ElektroStudios
  3. ' Modified : 19-April-2024
  4. ' ***********************************************************************
  5.  
  6. #Region " Option Statements "
  7.  
  8. Option Strict On
  9. Option Explicit On
  10. Option Infer Off
  11.  
  12. #End Region
  13.  
  14. #Region " Imports "
  15.  
  16. Imports System.ComponentModel
  17. Imports System.Drawing
  18. Imports System.Runtime.InteropServices
  19. Imports System.Windows.Forms
  20. Imports System.Windows.Forms.Design
  21.  
  22. #End Region
  23.  
  24. #Region " ToolStripTrackBar "
  25.  
  26. ' ReSharper disable once CheckNamespace
  27.  
  28. Namespace DevCase.UI.Components
  29.  
  30.    ''' <summary>
  31.    ''' Represents a selectable track bar <see cref="ToolStripItem"/>.
  32.    ''' </summary>
  33.    ''' <seealso cref="ToolStripControlHost"/>
  34.    <
  35.        ComVisible(True),
  36.        DebuggerStepThrough,
  37.        DefaultEvent(NameOf(ToolStripTrackBar.Scroll)),
  38.        DefaultProperty(NameOf(ToolStripTrackBar.Value)),
  39.        DefaultBindingProperty(NameOf(ToolStripTrackBar.Value)),
  40.        Description("Represents a selectable track bar ToolStripItem."),
  41.        Designer("System.Windows.Forms.Design.ToolStripItemDesigner, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"),
  42.        DesignerCategory(NameOf(DesignerCategoryAttribute.Generic)),
  43.        DesignTimeVisible(False),
  44.        DisplayName(NameOf(ToolStripTrackBar)),
  45.        Localizable(True),
  46.        ToolboxBitmap(GetType(TrackBar), "TrackBar.bmp"),
  47.        ToolboxItem(False),
  48.        ToolboxItemFilter("System.Windows.Forms", ToolboxItemFilterType.Allow),
  49.        ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ToolStrip Or ToolStripItemDesignerAvailability.StatusStrip)
  50.    >
  51.    Public Class ToolStripTrackBar : Inherits ToolStripControlHost
  52.  
  53. #Region " Properties "
  54.  
  55.        ''' <summary>
  56.        ''' Gets the <see cref="TrackBar"/> control that is hosted by this <see cref="ToolStripTrackBar"/>.
  57.        ''' </summary>
  58.        <
  59.            Browsable(True), EditorBrowsable(EditorBrowsableState.Advanced),
  60.            DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
  61.            Category("Components"), Description("The TrackBar control that is hosted by this control.")
  62.        >
  63.        Public Shadows ReadOnly Property Control As TrackBar
  64.            Get
  65.                Return DirectCast(MyBase.Control, TrackBar)
  66.            End Get
  67.        End Property
  68.  
  69.        ''' <summary>
  70.        ''' Gets or sets a numeric value that represents the current position of the scroll box on this <see cref="ToolStripTrackBar"/>.
  71.        ''' </summary>
  72.        '''
  73.        ''' <value>
  74.        ''' The numeric value that represents the current position of the scroll box on this <see cref="ToolStripTrackBar"/>.
  75.        ''' </value>
  76.        <
  77.            Bindable(True),
  78.            DefaultValue(0I),
  79.            Category("Behavior"), Description("The numeric value that represents the current position of the scroll box on this control.")
  80.        >
  81.        Public Property Value As Integer
  82.            Get
  83.                Return Me.Control.Value
  84.            End Get
  85.            Set(value As Integer)
  86.                Me.Control.Value = value
  87.            End Set
  88.        End Property
  89.  
  90.        ''' <summary>
  91.        ''' Gets or sets the lower limit of the range this <see cref="ToolStripTrackBar"/> is working with.
  92.        ''' </summary>
  93.        '''
  94.        ''' <value>
  95.        ''' The minimum value for this <see cref="ToolStripTrackBar"/>. The default is 0.
  96.        ''' </value>
  97.        <
  98.            Bindable(True),
  99.            DefaultValue(0I),
  100.            RefreshProperties(RefreshProperties.All),
  101.            Category("Behavior"), Description("The minimum value for this control.")
  102.        >
  103.        Public Property Minimum As Integer
  104.            Get
  105.                Return Me.Control.Minimum
  106.            End Get
  107.            Set(value As Integer)
  108.                Me.Control.Minimum = value
  109.            End Set
  110.        End Property
  111.  
  112.        ''' <summary>
  113.        ''' Gets or sets the upper limit of the range this <see cref="ToolStripTrackBar"/> is working with.
  114.        ''' </summary>
  115.        '''
  116.        ''' <value>
  117.        ''' The maximum value for this <see cref="ToolStripTrackBar"/>. The default is 10.
  118.        ''' </value>
  119.        <
  120.            Bindable(True),
  121.            DefaultValue(10I),
  122.            RefreshProperties(RefreshProperties.All),
  123.            Category("Behavior"), Description("The maximum value for this control.")
  124.        >
  125.        Public Property Maximum As Integer
  126.            Get
  127.                Return Me.Control.Maximum
  128.            End Get
  129.            Set(value As Integer)
  130.                Me.Control.Maximum = value
  131.            End Set
  132.        End Property
  133.  
  134.        ''' <summary>
  135.        ''' This property is not applicable for this control.
  136.        ''' </summary>
  137.        <
  138.            Browsable(False), EditorBrowsable(EditorBrowsableState.Never),
  139.            Category("Not Applicable"), Description("This property is not applicable for this control.")
  140.        >
  141.        Public Overrides Property BackgroundImage As Image
  142.            Get
  143.                Return Nothing
  144.            End Get
  145.            Set(value As Image)
  146.                MyBase.BackgroundImage = Nothing
  147.            End Set
  148.        End Property
  149.  
  150.        ''' <summary>
  151.        ''' This property is not applicable for this control.
  152.        ''' </summary>
  153.        <
  154.            Browsable(False), EditorBrowsable(EditorBrowsableState.Never),
  155.            Category("Not Applicable"), Description("This property is not applicable for this control.")
  156.        >
  157.        Public Overrides Property BackgroundImageLayout As ImageLayout
  158.            Get
  159.                Return MyBase.BackgroundImageLayout
  160.            End Get
  161.            Set(value As ImageLayout)
  162.                MyBase.BackgroundImageLayout = value
  163.            End Set
  164.        End Property
  165.  
  166.        ''' <summary>
  167.        ''' This property is not applicable for this control.
  168.        ''' </summary>
  169.        <
  170.            Browsable(False), EditorBrowsable(EditorBrowsableState.Never),
  171.            Category("Not Applicable"), Description("This property is not applicable for this control.")
  172.        >
  173.        Public Overrides Property Image As Image
  174.            Get
  175.                Return Nothing
  176.            End Get
  177.            Set(value As Image)
  178.                MyBase.Image = Nothing
  179.            End Set
  180.        End Property
  181.  
  182. #End Region
  183.  
  184. #Region " Events "
  185.  
  186.        ''' <summary>
  187.        ''' Occurs when either a mouse or keyboard action moves the scroll box.
  188.        ''' </summary>
  189.        <
  190.            Category("Behavior"), Description("Occurs when either a mouse or keyboard action moves the scroll box.")
  191.        >
  192.        Public Event Scroll As EventHandler
  193.  
  194.        ''' <summary>
  195.        ''' Occurs when the <see cref="ToolStripTrackBar.Value"/> property changes,
  196.        ''' either by movement of the scroll box or by manipulation in code.
  197.        ''' </summary>
  198.        <
  199.            Category("Action"), Description("Occurs when the Value property changes, either by movement of the scroll box or by manipulation in code.")
  200.        >
  201.        Public Event ValueChanged As EventHandler
  202.  
  203. #End Region
  204.  
  205. #Region " Constructors "
  206.  
  207.        ''' <summary>
  208.        ''' Initializes a new instance of the <see cref="ToolStripTrackBar"/> class.
  209.        ''' </summary>
  210.        Public Sub New()
  211.            MyBase.New(ToolStripTrackBar.CreateControlInstance())
  212.        End Sub
  213.  
  214. #End Region
  215.  
  216. #Region " Event Invocators "
  217.  
  218.        ''' <summary>
  219.        ''' Raises the <see cref="ToolStripTrackBar.Scroll"/> event.
  220.        ''' </summary>
  221.        '''
  222.        ''' <param name="sender">
  223.        ''' The source of the event.
  224.        ''' </param>
  225.        '''
  226.        ''' <param name="e">
  227.        ''' The <see cref="EventArgs"/> instance containing the event data.
  228.        ''' </param>
  229.        Private Sub OnScroll(sender As Object, e As EventArgs)
  230.            If Me.ScrollEvent IsNot Nothing Then
  231.                RaiseEvent Scroll(Me, e)
  232.            End If
  233.        End Sub
  234.  
  235.        ''' <summary>
  236.        ''' Raises the <see cref="ToolStripTrackBar.Scroll"/> event.
  237.        ''' </summary>
  238.        '''
  239.        ''' <param name="sender">
  240.        ''' The source of the event.
  241.        ''' </param>
  242.        '''
  243.        ''' <param name="e">
  244.        ''' The <see cref="EventArgs"/> instance containing the event data.
  245.        ''' </param>
  246.        Private Sub OnValueChanged(sender As Object, e As EventArgs)
  247.            If Me.ValueChangedEvent IsNot Nothing Then
  248.                RaiseEvent ValueChanged(Me, e)
  249.            End If
  250.        End Sub
  251.  
  252. #End Region
  253.  
  254. #Region " Event Invocators (Overriden) "
  255.  
  256.        ''' <summary>
  257.        ''' Subscribes events from the hosted control
  258.        ''' </summary>
  259.        '''
  260.        ''' <param name="control">
  261.        ''' The control from which to subscribe events.
  262.        ''' </param>
  263.        Protected Overrides Sub OnSubscribeControlEvents(control As Control)
  264.            MyBase.OnSubscribeControlEvents(control)
  265.  
  266.            AddHandler DirectCast(control, TrackBar).Scroll, AddressOf Me.OnScroll
  267.            AddHandler DirectCast(control, TrackBar).ValueChanged, AddressOf Me.OnValueChanged
  268.        End Sub
  269.  
  270.        ''' <summary>
  271.        ''' Unsubscribes events from the hosted control
  272.        ''' </summary>
  273.        '''
  274.        ''' <param name="control">
  275.        ''' The control from which to unsubscribe events.
  276.        ''' </param>
  277.        Protected Overrides Sub OnUnsubscribeControlEvents(control As Control)
  278.            MyBase.OnUnsubscribeControlEvents(control)
  279.  
  280.            RemoveHandler DirectCast(control, TrackBar).Scroll, AddressOf Me.OnScroll
  281.            RemoveHandler DirectCast(control, TrackBar).ValueChanged, AddressOf Me.Onvaluechanged
  282.        End Sub
  283.  
  284. #End Region
  285.  
  286. #Region " Private Methods "
  287.  
  288.        ''' <summary>
  289.        ''' Creates the control instance.
  290.        ''' </summary>
  291.        '''
  292.        ''' <returns>
  293.        ''' The control.
  294.        ''' </returns>
  295.        Private Shared Function CreateControlInstance() As Control
  296.            Using ts As New ToolStrip()
  297.                Return New TrackBar() With {
  298.                    .AutoSize = False,
  299.                    .Size = New Size(80, ts.Height)
  300.                }
  301.            End Using
  302.        End Function
  303.  
  304. #End Region
  305.  
  306.    End Class
  307.  
  308. End Namespace
  309.  
  310. #End Region
  311.  
  312.  
12  Media / Multimedia / Re: Descargar video curso online alojado Vimeo en: 16 Abril 2024, 13:11 pm
Bueno, pues ya que el tema ha quedado resuelto (por cierto, me alegro de que lo hayas podido solucionar), aprovecho para decir lo siguiente:

@EdePC
Si estoy entendiendo que esta metodología realmente sirve para descargar videos de Vimeo protegidos con contraseña, es para besarte el... (_*_)

Me parecen bastantes meritorias todas las explicaciones expuestas en este hilo. Tengo que ponerlo en práctica más tarde.

Lástima que no haya una funcionalidad para dar en el foro, je!.

Un saludo.

13  Programación / .NET (C#, VB.NET, ASP) / Re: Librería de Snippets para VB.NET !! (Compartan aquí sus snippets) en: 16 Abril 2024, 12:24 pm
Un método de extensión para impedir que un ToolStripMenuItem se cierre al hacer click en uno de sus items hijos.

Ejemplo de uso:

Código
  1. Dim menuItem As ToolStripMenuItem = Me.ToolStripMenuItem1
  2. Dim preventClosure As Boolean = True
  3. Dim recursive As Boolean = False
  4. menuItem.SetClosureBehaviorOnClick(preventClosure, recursive)



El código:

Código
  1. ' ***********************************************************************
  2. ' Author   : ElektroStudios
  3. ' Modified : 12-April-2024
  4. ' ***********************************************************************
  5.  
  6. #Region " Public Members Summary "
  7.  
  8. ' ToolStripMenuItem.SetClosureBehaviorOnClick(Boolean, Boolean)
  9.  
  10. #End Region
  11.  
  12. #Region " Option Statements "
  13.  
  14. Option Strict On
  15. Option Explicit On
  16. Option Infer Off
  17.  
  18. #End Region
  19.  
  20. #Region " Imports "
  21.  
  22. Imports System.Collections.Generic
  23. Imports System.ComponentModel
  24. Imports System.Linq
  25. Imports System.Runtime.CompilerServices
  26. Imports System.Windows.Forms
  27.  
  28. #End Region
  29.  
  30. #Region " ToolStripMenuItem Extensions "
  31.  
  32. Namespace DevCase.Core.Extensions
  33.  
  34.    ''' ----------------------------------------------------------------------------------------------------
  35.    ''' <summary>
  36.    ''' Provides extension methods to use with the <see cref="ToolStripMenuItem"/> class.
  37.    ''' </summary>
  38.    ''' ----------------------------------------------------------------------------------------------------
  39.    <HideModuleName>
  40.    Public Module ToolStripMenuItemExtensions
  41.  
  42. #Region " Public Extension Methods "
  43.  
  44.        ''' <summary>
  45.        ''' A <see cref="ToolStripDropDownClosingEventHandler"/> delegate used to control
  46.        ''' the <see cref="ToolStripDropDown.Closing"/> event of a <see cref="ToolStripDropDown"/>.
  47.        ''' <para></para>
  48.        ''' This handler depends on <see cref="ToolStripMenuItemExtensions.SetClosureBehaviorOnClick"/> method.
  49.        ''' </summary>
  50.        Private closingHandler As ToolStripDropDownClosingEventHandler
  51.  
  52.        ''' <summary>
  53.        ''' A collection of <see cref="ToolStripDropDown"/> items
  54.        ''' whose <see cref="ToolStripDropDown.Closing"/> event
  55.        ''' has been associated to <see cref="ToolStripMenuItemExtensions.closingHandler"/>.
  56.        ''' <para></para>
  57.        ''' This collection depends on <see cref="ToolStripMenuItemExtensions.SetClosureBehaviorOnClick"/> method.
  58.        ''' </summary>
  59.        Private closingHandlerAssociatedItems As HashSet(Of ToolStripDropDown)
  60.  
  61.        ''' <summary>
  62.        ''' Sets the closure behavior for the source <see cref="ToolStripMenuItem"/> when its drop-down items are clicked.
  63.        ''' </summary>
  64.        '''
  65.        ''' <remarks>
  66.        ''' This method associates the underlying
  67.        ''' <see cref="ToolStripMenuItem.DropDown"/>'s <see cref="ToolStripDropDown.Closing"/> event
  68.        ''' with a handler to control the closure behavior.
  69.        ''' </remarks>
  70.        '''
  71.        ''' <example> This is a code example.
  72.        ''' <code language="VB">
  73.        ''' Dim menuItem As ToolStripMenuItem = Me.ToolStripMenuItem1
  74.        ''' Dim preventClosure As Boolean = True
  75.        ''' Dim recursive As Boolean = True
  76.        '''
  77.        ''' menuItem.SetClosureBehaviorOnClick(preventClosure, recursive)
  78.        ''' </code>
  79.        ''' </example>
  80.        '''
  81.        ''' <param name="menuItem">
  82.        ''' The <see cref="ToolStripMenuItem"/> to set the closure behavior for.
  83.        ''' </param>
  84.        '''
  85.        ''' <param name="preventClosure">
  86.        ''' <see langword="True"/> to prevent closure of the source <see cref="ToolStripMenuItem"/>
  87.        ''' when its drop-down items are clicked; otherwise, <see langword="False"/>.
  88.        ''' </param>
  89.        <DebuggerStepThrough>
  90.        <Extension>
  91.        <EditorBrowsable(EditorBrowsableState.Always)>
  92.        Public Sub SetClosureBehaviorOnClick(menuItem As ToolStripMenuItem, preventClosure As Boolean, recursive As Boolean)
  93.            If menuItem Is Nothing Then
  94.                Throw New ArgumentNullException(paramName:=NameOf(menuItem))
  95.            End If
  96.  
  97.            If Not menuItem.HasDropDown Then
  98.                Throw New InvalidOperationException(
  99.                "The ToolStripDropDownItem.DropDown for the ToolStripDropDownItem has not been created.")
  100.            End If
  101.  
  102.            If ToolStripMenuItemExtensions.closingHandler Is Nothing Then
  103.                ToolStripMenuItemExtensions.closingHandler =
  104.                    Sub(sender As Object, e As ToolStripDropDownClosingEventArgs)
  105.                        e.Cancel = (e.CloseReason = ToolStripDropDownCloseReason.ItemClicked)
  106.                    End Sub
  107.            End If
  108.  
  109.            If ToolStripMenuItemExtensions.closingHandlerAssociatedItems Is Nothing Then
  110.                ToolStripMenuItemExtensions.closingHandlerAssociatedItems = New HashSet(Of ToolStripDropDown)
  111.            End If
  112.  
  113.            Dim dropdownAction As Action(Of ToolStripDropDown) =
  114.                Sub(dropdown As ToolStripDropDown)
  115.                    If preventClosure Then
  116.                        If Not ToolStripMenuItemExtensions.closingHandlerAssociatedItems.Contains(dropdown) Then
  117.                            AddHandler dropdown.Closing, ToolStripMenuItemExtensions.closingHandler
  118.                            ToolStripMenuItemExtensions.closingHandlerAssociatedItems.Add(dropdown)
  119.                        End If
  120.                    Else
  121.                        If ToolStripMenuItemExtensions.closingHandlerAssociatedItems.Contains(dropdown) Then
  122.                            RemoveHandler dropdown.Closing, ToolStripMenuItemExtensions.closingHandler
  123.                            ToolStripMenuItemExtensions.closingHandlerAssociatedItems.Remove(dropdown)
  124.                        End If
  125.                    End If
  126.                End Sub
  127.  
  128.            Dim queue As New Queue(Of ToolStripDropDown)
  129.  
  130.            ' Root level items iteration.
  131.            If recursive Then
  132.                queue.Enqueue(menuItem.DropDown)
  133.            Else
  134.                If TypeOf menuItem Is ToolStripMenuItem Then
  135.                    dropdownAction(menuItem.DropDown)
  136.                End If
  137.            End If
  138.  
  139.            ' Recursive items iteration.
  140.            While queue.Any()
  141.                Dim currentItem As ToolStripDropDown = queue.Dequeue()
  142.                dropdownAction(currentItem)
  143.  
  144.                If currentItem.HasChildren Then
  145.                    For Each subMenuItem As ToolStripMenuItem In currentItem.Items.OfType(Of ToolStripMenuItem)
  146.                        If subMenuItem.HasDropDown Then
  147.                            queue.Enqueue(subMenuItem.DropDown)
  148.                        End If
  149.                    Next
  150.                End If
  151.            End While
  152.        End Sub
  153.  
  154. #End Region
  155.  
  156.    End Module
  157.  
  158. End Namespace
  159.  
  160. #End Region
  161.  
14  Programación / .NET (C#, VB.NET, ASP) / Re: Librería de Snippets para VB.NET !! (Compartan aquí sus snippets) en: 16 Abril 2024, 08:45 am
Dos métodos de extensión que nos permiten, de forma simple y sencilla usado solamente una línea de código, desactivar o activar una o varias pestañas de un TabControl, lo que no se limita solamente a desactivar la página (propiedad: TabPage.Enabled), sino también a prohibir o permitir que las pestañas puedan seleccionarse en el TabControl.

Modo de empleo:

Para desactivar una o varias pestañas:
Código
  1. TabControl1.DisableTabs(TabPage1, TabPage2)

Para (re)activar una o varias pestañas:
Código
  1. TabControl1.EnableTabs(TabPage1, TabPage2)

El Código:

Código
  1. Imports System.Runtime.CompilerServices
  2.  
  3. ''' <summary>
  4. ''' Provides extension methods for a <see cref="TabControl"/> control.
  5. ''' </summary>
  6. <HideModuleName>
  7. Public Module TabControlExtensions
  8.  
  9.    ''' <summary>
  10.    ''' Collection used to store tab pages whose tab header need to remain disabled on a <see cref="TabControl"/>.
  11.    ''' <para></para>
  12.    ''' This collection depends on <see cref="TabControlExtensions.DisableOrEnableTabs_Internal"/> method.
  13.    ''' </summary>
  14.    Private disabledTabs As HashSet(Of TabPage)
  15.  
  16.    ''' <summary>
  17.    ''' Collection used to store tab controls whose its <see cref="TabControl.Selecting"/> event
  18.    ''' has been associated to <see cref="TabControlExtensions.disableTabPageHandler"/>.
  19.    ''' <para></para>
  20.    ''' This collection depends on <see cref="TabControlExtensions.DisableOrEnableTabs_Internal"/> method.
  21.    ''' </summary>
  22.    Private tabHandlerAddedControls As HashSet(Of TabControl)
  23.  
  24.    ''' <summary>
  25.    ''' A <see cref="TabControlCancelEventHandler"/> delegate used for disabling tabs on a <see cref="TabControl"/>.
  26.    ''' <para></para>
  27.    ''' This handler depends on <see cref="TabControlExtensions.DisableOrEnableTabs_Internal"/> method.
  28.    ''' </summary>
  29.    Private tabDisablerHandler As TabControlCancelEventHandler
  30.  
  31.    ''' <summary>
  32.    ''' Disables one or multiple <see cref="TabPage"/>,
  33.    ''' making the tabs unselectable in the source <see cref="TabControl"/>.
  34.    ''' </summary>
  35.    '''
  36.    ''' <param name="tabControl">
  37.    ''' The source <see cref="TabControl"/>.
  38.    ''' </param>
  39.    '''
  40.    ''' <param name="tabPages">
  41.    ''' An Array of <see cref="TabPage"/> to disable.
  42.    ''' </param>
  43.    <Extension>
  44.    <DebuggerStepThrough>
  45.    Public Sub DisableTabs(tabControl As TabControl, ParamArray tabPages As TabPage())
  46.        TabControlExtensions.DisableOrEnableTabs_Internal(tabControl, enabled:=False, tabPages)
  47.    End Sub
  48.  
  49.    ''' <summary>
  50.    ''' Enables one or multiple <see cref="TabPage"/> that were previously
  51.    ''' disabled by a call to <see cref="TabControlExtensions.DisableTabPages"/> method,
  52.    ''' making the tabs selectable again in the source <see cref="TabControl"/>.
  53.    ''' </summary>
  54.    '''
  55.    ''' <param name="tabControl">
  56.    ''' The source <see cref="TabControl"/>.
  57.    ''' </param>
  58.    '''
  59.    ''' <param name="tabPages">
  60.    ''' An Array of <see cref="TabPage"/> to enable.
  61.    ''' </param>
  62.    <Extension>
  63.    <DebuggerStepThrough>
  64.    Public Sub EnableTabs(tabControl As TabControl, ParamArray tabPages As TabPage())
  65.        TabControlExtensions.DisableOrEnableTabs_Internal(tabControl, enabled:=True, tabPages)
  66.    End Sub
  67.  
  68.    ''' <summary>
  69.    ''' *** FOR INTERNAL USE ONLY ***
  70.    ''' <para></para>
  71.    ''' Disables or enables one or multiple <see cref="TabPage"/>,
  72.    ''' denying or allowing their tab selection in the source <see cref="TabControl"/>.
  73.    ''' </summary>
  74.    '''
  75.    ''' <param name="tabControl">
  76.    ''' The source <see cref="TabControl"/>.
  77.    ''' </param>
  78.    '''
  79.    ''' <param name="enabled">
  80.    ''' If <see langword="False"/>, disables the tab pages and make them unselectable in the source <see cref="TabControl"/>;
  81.    ''' otherwise, enable the tab pages and allows to be selected in the source <see cref="TabControl"/>.
  82.    ''' </param>
  83.    '''
  84.    ''' <param name="tabPages">
  85.    ''' An Array of the tab pages to disable or enable.
  86.    ''' </param>
  87.    <DebuggerStepThrough>
  88.    Private Sub DisableOrEnableTabs_Internal(tabControl As TabControl, enabled As Boolean, ParamArray tabPages As TabPage())
  89.        If tabControl Is Nothing Then
  90.            Throw New ArgumentNullException(paramName:=NameOf(tabControl))
  91.        End If
  92.        If tabPages Is Nothing Then
  93.            Throw New ArgumentNullException(paramName:=NameOf(tabPages))
  94.        End If
  95.  
  96.        ' Initialize collections.
  97.        If TabControlExtensions.disabledTabs Is Nothing Then
  98.            TabControlExtensions.disabledTabs = New HashSet(Of TabPage)
  99.        End If
  100.        If TabControlExtensions.tabHandlerAddedControls Is Nothing Then
  101.            TabControlExtensions.tabHandlerAddedControls = New HashSet(Of TabControl)
  102.        End If
  103.  
  104.        ' Initialize handler.
  105.        If TabControlExtensions.tabDisablerHandler Is Nothing Then
  106.            TabControlExtensions.tabDisablerHandler =
  107.                Sub(sender As Object, e As TabControlCancelEventArgs)
  108.                    If e.TabPageIndex < 0 Then
  109.                        Exit Sub
  110.                    End If
  111.  
  112.                    Select Case e.Action
  113.                        Case TabControlAction.Selecting, TabControlAction.Selected
  114.                            e.Cancel = TabControlExtensions.disabledTabs.Contains(e.TabPage)
  115.                        Case Else
  116.                            Exit Sub
  117.                    End Select
  118.                End Sub
  119.        End If
  120.  
  121.        For Each tabPage As TabPage In tabPages
  122.            If tabPage Is Nothing Then
  123.                Throw New NullReferenceException($"{NameOf(tabPage)} object is null.")
  124.            End If
  125.  
  126.            ' Disable or enable the tab page.
  127.            tabPage.Enabled = enabled
  128.  
  129.            If Not enabled Then ' Disable the tab header.
  130.                Dim success As Boolean = disabledTabs.Add(tabPage)
  131.                If success AndAlso Not TabControlExtensions.tabHandlerAddedControls.Contains(tabControl) Then
  132.                    AddHandler tabControl.Selecting, TabControlExtensions.tabDisablerHandler
  133.                    TabControlExtensions.tabHandlerAddedControls.Add(tabControl)
  134.                End If
  135.            Else ' Enable the tab header.
  136.                Dim success As Boolean = disabledTabs.Remove(tabPage)
  137.                If success AndAlso TabControlExtensions.tabHandlerAddedControls.Contains(tabControl) AndAlso
  138.                               Not TabControlExtensions.disabledTabs.Any() Then
  139.                    RemoveHandler tabControl.Selecting, TabControlExtensions.tabDisablerHandler
  140.                    TabControlExtensions.tabHandlerAddedControls.Remove(tabControl)
  141.                End If
  142.            End If
  143.        Next tabPage
  144.  
  145.    End Sub
  146.  
  147. End Module
15  Programación / .NET (C#, VB.NET, ASP) / Re: Librería de Snippets para VB.NET !! (Compartan aquí sus snippets) en: 15 Abril 2024, 12:40 pm
El siguiente método sirve para aplicar, de forma automatizada, y recursivamente, los recursos aplicables de localización para un Form específico, o para todos los Forms visibles de la aplicación actual.

En otras palabras, el siguiente método sirve para automatizar un cambio de idioma en nuestra aplicación, y tan solo necesitando una línea de código para llamar a dicho método...



He tenido que desarrollar este método, por que todas las alternativas que hay disponibles por Internet son muy básicas e ineficientes, ya que se limitan a iterar los controles y controles hijo, mientras que mi implementación además también itera los menús y sus items de forma recursiva, y los componentes de un form (como un NotifyIcon).



Ejemplos de uso:

Código
  1. ' Aplica recursos de localización a un form específico
  2. Dim form As Form = Me
  3. Dim cultureName As String = "es-ES"
  4. ApplyCultureResources(form, cultureName)

Código
  1. ' Aplica recursos de localización a todos los forms de la aplicación
  2. Dim cultureName As String = "es-ES"
  3. ApplyCultureResources(cultureName)

Salida de depuración (ejemplo limitado):

Cambio de idioma a Inglés:
Código:
Culture: English (en), Component: Form1                 , Text: My Form
Culture: English (en), Component: Button1               , Text: My Button
Culture: English (en), Component: ToolStrip1            , Text: (null)
Culture: English (en), Component: ToolStripStatusLabel1 , Text: Testing
Culture: English (en), Component: MenuStrip1            , Text: (null)
Culture: English (en), Component: ToolStripMenuItem1    , Text: One
Culture: English (en), Component: ToolStripMenuItem2    , Text: Two
Culture: English (en), Component: TabControl1           , Text: (null)
Culture: English (en), Component: TabPage1              , Text: Page 1
Culture: English (en), Component: TabPage2              , Text: Page 2
Culture: English (en), Component: NotifyIcon1           , Text: Icon

Cambio de idioma a Español:
Código:
Culture: Spanish (es), Component: Form1                 , Text: Mi Form
Culture: Spanish (es), Component: Button1               , Text: Mi Botón
Culture: Spanish (es), Component: ToolStrip1            , Text: (null)
Culture: Spanish (es), Component: ToolStripStatusLabel1 , Text: Probando
Culture: Spanish (es), Component: MenuStrip1            , Text: (null)
Culture: Spanish (es), Component: ToolStripMenuItem1    , Text: Uno
Culture: Spanish (es), Component: ToolStripMenuItem2    , Text: Dos
Culture: Spanish (es), Component: TabControl1           , Text: (null)
Culture: Spanish (es), Component: TabPage1              , Text: Página 1
Culture: Spanish (es), Component: TabPage2              , Text: Página 2
Culture: Spanish (es), Component: NotifyIcon1           , Text: Icono



IMPORTANTE: el siguiente método depende de los métodos de extensión ForEachControl y ForEachItem que compartí en el post anterior de este hilo:


Y también depende de este otro método de extensión:

Código
  1. ''' <summary>
  2. ''' Provides extension methods for the <see cref="WinForms.IContainerControl"/> interface.
  3. ''' </summary>
  4. <HideModuleName>
  5. Public Module IContainerControlExtensions
  6.  
  7.  
  8.    ''' <summary>
  9.    ''' Gets the underlying <see cref="System.ComponentModel.ComponentCollection"/> collection
  10.    ''' of the source <see cref="IContainerControl"/>.
  11.    ''' </summary>
  12.    '''
  13.    ''' <param name="container">
  14.    ''' The source <see cref="IContainerControl"/>.
  15.    ''' </param>
  16.    '''
  17.    ''' <returns>
  18.    ''' The underlying <see cref="System.ComponentModel.ComponentCollection"/> collection
  19.    ''' of the source <see cref="IContainerControl"/>.
  20.    ''' </returns>
  21.    <DebuggerStepThrough>
  22.    <Extension>
  23.    <EditorBrowsable(EditorBrowsableState.Always)>
  24.    Public Function GetComponentCollection(container As IContainerControl) As ComponentCollection
  25.        Dim type As Type = container.GetType()
  26.        Dim componentsField As FieldInfo = type.GetField("components", BindingFlags.NonPublic Or BindingFlags.Instance)
  27.  
  28.        If componentsField Is Nothing Then
  29.            Throw New InvalidOperationException("""components"" field was not found through Reflection.")
  30.        End If
  31.  
  32.        Dim containerComponents As IContainer = TryCast(componentsField.GetValue(container), IContainer)
  33.        Return containerComponents?.Components
  34.    End Function
  35.  
  36. End Module



El código:

Código
  1. ''' <summary>
  2. ''' This method sets the current UI culture to the specified culture name,
  3. ''' then applies culture-specific resources to the specified <see cref="Form"/>,
  4. ''' to its controls and child controls, including menus and their items, and
  5. ''' the components in the form's <see cref="ComponentCollection"/>, recursively.
  6. ''' </summary>
  7. '''
  8. ''' <example> This is a code example.
  9. ''' <code language="VB">
  10. ''' Dim form As Form = Me
  11. ''' Dim cultureName As String = "es-ES"
  12. ''' ApplyCultureResources(form, cultureName)
  13. ''' </code>
  14. ''' </example>
  15. '''
  16. ''' <param name="form">
  17. ''' The form to apply resources to.
  18. ''' </param>
  19. '''
  20. ''' <param name="cultureName">
  21. ''' The culture name of the resources to apply.
  22. ''' </param>
  23. Public Shared Sub ApplyCultureResources(form As Form, cultureName As String)
  24.  
  25.    Dim culture As CultureInfo = CultureInfo.GetCultureInfo(cultureName)
  26. #If Not NETCOREAPP Then
  27.            My.Application.ChangeUICulture(cultureName)
  28. #Else
  29.            Thread.CurrentThread.CurrentUICulture = culture
  30. #End If
  31.  
  32.    Dim resources As New ComponentResourceManager(form.GetType())
  33.  
  34.    ' Action delegate that applies resources to an IComponent.
  35.    Dim applyResources As Action(Of IComponent, String) =
  36.        Sub(component As IComponent, name As String)
  37.            If String.IsNullOrEmpty(name) Then
  38.                ' Not valid to apply localization resources.
  39.                Exit Sub
  40.            Else
  41.                resources.ApplyResources(component, name, culture)
  42.            End If
  43.  
  44.            ' Applies resources to the items and subitems of a ToolStrip component, recursively.
  45.            If TypeOf component Is ToolStrip Then
  46.                Dim ts As ToolStrip = DirectCast(component, ToolStrip)
  47.                ToolStripExtensions.ForEachItem(ts, recursive:=True, Sub(item) applyResources(item, item.Name))
  48.            End If
  49.  
  50. #If DEBUG Then ' Prints debug information.
  51.            ' Flags to retrieve the "Text" property of a component.
  52.            Const textPropBindingFlags As BindingFlags =
  53.                BindingFlags.Instance Or BindingFlags.Static Or
  54.                BindingFlags.Public Or BindingFlags.NonPublic
  55.  
  56.            Dim textProp As PropertyInfo =
  57.                (From prop As PropertyInfo In component.GetType().GetProperties(textPropBindingFlags)
  58.                 Where prop.PropertyType Is GetType(String) AndAlso
  59.                       prop.Name.Equals("Text", StringComparison.OrdinalIgnoreCase)
  60.                ).SingleOrDefault()
  61.  
  62.            Dim text As String = DirectCast(textProp?.GetValue(component), String)
  63.            If String.IsNullOrEmpty(text) Then
  64.                text = "(null)"
  65.            End If
  66.            Debug.WriteLine($"Culture: {culture.EnglishName} ({culture.Name}), Component: {name,-40}, Text: {text}")
  67. #End If
  68.        End Sub
  69.  
  70.    ' Apply resources to the form.
  71.    applyResources(form, form.Name)
  72.  
  73.    ' Apply resources to the controls hosted in the form, recursively.
  74.    FormExtensions.ForEachControl(form, recursive:=True, Sub(ctrl) applyResources(ctrl, ctrl.Name))
  75.  
  76.    ' Apply resources to the components hosted in the ComponentCollection of the form.
  77.    Dim components As ComponentCollection = IContainerControlExtensions.GetComponentCollection(form)
  78.    If components IsNot Nothing Then
  79.        ' Flags to retrieve the "Name" property of a component.
  80.        Const namePropBindingFlags As BindingFlags =
  81.            BindingFlags.Instance Or BindingFlags.Static Or
  82.            BindingFlags.Public Or BindingFlags.NonPublic
  83.  
  84.        For Each component As IComponent In components
  85.            Dim nameProp As PropertyInfo =
  86.                  (From prop As PropertyInfo In component.GetType().GetProperties(namePropBindingFlags)
  87.                   Where prop.PropertyType Is GetType(String) AndAlso
  88.                         prop.Name.Equals("Name", StringComparison.OrdinalIgnoreCase)
  89.                  ).SingleOrDefault()
  90.  
  91.            Dim name As String = DirectCast(nameProp?.GetValue(component), String)
  92.            applyResources(component, name)
  93.        Next component
  94.    End If
  95.  
  96.    ' This code finds and applies resources to component fields declared at the form level
  97.    ' (including those in the auto-generated code of the form designer) that doesn't have
  98.    ' defined a "Name" property (such as NotifyIcon, ColorDialog, OpenFileDialog, etc).
  99.    Const fieldsBindingFlags As BindingFlags =
  100.        BindingFlags.Instance Or BindingFlags.DeclaredOnly Or BindingFlags.Static Or
  101.        BindingFlags.Public Or BindingFlags.NonPublic
  102.  
  103.    Dim fields As IEnumerable(Of FieldInfo) =
  104.                From field As FieldInfo In form.GetType().GetFields(fieldsBindingFlags)
  105.                Where GetType(IComponent).IsAssignableFrom(field.FieldType) AndAlso
  106.                  Not GetType(Control).IsAssignableFrom(field.FieldType) AndAlso
  107.                  Not GetType(ToolStripItem).IsAssignableFrom(field.FieldType)
  108.  
  109.    For Each field As FieldInfo In fields
  110.        Dim component As IComponent = DirectCast(field.GetValue(form), IComponent)
  111.        Dim name As String = field.Name.TrimStart("_"c) ' E.g.: "_NotifyIcon1" -> "NotifyIcon1"
  112.        applyResources(component, name)
  113.    Next field
  114.  
  115. End Sub

Código
  1. ''' <summary>
  2. ''' This method sets the current UI culture to the specified culture name,
  3. ''' then applies culture-specific resources to the open forms of the current application,
  4. ''' to its controls and child controls, including menus and their items, and
  5. ''' the components in the form's <see cref="ComponentCollection"/>, recursively.
  6. ''' </summary>
  7. '''
  8. ''' <example> This is a code example.
  9. ''' <code language="VB">
  10. ''' Dim cultureName As String = "es-ES"
  11. ''' ApplyCultureResources(cultureName)
  12. ''' </code>
  13. ''' </example>
  14. '''
  15. ''' <param name="cultureName">
  16. ''' The culture name of the resources to apply.
  17. ''' </param>
  18. Public Shared Sub ApplyCultureResources(cultureName As String)
  19.    For Each form As Form In System.Windows.Forms.Application.OpenForms
  20.        ApplyCultureResources(form, cultureName)
  21.    Next form
  22. End Sub
16  Programación / .NET (C#, VB.NET, ASP) / Re: Problema con PostMessage y SendMessage en: 13 Abril 2024, 12:59 pm
Comparto el código fuente anterior, pero con documentación reducida, por si alguien lo prefiere así sin tanto texto adicional.

(EL SIGUIENTE CÓDIGO HA SIDO REFACTORIZADO Y PUBLICADO A LAS 16:35 HORA ESPAÑOLA, SIMPLIFICANDO Y MEJORANDO VARIOS ASPECTOS GENERALES.)

Son 280 líneas, en comparación con las 694 del post anterior.
Son 328 líneas, en comparación con las 757 del post anterior.

DevCase.cs
Código
  1. using System;
  2. using System.ComponentModel;
  3. using System.Diagnostics;
  4. using System.Drawing;
  5. using System.Linq;
  6. using System.Runtime.InteropServices;
  7. using System.Security;
  8. using System.Threading;
  9.  
  10. using DevCase.Win32;
  11. using DevCase.Win32.Enums;
  12.  
  13. namespace DevCase {
  14.  
  15.    namespace Core.IO.Devices.Input {
  16.  
  17.        /// <summary>
  18.        /// Provides mouse interaction related utilities.
  19.        /// </summary>
  20.        internal sealed class UtilMouse {
  21.  
  22.            [DebuggerNonUserCode]
  23.            private UtilMouse() { }
  24.  
  25.            /// <summary>
  26.            /// Defines a button message to send to a window.
  27.            /// </summary>
  28.            internal enum MouseButtonMessage : int {
  29.                LeftDown = WindowMessages.WM_LButtonDown,
  30.                LeftUp = WindowMessages.WM_LButtonUp,
  31.                RightDown = WindowMessages.WM_RButtonDown,
  32.                RightUp = WindowMessages.WM_RButtonUp,
  33.                MiddleDown = WindowMessages.WM_MButtonDown,
  34.                MiddleUp = WindowMessages.WM_MButtonUp,
  35.                WheelDown,
  36.                WheelUp,
  37.                WheelLeft,
  38.                WheelRight
  39.  
  40.            }
  41.  
  42.            /// <summary>
  43.            /// Defines a click of a mouse button.
  44.            /// </summary>
  45.            internal enum MouseButtonClick : int {
  46.                LeftButton,
  47.                RightButton,
  48.                MiddleButton
  49.            }
  50.  
  51.            /// <summary>
  52.            /// Sends a mouse button message to the specified window,
  53.            /// on the specified coordinates relative to its client-area,
  54.            /// by calling <see cref="Win32.NativeMethods.SendMessage"/> function.
  55.            /// </summary>
  56.            [DebuggerStepThrough]
  57.            internal static bool SendMouseButtonMessage(IntPtr hWnd, MouseButtonMessage button, Point pt) {
  58.                return UtilMouse.SendMouseButtonMessage_Internal(hWnd, button, pt, async: false);
  59.            }
  60.  
  61.            /// <summary>
  62.            /// Asynchronouslly sends a mouse button message to the specified window,
  63.            /// on the specified coordinates relative to its client-area,
  64.            /// by calling <see cref="Win32.NativeMethods.PostMessage"/> function.
  65.            /// </summary>
  66.            [DebuggerStepThrough]
  67.            internal static bool SendMouseButtonMessageAsync(IntPtr hWnd, MouseButtonMessage button, Point pt) {
  68.                return UtilMouse.SendMouseButtonMessage_Internal(hWnd, button, pt, async: true);
  69.            }
  70.  
  71.            /// <summary>
  72.            /// Sends a mouse button click to the specified window,
  73.            /// on the specified coordinates relative to its client-area,
  74.            /// by calling <see cref="Win32.NativeMethods.SendMessage"/> function.
  75.            /// </summary>
  76.            [DebuggerStepThrough]
  77.            internal static bool SendMouseButtonClick(IntPtr hWnd, MouseButtonClick button, Point pt) {
  78.                return UtilMouse.SendMouseButtonClick_Internal(hWnd, button, pt, async: false);
  79.            }
  80.  
  81.            /// <summary>
  82.            /// Asynchronouslly sends a mouse button click to the specified window,
  83.            /// on the specified coordinates relative to its client-area,
  84.            /// by calling <see cref="Win32.NativeMethods.PostMessage"/> function.
  85.            /// </summary>
  86.            [DebuggerStepThrough]
  87.            internal static bool SendMouseButtonClickAsync(IntPtr hWnd, MouseButtonClick button, Point pt) {
  88.                return UtilMouse.SendMouseButtonClick_Internal(hWnd, button, pt, async: true);
  89.            }
  90.  
  91.            /// <summary>
  92.            /// *** FOR INTERNAL USE ONLY ***
  93.            /// <para></para>
  94.            /// Sends a mouse button message to the specified window,
  95.            /// on the specified coordinates relative to its client-area.
  96.            /// </summary>
  97.            private static bool SendMouseButtonMessage_Internal(IntPtr hWnd, MouseButtonMessage button, Point pt, bool async) {
  98.  
  99.                if (pt == null) {
  100.                    pt = Point.Empty;
  101.                }
  102.  
  103.                Delegate msgFunc = async ?
  104.                    (Delegate)(new Func<IntPtr, WindowMessages, IntPtr, IntPtr, bool>(NativeMethods.PostMessage)) :
  105.                    (Delegate)(new Func<IntPtr, WindowMessages, IntPtr, IntPtr, IntPtr>(NativeMethods.SendMessage));
  106.  
  107.                WindowMessages msg = (WindowMessages)button;
  108.                IntPtr lParam = UtilWin32.MakeLParam(pt.X, pt.Y);
  109.                IntPtr wParam = System.IntPtr.Zero;
  110.  
  111.                switch (button) {
  112.                    case MouseButtonMessage.LeftUp:
  113.                    case MouseButtonMessage.RightUp:
  114.                    case MouseButtonMessage.MiddleUp:
  115.                        wParam = IntPtr.Zero;
  116.                        break;
  117.  
  118.                    case MouseButtonMessage.LeftDown:
  119.                        wParam = new IntPtr((int)WParams.MK_LButton);
  120.                        break;
  121.  
  122.                    case MouseButtonMessage.RightDown:
  123.                        wParam = new IntPtr((int)WParams.MK_RButton);
  124.                        break;
  125.  
  126.                    case MouseButtonMessage.MiddleDown:
  127.                        wParam = new IntPtr((int)WParams.MK_MButton);
  128.                        break;
  129.  
  130.                    case MouseButtonMessage.WheelDown:
  131.                        msg = WindowMessages.WM_MouseWheel;
  132.                        wParam = UtilWin32.MakeLParam(0, -120);
  133.                        break;
  134.  
  135.                    case MouseButtonMessage.WheelUp:
  136.                        msg = WindowMessages.WM_MouseWheel;
  137.                        wParam = UtilWin32.MakeLParam(0, 120);
  138.                        break;
  139.  
  140.                    case MouseButtonMessage.WheelLeft:
  141.                        msg = WindowMessages.WM_MouseHWheel;
  142.                        wParam = UtilWin32.MakeLParam(0, -120);
  143.                        break;
  144.  
  145.                    case MouseButtonMessage.WheelRight:
  146.                        msg = WindowMessages.WM_MouseHWheel;
  147.                        wParam = UtilWin32.MakeLParam(0, 120);
  148.                        break;
  149.  
  150.                    default:
  151.                        throw new InvalidEnumArgumentException(nameof(button), (int)button, typeof(MouseButtonMessage));
  152.                }
  153.  
  154.                // Ensures the target window has focus.
  155.                NativeMethods.SetFocus(hWnd);
  156.  
  157.                object success = msgFunc.DynamicInvoke(hWnd, msg, wParam, lParam);
  158.                return (async ? (bool)success : (IntPtr)success == IntPtr.Zero);
  159.            }
  160.  
  161.            /// <summary>
  162.            /// *** FOR INTERNAL USE ONLY ***
  163.            /// <para></para>
  164.            /// Sends a mouse button click to the specified window,
  165.            /// on the specified coordinates relative to its client-area.
  166.            /// </summary>
  167.            private static bool SendMouseButtonClick_Internal(IntPtr hWnd, MouseButtonClick button, Point pt, bool async) {
  168.  
  169.                MouseButtonMessage msgButtonDown;
  170.                MouseButtonMessage msgButtonUp;
  171.  
  172.                switch (button) {
  173.                    case MouseButtonClick.LeftButton:
  174.                        msgButtonDown = MouseButtonMessage.LeftDown;
  175.                        msgButtonUp = MouseButtonMessage.LeftUp;
  176.                        break;
  177.  
  178.                    case MouseButtonClick.RightButton:
  179.                        msgButtonDown = MouseButtonMessage.RightDown;
  180.                        msgButtonUp = MouseButtonMessage.RightUp;
  181.                        break;
  182.  
  183.                    case MouseButtonClick.MiddleButton:
  184.                        msgButtonDown = MouseButtonMessage.MiddleDown;
  185.                        msgButtonUp = MouseButtonMessage.MiddleUp;
  186.                        break;
  187.  
  188.                    default:
  189.                        throw new InvalidEnumArgumentException(nameof(button), (int)button, typeof(MouseButtonClick));
  190.                }
  191.  
  192.                // Milliseconds to wait between sequentially sendig WM_#BUTTON_DOWN + WM_#BUTTON_UP message combination.
  193.                const int msgIntervalMs = 100;
  194.  
  195.                bool successButtonDown = UtilMouse.SendMouseButtonMessage_Internal(hWnd, msgButtonDown, pt, async);
  196.                Thread.Sleep(msgIntervalMs);
  197.                bool successButtonUp = UtilMouse.SendMouseButtonMessage_Internal(hWnd, msgButtonUp, pt, async);
  198.  
  199.                return successButtonDown & successButtonUp;
  200.            }
  201.  
  202.        }
  203.  
  204.    }
  205.  
  206.    namespace Win32 {
  207.  
  208.        /// <summary>
  209.        /// Platform Invocation (P/Invoke) methods, access unmanaged code.
  210.        /// </summary>
  211.        [SuppressUnmanagedCodeSecurity]
  212.        internal sealed class NativeMethods {
  213.  
  214.            [DebuggerNonUserCode]
  215.            private NativeMethods() { }
  216.  
  217.            #region  User32.dll
  218.  
  219.            /// <summary>
  220.            /// Sets the keyboard focus to the specified window.
  221.            /// <para></para>
  222.            /// The window must be attached to the calling thread's message queue.
  223.            /// </summary>
  224.            [DllImport("User32.dll", SetLastError = true)]
  225.            internal static extern IntPtr SetFocus([In, Optional] IntPtr hWnd);
  226.  
  227.            /// <summary>
  228.            /// Sends the specified message to a window or windows.
  229.            /// <para></para>
  230.            /// The SendMessage function calls the window procedure for the specified window
  231.            /// and does not return until the window procedure has processed the message.
  232.            /// </summary>
  233.            [DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
  234.            [return: MarshalAs(UnmanagedType.SysInt)]
  235.            internal static extern IntPtr SendMessage([In, MarshalAs(UnmanagedType.SysInt)] IntPtr hWnd,
  236.                                                      [In, MarshalAs(UnmanagedType.I4)] WindowMessages msg,
  237.                                                      [In, MarshalAs(UnmanagedType.SysInt)] IntPtr wParam,
  238.                                                      [In, MarshalAs(UnmanagedType.SysInt)] IntPtr lParam);
  239.  
  240.            /// <summary>
  241.            /// Places (posts) a message in the message queue associated with the thread that created
  242.            /// the specified window and returns without waiting for the thread to process the message.
  243.            /// </summary>
  244.            [DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
  245.            [return: MarshalAs(UnmanagedType.Bool)]
  246.            internal static extern bool PostMessage([In, Optional, MarshalAs(UnmanagedType.SysInt)] IntPtr hWnd,
  247.                                                    [In, MarshalAs(UnmanagedType.I4)] WindowMessages msg,
  248.                                                    [In, MarshalAs(UnmanagedType.SysInt)] IntPtr wparam,
  249.                                                    [In, MarshalAs(UnmanagedType.SysInt)] IntPtr lparam);
  250.  
  251.            #endregion
  252.        }
  253.  
  254.        /// <summary>
  255.        /// Provides Windows API related utilites.
  256.        /// </summary>
  257.        internal sealed class UtilWin32 {
  258.  
  259.            [DebuggerNonUserCode]
  260.            private UtilWin32() { }
  261.  
  262.            /// <summary>
  263.            /// Creates a LONG Param (LParam) value for a window message, from two <see cref="Integer"/> values.
  264.            /// <para></para>
  265.            /// You must call this method if you need to use negative values.
  266.            /// </summary>
  267.            [DebuggerStepThrough]
  268.            internal static IntPtr MakeLParam(int lo, int hi) {
  269.                byte[] loBytes = { BitConverter.GetBytes(lo)[0], BitConverter.GetBytes(lo)[1] };
  270.                byte[] hiBytes = { BitConverter.GetBytes(hi)[0], BitConverter.GetBytes(hi)[1] };
  271.                byte[] combined = loBytes.Concat(hiBytes).ToArray();
  272.  
  273.                return new IntPtr(BitConverter.ToInt32(combined, 0));
  274.            }
  275.  
  276.            /// <summary>
  277.            /// Creates a LONG Param (LParam) value for a window message, from two <see cref="UShort"/> values.
  278.            /// </summary>
  279.            [DebuggerStepThrough]
  280.            internal static IntPtr MakeLParam(ushort loWord, ushort hiWord) {
  281.                return new IntPtr(UtilWin32.MakeDWord(loWord, hiWord));
  282.            }
  283.  
  284.            /// <summary>
  285.            /// Creates a Double WORD (DWORD, 32-Bit Unsigned Integer) value from a LOWORD and a HIWORD value.
  286.            /// </summary>
  287.            [DebuggerStepThrough]
  288.            internal static uint MakeDWord(ushort loWord, ushort hiWord) {
  289.                byte[] loBytes = BitConverter.GetBytes(loWord);
  290.                byte[] hiBytes = BitConverter.GetBytes(hiWord);
  291.                byte[] combined = loBytes.Concat(hiBytes).ToArray();
  292.  
  293.                return BitConverter.ToUInt32(combined, 0);
  294.            }
  295.        }
  296.    }
  297.  
  298.    namespace Win32.Enums {
  299.  
  300.        /// <summary>
  301.        /// Defines additional message-specific information for the WORD Param (WParam) value of window messages.
  302.        /// </summary>
  303.        internal enum WParams : int {
  304.            Null = 0x0,
  305.            MK_LButton = 0x1,
  306.            MK_MButton = 0x10,
  307.            MK_RButton = 0x2
  308.        }
  309.  
  310.        /// <summary>
  311.        /// Defines window messages.
  312.        /// </summary>
  313.        internal enum WindowMessages : int {
  314.            WM_LButtonDown = 0x201,
  315.            WM_LButtonUp = 0x202,
  316.            WM_MButtonDown = 0x207,
  317.            WM_MButtonUp = 0x208,
  318.            WM_RButtonDown = 0x204,
  319.            WM_RButtonUp = 0x205,
  320.            WM_XButtonDown = 0x20B,
  321.            WM_XButtonUp = 0x20C,
  322.            WM_MouseWheel = 0x20A,
  323.            WM_MouseHWheel = 0x20E
  324.        }
  325.  
  326.    }
  327.  
  328. }

Aténtamente,
Elektro.
17  Foros Generales / Sugerencias y dudas sobre el Foro / Re: ¿Cómo desactivo o cambio el corrector ortográfico en el foro? en: 13 Abril 2024, 12:44 pm
Tendrás que seleccionar el idioma español en los ajustes del firefox. Creo que está en el la pestaña 'General', por ahí en lo de 'Idioma', asegúrate de que esté seleccionado el 'Español (ES)', y en lo de 'Elegir el idioma preferido para mostrar las paginas web' pica en 'Seleccionar' y pon arriba del todo los idiomas españoles.
Saludos...

Songoku


Gracias :)
18  Foros Generales / Sugerencias y dudas sobre el Foro / Re: ¿Cómo desactivo o cambio el corrector ortográfico en el foro? en: 13 Abril 2024, 12:28 pm
Yo también pienso que es cosa de tu navegador osea del firefox. Instálate esta extensión o mas bien diccionario: https://addons.mozilla.org/es/firefox/addon/diccionario-de-espa%C3%B1ol-espa%C3%B1a/

Songoku, ya tenía instalado ese diccionario. :-\

De todas formas lo he eliminado y vuelto a instalar. Nada, todas las palabras que estoy escribiendo ahora mismo en este post se siguen resaltando como si estuvieran mal escritas.

Y para colmo, al reinstalar la extensión, de repente me ha cambiado la fuente de texto de algunos elementos del foro (se ve con una letra difícil de leer), es alucinante, ¿¡por qué me pasa esto!?. xD Lo de la fuente de texto se ha solucionado por si solo reiniciando el proceso del navegador.



Ya he averiguado como solucionarlo. Hay que hacer click derecho sobre un espacio en blanco del editor de texto, y seleccionar el idioma Español:



Al parecer solo necesito hacerlo una vez, y ya se queda así en el foro, y al parecer este cambio solo afecta al foro, ya que en otros sitios web sigo teniendo seleccionado el idioma Inglés por defecto.

Nunca me había fijado en esa opción del menú contextual, por que nunca lo he necesitado (como ya digo en otras páginas esto no me pasa), me ha dado por mirar ahora a ver si me salía algo relevante en el menú contextual.

Qué fácil era, joder. ¡Y qué alivio!. xD

Tampoco es que le haya dado mucha importancia hasta ahora, pero se hacía incómodo escribir así.

¡Gracias a los dos por la ayuda!.
19  Foros Generales / Sugerencias y dudas sobre el Foro / Re: ¿Cómo desactivo o cambio el corrector ortográfico en el foro? en: 13 Abril 2024, 11:55 am
Lo más probable es que se pueda solucionar agregando un corrector ortográfico al navegador que utilices en cada momento. Una vez instalado hay que seleccionar el idioma, entre los instalados, que se quiera en cada momento o definir como preferido el que sea igual a la lengua que se escriba.

Pero no necesito instalar un corrector de terceros. Cuando estoy escribiendo en otra página española, se me activa automáticamente el corrector en Español. Y si estoy en una página de EEUU, se me activa el corrector en Inglés. Solo me pasa en este foro que se me activa el corrector en Inglés.

Yo supongo, en mi ignorancia, que esto se debe a Cloudflare, o lo que sea, que hace que el servidor de la página esté en EEUU:



...pero no se como solucionar este problema del correcto de forma eficiente. No se si es posible configurar el navegador para que en esta página (el foro) se me active el corrector en Español y no en Inglés, sin tener que cambiar drasticamente el corrector de forma permanente para que afecte a mi experiencia en otros sitios web.

A ver, quizás lo primero de todo que yo debería haber preguntado es: ¿soy el único al que le pasa esto (con Firefox)?, ¿a ustedes se le activa el correcto en Español en el foro?.
20  Programación / .NET (C#, VB.NET, ASP) / Re: Problema con PostMessage y SendMessage en: 13 Abril 2024, 11:23 am
Solución al problema

El siguiente código fuente está elaborado mediante porciones de código que he extraído y posteriormente los he combinado, de un proyecto mucho más amplio (una librería de clases comercial que tengo a la venta, por lo que no puedo compartirlo todo), y originalmente escrito en VB.NET, por lo que he tenido que convertido a C#.

Aqui está todo lo necesario para que puedas simular una pulsación o 'click' del ratón, mediante una de las siguientes funciones:

  • SimulateMouseButtonAction (que internamente llamará a la función SendMessage)
  • SimulateMouseButtonActionAsync (que internamente llamará a la función PostMessage)

Al final de este post comparto un ejemplo de como utilizar el código. Es bien sencillo.

Cabe mencionar que todo esto también podrías llevarlo a cabo utilizando la función SendInput:


De hecho, esa sería la forma óptima.

Para poder utilizar la función SendInput es necesario implementar ciertas estructuras y enumeraciones (INPUT, MOUSEINPUT, etc). Yo lo tengo todo implementado en mi librería de clases comercial, si necesitas puedo extraerlo, adaptarlo, y convertirlo a C#, pero me llevaría otro rato.

De todas formas creo que con el siguiente código es más que suficiente, ya que te debería funcionar de igual forma.

(EL SIGUIENTE CÓDIGO HA SIDO REFACTORIZADO Y PUBLICADO A LAS 16:35 HORA ESPAÑOLA, SIMPLIFICANDO Y MEJORANDO VARIOS ASPECTOS GENERALES. HE TENIDO QUE LIMITAR BASTANTE LA DOCUMENTACIÓN Y LOS ENLACES EXTERNOS, POR QUE NO CABE TODO EL CÓDIGO DEBIDO AL LÍMITE DE CARACTERES)

DevCase.cs
Código
  1. using System;
  2. using System.ComponentModel;
  3. using System.Diagnostics;
  4. using System.Drawing;
  5. using System.Linq;
  6. using System.Runtime.InteropServices;
  7. using System.Security;
  8. using System.Threading;
  9. using System.Windows.Forms;
  10.  
  11. using DevCase.Win32;
  12. using DevCase.Win32.Enums;
  13.  
  14. namespace DevCase {
  15.  
  16.    namespace Core.IO.Devices.Input {
  17.  
  18.        /// <summary>
  19.        /// Provides mouse interaction related utilities.
  20.        /// </summary>
  21.        internal sealed class UtilMouse {
  22.  
  23.            /// <summary>
  24.            /// Prevents a default instance of the <see cref="UtilMouse"/> class from being created.
  25.            /// </summary>
  26.            [DebuggerNonUserCode]
  27.            private UtilMouse() { }
  28.  
  29.            /// <summary>
  30.            /// Defines a button message to send to a window.
  31.            /// </summary>
  32.            internal enum MouseButtonMessage : int {
  33.  
  34.                /// <summary>
  35.                /// Hold down the left mouse button.
  36.                /// </summary>
  37.                LeftDown = WindowMessages.WM_LButtonDown,
  38.  
  39.                /// <summary>
  40.                /// Release up the left mouse button.
  41.                /// </summary>
  42.                LeftUp = WindowMessages.WM_LButtonUp,
  43.  
  44.                /// <summary>
  45.                /// Hold down the right mouse button.
  46.                /// </summary>
  47.                RightDown = WindowMessages.WM_RButtonDown,
  48.  
  49.                /// <summary>
  50.                /// Release up the right mouse button.
  51.                /// </summary>
  52.                RightUp = WindowMessages.WM_RButtonUp,
  53.  
  54.                /// <summary>
  55.                /// Hold down the middle mouse button.
  56.                /// </summary>
  57.                MiddleDown = WindowMessages.WM_MButtonDown,
  58.  
  59.                /// <summary>
  60.                /// Release up the middle mouse button.
  61.                /// </summary>
  62.                MiddleUp = WindowMessages.WM_MButtonUp,
  63.  
  64.                /// <summary>
  65.                /// Move down the mouse wheel.
  66.                /// </summary>
  67.                WheelDown,
  68.  
  69.                /// <summary>
  70.                /// Move up the mouse wheel.
  71.                /// </summary>
  72.                WheelUp,
  73.  
  74.                /// <summary>
  75.                /// Tilt horizontal mouse wheel to left.
  76.                /// </summary>
  77.                WheelLeft,
  78.  
  79.                /// <summary>
  80.                /// Tilt horizontal mouse wheel to right.
  81.                /// </summary>
  82.                WheelRight
  83.  
  84.            }
  85.  
  86.            /// <summary>
  87.            /// Defines a click of a mouse button.
  88.            /// </summary>
  89.            internal enum MouseButtonClick : int {
  90.  
  91.                /// <summary>
  92.                /// Left mouse button click.
  93.                /// </summary>
  94.                LeftButton,
  95.  
  96.                /// <summary>
  97.                /// Right mouse button click.
  98.                /// </summary>
  99.                RightButton,
  100.  
  101.                /// <summary>
  102.                /// Middle mouse button click.
  103.                /// </summary>
  104.                MiddleButton
  105.            }
  106.  
  107.            /// <summary>
  108.            /// Sends a mouse button message to the specified window,
  109.            /// on the specified coordinates relative to its client-area,
  110.            /// by calling <see cref="Win32.NativeMethods.SendMessage"/> function.
  111.            /// </summary>
  112.            ///
  113.            /// <param name="hWnd">
  114.            /// A handle to the target window.
  115.            /// </param>
  116.            ///
  117.            /// <param name="button">
  118.            /// The mouse button message to send.
  119.            /// </param>
  120.            ///
  121.            /// <param name="pt">
  122.            /// The coordinates within the client area of the window,
  123.            /// where to send the mouse button message.
  124.            /// </param>
  125.            ///
  126.            /// <returns>
  127.            /// <see langword="True"/> if the function succeeds; otherwise, <see langword="False"/>.
  128.            /// </returns>
  129.            [DebuggerStepThrough]
  130.            internal static bool SendMouseButtonMessage(IntPtr hWnd, MouseButtonMessage button, Point pt) {
  131.                return UtilMouse.SendMouseButtonMessage_Internal(hWnd, button, pt, async: false);
  132.            }
  133.  
  134.            /// <summary>
  135.            /// Asynchronouslly sends a mouse button message to the specified window,
  136.            /// on the specified coordinates relative to its client-area,
  137.            /// by calling <see cref="Win32.NativeMethods.PostMessage"/> function.
  138.            /// </summary>
  139.            ///
  140.            /// <param name="hWnd">
  141.            /// A handle to the target window.
  142.            /// </param>
  143.            ///
  144.            /// <param name="button">
  145.            /// The mouse button message to send.
  146.            /// </param>
  147.            ///
  148.            /// <param name="pt">
  149.            /// The coordinates within the client area of the window,
  150.            /// where to send the mouse button message.
  151.            /// </param>
  152.            ///
  153.            /// <returns>
  154.            /// <see langword="True"/> if the function succeeds; otherwise, <see langword="False"/>.
  155.            /// </returns>
  156.            [DebuggerStepThrough]
  157.            internal static bool SendMouseButtonMessageAsync(IntPtr hWnd, MouseButtonMessage button, Point pt) {
  158.                return UtilMouse.SendMouseButtonMessage_Internal(hWnd, button, pt, async: true);
  159.            }
  160.  
  161.            /// <summary>
  162.            /// Sends a mouse button click to the specified window,
  163.            /// on the specified coordinates relative to its client-area,
  164.            /// by calling <see cref="Win32.NativeMethods.SendMessage"/> function.
  165.            /// </summary>
  166.            ///
  167.            /// <param name="hWnd">
  168.            /// A handle to the target window.
  169.            /// </param>
  170.            ///
  171.            /// <param name="button">
  172.            /// The mouse button click to send.
  173.            /// </param>
  174.            ///
  175.            /// <param name="pt">
  176.            /// The coordinates within the client area of the window,
  177.            /// where to send the mouse button click.
  178.            /// </param>
  179.            ///
  180.            /// <returns>
  181.            /// <see langword="True"/> if the function succeeds; otherwise, <see langword="False"/>.
  182.            /// </returns>
  183.            [DebuggerStepThrough]
  184.            internal static bool SendMouseButtonClick(IntPtr hWnd, MouseButtonClick button, Point pt) {
  185.                return UtilMouse.SendMouseButtonClick_Internal(hWnd, button, pt, async: false);
  186.            }
  187.  
  188.            /// <summary>
  189.            /// Asynchronouslly sends a mouse button click to the specified window,
  190.            /// on the specified coordinates relative to its client-area,
  191.            /// by calling <see cref="Win32.NativeMethods.PostMessage"/> function.
  192.            /// </summary>
  193.            ///
  194.            /// <param name="hWnd">
  195.            /// A handle to the target window.
  196.            /// </param>
  197.            ///
  198.            /// <param name="button">
  199.            /// The mouse button click to send.
  200.            /// </param>
  201.            ///
  202.            /// <param name="pt">
  203.            /// The coordinates within the client area of the window,
  204.            /// where to send the mouse button click.
  205.            /// </param>
  206.            ///
  207.            /// <returns>
  208.            /// <see langword="True"/> if the function succeeds; otherwise, <see langword="False"/>.
  209.            /// </returns>
  210.            [DebuggerStepThrough]
  211.            internal static bool SendMouseButtonClickAsync(IntPtr hWnd, MouseButtonClick button, Point pt) {
  212.                return UtilMouse.SendMouseButtonClick_Internal(hWnd, button, pt, async: true);
  213.            }
  214.  
  215.            /// <summary>
  216.            /// *** FOR INTERNAL USE ONLY ***
  217.            /// <para></para>
  218.            /// Sends a mouse button message to the specified window,
  219.            /// on the specified coordinates relative to its client-area.
  220.            /// </summary>
  221.            ///
  222.            /// <param name="hWnd">
  223.            /// A handle to the target window.
  224.            /// </param>
  225.            ///
  226.            /// <param name="button">
  227.            /// The mouse button message to send.
  228.            /// </param>
  229.            ///
  230.            /// <param name="pt">
  231.            /// The coordinates within the client area of the window,
  232.            /// where to send the mouse button message.
  233.            /// </param>
  234.            ///
  235.            /// <param name="async">
  236.            /// If <see langword="True"/>, calls PostMessage function rather than SendMessage.
  237.            /// </param>
  238.            ///
  239.            /// <returns>
  240.            /// <see langword="True"/> if the function succeeds; otherwise, <see langword="False"/>.
  241.            /// </returns>
  242.            private static bool SendMouseButtonMessage_Internal(IntPtr hWnd, MouseButtonMessage button, Point pt, bool async) {
  243.  
  244.                if (pt == null) {
  245.                    pt = Point.Empty;
  246.                }
  247.  
  248.                Delegate msgFunc = async ?
  249.                    (Delegate)(new Func<IntPtr, WindowMessages, IntPtr, IntPtr, bool>(NativeMethods.PostMessage)) :
  250.                    (Delegate)(new Func<IntPtr, WindowMessages, IntPtr, IntPtr, IntPtr>(NativeMethods.SendMessage));
  251.  
  252.                WindowMessages msg = (WindowMessages)button;
  253.                IntPtr lParam = UtilWin32.MakeLParam(pt.X, pt.Y);
  254.                IntPtr wParam = System.IntPtr.Zero;
  255.  
  256.                switch (button) {
  257.                    case MouseButtonMessage.LeftUp:
  258.                    case MouseButtonMessage.RightUp:
  259.                    case MouseButtonMessage.MiddleUp:
  260.                        wParam = IntPtr.Zero;
  261.                        break;
  262.  
  263.                    case MouseButtonMessage.LeftDown:
  264.                        wParam = new IntPtr((int)WParams.MK_LButton);
  265.                        break;
  266.  
  267.                    case MouseButtonMessage.RightDown:
  268.                        wParam = new IntPtr((int)WParams.MK_RButton);
  269.                        break;
  270.  
  271.                    case MouseButtonMessage.MiddleDown:
  272.                        wParam = new IntPtr((int)WParams.MK_MButton);
  273.                        break;
  274.  
  275.                    case MouseButtonMessage.WheelDown:
  276.                        msg = WindowMessages.WM_MouseWheel;
  277.                        wParam = UtilWin32.MakeLParam(0, -120);
  278.                        break;
  279.  
  280.                    case MouseButtonMessage.WheelUp:
  281.                        msg = WindowMessages.WM_MouseWheel;
  282.                        wParam = UtilWin32.MakeLParam(0, 120);
  283.                        break;
  284.  
  285.                    case MouseButtonMessage.WheelLeft:
  286.                        msg = WindowMessages.WM_MouseHWheel;
  287.                        wParam = UtilWin32.MakeLParam(0, -120);
  288.                        break;
  289.  
  290.                    case MouseButtonMessage.WheelRight:
  291.                        msg = WindowMessages.WM_MouseHWheel;
  292.                        wParam = UtilWin32.MakeLParam(0, 120);
  293.                        break;
  294.  
  295.                    default:
  296.                        throw new InvalidEnumArgumentException(nameof(button), (int)button, typeof(MouseButtonMessage));
  297.                }
  298.  
  299.                // Ensures the target window has focus.
  300.                NativeMethods.SetFocus(hWnd);
  301.  
  302.                object success = msgFunc.DynamicInvoke(hWnd, msg, wParam, lParam);
  303.                return (async ? (bool)success : (IntPtr)success == IntPtr.Zero);
  304.            }
  305.  
  306.            /// <summary>
  307.            /// *** FOR INTERNAL USE ONLY ***
  308.            /// <para></para>
  309.            /// Sends a mouse button click to the specified window,
  310.            /// on the specified coordinates relative to its client-area.
  311.            /// </summary>
  312.            ///
  313.            /// <param name="hWnd">
  314.            /// A handle to the target window.
  315.            /// </param>
  316.            ///
  317.            /// <param name="button">
  318.            /// The mouse button click to send.
  319.            /// </param>
  320.            ///
  321.            /// <param name="pt">
  322.            /// The coordinates within the client area of the window,
  323.            /// where to send the mouse button click.
  324.            /// </param>
  325.            ///
  326.            /// <param name="async">
  327.            /// If <see langword="True"/>, calls PostMessage function rather than SendMessage.
  328.            /// </param>
  329.            ///
  330.            /// <returns>
  331.            /// <see langword="True"/> if the function succeeds; otherwise, <see langword="False"/>.
  332.            /// </returns>
  333.            private static bool SendMouseButtonClick_Internal(IntPtr hWnd, MouseButtonClick button, Point pt, bool async) {
  334.  
  335.                MouseButtonMessage msgButtonDown;
  336.                MouseButtonMessage msgButtonUp;
  337.  
  338.                switch (button) {
  339.                    case MouseButtonClick.LeftButton:
  340.                        msgButtonDown = MouseButtonMessage.LeftDown;
  341.                        msgButtonUp = MouseButtonMessage.LeftUp;
  342.                        break;
  343.  
  344.                    case MouseButtonClick.RightButton:
  345.                        msgButtonDown = MouseButtonMessage.RightDown;
  346.                        msgButtonUp = MouseButtonMessage.RightUp;
  347.                        break;
  348.  
  349.                    case MouseButtonClick.MiddleButton:
  350.                        msgButtonDown = MouseButtonMessage.MiddleDown;
  351.                        msgButtonUp = MouseButtonMessage.MiddleUp;
  352.                        break;
  353.  
  354.                    default:
  355.                        throw new InvalidEnumArgumentException(nameof(button), (int)button, typeof(MouseButtonClick));
  356.                }
  357.  
  358.                // Milliseconds to wait between sequentially sendig WM_#BUTTON_DOWN + WM_#BUTTON_UP message combination.
  359.                const int msgIntervalMs = 100;
  360.  
  361.                bool successButtonDown = UtilMouse.SendMouseButtonMessage_Internal(hWnd, msgButtonDown, pt, async);
  362.                Thread.Sleep(msgIntervalMs);
  363.                bool successButtonUp = UtilMouse.SendMouseButtonMessage_Internal(hWnd, msgButtonUp, pt, async);
  364.  
  365.                return successButtonDown & successButtonUp;
  366.            }
  367.  
  368.        }
  369.  
  370.    }
  371.  
  372.    namespace Win32 {
  373.  
  374.        /// <summary>
  375.        /// Platform Invocation (P/Invoke) methods, access unmanaged code.
  376.        /// </summary>
  377.        [SuppressUnmanagedCodeSecurity]
  378.        internal sealed class NativeMethods {
  379.  
  380.            /// <summary>
  381.            /// Prevents a default instance of the <see cref="NativeMethods"/> class from being created.
  382.            /// </summary>
  383.            [DebuggerNonUserCode]
  384.            private NativeMethods() { }
  385.  
  386.            #region  User32.dll
  387.  
  388.            /// <summary>
  389.            /// Sets the keyboard focus to the specified window.
  390.            /// <para></para>
  391.            /// The window must be attached to the calling thread's message queue.
  392.            /// </summary>
  393.            ///
  394.            /// <param name="hWnd">
  395.            /// A handle to the window that will receive the keyboard input.
  396.            /// <para></para>
  397.            /// If this parameter is <see cref="IntPtr.Zero"/>, keystrokes are ignored.
  398.            /// </param>
  399.            ///
  400.            /// <returns>
  401.            /// If the function succeeds, the return value is the handle to the window that previously had the keyboard focus.
  402.            /// <para></para>
  403.            /// If the <paramref name="hWnd"/> parameter is invalid or
  404.            /// the window is not attached to the calling thread's message queue,
  405.            /// the return value is <see cref="IntPtr.Zero"/>.
  406.            /// <para></para>
  407.            /// To get extended error information, call <see cref="Marshal.GetLastWin32Error"/>.
  408.            /// </returns>
  409.            [DllImport("User32.dll", SetLastError = true)]
  410.            internal static extern IntPtr SetFocus([In, Optional] IntPtr hWnd);
  411.  
  412.            /// <summary>
  413.            /// Sends the specified message to a window or windows.
  414.            /// <para></para>
  415.            /// The SendMessage function calls the window procedure for the specified window
  416.            /// and does not return until the window procedure has processed the message.
  417.            /// </summary>
  418.            ///
  419.            /// <param name="hWnd">
  420.            /// A handle to the window whose window procedure will receive the message.
  421.            /// </param>
  422.            ///
  423.            /// <param name="msg">
  424.            /// The message to be sent.
  425.            /// </param>
  426.            ///
  427.            /// <param name="wParam">
  428.            /// Additional message-specific information.
  429.            /// </param>
  430.            ///
  431.            /// <param name="lParam">
  432.            /// Additional message-specific information.
  433.            /// </param>
  434.            ///
  435.            /// <returns>
  436.            /// The return value specifies the result of the message processing; it depends on the message sent.
  437.            /// </returns>
  438.            [DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
  439.            [return: MarshalAs(UnmanagedType.SysInt)]
  440.            internal static extern IntPtr SendMessage([In, MarshalAs(UnmanagedType.SysInt)] IntPtr hWnd,
  441.                                                      [In, MarshalAs(UnmanagedType.I4)] WindowMessages msg,
  442.                                                      [In, MarshalAs(UnmanagedType.SysInt)] IntPtr wParam,
  443.                                                      [In, MarshalAs(UnmanagedType.SysInt)] IntPtr lParam);
  444.  
  445.            /// <summary>
  446.            /// Places (posts) a message in the message queue associated with the thread that created
  447.            /// the specified window and returns without waiting for the thread to process the message.
  448.            /// </summary>
  449.            ///
  450.            /// <param name="hWnd">
  451.            /// Handle to the window whose window procedure will receive the message.
  452.            /// <para></para>
  453.            /// If this parameter is WindowMessages.HWND_Broadcast,
  454.            /// the message is sent to all top-level windows in the system,
  455.            /// including disabled or invisible unowned windows, overlapped windows, and pop-up windows;
  456.            /// but the message is not sent to child windows.
  457.            /// </param>
  458.            ///
  459.            /// <param name="msg">
  460.            /// The message to be sent.
  461.            /// </param>
  462.            ///
  463.            /// <param name="wparam">
  464.            /// Additional message-specific information.
  465.            /// </param>
  466.            ///
  467.            /// <param name="lparam">
  468.            /// Additional message-specific information.
  469.            /// </param>
  470.            ///
  471.            /// <returns>
  472.            /// If the function succeeds, the return value is <see langword="true"/>.
  473.            /// <para></para>
  474.            /// If the function fails, the return value is <see langword="false"/>.
  475.            /// <para></para>
  476.            /// To get extended error information, call <see cref="Marshal.GetLastWin32Error"/>.
  477.            /// </returns>
  478.            [DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
  479.            [return: MarshalAs(UnmanagedType.Bool)]
  480.            internal static extern bool PostMessage([In, Optional, MarshalAs(UnmanagedType.SysInt)] IntPtr hWnd,
  481.                                                    [In, MarshalAs(UnmanagedType.I4)] WindowMessages msg,
  482.                                                    [In, MarshalAs(UnmanagedType.SysInt)] IntPtr wparam,
  483.                                                    [In, MarshalAs(UnmanagedType.SysInt)] IntPtr lparam);
  484.  
  485.            #endregion
  486.        }
  487.  
  488.        /// <summary>
  489.        /// Provides Windows API related utilites.
  490.        /// </summary>
  491.        internal sealed class UtilWin32 {
  492.  
  493.            /// <summary>
  494.            /// Prevents a default instance of the <see cref="UtilWin32"/> class from being created.
  495.            /// </summary>
  496.            [DebuggerNonUserCode]
  497.            private UtilWin32() { }
  498.  
  499.            /// <summary>
  500.            /// Creates a LONG Param (LParam) value for a window message, from two <see cref="Integer"/> values.
  501.            /// <para></para>
  502.            /// You must call this method if you need to use negative values.
  503.            /// <para></para>
  504.            /// <seealso cref="Message.LParam"/>
  505.            /// </summary>
  506.            ///
  507.            /// <remarks>
  508.            /// <see href="https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-makelparam"/>
  509.            /// </remarks>
  510.            ///
  511.            /// <example> This is a code example.
  512.            /// <code language="VB.NET">
  513.            /// Dim lParam as IntPtr = MakeLParam(Integer.MaxValue, Integer.MaxValue)
  514.            /// </code>
  515.            /// </example>
  516.            ///
  517.            /// <param name="lo">
  518.            /// The low-order <see cref="Integer"/> value.
  519.            /// </param>
  520.            ///
  521.            /// <param name="hi">
  522.            /// The high-order <see cref="Integer"/> value.
  523.            /// </param>
  524.            ///
  525.            /// <returns>
  526.            /// The resulting LParam value.
  527.            /// </returns>
  528.            [DebuggerStepThrough]
  529.            internal static IntPtr MakeLParam(int lo, int hi) {
  530.                byte[] loBytes = { BitConverter.GetBytes(lo)[0], BitConverter.GetBytes(lo)[1] };
  531.                byte[] hiBytes = { BitConverter.GetBytes(hi)[0], BitConverter.GetBytes(hi)[1] };
  532.                byte[] combined = loBytes.Concat(hiBytes).ToArray();
  533.  
  534.                return new IntPtr(BitConverter.ToInt32(combined, 0));
  535.            }
  536.  
  537.            /// <summary>
  538.            /// Creates a LONG Param (LParam) value for a window message, from two <see cref="UShort"/> values.
  539.            /// <para></para>
  540.            /// <seealso cref="Message.LParam"/>
  541.            /// </summary>
  542.            ///
  543.            /// <remarks>
  544.            /// <see href="https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-makelparam"/>
  545.            /// </remarks>
  546.            ///
  547.            /// <example> This is a code example.
  548.            /// <code language="VB.NET">
  549.            /// Dim lParam as IntPtr = MakeLParam(UShort.MaxValue, UShort.MaxValue)
  550.            /// </code>
  551.            /// </example>
  552.            ///
  553.            /// <param name="loWord">
  554.            /// The low-order WORD value.
  555.            /// </param>
  556.            ///
  557.            /// <param name="hiWord">
  558.            /// The high-order WORD value.
  559.            /// </param>
  560.            ///
  561.            /// <returns>
  562.            /// The resulting LParam value.
  563.            /// </returns>
  564.            [DebuggerStepThrough]
  565.            internal static IntPtr MakeLParam(ushort loWord, ushort hiWord) {
  566.                return new IntPtr(UtilWin32.MakeDWord(loWord, hiWord));
  567.            }
  568.  
  569.            /// <summary>
  570.            /// Creates a Double WORD (DWORD, 32-Bit Unsigned Integer) value from a LOWORD and a HIWORD value.
  571.            /// </summary>
  572.            ///
  573.            /// <example> This is a code example.
  574.            /// <code language="VB.NET">
  575.            /// Dim value as UInteger = MakeDWord(UShort.MaxValue, UShort.MaxValue)
  576.            /// </code>
  577.            /// </example>
  578.            ///
  579.            /// <param name="loWord">
  580.            /// The low-order WORD.
  581.            /// </param>
  582.            ///
  583.            /// <param name="hiWord">
  584.            /// The high-order WORD.
  585.            /// </param>
  586.            ///
  587.            /// <returns>
  588.            /// The resulting DWORD value.
  589.            /// </returns>
  590.            [DebuggerStepThrough]
  591.            internal static uint MakeDWord(ushort loWord, ushort hiWord) {
  592.                byte[] loBytes = BitConverter.GetBytes(loWord);
  593.                byte[] hiBytes = BitConverter.GetBytes(hiWord);
  594.                byte[] combined = loBytes.Concat(hiBytes).ToArray();
  595.  
  596.                return BitConverter.ToUInt32(combined, 0);
  597.            }
  598.        }
  599.    }
  600.  
  601.    namespace Win32.Enums {
  602.  
  603.        /// <summary>
  604.        /// Defines additional message-specific information for the WORD Param (WParam) value of window messages.
  605.        /// </summary>
  606.        ///
  607.        /// <remarks>
  608.        /// <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms644927%28v=vs.85%29.aspx#system_defined"/>
  609.        /// </remarks>
  610.        internal enum WParams : int {
  611.            /// <summary>
  612.            /// A null WParam.
  613.            /// </summary>
  614.            Null = 0x0,
  615.  
  616.            /// <summary>
  617.            /// The left mouse button is down.
  618.            /// <para></para>
  619.            /// wParam to use with <see cref="WindowMessages.WM_LButtonDown"/> message.
  620.            /// </summary>
  621.            MK_LButton = 0x1,
  622.  
  623.            /// <summary>
  624.            /// The middle mouse button is down.
  625.            /// <para></para>
  626.            /// wParam to use with <see cref="WindowMessages.WM_LButtonDown"/> and <see cref="WindowMessages.WM_LButtonUp"/> messages.
  627.            /// </summary>
  628.            MK_MButton = 0x10,
  629.  
  630.            /// <summary>
  631.            /// The right mouse button is down.
  632.            /// <para></para>
  633.            /// wParam to use with <see cref="WindowMessages.WM_LButtonDown"/> and <see cref="WindowMessages.WM_LButtonUp"/> messages.
  634.            /// </summary>
  635.            MK_RButton = 0x2
  636.        }
  637.  
  638.        /// <summary>
  639.        /// Defines window messages.
  640.        /// <para></para>
  641.        /// The system sends or posts a system-defined message when it communicates with an application.
  642.        /// <para></para>
  643.        /// It uses these messages to control the operations of applications and to provide input and other information for applications to process.
  644.        /// <para></para>
  645.        /// An application can also send or post system-defined messages.
  646.        /// <para></para>
  647.        /// Applications generally use these messages to control the operation of control windows created by using preregistered window classes.
  648.        /// </summary>
  649.        ///
  650.        /// <remarks>
  651.        /// <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms644927%28v=vs.85%29.aspx"/>
  652.        /// </remarks>
  653.        internal enum WindowMessages : int {
  654.  
  655.            /// <summary>
  656.            /// The message is posted when the user presses the left mouse button while the cursor is in the
  657.            /// client area of a window.
  658.            /// <para></para>
  659.            /// If the mouse is not captured the message is posted to the window beneath the cursor.
  660.            /// <para></para>
  661.            /// Otherwise the message is posted to the window that has captured the mouse.
  662.            /// </summary>
  663.            WM_LButtonDown = 0x201,
  664.  
  665.            /// <summary>
  666.            /// The message is posted when the user releases the left mouse button while the cursor is in the
  667.            /// client area of a window.
  668.            /// <para></para>
  669.            /// If the mouse is not captured the message is posted to the window beneath the cursor.
  670.            /// <para></para>
  671.            /// Otherwise the message is posted to the window that has captured the mouse.
  672.            /// </summary>
  673.            WM_LButtonUp = 0x202,
  674.  
  675.            /// <summary>
  676.            /// The message is posted when the user presses the middle mouse button while the cursor is in the
  677.            /// client area of a window.
  678.            /// <para></para>
  679.            /// If the mouse is not captured the message is posted to the window beneath the cursor.
  680.            /// <para></para>
  681.            /// Otherwise the message is posted to the window that has captured the mouse.
  682.            /// </summary>
  683.            WM_MButtonDown = 0x207,
  684.  
  685.            /// <summary>
  686.            /// The message is posted when the user releases the middle mouse button while the cursor is in the
  687.            /// client area of a window.
  688.            /// <para></para>
  689.            /// If the mouse is not captured the message is posted to the window beneath the cursor.
  690.            /// <para></para>
  691.            /// Otherwise the message is posted to the window that has captured the mouse.
  692.            /// </summary>
  693.            WM_MButtonUp = 0x208,
  694.  
  695.            /// <summary>
  696.            /// The message is posted when the user presses the right mouse button while the cursor is in the
  697.            /// client area of a window.
  698.            /// <para></para>
  699.            /// If the mouse is not captured the message is posted to the window beneath the cursor.
  700.            /// <para></para>
  701.            /// Otherwise the message is posted to the window that has captured the mouse.
  702.            /// </summary>
  703.            WM_RButtonDown = 0x204,
  704.  
  705.            /// <summary>
  706.            /// The message is posted when the user releases the right mouse button while the cursor is in the
  707.            /// client area of a window.
  708.            /// <para></para>
  709.            /// If the mouse is not captured the message is posted to the window beneath the cursor.
  710.            /// <para></para>
  711.            /// Otherwise the message is posted to the window that has captured the mouse.
  712.            /// </summary>
  713.            WM_RButtonUp = 0x205,
  714.  
  715.            /// <summary>
  716.            /// Posted when the user presses the first or second X button while the cursor is in the client area of a window.
  717.            /// <para></para>
  718.            /// If the mouse is not captured, the message is posted to the window beneath the cursor.
  719.            /// <para></para>
  720.            /// Otherwise, the message is posted to the window that has captured the mouse.
  721.            /// </summary>
  722.            WM_XButtonDown = 0x20B,
  723.  
  724.            /// <summary>
  725.            /// Posted when the user releases the first or second X button while the cursor is in the client area of a window.
  726.            /// <para></para>
  727.            /// If the mouse is not captured, the message is posted to the window beneath the cursor.
  728.            /// <para></para>
  729.            /// Otherwise, the message is posted to the window that has captured the mouse.
  730.            /// </summary>
  731.            WM_XButtonUp = 0x20C,
  732.  
  733.            /// <summary>
  734.            /// The message is sent to the focus window when the mouse wheel is rotated.
  735.            /// <para></para>
  736.            /// The <c>DefWindowProc</c> function propagates the message to the window's parent.
  737.            /// <para></para>
  738.            /// There should be no internal forwarding of the message since <c>DefWindowProc</c> propagates it up the
  739.            /// parent chain until it finds a window that processes it.
  740.            /// </summary>
  741.            WM_MouseWheel = 0x20A,
  742.  
  743.            /// <summary>
  744.            /// The message is sent to the focus window when the mouse's horizontal scroll wheel is tilted or rotated.
  745.            /// <para></para>
  746.            /// The <c>DefWindowProc</c> function propagates the message to the window's parent.
  747.            /// <para></para>
  748.            /// There should be no internal forwarding of the message since <c>DefWindowProc</c> propagates it up
  749.            /// the parent chain until it finds a window that processes it.
  750.            /// </summary>
  751.            WM_MouseHWheel = 0x20E
  752.  
  753.        }
  754.  
  755.    }
  756.  
  757. }



Ejemplo de uso:

Código
  1. using System;
  2. using System.Drawing;
  3. using System.Windows.Forms;
  4.  
  5. using DevCase.Core.IO.Devices.Input;
  6.  
  7. namespace WindowsFormsApp1 {
  8.  
  9.    public partial class Form1 : Form {
  10.        public Form1() {
  11.            this.InitializeComponent();
  12.        }
  13.  
  14.        private void Button1_Click(object sender, EventArgs e) {
  15.            IntPtr hWnd = this.button2.Handle;
  16.            Point pt = Point.Empty;
  17.            bool success = UtilMouse.SendMouseButtonClick(hWnd, MouseButtonClick.LeftButton, pt);
  18.  
  19.            // O también:
  20.            // bool success =
  21.            //     UtilMouse.SendMouseButtonMessage(hWnd, MouseButtonMessage.LeftDown, point) &
  22.            //     UtilMouse.SendMouseButtonMessage(hWnd, MouseButtonMessage.LeftUp, point);
  23.  
  24.            Console.WriteLine($"{nameof(success)}: {success}");
  25.        }
  26.  
  27.        private void Button2_Click(object sender, EventArgs e) {
  28.            MessageBox.Show("Button Clicked!");
  29.        }
  30.    }
  31. }

Aténtamente,
Elektro.
Páginas: 1 [2] 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ... 1236
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines