Foro de elhacker.net

Programación => .NET (C#, VB.NET, ASP) => Mensaje iniciado por: SrTrp en 26 Noviembre 2017, 05:21 am



Título: ¿Es posible mover/achicar ventanas de otros programas con .NET?
Publicado por: SrTrp en 26 Noviembre 2017, 05:21 am
Quería saber eso por ejemplo que al presionar el boton poner la ventana de google chrome en 700 de ancho y 700 de altura y ponerla en la posisión x=0 y y =0 :/ no quiero que me brinden un código solo si pudiesen decirme que se puede eh estado buscando documentación pero no encuentro.


Título: Re: ¿Es posible mover/achicar ventanas de otros programas con .NET?
Publicado por: Eleкtro en 26 Noviembre 2017, 13:03 pm
que al presionar el boton poner la ventana de google chrome en 700 de ancho y 700 de altura y ponerla en la posisión x=0 y y =0

Mediante la función MoveWindow  de la API de Windows puedes llevar a cabo ambas cosas, es decir, mover la ventana y también redimensionarla. A continuación te muestro un ejemplo completo:

NOTA INFORMATIVA:
---
EL SIGUIENTE CÓDIGO HA SIDO EXTRAIDO Y OFRECIDO DE FORMA GRATUITA A PARTIR DE MI FRAMEWORK COMERCIAL ELEKTROKIT FRAMEWORK , EL CUAL CONTIENE UNA INFINIDAD DE UTILIDADES ENFOCADAS A UNA AMPLIA VARIEDAD DE TEMÁTICAS Y ESCENARIOS EN LA PROGRAMACIÓN .NET, COMO ÉSTE. SI QUIEREN CONOCER MÁS ACERCA DEL PRODUCTO, PUEDEN ENCONTRARLO EN MI FIRMA DE USUARIO DEL FORO.
ESTE CÓDIGO SE PUEDE USAR Y MODIFICAR DE FORMA LIBRE COMO LES APETEZCA.

---

Definición de estructuras nativas ( RECT ):

Código
  1. #Region " Imports "
  2.  
  3. Imports System.Diagnostics
  4. Imports System.Drawing
  5. Imports System.Runtime.InteropServices
  6.  
  7. #End Region
  8.  
  9. #Region " NativeRectangle (RECT) "
  10.  
  11. Namespace ElektroKit.Interop.Win32.Types
  12.  
  13.    ''' <summary>
  14.    ''' Defines the coordinates of the upper-left and lower-right corners of a rectangle.
  15.    ''' </summary>
  16.    ''' <remarks>
  17.    ''' <see href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd162897%28v=vs.85%29.aspx"/>
  18.    ''' <para></para>
  19.    ''' <see href="http://www.pinvoke.net/default.aspx/Structures/rect.html"/>
  20.    ''' </remarks>
  21.    <StructLayout(LayoutKind.Sequential)>
  22.    <DebuggerStepThrough>
  23.    Public Structure NativeRectangle
  24.  
  25. #Region " Auto-implemented Properties "
  26.  
  27.        ''' <summary>
  28.        ''' Gets or sets the x-coordinate of the upper-left corner of the rectangle.
  29.        ''' </summary>
  30.        Public Property Left As Integer
  31.  
  32.        ''' <summary>
  33.        ''' Gets or sets the y-coordinate of the upper-left corner of the rectangle.
  34.        ''' </summary>
  35.        Public Property Top As Integer
  36.  
  37.        ''' <summary>
  38.        ''' Gets or sets the x-coordinate of the lower-right corner of the rectangle.
  39.        ''' </summary>
  40.        Public Property Right As Integer
  41.  
  42.        ''' <summary>
  43.        ''' Gets or sets the y-coordinate of the lower-right corner of the rectangle.
  44.        ''' </summary>
  45.        Public Property Bottom As Integer
  46.  
  47. #End Region
  48.  
  49. #Region " Constructors "
  50.  
  51.        ''' <summary>
  52.        ''' Initializes a new instance of the <see cref="NativeRectangle"/> struct.
  53.        ''' </summary>
  54.        Public Sub New(ByVal left As Integer, ByVal top As Integer,
  55.                       ByVal right As Integer, ByVal bottom As Integer)
  56.  
  57.            Me.Left = left
  58.            Me.Top = top
  59.            Me.Right = right
  60.            Me.Bottom = bottom
  61.  
  62.        End Sub
  63.  
  64.        ''' <summary>
  65.        ''' Initializes a new instance of the <see cref="NativeRectangle"/> struct.
  66.        ''' </summary>
  67.        Public Sub New(ByVal rect As Rectangle)
  68.            Me.New(rect.Left, rect.Top, rect.Right, rect.Bottom)
  69.        End Sub
  70.  
  71. #End Region
  72.  
  73. #Region " Operator Conversions "
  74.  
  75.        ''' <summary>
  76.        ''' Performs an implicit conversion from <see cref="NativeRectangle"/> to <see cref="Rectangle"/>.
  77.        ''' </summary>
  78.        Public Shared Widening Operator CType(ByVal rect As NativeRectangle) As Rectangle
  79.            Return New Rectangle(rect.Left, rect.Top, (rect.Right - rect.Left), (rect.Bottom - rect.Top))
  80.        End Operator
  81.  
  82.        ''' <summary>
  83.        ''' Performs an implicit conversion from <see cref="Rectangle"/> to <see cref="NativeRectangle"/>.
  84.        ''' </summary>
  85.        Public Shared Widening Operator CType(rect As Rectangle) As NativeRectangle
  86.            Return New NativeRectangle(rect)
  87.        End Operator
  88.  
  89. #End Region
  90.  
  91.    End Structure
  92.  
  93. End Namespace
  94.  
  95. #End Region

Definición de funciones nativas de Windows:

Código
  1. #Region " Imports "
  2.  
  3. Imports System.Diagnostics
  4. Imports System.Runtime.InteropServices
  5. Imports System.Security
  6.  
  7. Imports ElektroKit.Interop.Win32.Types
  8.  
  9. #End Region
  10.  
  11. #Region " NativeMethods "
  12.  
  13. Namespace ElektroKit.Interop.Win32
  14.  
  15.    ''' <summary>
  16.    ''' Platform Invocation methods (P/Invoke), access unmanaged code.
  17.    ''' <para></para>
  18.    ''' This class does not suppress stack walks for unmanaged code permission.
  19.    ''' <see cref="SuppressUnmanagedCodeSecurityAttribute"/> must not be applied to this class.
  20.    ''' <para></para>
  21.    ''' This class is for methods that can be used anywhere because a stack walk will be performed.
  22.    ''' </summary>
  23.    ''' <remarks>
  24.    ''' <see href="http://msdn.microsoft.com/en-us/library/ms182161.aspx"/>
  25.    ''' </remarks>
  26.    Public NotInheritable Class NativeMethods ' <SuppressUnmanagedCodeSecurity>
  27.  
  28. #Region " Constructors "
  29.  
  30.        ''' ----------------------------------------------------------------------------------------------------
  31.        ''' <summary>
  32.        ''' Prevents a default instance of the <see cref="NativeMethods"/> class from being created.
  33.        ''' </summary>
  34.        ''' ----------------------------------------------------------------------------------------------------
  35.        <DebuggerNonUserCode>
  36.        Private Sub New()
  37.        End Sub
  38.  
  39. #End Region
  40.  
  41. #Region " User32.dll Functions "
  42.  
  43.        ''' <summary>
  44.        ''' Retrieves the dimensions of the bounding rectangle of the specified window.
  45.        ''' <para></para>
  46.        ''' The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
  47.        ''' </summary>
  48.        ''' <remarks>
  49.        ''' <see href="http://msdn.microsoft.com/es-es/library/windows/desktop/ms633519%28v=vs.85%29.aspx"/>
  50.        ''' </remarks>
  51.        ''' <param name="hwnd">
  52.        ''' A <see cref="IntPtr"/> handle to the window.
  53.        ''' </param>
  54.        ''' <param name="refRect">
  55.        ''' A pointer to a <see cref="NativeRectangle"/> structure that receives the screen coordinates of the
  56.        ''' upper-left and lower-right corners of the window.
  57.        ''' </param>
  58.        ''' <returns>
  59.        ''' <see langword="True"/> if the function succeeds, <see langword="False"/> otherwise.
  60.        ''' </returns>
  61.        <DllImport("User32.dll", SetLastError:=True)>
  62.        Public Shared Function GetWindowRect(ByVal hwnd As IntPtr,
  63.                                       <Out> ByRef refRect As NativeRectangle
  64.        ) As <MarshalAs(UnmanagedType.Bool)> Boolean
  65.        End Function
  66.  
  67.        ''' <summary>
  68.        ''' Retrieves the dimensions of the bounding rectangle of the specified window.
  69.        ''' <para></para>
  70.        ''' The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
  71.        ''' </summary>
  72.        <DllImport("User32.dll", SetLastError:=True)>
  73.        Public Shared Function GetWindowRect(ByVal hwnd As HandleRef,
  74.                                       <Out> ByRef refRect As NativeRectangle
  75.        ) As <MarshalAs(UnmanagedType.Bool)> Boolean
  76.        End Function
  77.  
  78.        ''' <summary>
  79.        ''' Changes the position and dimensions of the specified window.
  80.        ''' <para></para>
  81.        ''' For a top-level window, the position and dimensions are relative to the upper-left corner of the screen.
  82.        ''' <para></para>
  83.        ''' For a child window, they are relative to the upper-left corner of the parent window's client area.
  84.        ''' </summary>
  85.        ''' <remarks>
  86.        ''' <see href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms633534%28v=vs.85%29.aspx"/>
  87.        ''' </remarks>
  88.        ''' <param name="hwnd">
  89.        ''' A handle to the window.
  90.        ''' </param>
  91.        ''' <param name="x">
  92.        ''' The new position of the left side of the window.
  93.        ''' </param>
  94.        ''' <param name="y">
  95.        ''' The new position of the top of the window.
  96.        ''' </param>
  97.        ''' <param name="width">
  98.        ''' The new width of the window.
  99.        ''' </param>
  100.        ''' <param name="height">
  101.        ''' The new height of the window.
  102.        ''' </param>
  103.        ''' <param name="repaint">
  104.        ''' Indicates whether the window is to be repainted.
  105.        ''' <para></para>
  106.        ''' If this parameter is <see langword="True"/>, the window receives a message.
  107.        ''' If the parameter is <see langword="False"/>, no repainting of any kind occurs.
  108.        ''' <para></para>
  109.        ''' This applies to the client area, the nonclient area (including the title bar and scroll bars),
  110.        ''' and any part of the parent window uncovered as a result of moving a child window.
  111.        ''' </param>
  112.        ''' <returns>
  113.        ''' <see langword="True"/> if the function succeeds, <see langword="False"/> otherwise.
  114.        ''' </returns>
  115.        <DllImport("User32.dll", SetLastError:=True)>
  116.        Public Shared Function MoveWindow(ByVal hwnd As IntPtr,
  117.                                          ByVal x As Integer,
  118.                                          ByVal y As Integer,
  119.                                          ByVal width As Integer,
  120.                                          ByVal height As Integer,
  121.          <MarshalAs(UnmanagedType.Bool)> ByVal repaint As Boolean
  122.        ) As <MarshalAs(UnmanagedType.Bool)> Boolean
  123.        End Function
  124.  
  125.        ''' <summary>
  126.        ''' Changes the position and dimensions of the specified window.
  127.        ''' <para></para>
  128.        ''' For a top-level window, the position and dimensions are relative to the upper-left corner of the screen.
  129.        ''' <para></para>
  130.        ''' For a child window, they are relative to the upper-left corner of the parent window's client area.
  131.        ''' </summary>
  132.        <DllImport("User32.dll", SetLastError:=True)>
  133.        Public Shared Function MoveWindow(ByVal hwnd As HandleRef,
  134.                                          ByVal x As Integer,
  135.                                          ByVal y As Integer,
  136.                                          ByVal width As Integer,
  137.                                          ByVal height As Integer,
  138.          <MarshalAs(UnmanagedType.Bool)> ByVal repaint As Boolean
  139.        ) As <MarshalAs(UnmanagedType.Bool)> Boolean
  140.        End Function
  141.  
  142. #End Region
  143.  
  144.    End Class
  145.  
  146. End Namespace
  147.  
  148. #End Region

Definición de wrappers para las funciones nativas:

Código
  1. #Region " Imports "
  2.  
  3. Imports System.ComponentModel
  4. Imports System.Diagnostics
  5. Imports System.Runtime.InteropServices
  6. Imports System.Security
  7.  
  8. Imports ElektroKit.Interop.Win32
  9. Imports ElektroKit.Interop.Win32.Types
  10.  
  11. #End Region
  12.  
  13. ''' <summary>
  14. ''' Provides utilities for window automation.
  15. ''' </summary>
  16. <DebuggerStepThrough>
  17. Public NotInheritable Class WindowAutomationUtil
  18.  
  19.    ''' <summary>
  20.    ''' Set the position for the main window of the specified process.
  21.    ''' </summary>
  22.    ''' <param name="process">
  23.    ''' The source <see cref="Process"/>.
  24.    ''' </param>
  25.    ''' <param name="position">
  26.    ''' The new window position.
  27.    ''' </param>
  28.    ''' <returns>
  29.    ''' <see langword="True"/> if successful; <see langword="False"/> otherwise.
  30.    ''' </returns>
  31.    Public Shared Function MoveWindow(ByVal process As Process,
  32.                                      ByVal position As Point) As Boolean
  33.  
  34.        If (process Is Nothing) Then
  35.            Throw New ArgumentException(message:="No process found with the specified name.", paramName:="processName")
  36.  
  37.        Else
  38.            Dim unmanagedRect As NativeRectangle         ' Windows Rectangle definition.
  39.            Dim managedRect As Rectangle = unmanagedRect ' .NET Rectangle definition.
  40.  
  41.            Dim result As Boolean
  42.            Dim win32err As Integer
  43.  
  44.            result = NativeMethods.GetWindowRect(process.MainWindowHandle, unmanagedRect)
  45.            win32err = Marshal.GetLastWin32Error()
  46.            If Not (result) Then
  47.                Throw New Win32Exception(win32err)
  48.            End If
  49.  
  50.            result = NativeMethods.MoveWindow(process.MainWindowHandle,
  51.                                              position.X, position.Y,
  52.                                              managedRect.Width, managedRect.Height,
  53.                                              repaint:=True)
  54.            win32err = Marshal.GetLastWin32Error()
  55.            If Not (result) Then
  56.                Throw New Win32Exception(win32err)
  57.            End If
  58.  
  59.            Return result
  60.  
  61.        End If
  62.  
  63.    End Function
  64.  
  65.    ''' <summary>
  66.    ''' Set the size for the main window of the specified process.
  67.    ''' </summary>
  68.    ''' <param name="process">
  69.    ''' The source <see cref="Process"/>.
  70.    ''' </param>
  71.    ''' <param name="size">
  72.    ''' The new window size.
  73.    ''' </param>
  74.    ''' <returns>
  75.    ''' <see langword="True"/> if successful; <see langword="False"/> otherwise.
  76.    ''' </returns>
  77.    Public Shared Function ResizeWindow(ByVal process As Process,
  78.                                        ByVal size As Size) As Boolean
  79.  
  80.        If (process Is Nothing) Then
  81.            Throw New ArgumentException(message:="No process found with the specified name.", paramName:="processName")
  82.  
  83.        Else
  84.            Dim unmanagedRect As NativeRectangle         ' Windows Rectangle definition.
  85.            Dim managedRect As Rectangle = unmanagedRect ' .NET Rectangle definition.
  86.  
  87.            Dim result As Boolean
  88.            Dim win32err As Integer
  89.  
  90.            result = NativeMethods.GetWindowRect(process.MainWindowHandle, unmanagedRect)
  91.            win32err = Marshal.GetLastWin32Error()
  92.            If Not (result) Then
  93.                Throw New Win32Exception(win32err)
  94.            End If
  95.  
  96.            result = NativeMethods.MoveWindow(process.MainWindowHandle,
  97.                                              managedRect.Left, managedRect.Top,
  98.                                              size.Width, size.Height,
  99.                                              repaint:=True)
  100.            win32err = Marshal.GetLastWin32Error()
  101.            If Not (result) Then
  102.                Throw New Win32Exception(win32err)
  103.            End If
  104.  
  105.            Return result
  106.  
  107.        End If
  108.  
  109.    End Function
  110.  
  111. End Class

Modo de empleo:
Código
  1. Dim p As Process = Process.GetProcessesByName("notepad").FirstOrDefault()
  2.  
  3. Dim newPos As New Point(x:=0, y:=0)
  4. Dim newSize As New Size(width:=256, height:=256)
  5.  
  6. WindowAutomationUtil.MoveWindow(p, newPos)
  7. WindowAutomationUtil.ResizeWindow(p, newSize)



Nótese que para el análisis de ventanas con borde invisible de Windows 10 quizás quieras perfeccionar un poco más el algoritmo, según cuales sean tus necesidades. En ese caso primero debes comprobar que el sistema operativo en ejecución sea Windows 10, y posteriormente llamar a la función Win32 DwmGetWindowAttribute.

Te muestro un ejemplo, pero ojo, tómalo a modo de pseudo-código, este código no es funcional ya que no puedo compartir el resto de definiciones necesarias por falta de espacio:

Determinar si el sistema operativo es Windows 10:
Código
  1.        ''' ----------------------------------------------------------------------------------------------------
  2.        ''' <summary>
  3.        ''' Gets a value that determines whether the current operating system is <c>Windows 10</c>.
  4.        ''' </summary>
  5.        ''' ----------------------------------------------------------------------------------------------------
  6.        ''' <example> This is a code example.
  7.        ''' <code>
  8.        ''' If IsWin10 Then
  9.        '''     Throw New PlatformNotSupportedException("This application cannot run under Windows 10.")
  10.        ''' End If
  11.        ''' </code>
  12.        ''' </example>
  13.        ''' ----------------------------------------------------------------------------------------------------
  14.        Public Shared ReadOnly Property IsWin10 As Boolean
  15.            <DebuggerStepThrough>
  16.            Get
  17.                Return (Environment.OSVersion.Platform = PlatformID.Win32NT) AndAlso (InternalIsWin10())
  18.            End Get
  19.        End Property
  20.  
  21.        ''' ----------------------------------------------------------------------------------------------------
  22.        ''' <summary>
  23.        ''' Determines whether the current operating system is <c>Windows 10</c>.
  24.        ''' </summary>
  25.        ''' ----------------------------------------------------------------------------------------------------
  26.        ''' <remarks>
  27.        ''' <see href="http://msdn.microsoft.com/es-es/library/windows/desktop/dn424972%28v=vs.85%29.aspx"/>
  28.        ''' </remarks>
  29.        ''' ----------------------------------------------------------------------------------------------------
  30.        ''' <returns>
  31.        ''' <see langword="True"/> if the current operating system is <c>Windows 10</c>; otherwise, <see langword="False"/>.
  32.        ''' </returns>
  33.        ''' ----------------------------------------------------------------------------------------------------
  34.        <DebuggerStepThrough>
  35.        Private Shared Function InternalIsWin10() As Boolean
  36.  
  37.            Using reg As RegistryKey = Microsoft.Win32.Registry.LocalMachine.
  38.                                       OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion", writable:=False)
  39.  
  40.                Dim productName As String = DirectCast(reg.GetValue("ProductName", "Empty", RegistryValueOptions.None), String)
  41.                Return productName.StartsWith("Windows 10", StringComparison.OrdinalIgnoreCase)
  42.  
  43.            End Using
  44.  
  45.        End Function
  46.  

Metogología alternativa (menos universal y más tediosa por el requisito del archivo de manifiesto):
  • http://msdn.microsoft.com/es-es/library/windows/desktop/dn424972%28v=vs.85%29.aspx (http://msdn.microsoft.com/es-es/library/windows/desktop/dn424972%28v=vs.85%29.aspx)

Obtener tamaño de ventana:
Código
  1.    ''' <summary>
  2.    ''' Gets the non-client area of a window.
  3.    ''' <para></para>
  4.    ''' This method supports a <c>Windows 10</c> window with invisible border or shadows.
  5.    ''' </summary>
  6.    ''' <param name="hwnd">
  7.    ''' A handle to the window.
  8.    ''' </param>
  9.    ''' <returns>
  10.    ''' The resulting non-client area of the window.
  11.    ''' </returns>
  12.    <DebuggerStepThrough>
  13.    Public Shared Function GetRealWindowRect(ByVal hwnd As IntPtr) As Rectangle
  14.  
  15.        Dim rc As NativeRectangle = Rectangle.Empty
  16.  
  17.        If (IsWin10) Then
  18.            Dim hResult As Integer
  19.            hResult = NativeMethods.DwmGetWindowAttribute(hwnd, ElektroKit.Interop.Win32.Enums.DwmWindowAttribute.ExtendedFrameBounds, rc, Marshal.SizeOf(rc)) ' DwmWindowAttribute.ExtendedFrameBounds = 9
  20.            If (DirectCast(hResult, ElektroKit.Interop.Win32.Enums.HResult) <> ElektroKit.Interop.Win32.Enums.HResult.S_OK) Then ' HResult.S_OK = 0
  21.                Marshal.ThrowExceptionForHR(hResult)
  22.            End If
  23.  
  24.        Else
  25.            Dim result As Boolean
  26.            Dim win32Err As Integer
  27.            result = NativeMethods.GetWindowRect(hwnd, rc)
  28.            win32Err = Marshal.GetLastWin32Error()
  29.            If Not (result) Then
  30.                Throw New Win32Exception(win32Err)
  31.            End If
  32.  
  33.        End If
  34.  
  35.        Return rc
  36.  
  37.    End Function
  38.  
  39.    ''' ----------------------------------------------------------------------------------------------------
  40.    ''' <summary>
  41.    ''' Gets the non-client area of a window.
  42.    ''' <para></para>
  43.    ''' This method supports a <c>Windows 10</c> window with invisible border or shadows.
  44.    ''' </summary>
  45.    ''' <param name="window">
  46.    ''' The source window.
  47.    ''' </param>
  48.    ''' <returns>
  49.    ''' The resulting non-client area of the window.
  50.    ''' </returns>
  51.    <DebuggerStepThrough>
  52.    Public Shared Function GetRealWindowRect(ByVal window As IWin32Window) As Rectangle
  53.        Return GetRealWindowRect(window.Handle)
  54.    End Function
  55.  
  56.    ''' <summary>
  57.    ''' Gets the non-client area of a <see cref="Form"/> window.
  58.    ''' <para></para>
  59.    ''' This method supports a <c>Windows 10</c> <see cref="Form"/> window with invisible border or shadows.
  60.    ''' </summary>
  61.    ''' <param name="form">
  62.    ''' The source <see cref="Form"/>.
  63.    ''' </param>
  64.    ''' <returns>
  65.    ''' The resulting non-client area of the <see cref="Form"/> window.
  66.    ''' </returns>
  67.    <DebuggerStepThrough>
  68.    Public Shared Function GetRealWindowRect(ByVal form As Form) As Rectangle
  69.        Return GetRealWindowRect(DirectCast(form, IWin32Window).Handle)
  70.    End Function

Saludos.