Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 05-11-2012
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Probando la función RealGetWindowClass

Un favor. Les estaré agradecido si pudieran realizar esta sencilla prueba en Delphi de la función de la API de Windows RealGetWindowClass y decirme qué resultado les arroja en pantalla:

Código Delphi [-]
Function BaseClassName (Const Window :THandle) :String;
Var
  Name :Array [0..255] Of Char;
Begin
  SetString (Result, Name,
    RealGetWindowClass (Window, Name, Length (Name)));
End;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage (BaseClassName (Button1.Handle));
end;

En mi caso y con Windows XP, la cadena que devuelve BaseClassName es 'Button'. Me interesa conocer si esto será así en todas las versiones de Windows, o si en algunos casos Windows pudiera devolver la cadena totalmente en mayúsculas.

La duda me surge a raíz de que toda la documentación oficial sobre las clases predefinidas de Windows, refieren a éstas con letras mayúsculas (BUTTON, EDIT, COMBOBOX, etcétera). Quiero estar seguro de que si RealGetWindowClass devuelve "Button", entonces siempre será "Button" y no a veces "BUTTON".

Muchas gracias, saludos.
Responder Con Cita
  #2  
Antiguo 05-11-2012
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola Al.
  • Windows Vista : Button
  • Windows 7 : Button

Saludos.
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #3  
Antiguo 05-11-2012
[egostar] egostar is offline
Registrado
 
Registrado: feb 2006
Posts: 6.556
Poder: 25
egostar Va camino a la fama
Hola Alberto

[Window Title]
Project1
[Content]
TButton
[OK]

Windows 7, Delphi XE2 y XE3

Saludos
__________________
"La forma de empezar es dejar de hablar y empezar a hacerlo." - Walt Disney
Responder Con Cita
  #4  
Antiguo 05-11-2012
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Poder: 21
nlsgarcia Tiene un aura espectacularnlsgarcia Tiene un aura espectacular
[Al González],

En Windows XP Professional SP3 x32 la función BaseClassName retorna : Button

En Windows 7 Professional SP1 x32 la función BaseClassName retorna : Button

En Windows 7 Professional x64 la función BaseClassName retorna : Button

Espero sea útil

Nelson.
Responder Con Cita
  #5  
Antiguo 05-11-2012
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Gracias ecfisa, Eliseo y Nelson.

Eliseo: Me llamó la atención tu resultado. Acabo de hacer la prueba en XE2 y Delphi 2007, y en efecto, me da 'TButton' cuando en Delphi 7 arroja 'Button'.

Esto podría significar que algo cambió en la VCL respecto a la forma de hacer superclasificación. Con esto le sale otro tentáculo al problema que intento solucionar, ya que pensé que sólo habría de preocuparme el asunto de las mayúsculas y minúsculas, y casi daba por hecho que RealGetWindowClass serviría para obtener el nombre de la clase Windows sobre la que se basan algunos controles.

Trato de encontrar el mecanismo por el cual, teniendo un identificador de ventana Windows (HWND) que no necesariamente sea de un objeto Delphi, pueda determinar si ese identificador es de un botón de presión normal, un cuadro de verificación (check box), un botón de radio (radio button), u otro tipo de objeto. Una dificultad estriba en que los tres primeros tipos de controles comparten en Windows la misma clase: "Button", pero se resolvería apoyándome en la función GetWindowLong con el parámetro gwl_Style para saber cuál de los tres tipos es. No podría usar solamente ésta última, porque las constantes de estilo comparten valor entre diferentes tipos de objetos Windows.

Lo primero es determinar si un Handle dado es "Button" o no es "Button". GetClassName no sirve para eso con objetos Delphi y de otros lenguajes, ya que devuelve el nombre que una clase de componente registra en Windows (TButton, TCheckBox, TRadioButton). Como es de suponerse, estos nombres no son de fiar para determinar lo que se busca (podría haber un componente TColorCheckBox y no por que diga "CheckBox" significa que sea un cuadro de verificación). En cambio, y al menos en Delphi 7, RealGetWindowClass devuelve el nombre de la clase base, que por lo general es nativa de Windows y eso da cierta certeza.

Pero ahora veo que Delphi 2007 o alguna versión anterior cambió esta regla y no será posible usar RealGetWindowClass...¿no será un "bug"? Lo sé, debí poner un título más descriptivo y empezar por detallar el objetivo, pero como creí que sólo iba a ser una cuestión de mayúsculas y minúsculas...

Vamos a descansar, habrá de ocurrírsenos algo...

Última edición por Al González fecha: 05-11-2012 a las 09:46:23.
Responder Con Cita
  #6  
Antiguo 05-11-2012
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Encontré que la función de Windows GetClassInfo podría ser la culpable, o más bien señalar al culpable. GetClassInfo trabaja de manera distinta si se activa la opción de proyecto Enable runtime themes.

Cuando se compila con esa opción, la cadena que devuelve RealGetWindowClass es 'TButton' y cuando no, la cadena devuelta es 'Button' (la que espero obtener). Esto ocurre porque momentos antes se llama a GetClassInfo para llenar una estructura WNDCLASS (lo cual es normal), pero el campo lpfnWndProc de esta estructura queda con un valor diferente al esperado cuando se utilizan "temas". Los invito a hacer nuevamente la prueba de antes con y sin temas.

Toca indagar más sobre esta característica y ver qué tanto obstaculiza obtener la clase base de un HWND...

Saludos y gracias nuevamente.
Responder Con Cita
  #7  
Antiguo 05-11-2012
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por Al González Ver Mensaje
Esto ocurre porque momentos antes se llama a GetClassInfo para llenar una estructura WNDCLASS
¿Momentos antes de qué?

// Saludos
Responder Con Cita
  #8  
Antiguo 06-11-2012
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Cita:
Empezado por roman Ver Mensaje
¿Momentos antes de qué?
Momentos antes de la prueba del primer mensaje (admito que la frase fue ambigua).

Esto se explica porque para hacer superclasificación (el enlace de mi segundo mensaje), se recurre en primer lugar a la función GetClassInfo para obtener información de la clase ya registrada sobre la cual se quiere crear una "derivada". No hablo de clases de objetos propiamente, sino de lo que Microsoft llama window class en el ámbito de su sistema operativo

En Delphi, esa llamada a GetClassInfo ocurre desde el método TWinControl.CreateSubClass al crearse objetos como TEdit, TButton, TCheckBox, etcétera.

Código Delphi [-]
procedure TCustomCheckBox.CreateParams(var Params: TCreateParams);
const
  Alignments: array[Boolean, TLeftRight] of DWORD =
    ((BS_LEFTTEXT, 0), (0, BS_LEFTTEXT));
begin
  inherited CreateParams(Params);
  CreateSubClass(Params, 'BUTTON');
  with Params do
  begin
    Style := Style or BS_3STATE or
      Alignments[UseRightToLeftAlignment, FAlignment];
    WindowClass.style := WindowClass.style and not (CS_HREDRAW or CS_VREDRAW);
  end;
end;
Código Delphi [-]
procedure TButton.CreateParams(var Params: TCreateParams);
const
  ButtonStyles: array[Boolean] of DWORD = (BS_PUSHBUTTON, BS_DEFPUSHBUTTON);
begin
  inherited CreateParams(Params);
  CreateSubClass(Params, 'BUTTON');
  Params.Style := Params.Style or ButtonStyles[FDefault];
end;

Es decir, nuestro "botón de indias" Button1 es creado (al crearse el formulario, como es habitual), y luego lo presionamos con el fin de probar la función RealGetWindowClass. Pero el "daño" ya está hecho para entonces debido a lo que previamente regresó GetClassInfo, especialmente el campo lpfnWndProc de la estructura WNDCLASS. El valor de este campo queda relacionado de cierta forma con el objeto y eso es determinante, por lo que veo, para la cadena que regresa más tarde RealGetWindowClass.

El procedimiento al que apunta lpfnWndProc es uno cuando se usan "temas" y otro cuando no se usan. Tras llamar a GetClassInfo, lpfnWndProc es el Window Procedure de la clase que hemos consultado.

Perdón por tanto rollo. Cuando tenga todas las piezas veré si puedo ponerlo "en limpio".
Responder Con Cita
  #9  
Antiguo 06-11-2012
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Al, como has hablado de "otros lenguajes de programación y tal..." ¿has pensado en suites de componentes?, Por ejemplo los jfControls definen un panel donde pintar, y a partir de ahí crean sus checkboxes (con imágenes definidas por el usuario), stringgrids, botones, grids, etc. todo desde la base de un panel.

Saludos y siento ser un agua fiestas
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
  #10  
Antiguo 06-11-2012
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Cita:
Empezado por Lepe Ver Mensaje
Al, como has hablado de "otros lenguajes de programación y tal..." ¿has pensado en suites de componentes?, Por ejemplo los jfControls definen un panel donde pintar, y a partir de ahí crean sus checkboxes [...] Saludos y siento ser un agua fiestas
Hola Lepe, no aguas ninguna fiesta.

Vaya que he considerado los componentes de terceros. Hasta ahora las pruebas que he realizado incluyen a los "cx" (Developer Express). Y desde el comienzo era de esperarse que la función RealGetWindowClass no fuese suficiente.

Hablando de esa función, en el camino encontré interesantes textos que no tienen desperdicio, como los siguientes:

The history of the Windows XP common controls

What's up with RealGetWindowClass()? » Forum Post by Ian Hanschen

De momento emplearé una solución "mixta", apoyada en:

1. La función de Windows RealGetWindowClass.- Para intentar obtener la clase base.
2. La función de Delphi FindControl.- Para obtener la instancia Delphi asociada a un HWND (cuando la haya) y comprobarla con el operador Is.

Y la que quizá sea la "solución diplomática" a todo esto:

3. Enviar a la ventana el mensaje estándar wm_GetDlgCode, que como respuesta "debe" regresar una combinación de las constantes:

DLGC_WANTARROWS = 1; { Control wants arrow keys }
DLGC_WANTTAB = 2; { Control wants tab keys }
DLGC_WANTALLKEYS = 4; { Control wants all keys }
DLGC_WANTMESSAGE = 4; { Pass message to control }
DLGC_HASSETSEL = 8; { Understands EM_SETSEL message }
DLGC_DEFPUSHBUTTON = $10; { Default pushbutton }
DLGC_UNDEFPUSHBUTTON = $20; { Non-default pushbutton }
DLGC_RADIOBUTTON = $40; { Radio button }

DLGC_WANTCHARS = $80; { Want WM_CHAR messages }
DLGC_STATIC = $100; { Static item: don't include }
DLGC_BUTTON = $2000; { Button item: can be checked }

Si el tercer punto se cumpliera siempre en los componentes de terceros (en mi opinión siempre debería responderse con la verdad al mensaje wm_GetDlgCode), los puntos 1 y 2 serían innecesarios. Pero sabiendo que algunos componentes de terceros no respetan del todo ese mensaje estándar, yo tampoco los respetaré demasiado; a lo mucho les ayudaré a "mostrar lo que son" empleando los otros dos mecanismos como refuerzo.

Parece que salvaremos el día.

Saludos.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Probando el emsamblador de Delphi Mav API de Windows 8 28-03-2008 06:51:13
Probando el ensamblador de Delphi 2 Mav Varios 5 31-10-2007 04:15:33


La franja horaria es GMT +2. Ahora son las 22:41:45.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi