PDA

Ver la Versión Completa : Usando SetWindowLong / GetWindowLong


ecfisa
10-09-2011, 17:06:15
Hola amigos

Para quienes pueda servirle o desconozcan su uso, aquí les dejo algunas de las muchas utilidades que podemos darle a la función SetWindowLong (http://msdn.microsoft.com/en-us/library/ms633591%28v=vs.85%29.aspx).


(* Admitir sólo números *)
procedure OnlyNumber(Sender: TWinControl);
begin
SetWindowLong(Sender.Handle, GWL_STYLE,
GetWindowLong(Sender.Handle, GWL_STYLE) + ES_NUMBER);
end;

(* Centrar texto *)
procedure CenterJustifyText(Sender: TWinControl);
begin
SetWindowlong(Sender.Handle, GWL_STYLE,
GetWindowlong(Sender.Handle, GWL_STYLE) + ES_CENTER);
end;

(* Alinear a la derecha *)
procedure RightJustifyText(Sender: TWinControl);
begin
SetWindowLong(Sender.Handle, GWL_STYLE,
GetWindowLong(Sender.Handle, GWL_STYLE) + ES_RIGHT);
end;


Ejemplos de uso:

procedure TForm1.FormCreate(Sender: TObject);
begin
...
OnlyNumber(Edit1);
CenterJustifyText(Memo1);
RightJustifyText(DBEdit1);
...
end;


Saludos. :)

Casimiro Notevi
10-09-2011, 17:55:04
Muuuy interesante, gracias :)
Espero no olvidarme cuando me haga falta :D

marcoszorrilla
10-09-2011, 18:13:09
Pues lo acabo de probar y solamente me funciona OnlyNumber.
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure OnlyNumber(Sender: TWinControl);
begin
SetWindowLong(Sender.Handle, GWL_STYLE,
GetWindowLong(Sender.Handle, GWL_STYLE) + ES_NUMBER);
end;

(* Centrar texto *)
procedure CenterJustifyText(Sender: TWinControl);
begin
SetWindowlong(Sender.Handle, GWL_STYLE,
GetWindowlong(Sender.Handle, GWL_STYLE) + ES_CENTER);
end;

(* Alinear a la derecha *)
procedure RightJustifyText(Sender: TWinControl);
begin
SetWindowLong(Sender.Handle, GWL_STYLE,
GetWindowLong(Sender.Handle, GWL_STYLE) + ES_RIGHT);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
OnlyNumber(Edit1);
CenterJustifyText(Edit2);
RightJustifyText(Edit3);
end;

end.
Un Saludo.

ecfisa
10-09-2011, 18:39:16
Hola Marcos.

Que extraño, tal vez sea la versión de Delphi aunque sería raro... , las pruebas las hice sobre Delphi 7.

Pero por si acaso aca te pongo un demo con un Edit, un Memo y un LabeledEdit que aquí esta funcionando, a ver si sucede lo mismo.

Un saludo.

ecfisa
10-09-2011, 18:52:11
Para descartar toda posibilidad de que pudiera haber cometido un error, reproduje tu prueba usando tres Edits y sigue funcionando correctamente:

http://www.imagengratis.org/images/demohu1th.jpg

A menos que esto tuviera que ver en tu caso:

"To write code that is compatible with both 32-bit and 64-bit versions of Windows, use the SetWindowLongPtr function"

Pero al menos con Delphi 7/Vista 32 no me reconoce esa función

Un saludo.

Casimiro Notevi
10-09-2011, 21:07:41
A mí me funciona sólo onlynumber :confused:
D2007

ecfisa
10-09-2011, 21:46:12
Hola Casimiro.

No pude encontrar una referencia exacta a los usos de SetWindowLong con conflictos, pero encontré varias con casos similares.
Aparentemente algunos usos sólo corren compiladas con versiones Delphi 2006 y anteriores.
Pareciera que el problema se produce por que a partir de la versión 2007, algunos controles son manejados por la VCL.

De las referencias de donde infiero esto destaco estas dos:

To remove the flicker when calling the SetWindowLong, you first hide the window then show it again using ShowWindow with parameters SW_HIDE and SW_SHOW.
Not working with Delphi 2007 :(
For applications created with Delphi 2007 the above code will not work - taskbar button will not be hidden.

( about (http://delphi.about.com/od/adptips1999/qt/hidefromtaskbar.htm))




With Delphi 2007, a new property of the Application object, the MainFormOnTaskbar property controls how Windows taskbar buttons are handled by VCL

( about (http://delphi.about.com/od/delphitips2008/qt/hide_taskbutton.htm))




Así que las funciones que puse arriba (exeptuando OnlyNumbers) aparentemente sólo funcionarían hasta la versión de Delphi 2006 (quedaría probarlas con esa versión para confirmarlo).


Un saludo.

marcoszorrilla
10-09-2011, 21:46:41
La prueba la hice con D7, ahora me he descargado tu ejemplo y me ocurre lo mismo solamente funciona OnlyNumber.

Un Saludo.

ecfisa
10-09-2011, 22:08:41
La prueba la hice con D7, ahora me he descargado tu ejemplo y me ocurre lo mismo solamente funciona OnlyNumber.

Un Saludo.

Hola Marcos.

Si no es mucho abusar de tu tiempo ¿ Podrías probar este ejecutable compilado en mi máquina ? (el archivo está limpio)

Despues de enterarme que usas Delphi 7 estoy totalmente desconcertado... ya que me a mí todas la funciones me las ejecuta correctamente. :confused::confused::confused:

Un saludo y gracias.

Edito: Y ya a esta altura estoy intrigadísimo por encontrar el motivo ... :)

marcoszorrilla
10-09-2011, 22:38:16
Acabo de ejecutarlo y ocurre lo mismo, quizás obedezca a alguna configuración relacionada con el país.....

Un Saludo.

ecfisa
10-09-2011, 22:45:09
Hola Marcos.

Muchisimas gracias por tu atención.

Voy a investigar el por qué de tán extraño comportamiento... :confused:, y les comunico cualquier novedad.

Un saludo y gracias nuevamente.:)

Casimiro Notevi
10-09-2011, 23:37:38
Yo lo he ejecutado también con wine en ubuntu y funciona sólo onlynumber.
Y ahí no tiene nada que ver windows, delphi, ni nada de eso.
Qué cosas más extrañas :)

ecfisa
11-09-2011, 00:14:34
Hola amigos.

Acabo de pasar el código fuente a un colega que tiene Delphi XE y a él también le funciona correctamente.
Cambié la configuración regional a España y de idioma a español tomando en cuenta la observación de Marcos y nada... sigue funcionando bién.
Aunque estoy convencido que Marcos le está arrimando bastante al orígen del problema ya que el ejecutable en mi máquina funciona y en la de ustedes no. ;)

Ante la imposibilidad reproducir que no funcione, ando dando palos a ciegas... :mad:

Leí por ahí que usar InvalidateRect podría ser necesario en algunos casos

procedure CenterJustifyText(Sender: TWinControl);
begin
SetWindowlong(Sender.Handle, GWL_STYLE,
GetWindowlong(Sender.Handle, GWL_STYLE) + ES_CENTER);
InvalidateRect(Sender.Handle, nil, True);
end;

Pero realmente no sé si solucionará algo por que en mi caso funciona del mismo modo.


Ojalá algún compañero pueda justificar esta diferencia de comportamiento. La verdad es que no encuentro el por qué. :confused:

Un desconcertado saludo. :)

Casimiro Notevi
11-09-2011, 00:16:36
Pasa el código fuente del proyecto para compilarlo, a ver si es algo del compilador.

ecfisa
11-09-2011, 00:26:23
Hola Casimiro.

Está en el mensaje #4, si tenés algún inconveniente para verlo lo subo nuevamente.

Un saludo.

Casimiro Notevi
11-09-2011, 01:00:04
Perdón, no me había dado cuenta, sólo había visto el ejecutable.

Lo he compilado y ejecutado, el resultado es el mismo, sólo funciona onlynumber.

He desempolvado un viejo equipo que tiene winxp y delphi 5, lo he ejecutado y sólo funciona onlynumber.
:confused::confused::confused:

nlsgarcia
15-09-2011, 16:15:31
Hola ecfisa:

Usando Delphi 7 Enterprise en un PC con Windows XP SP3 en ingles, solo funciona ES_NUMBER.

Usando Delphi 7 Enterprise en un PC con Windows 7 Professional en ingles, todo funciona.

Usando Delphi 7 Enterprise en un PC con Windows Vista Home Premium SP2 en Español, todo funciona.

Por ser un API el funcionamiento depende del OS : http://www.delphi3000.com/articles/article_3833.asp?SK=SetWindowLong

¿Que OS tienen los PC donde funciono?

Como nota adicional pruebas con los Edit styles : ES_PASSWORD, ES_READONLY y ES_UPPERCASE no funcionaron en ninguno de los anteriores OS.

Ver estos links:

http://www.delphigroups.info/3/3/144938.html
http://www.autohotkey.com/docs/misc/Styles.htm#Edit

Saludos,

Nelson.

Enan0
15-09-2011, 16:24:35
acabo de testear el archivo compilado, Sobre un windows XP Profesional (Version 2002) SP3 y funciona correctamente.

saludos.

PD:
Configuracion Regional: Español Argentina.
Numeros: Separador de miles "." de Decimales ","

saludos.