Cambiar el ClassName de un formulario

Iniciado por Lekim, 2 Marzo 2016, 16:09 PM

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

Lekim

Hola

Es algo que se ha preguntado mucho pero que parece no haber respuesta y es como cambiar el ClassName de un formulario VB.

He comprobado el ClassName de todas las aplicaciones que tengo y jamás me ha aparecido el ThunderRT6... o WindowsForms10.Window.8... típico de formularios de VB. Luego ¿Nadie programa con VB? Con el viejo VB6 no se podía, ¿ahora tampoco? O es que VB es solo para memos  :¬¬


S2s

kub0x

#1
En C++ cuando creas una instancia de una ventana puedes registrar el nombre de su clase con la API RegisterClassEx antes de llamar a CreateWindowEx. Supongo que es algo que hace el framework por defecto al crear la instancia de tu Windows Form.

Aunque con SetWindowLongPtr he llegado a cambiar hasta el bucle de eventos por el mío propio, así que como la MSDN dice, SetWindowLongPtr sirve para cambiar aspectos de la ventana especificada. También tienes SetClassLongPtr que te permite cambiar atributos de la estructura WNDCLASSEX, estructura que tiene un campo para el nombre de la clase. Así que supongo que por ahí van los tiros. Suele ser una práctica implementada en packers o programas que ocultan la traza del lenguaje en el que fue codeada la aplicación.

Saludos!
Viejos siempre viejos,
Ellos tienen el poder,
Y la juventud,
¡En el ataúd! Criaturas Al poder.

Visita mi perfil en ResearchGate


Lekim

#2
Bueno, en realidad también se puede hacer lo mismo en VB que en C++ siempre y cuando crees una ventana mediante CreateWindowEx e iniciando la aplicación desde Sub Main (en vb6 no he probado en .Net). En tal caso es cuando se puede usar RegisterClassEx.

Pero entonces no vale la pena programar con VB para eso yo me pasaría a C /C++ diréctamente. Lo bueno de VB es la facilidad de entorno de programación, la facilidad del diseño gráfico y el no tener que crear ventanas, ni controles mediante código.




Eleкtro

#3
Cita de: Lekim en  2 Marzo 2016, 16:09 PMHe comprobado el ClassName de todas las aplicaciones que tengo y jamás me ha aparecido el ThunderRT6... o WindowsForms10.Window.8... típico de formularios de VB. Luego ¿Nadie programa con VB?

La conclusión a la que has llegado no es acertada, el "prefijo" WindowsForms10 del nombre de la clase de ventana se refiere a la versión de la tecnología Windows Forms (10), y esto a su vez indica que se trata de una app que está desarrallada bajo cualquier lenguaje soportado por dicha tecnología (como por ejemplo C#), no tiene por que ser Vb.Net, por ende, no tiene sentido pensar que nadie programa en Vb.Net (o C#) solamente por no encontrar ese tipo de classname en las aplicaciones instaladas en un PC cualquiera.




Para Microsoft, cada ventana debe tener un nombre de clase de ventana único para evitar colisiones con otros nombres de clase de ventana en otros procesos, es por ese motivo que en la implementación de WindowsForms los nombres de classes se autogeneran dinamicamente siguiendo estas reglas de identificación de ventana:

<windowsformsversion>.<windowstyle>.app<hexappdomainhash>

No es posible asignar un nombre distinto de forma arbitraria, pero por otro lado, para la mayoría de classes que implementan la interfáz IWin32Window (como Form, o Control) se puede hackear el identificador del estilo de ventana (<windowstyle>) de forma sencilla mediante el uso de la propiedad que controla los parámetros de la ventana, conocida como CreateParams), de la siguiente manera:

Código (vbnet) [Seleccionar]
Public NotInheritable Class Form2 : Inherits Form

   Protected Overrides ReadOnly Property CreateParams As CreateParams
       Get
           MyBase.CreateParams.ClassName = "BUTTON" ' WindowsForms10.BUTTON.app***
           Return MyBase.CreateParams
       End Get
   End Property
 
End Class



También podemos crear una simple ventana Win32 y podemos registrar un nombre de clase para dicha ventana con la función RegisterClassEx de la API de Microsoft Windows como ya ha mencionado el compañero @Kub0x (aunque basicamente esto en realidad es una colección de valores o flags que determinan el estilo de ventana), es algo más tedioso, así que he buscado un ejemplo ya desarrollado para mostrar:

PD: En WPF, UWP, y otras tecnologías de Microsoft, imagino que la mecánica o estructura de los classnames será más o menos la misma que en Windows Forms, no me he llegado a fijar nunca en si hay un patrón, pero no hay motivo para pensar lo contrario.

Saludos!








Lekim

#4
Cita de: Eleкtro en  3 Marzo 2016, 17:17 PM
WindowsForms10 del nombre de la clase de ventana se refiere a la versión de la tecnología Windows Forms (10),

Obvio , y si es la versión VB56 pues será WindowsForms56 pero aún falta mucho para eso XD. Se entiende que son ejemplos...

Cita de: Eleкtro en  3 Marzo 2016, 17:17 PM
se puede hackear el identificador del estilo de ventana (<windowstyle>) de forma sencilla mediante el uso de la propiedad que controla los parámetros de la ventana, conocida como CreateParams), de la siguiente manera:

Este método ya lo conocía, si no recuerdo mal colgué el mismo método para cambiar los estilos del form. Pero cambiar solo WindowsForms10.MyForm... o lo que sea pues no me sirve, pero se agradece el ejemplo.

http://foro.elhacker.net/net/cambiar_estilo_de_las_ventanas_invertir_quitar_botones_bloquear_etc-t444898.0.html

También podemos crear una simple ventana Win32 y podemos registrar un nombre de clase para dicha ventana con la función RegisterClassEx

Bien, eso es lo que he comentado yo, pero para eso no vale la pena, según me parecer programar con VB. Por lo que ya he explicado. En su día lo hacía con VB6 iniciando desde Sub Main, pero como he dicho no he probado con VB.Net. De hecho cuando empecé hace poco en VB.Net, esperaba no tener que usar RegisterClassEx y no tener que crear mi propia ventana.

Método con VB6:
http://visualbasic.happycodings.com/api-and-miscellaneous/code12.html


Código (vb) [Seleccionar]
Private Sub CreateForm()
   Const CLASSNAME = "Custom_Form"
   Const TITLE = "TITLE"
   
   Dim lhwndWindow As Long, lHwndLabel As Long
   
   Dim tCreate As CREATESTRUCT
   Dim tWinClass As WNDCLASSEX
   Dim tMessage As MSG

'....

   'Create a window
   lhwndWindow = CreateWindowEx(0&, CLASSNAME, TITLE, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0&, 0&, App.hInstance, 0&)



En este ejemplo el Form tendría com nombre de clase Custom_Form

Sl2s