Cambiar estilo de las ventanas (invertir, quitar botones, bloquear, etc)

Iniciado por Lekim, 27 Noviembre 2015, 19:07 PM

0 Miembros y 1 Visitante están viendo este tema.

Lekim

Hola

He creado este código para cambiar el estilo de las ventanas, se puede invertir la barra de título sin alterar el resto del form, bloquear el form, quitar los botones, desactivar botones de la barra, cambiar la posición de título de la barra de título, quitar los bordes, mostrar el form como un popup menú, etc.

Los cambios son combinables en algunos casos.



CAMBIAR EL ESTILO DE LAS VENTANAS

Código (vbnet) [Seleccionar]
#Region "Cambiar estilo de la ventana"
Public Module modChangeStyleWindow
   Const GWL_ID = (-12)
   Const GWL_STYLE = (-16)
   Const HWND_NOTOPMOST = -2
   Const SWP_NOZORDER = &H4
   Const SWP_NOSIZE = &H1
   Const SWP_NOMOVE = &H2
   Const SWP_FRAMECHANGED = &H20
   Const SWP_DRAWFRAME = SWP_FRAMECHANGED

   Enum WindowsStyle
       WS_SIZABLE = &H0                                'Con todos los botones y la barra de título
       WS_SIZABLE_DISABLEMAXB = &HFFFFFFFFFFFFFFFF     'Desactiva el botón maximizar
       WS_SIZABLE_DISABLEMINB = &HFFFFFFFFFFFE5E08     'Desactiva el botón minimizar
       WS_DLGFRAME_DISABLE = &H5FD8220                 'Cuadro diálogo desactivado (no permite ninguna interacción con el form)
       WS_DLGFRAME_FIXEDSINGLE = &HFFFFFFFFFFF9CA28    'Cuadro diálogo no redimensionable
       WS_DLGFRAME_SIZABLE = &HFFFFFFFFFFFDC5B0        'Cuadro diálogo redimensionable
       WS_DISABLED = &H8000000                         'Desactivado (no permite ninguna interacción con el form)
       WS_SYSMENU_DISABLE = &H5F5E100                  'Desactiva el menú y desactivado              
       WS_SYSMENU_SIZABLE = &HFFFFFFFFFFF8F350         'Desactiva el menú y redimensionable
       WS_SYSMENU_FIXEDSINGLE = &HFFFFFFFFFFF4EC10     'Desactiva el menú y no es redimensionable
       WS_FIXEDSINGLE = &HFFFFFFFFFFFCEAF0             'No redimensionable
       WS_FIXEDSINGLE_DISABLEMAXB = &HFFFFFFFFFFFBBA40 'No redimensionable y desactiva el botón maximizar
       WS_FIXEDSINGLE_DISABLEMINB = &HFFFFFFFFFFFAEF20 'No redimensionable y desactvia el botón minimizar
       WS_NOBORDER = &H325AA0                          'Sin bordes
       WS_FLAT3D = &HB1FE68                            'Sin bordes con línea exterior
       WS_POPUP = &H712CA8                             'Menú Popup
   End Enum

   <System.Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True)> _
   Private Function SetWindowLong(ByVal hwnd As IntPtr, _
                                         ByVal nIndex As Integer, _
                                         ByVal dwNewLong As Integer) As Integer
   End Function


   <System.Runtime.InteropServices.DllImport("user32.dll", SetLastError:=False)> _
   Private Function SetWindowPos(ByVal hwnd As IntPtr, _
                                        ByVal hWndInsertAfter As IntPtr, _
                                        ByVal X As Integer, _
                                        ByVal y As Integer, _
                                        ByVal cx As Integer, _
                                        ByVal cy As Integer, _
                                        ByVal wFlags As Integer) As Integer
   End Function


   <System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="GetWindowLongA", SetLastError:=True)> _
   Private Function GetWindowLong(ByVal hWnd As IntPtr, _
                                         <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.I4)> ByVal nIndex As Integer) As Integer
   End Function

   Public Sub ChangeStyleWindow(ByVal hwnd As IntPtr, ByVal StyleForm As Integer, ByVal SetStyle As Boolean)
       'mantiene el tamaño de la ventana
       Dim stl As Integer = GetWindowLong(hwnd, GWL_STYLE)

       Select Case SetStyle
           '//Solo Ventana 'Sizable'
           'Case True : If stl = &H16CF0000 Then stl += StyleForm
           'Case False : If stl = &H16CF0000 + StyleForm Then stl -= StyleForm
           '//Cualquier tipo de ventana u objeto con handle
           Case True : stl += StyleForm
           Case False : stl -= StyleForm
       End Select

       SetWindowLong(hwnd, GWL_STYLE, stl)
       Call SetWindowPos(hwnd, HWND_NOTOPMOST, Nothing, Nothing, Nothing, Nothing, _
       SWP_NOZORDER + SWP_NOSIZE + SWP_NOMOVE + SWP_DRAWFRAME)
   End Sub

End Module
#End Region



CAMBIAR EL ESTILO DE LA BARRA
Código (vbnet) [Seleccionar]
Region "Cambiar estilo de la Barra de Título"
Module modChangeStyleBar
   Const GWL_ID = (-12)
   Const GWL_STYLE = (-16)
   Const GWL_EXSTYLE = (-20)
   Const HWND_NOTOPMOST = -2
   Const SWP_NOZORDER = &H4
   Const SWP_NOSIZE = &H1
   Const SWP_NOMOVE = &H2
   Const SWP_FRAMECHANGED = &H20
   Const SWP_DRAWFRAME = SWP_FRAMECHANGED

   Enum WStyleBarTitle
       WStB_NORMAL_THICKBORDER = &H200                             'Normal con borde ancho
       WStB_NORMALCAPTIONLEFT = &H0                                'Título a la izquierda
       WStB_NORMAL_CAPTIONRIGHT = &H1000                           'Título a la derecha
       WStB_INVERT_CAPTIONLEFT = &H405000                          'Invertido con título a la izquierda
       WStB_INVERT_CAPTIONRIGHT = &H400000                         'Invertido con título a la derecha
       WStB_TOOLWINDOW_CAPTIONLEFT = &H6590                        'Tool window con título a la izquierda y borde fino
       WStB_TOOLWINDOW_CAPTIONRIGHT = &H5580                       'Tool window con título a la derecha y borde fino
       WStB_TOOLWINDOW_THICKBORDER_CAPTONLEFT = &H68F              'Tool window con título a la izquierda y borde grueso
       WStB_TOOLWINDOW_THICKBORDER_CAPTONRIGHT = &H5A80            'Tool window con título a la derecha y borde grueso
       WStB_TOOLWINDOWS_INVERT_CAPTIONLEFT = &H401080              'Tool window Invertido con título a la izquierda y borde fino
       WStB_TOOLWINDOWS_INVERT_CAPTIONRIGHT = &H400180             'Tool window invertido con título a la derecha y borde fino
       WStB_TOOLWINDOWS_INVERT_THICKBORDER_TITLELEFT = &H403390    'Tool window Invertido con título a la izquierda y borde grueso
       WStB_TOOLWINDOWS_INVERT_THICKBORDER_TITLERIGHT = &H400290   'Tool window invertido con título a la derecha y borde grueso
       WS_EX_DLGMODALFRAME = &H1
       WS_EX_NOPARENTNOTIFY = &H4
       WS_EX_TOPMOST = &H8
       WS_EX_ACCEPTFILES = &H10                                    'Cambia el cursor cuando se arrastr un archivo a la ventana
       WS_EX_TRANSPARENT = &H20
       WS_EX_MDICHILD = &H40
       WS_EX_TOOLWINDOW = &H80
       WS_EX_WINDOWEDGE = &H100
       WS_EX_CLIENTEDGE = &H200
       WS_EX_CONTEXTHELP = &H400
       WS_EX_RIGHT = &H1000
       WS_EX_LEFT = &H0
       WS_EX_RTLREADING = &H2000
       WS_EX_LTRREADING = &H0
       WS_EX_LEFTSCROLLBAR = &H4000
       WS_EX_RIGHTSCROLLBAR = &H0
       WS_EX_CONTROLPARENT = &H10000
       WS_EX_STATICEDGE = &H20000
       WS_EX_APPWINDOW = &H40000
       WS_EX_OVERLAPPEDWINDOW = (WS_EX_WINDOWEDGE Or WS_EX_CLIENTEDGE)
       WS_EX_PALETTEWINDOW = (WS_EX_WINDOWEDGE Or WS_EX_TOOLWINDOW Or WS_EX_TOPMOST)
       WS_EX_LAYERED = &H80000
       WS_EX_NOINHERITLAYOUT = &H100000 ' Disable inheritence of mirroring by children
       WS_EX_LAYOUTRTL = &H400000 ' Right to left mirroring
       WS_EX_COMPOSITED = &H2000000
       WS_EX_NOACTIVATE = &H8000000
   End Enum
   <System.Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True)> _
   Private Function SetWindowLong(ByVal hwnd As IntPtr, _
                                         ByVal nIndex As Integer, _
                                         ByVal dwNewLong As Integer) As Integer
   End Function


   <System.Runtime.InteropServices.DllImport("user32.dll", SetLastError:=False)> _
   Private Function SetWindowPos(ByVal hwnd As IntPtr, _
                                        ByVal hWndInsertAfter As IntPtr, _
                                        ByVal X As Integer, _
                                        ByVal y As Integer, _
                                        ByVal cx As Integer, _
                                        ByVal cy As Integer, _
                                        ByVal wFlags As Integer) As Integer
   End Function


   <System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="GetWindowLongA", SetLastError:=True)> _
   Private Function GetWindowLong(ByVal hWnd As IntPtr, _
                                         <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.I4)> ByVal nIndex As Integer) As Integer
   End Function

   'Estilo de la barra de título
   Public Sub ChangeStyleBarWindow(ByVal hwnd As IntPtr, ByVal StyleBar As Integer)
       SetWindowLong(hwnd, GWL_EXSTYLE, StyleBar)
       Call SetWindowPos(hwnd, HWND_NOTOPMOST, Nothing, Nothing, Nothing, Nothing, _
       SWP_NOZORDER Or SWP_NOSIZE Or SWP_NOMOVE Or SWP_DRAWFRAME)
   End Sub
End Module
#End Region




EJEMPLO DE USO


Si se aplican varias veces el mismo estilo se pueden obtener estilos curiosos.



Código (vbnet) [Seleccionar]
   Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
       For i As Integer = 0 To 5
           modChangeStyleWindow.ChangeStyleWindow(Me.Handle, WindowsStyle.WS_SYSMENU_FIXEDSINGLE, True)
       Next i
   End Sub



para modo popup:

Código (vbnet) [Seleccionar]
  modChangeStyleWindow.ChangeStyleWindow(Me.Handle, WindowsStyle.WS_POPUP, True)


Para invertir la barra de título:
Código (vbnet) [Seleccionar]
      Call modChangeStyleBar.ChangeStyleBarWindow(Me.Handle, modChangeStyleBar.WStyleBarTitle.WStB_INVERT_CAPTIONRIGHT)


Invertido y desactivado:
Código (vbnet) [Seleccionar]
  Call modChangeStyleWindow.ChangeStyleWindow(Me.Handle, modChangeStyleWindow.WindowsStyle.WS_DISABLED, True)
       Call modChangeStyleBar.ChangeStyleBarWindow(Me.Handle, modChangeStyleBar.WStyleBarTitle.WStB_INVERT_CAPTIONRIGHT)



Espero os sirva  ;)

Sl2s



Se me olvidaba, para restaurar la ventana establecer 'False'
'Activa el cambio
Código (vbnet) [Seleccionar]
Call modChangeStyleWindow.ChangeStyleWindow(Me.Handle, modChangeStyleWindow.WindowsStyle.WS_DISABLED, True)

'Desactiva el cambio (en este caso se tendría que hacer con un timer o similar ya que WS_DISABLE no permite la interacción con el form ni con los controles que contiene)
Código (vbnet) [Seleccionar]
Call modChangeStyleWindow.ChangeStyleWindow(Me.Handle, modChangeStyleWindow.WindowsStyle.WS_DISABLED, False)

sl2s

XresH

Gracias por el aporte, se ve excelente y muy bien explicado (Y)


Saludos.
[ - Si eres programador y quieres que tus proyectos esten en mi blog(con o sin source), consúltame! - ]
Entra A Mi Blog De Programación | | Dudas en este post :| | >>Clic para ir al Post<<

Eleкtro

#2
EDITO:

Lee esto:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms633585%28v=vs.85%29.aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/ms644898%28v=vs.85%29.aspx



EDITO 2:
Código (vbnet) [Seleccionar]
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Retrieves information about the specified window.
''' <para></para>
''' The function also retrieves the 32-bit (<c>DWORD</c>) value at the specified offset into the extra window memory.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <remarks>
''' <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms633584%28v=vs.85%29.aspx"/>
''' </remarks>
''' ----------------------------------------------------------------------------------------------------
<DllImport("user32.dll", EntryPoint:="GetWindowLong", SetLastError:=True)>
Public Shared Function GetWindowLong(ByVal hwnd As IntPtr,
      <MarshalAs(UnmanagedType.I4)> ByVal nIndex As WindowLongFlags
) As UInteger
End Function

''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Changes an attribute of the specified window.
''' <para></para>
''' The function also sets the 32-bit (<c>LONG</c>) value at the specified offset into the extra window memory.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <remarks>
''' <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms633591%28v=vs.85%29.aspx"/>
''' </remarks>
''' ----------------------------------------------------------------------------------------------------
<DllImport("user32.dll", EntryPoint:="SetWindowLong", SetLastError:=True)>
Public Shared Function SetWindowLong(ByVal hwnd As IntPtr,
      <MarshalAs(UnmanagedType.I4)> ByVal nIndex As WindowLongFlags,
                                    ByVal dwNewLong As UInteger
) As UInteger
End Function

''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Retrieves information about the specified window.
''' <para></para>
''' The function also retrieves the value at a specified offset into the extra window memory.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <remarks>
''' <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms633585%28v=vs.85%29.aspx"/>
''' </remarks>
''' ----------------------------------------------------------------------------------------------------
<SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist",
justification:="Code-Analysis is 32-Bit so it only checks for the entrypoint in the user32.dll of the Win32 API.")>
<DllImport("user32.dll", EntryPoint:="GetWindowLongPtr", SetLastError:=True)>
Public Shared Function GetWindowLongPtr(ByVal hwnd As IntPtr,
         <MarshalAs(UnmanagedType.I4)> ByVal nIndex As WindowLongFlags
) As IntPtr
End Function

''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Changes an attribute of the specified window.
''' <para></para>
''' The function also sets a value at the specified offset in the extra window memory.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <remarks>
''' <see href="https://msdn.microsoft.com/es-es/library/windows/desktop/ms644898%28v=vs.85%29.aspx"/>
''' </remarks>
''' ----------------------------------------------------------------------------------------------------
<SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist",
justification:="Code-Analysis is 32-Bit so it only checks for the entrypoint in the user32.dll of the Win32 API.")>
<DllImport("user32.dll", EntryPoint:="SetWindowLongPtr", SetLastError:=True)>
Public Shared Function SetWindowLongPtr(ByVal hwnd As IntPtr,
         <MarshalAs(UnmanagedType.I4)> ByVal nIndex As WindowLongFlags,
                                       ByVal dwNewLong As IntPtr
) As IntPtr
End Function

''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' The zero-based offset to the value to be set or retrieved.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <remarks>
''' <see href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548%28v=vs.85%29.aspx"/>
''' </remarks>
''' ----------------------------------------------------------------------------------------------------
Public Enum WindowLongFlags As Integer

   ''' <summary>
   ''' Retrieves the window styles.
   ''' </summary>
   WindowStyle = -16

   ''' <summary>
   ''' Retrieves the extended window styles.
   ''' </summary>
   WindowStyleEx = -20

   ''' <summary>
   ''' Retrieves a handle to the application instance.
   ''' </summary>
   HInstance = -6

   ''' <summary>
   ''' Retrieves a handle to the parent window, if any.
   ''' </summary>
   HwndParent = -8

   ''' <summary>
   ''' Retrieves the identifier of the window.
   ''' </summary>
   Id = -12

   ''' <summary>
   ''' Retrieves the user data associated with the window.
   ''' <para></para>
   ''' This data is intended for use by the application that created the window.
   ''' <para></para>
   ''' Its value is initially zero.
   ''' </summary>
   UserData = -21

   ''' <summary>
   ''' Retrieves the address of the window procedure, or a handle representing the address of the window procedure.
   ''' <para></para>
   ''' You must use the <c>CallWindowProc</c> function to call the window procedure.
   ''' </summary>
   WndProc = -4

   ''' <summary>
   ''' ( This value is only available when the <paramref name="hwnd"/> parameter identifies a dialog box. )
   ''' <para></para>
   ''' Retrieves extra information private to the application, such as handles or pointers.
   ''' </summary>
   DlgUser = 8

   ''' <summary>
   ''' ( This value is only available when the <paramref name="hwnd"/> parameter identifies a dialog box. )
   ''' <para></para>
   ''' Retrieves the return value of a message processed in the dialog box procedure.
   ''' </summary>
   DlgMsgresult = 0

   ''' <summary>
   ''' ( This value is only available when the <paramref name="hwnd"/> parameter identifies a dialog box. )
   ''' <para></para>
   ''' Retrieves the address of the dialog box procedure,
   ''' or a handle representing the address of the dialog box procedure.
   ''' <para></para>
   ''' You must use the <c>CallWindowProc</c> function to call the dialog box procedure.
   ''' </summary>
   DlgProc = 4

End Enum





Estuve implementado las enumeraciones de estilos de ventanas en mi (futura)api. Aquí les dejo las enumeraciones con documentación xml por si alguien lo prefiere así para aprovechar IntelliSense o compilar un archivo de ayuda:

Código (vbnet) [Seleccionar]
   ''' ----------------------------------------------------------------------------------------------------
   ''' <summary>
   ''' The following styles can be specified wherever a window style is required.
   ''' <para></para>
   ''' After the control has been created, these styles cannot be modified, except as noted.
   ''' </summary>
   ''' ----------------------------------------------------------------------------------------------------
   ''' <remarks>
   ''' <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms632600%28v=vs.85%29.aspx"/>
   ''' </remarks>
   ''' ----------------------------------------------------------------------------------------------------
   <Flags>
   Public Enum WindowStyles As UInteger

       ''' <summary>
       ''' The window has a thin-line border.
       ''' </summary>
       Border = &H800000UI

       ''' <summary>
       ''' The window has a title bar.
       ''' <para></para>
       ''' (includes the <see cref="WindowStyles.Border"/> style).
       ''' </summary>
       Caption = &HC00000UI

       ''' <summary>
       ''' The window is a child window.
       ''' <para></para>
       ''' A window with this style cannot have a menu bar.
       ''' <para></para>
       ''' This style cannot be used with the <see cref="WindowStyles.Popup"/> style.
       ''' </summary>
       Child = &H40000000UI

       ''' <summary>
       ''' Excludes the area occupied by child windows when drawing occurs within the parent window.
       ''' <para></para>
       ''' This style is used when creating the parent window.
       ''' </summary>
       ClipChildren = &H2000000UI

       ''' <summary>
       ''' Clips child windows relative to each other;
       ''' that is, when a particular child window receives a <c>WM_PAINT</c> message,
       ''' the <see cref="WindowStyles.ClipSiblings"/> style clips all other overlapping child windows out of the
       ''' region of the child window to be updated.
       ''' <para></para>
       ''' If <see cref="WindowStyles.ClipSiblings"/> is not specified and child windows overlap,
       ''' it is possible, when drawing within the client area of a child window,
       ''' to draw within the client area of a neighboring child window.
       ''' </summary>
       ClipSiblings = &H4000000UI

       ''' <summary>
       ''' The window is initially disabled.
       ''' <para></para>
       ''' A disabled window cannot receive input from the user.
       ''' <para></para>
       ''' To change this after a window has been created, use the <c>EnableWindow</c> function.
       ''' </summary>
       Disabled = &H8000000UI

       ''' <summary>
       ''' The window has a border of a style typically used with dialog boxes.
       ''' <para></para>
       ''' A window with this style cannot have a title bar.
       ''' </summary>
       DlgFrame = &H400000UI

       ''' <summary>
       ''' The window is the first control of a group of controls.
       ''' <para></para>
       ''' The group consists of this first control and all controls defined after it,
       ''' up to the next control with the <see cref="WindowStyles.Group"/> style.
       ''' <para></para>
       ''' The first control in each group usually has the <see cref="WindowStyles.TabStop"/> style
       ''' so that the user can move from group to group.
       ''' <para></para>
       ''' The user can subsequently change the keyboard focus from one control in the
       ''' group to the next control in the group by using the direction keys.
       ''' <para></para>
       ''' You can turn this style on and off to change dialog box navigation.
       ''' <para></para>
       ''' To change this style after a window has been created, use the <c>SetWindowLong</c> function.
       ''' </summary>
       Group = &H20000UI

       ''' <summary>
       ''' The window has a horizontal scroll bar.
       ''' </summary>
       HScroll = &H100000UI

       ''' <summary>
       ''' The window is initially maximized.
       ''' </summary>
       Maximize = &H1000000UI

       ''' <summary>
       ''' The window has a maximize button.
       ''' <para></para>
       ''' Cannot be combined with the <c>WS_EX_CONTEXTHELP</c> extended style.
       ''' <para></para>
       ''' The <see cref="WindowStyles.SysMenu"/> style must also be specified.
       ''' </summary>
       MaximizeBox = &H10000UI

       ''' <summary>
       ''' The window is initially minimized.
       ''' </summary>
       Minimize = &H20000000UI

       ''' <summary>
       ''' The window has a minimize button.
       ''' <para></para>
       ''' Cannot be combined with the <c>WS_EX_CONTEXTHELP</c> extended style.
       ''' <para></para>
       ''' The <see cref="WindowStyles.SysMenu"/> style must also be specified.
       ''' </summary>
       MinimizeBox = &H20000UI

       ''' <summary>
       ''' The window is an overlapped window.
       ''' <para></para>
       ''' An overlapped window has a title bar and a border.
       ''' </summary>
       Overlapped = &H0UI

       ''' <summary>
       ''' The window is an overlapped window.
       ''' </summary>
       OverlappedWindow = (Overlapped Or Caption Or SysMenu Or SizeFrame Or MinimizeBox Or MaximizeBox)

       ''' <summary>
       ''' The window is a pop-up window.
       ''' <para></para>
       ''' This style cannot be used with the <see cref="WindowStyles.Child"/> style.
       ''' </summary>
       Popup = &H80000000UI

       ''' <summary>
       ''' The window is a pop-up window.
       ''' <para></para>
       ''' The <see cref="WindowStyles.Caption"/> and <see cref="WindowStyles.PopupWindow"/> styles
       ''' must be combined to make the window menu visible.
       ''' </summary>
       PopupWindow = (Popup Or Border Or SysMenu)

       ''' <summary>
       ''' The window has a sizing border.
       ''' </summary>
       SizeFrame = &H40000UI

       ''' <summary>
       ''' The window has a window menu on its title bar.
       ''' <para></para>
       ''' The <see cref="WindowStyles.Caption"/> style must also be specified.
       ''' </summary>
       SysMenu = &H80000UI

       ''' <summary>
       ''' The window is a control that can receive the keyboard focus when the user presses the <c>TAB</c> key.
       ''' <para></para>
       ''' Pressing the <c>TAB</c> key changes the keyboard focus to the next control
       ''' with the <see cref="WindowStyles.TabStop"/> style.
       ''' <para></para>
       ''' You can turn this style on and off to change dialog box navigation.
       ''' <para></para>
       ''' To change this style after a window has been created, use the <c>SetWindowLong</c> function.
       ''' <para></para>
       ''' For user-created windows and modeless dialogs to work with tab stops,
       ''' alter the message loop to call the <c>IsDialogMessage</c> function.
       ''' </summary>
       TabStop = &H10000UI

       ''' <summary>
       ''' The window is initially visible.
       ''' <para></para>
       ''' This style can be turned on and off by using the <c>ShowWindow</c> or <c>SetWindowPos</c> function.
       ''' </summary>
       Visible = &H10000000UI

       ''' <summary>
       ''' The window has a vertical scroll bar.
       ''' </summary>
       VScroll = &H200000UI

   End Enum


Código (vbnet) [Seleccionar]
   ''' ----------------------------------------------------------------------------------------------------
   ''' <summary>
   ''' Extended window styles.
   ''' </summary>
   ''' ----------------------------------------------------------------------------------------------------
   ''' <remarks>
   ''' <see href="https://msdn.microsoft.com/es-es/library/windows/desktop/ff700543%28v=vs.85%29.aspx"/>
   ''' </remarks>
   ''' ----------------------------------------------------------------------------------------------------
   <Flags>
   Public Enum WindowStylesEx As UInteger

       ''' <summary>
       ''' Specifies a window that accepts drag-drop files.
       ''' </summary>
       AcceptFiles = &H10UI

       ''' <summary>
       ''' Forces a top-level window onto the taskbar when the window is visible.
       ''' </summary>
       AppWindow = &H40000UI

       ''' <summary>
       ''' Specifies a window that has a border with a sunken edge.
       ''' </summary>
       ClientEdge = &H200UI

       ''' <summary>
       ''' Specifies a window that paints all descendants in bottom-to-top painting order using double-buffering.
       ''' <para></para>
       ''' This cannot be used if the window has a class style of either <c>CS_OWNDC</c> or <c>CS_CLASSDC</c>.
       ''' <para></para>
       ''' This style is not supported in Windows 2000.
       ''' </summary>
       ''' <remarks>
       ''' With <see cref="WindowStylesEx.Composited"/> set,
       ''' all descendants of a window get bottom-to-top painting order using double-buffering.
       ''' <para></para>
       ''' Bottom-to-top painting order allows a descendent window to have translucency (alpha) and transparency (color-key) effects,
       ''' but only if the descendent window also has the<see cref="WindowStylesEx.Transparent"/> bit set.
       ''' <para></para>
       ''' Double-buffering allows the window and its descendents to be painted without flicker.
       ''' </remarks>
       Composited = &H2000000UI

       ''' <summary>
       ''' Specifies a window that includes a question mark in the title bar.
       ''' <para></para>
       ''' When the user clicks the question mark, the cursor changes to a question mark with a pointer.
       ''' <para></para>
       ''' If the user then clicks a child window, the child receives a <c>WM_HELP</c> message.
       ''' <para></para>
       ''' The child window should pass the message to the parent window procedure,
       ''' which should call the <c>WinHelp</c> function using the <c>HELP_WM_HELP</c> command.
       ''' <para></para>
       ''' The Help application displays a pop-up window that typically contains help for the child window.
       ''' <para></para>
       ''' <see cref="WindowStylesEx.ContextHelp"/> cannot be used with the <c>WS_MAXIMIZEBOX</c> or <c>WS_MINIMIZEBOX</c> styles.
       ''' </summary>
       ContextHelp = &H400UI

       ''' <summary>
       ''' Specifies a window which contains child windows that should take part in dialog box navigation.
       ''' <para></para>
       ''' If this style is specified, the dialog manager recurses into children of
       ''' this window when performing navigation operations
       ''' such as handling the <c>TAB</c> key, an arrow key, or a keyboard mnemonic.
       ''' </summary>
       ControlParent = &H10000UI

       ''' <summary>
       ''' Specifies a window that has a double border.
       ''' </summary>
       DlgModalFrame = &H1UI

       ''' <summary>
       ''' Specifies a window that is a layered window.
       ''' <para></para>
       ''' This cannot be used for child windows or if the window has a class style of either <c>CS_OWNDC</c> or <c>CS_CLASSDC</c>.
       ''' </summary>
       Layered = &H80000UI

       ''' <summary>
       ''' Specifies a window with the horizontal origin on the right edge.
       ''' <para></para>
       ''' Increasing horizontal values advance to the left.
       ''' <para></para>
       ''' The shell language must support reading-order alignment for this to take effect.
       ''' </summary>
       LayoutRtl = &H400000UI

       ''' <summary>
       ''' Specifies a window that has generic left-aligned properties.
       ''' <para></para>
       ''' This is the default.
       ''' </summary>
       Left = &H0UI

       ''' <summary>
       ''' Specifies a window with the vertical scroll bar (if present) to the left of the client area.
       ''' <para></para>
       ''' The shell language must support reading-order alignment for this to take effect.
       ''' </summary>
       LeftScrollbar = &H4000UI

       ''' <summary>
       ''' Specifies a window that displays text using left-to-right reading-order properties.
       ''' <para></para>
       ''' This is the default.
       ''' </summary>
       LtrReading = &H0UI

       ''' <summary>
       ''' Specifies a multiple-document interface (MDI) child window.
       ''' </summary>
       MdiChild = &H40UI

       ''' <summary>
       ''' Specifies a top-level window created with this style does not become the
       ''' foreground window when the user clicks it.
       ''' <para></para>
       ''' The system does not bring this window to the foreground when the user minimizes or closes the foreground window.
       ''' <para></para>
       ''' The window does not appear on the taskbar by default.
       ''' <para></para>
       ''' To force the window to appear on the taskbar, use the <see cref="WindowStylesEx.AppWindow"/> style.
       ''' <para></para>
       ''' To activate the window, use the <c>SetActiveWindow</c> or <c>SetForegroundWindow</c> function.
       ''' </summary>
       NoActivate = &H8000000UI

       ''' <summary>
       ''' Specifies a window which does not pass its window layout to its child windows.
       ''' </summary>
       NoInheritLayout = &H100000UI

       ''' <summary>
       ''' Specifies that a child window created with this style does not send the <c>WM_PARENTNOTIFY</c> message
       ''' to its parent window when it is created or destroyed.
       ''' </summary>
       NoParentNotify = &H4UI

       ''' <summary>
       ''' Specifies an overlapped window.
       ''' </summary>
       OverlappedWindow = (WindowEdge Or ClientEdge)

       ''' <summary>
       ''' Specifies a palette window, which is a modeless dialog box that presents an array of commands.
       ''' </summary>
       PaletteWindow = (WindowEdge Or ToolWindow Or TopMost)

       ''' <summary>
       ''' Specifies a window that has generic "right-aligned" properties. This depends on the window class.
       ''' <para></para>
       ''' The shell language must support reading-order alignment for this to take effect.
       ''' <para></para>
       ''' Using the <see cref="WindowStylesEx.Right"/> style has the same effect as
       ''' using the <c>SS_RIGHT</c> (static), <c>ES_RIGHT</c> (edit),
       ''' and <c>BS_RIGHT</c>/<c>BS_RIGHTBUTTON</c> (button) control styles.
       ''' </summary>
       Right = &H1000UI

       ''' <summary>
       ''' Specifies a window with the vertical scroll bar (if present) to the right of the client area.
       ''' <para></para>
       ''' This is the default.
       ''' </summary>
       RightScrollbar = &H0UI

       ''' <summary>
       ''' Specifies a window that displays text using right-to-left reading-order properties.
       ''' <para></para>
       ''' The shell language must support reading-order alignment for this to take effect.
       ''' </summary>
       RtlReading = &H2000UI

       ''' <summary>
       ''' Specifies a window with a three-dimensional border style intended to be used for
       ''' items that do not accept user input.
       ''' </summary>
       StaticEdge = &H20000UI

       ''' <summary>
       ''' Specifies a window that is intended to be used as a floating toolbar.
       ''' <para></para>
       ''' A tool window has a title bar that is shorter than a normal title bar,
       ''' and the window title is drawn using a smaller font.
       ''' <para></para>
       ''' A tool window does not appear in the taskbar or in the dialog that appears when the user presses <c>ALT</c>+<c>TAB</c>.
       ''' <para></para>
       ''' If a tool window has a system menu, its icon is not displayed on the title bar.
       ''' <para></para>
       ''' However, you can display the system menu by right-clicking or by typing <c>ALT</c>+<c>SPACE</c>.
       ''' </summary>
       ToolWindow = &H80UI

       ''' <summary>
       ''' Specifies a window that should be placed above all non-topmost windows and should stay above them,
       ''' even when the window is deactivated.
       ''' <para></para>
       ''' To add or remove this style, use the <c>SetWindowPos</c> function.
       ''' </summary>
       TopMost = &H8UI

       ''' <summary>
       ''' Specifies a window that should not be painted until siblings beneath the window
       ''' (that were created by the same thread) have been painted.
       ''' <para></para>
       ''' The window appears transparent because the bits of underlying sibling windows have already been painted.
       ''' <para></para>
       ''' To achieve transparency without these restrictions, use the <c>SetWindowRgn</c> function.
       ''' </summary>
       Transparent = &H20UI

       ''' <summary>
       ''' Specifies a window that has a border with a raised edge.
       ''' </summary>
       WindowEdge = &H100UI

   End Enum








Lekim

Gracias Elektro
¿Entonces según eso mi código no funcionaría en 64bits?
Tengo un PC con W764bits ahora lo pruebo y hago los cambios... jeje

Por cierto, se hace muy engorroso ver el código con el <summary>

Código (vbnet) [Seleccionar]
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Changes an attribute of the specified window.
''' <para></para>
''' The function also sets the 32-bit (<c>LONG</c>) value at the specified offset into the extra window memory.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <remarks>
''' <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms633591%28v=vs.85%29.aspx"/>
''' </remarks>


Creo que está bien pero en el navegador tienes que ir bajando y bajando.... :¬¬

Sl2s

Eleкtro

#4
Cita de: Lekim en 28 Noviembre 2015, 03:19 AM¿Entonces según eso mi código no funcionaría en 64bits?

Eso dice la MSDN.

De todas formas no lo he testeado en un Windows x86 (me da pereza encender la V.M.) así que no se que tipo de "incompatibilidad" causará, quizás devuelva valores incorrectos, no lo se. EDITO: si que me funciona incorrectamente.

Cuando juegues con el P/Invoking debes asegurarte de hacer un análisis de código con la herramienta Code-Analysis de VisualStudio, ya que suele detectar y advertirte de conflictos de ese tipo con firmas de p/invokes que no son portables.

En tu código, puedes escribir una condicional que evalue el tamaño en bytes de un IntPtr (Marshal.SizeOf(GetType(IntPtr))) lo que dará 4 bytes en Win32 y 8 bytes en Win64, o simplemente recurrir a la propiedad Environment.Is64BitOperatingSystem :

Código (vbnet) [Seleccionar]
If Environment.Is64BitOperatingSystem Then
...WindowLongPtr

Else
...WindowLong

End If


EDITO:
te muestro un ejemplo más extenso:
Código (vbnet) [Seleccionar]
Dim target As IntPtr = MyBase.Handle
Dim flag As WindowLongFlags = WindowLongFlags.WindowStyleEx
Dim oldStyle As WindowStylesEx
Dim newStyle As WindowStylesEx

If Environment.Is64BitOperatingSystem Then
   oldStyle = CType(NativeMethods.GetWindowLongPtr(target, flag).ToInt64, WindowStylesEx)
   newStyle = (oldStyle Or WindowStylesEx.ToolWindow)
   NativeMethods.SetWindowLongPtr(target, flag, New IntPtr(newStyle))

Else
   oldStyle = CType(NativeMethods.GetWindowLong(target, flag), WindowStylesEx)
   newStyle = (oldStyle Or WindowStylesEx.ToolWindow)
   NativeMethods.SetWindowLong(target, flag, newStyle)

End If





Cita de: Lekim en 28 Noviembre 2015, 03:19 AMPor cierto, se hace muy engorroso ver el código con el <summary>

Lo siento si se te hace engorroso, pero resulta necesario para generar la descripción del miembro en IntelliSense y/o compilar el archivos de ayuda html.

Siempre puedes colapsar toda la documentación XML usando la combinación CTRL + M + L.

saludos








Lekim

Está genial no sabía esa propiedad de Environtment  ;-)

Lo testearé en 64bits más tarde, porque el ratón se quedó sin pilas y estoy recargando y el ratón con teclado numérico es un palo.

sl2s



TESTEADO EN 64BITS

Bueno, ya lo he testeado funciona perfecto y no da ningún error.

Hay que tener en cuenta que el nombre que usé al declarar la función del API es irrelevante. Yo puedo poner VivaLaPepa y funcionaría igual:

Código (vbnet) [Seleccionar]
 <System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="GetWindowLongA", SetLastError:=True)> _
   Private Function VivaLaPepa(ByVal hWnd As IntPtr, _
                                         <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.I4)> ByVal nIndex As Integer) As Integer
   End Function


Lo importante es el punto de entrada GetWindowLongA. Si no establezco el punto de entrada como ocurre por ejemplo en SetWindowPos entonces NO puedo hacer la llamada con otro nombre que no sea SetWindowPos, pues este mismo nombre va actuar como punto de entrada.

Ahora bien, he importado las entradas de USER32.DLL tando en X86 com x64 (Windows 7 64bits) y he encontrado dos  entradas distintas que no se encuentran e x86. Estas son las entradas en User32.dll:

x86
1916  197 00017D64 GetWindowLongA
1919  19A 00019938 GetWindowLongW


x64

1916  197 00017D64 GetWindowLongA
1917  198 00016050 GetWindowLongPtrA
1918  199 0001B970 GetWindowLongPtrW
1919  19A 00019938 GetWindowLongW


Importar Apis


Sin embargo si uso la entrada GetWindowLongPtrA (en sistema de 64bits) o GetWindowLongPtr aparece el siguiente error:

Unable to find an entry point named 'GetWindowLongPtrA' in DLL 'user32.dll

Así no entiendo lo del MSDN. Además pone que para que sea compatible con 32bit y 64bits y ya era compatible con 32bits usando GetWindowLong normal y punto de entrada  GetWindowLongA. Ahora se también que sigue siendo compatible también a 64bits.

Y otro detalle importate. Como he mencionado en 32bits no existen las entradadas GetWindowLongPtrA y GetWindowLongPtrW ¿Por qué dice
To write code that is compatible with both 32-bit ? si dichas entradas no existen en 32 bits XD. No se puede que sea para Windows 8 o posterior o desde lenguaje C


Lo de Environment.Is64BitOperatingSystem ya me ha resultado útil y lo he añadido al código de Importar Apis  ;D. Me va genial para determinar que ProgramFiles usar.

Sl2s

[NUEVO DATO SOBRE ESTE TEMA]

Dandole vueltas al asunto y viendo que Elektro a usado la siguiente convención de llamada para GetWindoLong:
Código (vbnet) [Seleccionar]
<SuppressMessage("Microsoft.Interoperability", "CA1400:PInvokeEntryPointsShouldExist",justification:="Code-Analysis is 32-Bit so it only checks for the entrypoint in the user32.dll of the Win32 API.")><DllImport("user32.dll", EntryPoint:="GetWindowLongPtr", SetLastError:=True)>Public Shared Function GetWindowLongPtr(ByVal hwnd As IntPtr,          <MarshalAs(UnmanagedType.I4)> ByVal nIndex As WindowLongFlags) As IntPtrEnd Function

Me he preguntado ¿Y si mi apliación se está ejecutando con compatibilidad en X86 o como si se ejecutara en X86?

Así que me he dirigido a la configuración de mi proyecto haciendo doble click en My Project  en el Explorador de soluciones y en 'Compilar'
he visto que ponía CPU Destino = X86  y lo he cambiado a X64. He cambiado la llamada a GetWindowLong usando el punto de control GetWindowLongPtrA y sin suprimir errores:

Código (vbnet) [Seleccionar]
 <DllImport("user32.dll", EntryPoint:="GetWindowLongPtrA", SetLastError:=True)> _
   Public Function GetWindowLong(ByVal hwnd As IntPtr, _
    <MarshalAs(UnmanagedType.I4)> ByVal nIndex As Integer) As IntPtr
   End Function


Y NO me da error. Encuentra el punto de entrada  y el programa funciona perfecdtamente. Vuelvo a cambiar a  CPU Destino = X86 y denuevo me dice que no encuentra el punto de entrada.

Entonces llego a la conclusión que la llamada debe hacerse según como compiles el programa y no en el hecho que se ejecute en 32bits o 64bits. De modo que si lo compilo para 64bits y CPU Destino = X64 y llamo al punto de entrada GetWindowLongPtrA sólo será compatible con 64bits. Sin embargo si hago la llamada al punto de entrada GetWindowLongA es compatible en ambos.

Lekim

Otra forma de cambiar el estilo de una ventana...

Código (vbnet) [Seleccionar]
Public Class Form1
    Const WS_VSCROLL As Integer = &H200000
    Const WS_HSCROLL As Integer = &H100000
    Const WS_DISABLED As Integer = &H8000000

    Enum Style_Window
        FLAT = &H0
        NOBORDER_3D = &H400000 '3d sin bordes
        NOTITLEBAR = &H40000 'con bordes sin barra de título
        FLAT_3D = &H800000 'Flat style con línea externa
        BORDER_NOTITLEBAR_SCROLLBAR = &HBEBC20 'con bordes sin barra de título con ScrollBAr
        NOBUTTONSBAR = &HC00000 'sin botones en la barra y no redimensionable
        NOBUTTONSBAR_RESIZABLE = &HC50000 'sin botones en la barra y  redimensionable
        TYPE_MSGBOX = &HC89500 'solo boton cerrar no redimensionable (tipo msgbox)
        TYPE_MSGBOX_NOMIN = &HC99500 'Cerrar + max no redimensionable (tipo msgbox)
        TYPE_MSGBOX_NOMAX = &HCA0000 'Cerrar + min no redimensionable (tipo msgbox)
        TYPE_MSGBOX_ALLBUTTONS = &HCB0000 'todo no redimensionable
        ONLY_CLOSEBUTTON = &HCC0000 'Solo botón Cerrar redimensionable
        ONLY_CLOSE_MAX = &HCD0000 'Cerrar + max redimensionable
        ONLY_CLOSE_MIN = &HCE0000 'Cerrar + min redimensionable
        ALLBUTTONS_RESIZABLE = &HCF0000  'redimensionable
        SCROLLBARS = WS_VSCROLL + WS_HSCROLL
    End Enum
    Enum ExStyle_Window
        BIGBORDER = &H200  'borde ancho
        NORMAL_TITLE_LEFT = &H0 'título a la izquierda
        NORMAL_TITLE_RIGHT = &H1000  'título a la derecha
        INVERT_TITLE_LEFT = &H405000  'Invertido con título a la izquierda
        INVERT_TITLE_RIGHT = &H400000  'Invertido con título a la derecha
        TOOLWINDOW_BIGBORDER_TITLELEFT = &H102390 'Tool window con título a la izquierda y borde grueso
        TOOLWINDOW_BIGBORDER_TITLERIGHT = &H103390 'Tool window con título a la derecha y borde grueso
        TOOLWINDOW_TITLELEFT = &H102490 'Tool window Invertido con título a la izquierda y borde fino
        TOOLWINDOW_TITLERIGHT = &H103490 'Tool window invertido con título a la derecha y borde fino
        TOOLWINDOWS_INVERT_TITLELEFT = &H401080 'Tool window Invertido con título a la izquierda y borde fino
        TOOLWINDOWS_INVERT_TITLERIGHT = &H400180 'Tool window invertido con título a la derecha y borde fino
        TOOLWINDOWS_INVERT_BIGBORDER_TITLELEFT = &H403390 'Tool window Invertido con título a la izquierda y borde grueso
        TOOLWINDOWS_INVERT_BIGBORDER_TITLERIGHT = &H400290 'Tool window invertido con título a la derecha y borde grueso
    End Enum
    Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
        Get
            Dim cp As CreateParams = MyBase.CreateParams
            'cp.Style = cp.Style Or Style_Window.SCROLLBARS
            cp.ExStyle = ExStyle_Window.TOOLWINDOWS_INVERT_TITLERIGHT
            Return cp
        End Get
    End Property
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
    End Sub
End Class