Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Trucos (https://www.clubdelphi.com/foros/forumdisplay.php?f=52)
-   -   Obtener las verdaderas coordenadas de una ventana en Windows 10 (https://www.clubdelphi.com/foros/showthread.php?t=94389)

escafandra 15-01-2020 13:39:50

Obtener las verdaderas coordenadas de una ventana en Windows 10
 
El titulo puede parecer curioso pero me torturé la cabeza cuando me di cuenta de que en Win 10 las coordenadas del TRect devuelto por la API GetWindoRect ha dejado de ser correctas. En concreto:

1.- Top es correcto
2.- Left se desplaza 7 pixels a la izquierda
3.- Right se desplaza 7 pixels a la deracha
4.- Bottom de desplaza 7 pixels hacia abajo

Curiosamente en ese marco de 7 pixels ,a API WindowFromPoint Localiza la ventana con lo que parece que ese margen que parece que no es de la ventana y que es transparente, si es la ventana. Lo que parece es que M$ ha querido hacer un efecto visual, de hecho las ventanas en Win8 son un poco mas gruesas en su margen. Lo que parece es que es una especie de herencia del Aero de Vista

Todo esto no tendría ningún interés si no quisiésemos localizar con precisión lo que realmente estamos viendo dela ventana, por ejemplo para colocar un margen que nos la localice visualmente con exactitud. Veamos una imagen:







Ahora el tema está en ver como se corrige el aparente error.

La base es la API DwmGetWindowAttribute solicitando el parámetro DWMWA_EXTENDED_FRAME_BOUNDS y nos devolverá el rectángulo visual de la ventana.


Código Delphi [-]
function  GetTrueWindowRect(hWin: HWND; var Rect: TRect): BOOL;
type
  PDwmGetWindowAttribute  = function(hWin: HWND; dwAttribute: DWORD; pvAttribute: Pointer; cbAttribute:DWORD): HRESULT; stdcall; //Dwmapi.dll
var
  hLib: HMODULE;
  _DwmGetWindowAttribute: PDwmGetWindowAttribute;
begin
  Result:= GetWindowRect(hWin, Rect);
  if Win32MajorVersion >= 6 then
  begin
    hLib:= LoadLibrary('Dwmapi.dll');
    @_DwmGetWindowAttribute:= GetProcAddress(hLib, 'DwmGetWindowAttribute');
    if @_DwmGetWindowAttribute <> nil then
      Result:= (0 = _DwmGetWindowAttribute(hWin, 9 {DWMWA_EXTENDED_FRAME_BOUNDS}, @Rect, sizeof(TRect)));
    FreeLibrary(hLib);
  end;
end;


El uso de esta función, GetTrueWindowRect, es idéntico a GetWindowRect pero el resultado será el rectángulo corregido si nuestro S.O. es Vista o superior y el clásico en los otros casos.


Saludos.

Casimiro Notevi 15-01-2020 17:13:14

Gracias por compartirlo ^\||/

kurono 16-01-2020 04:33:00

¿esto solo ocurre en windows 10? no me habia dado cuenta

escafandra 16-01-2020 08:18:51

Cita:

Empezado por kurono (Mensaje 535228)
¿esto solo ocurre en windows 10? no me habia dado cuenta

En principio sólo lo he observado en Win10. En Win8.1 Los marcos de las ventanas son muy parecidas a Win10 pero el bordes son mas gruesos. Quizás en Win10 han querido dejarlos más finos para que el efecto de poner las ventanas en paralelo, quede un espacio transparente entre ellas de 14 pixels. En Win8.1 quedarían pegadas mientras que en Win10 quedaría un espacio.

Me llamó la atención la discordancia del resultado de GetWindowRect con lo que se ve porque necesitaba enmarcar las ventanas en un proyecto, así que investigué el asunto y publico el truco.


Saludos.

Neftali [Germán.Estévez] 16-01-2020 08:20:28

Gracias.
^\||/^\||/^\||/^\||/

kurono 17-01-2020 04:10:32

aaahh#:-)##:-)# ok gracias por la explicacion^\||/^\||/^\||/

hal1967 25-01-2020 23:48:48

Muy agradecido. Esto me lleva a revisar algún código que me fallaba

Julibest 27-04-2020 07:29:19

chevre ni sabia esos trucos ^\||/

MAXIUM 27-04-2020 15:34:06

Gracias.

Esto lo podemos aunar a un código que distinga si la APP corre sobre Win10, 8.1 o 7

Neftali [Germán.Estévez] 28-04-2020 08:54:27

¿Sabemos si tiene algo que ver con los temas?
¿Si desactivo temas en Windows 10 el valor será correcto?


La franja horaria es GMT +2. Ahora son las 12:03:19.

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