Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
 Как узнать включен ли Aero в Window 7/Vista  [new]
zark
Member

Откуда: Киев
Сообщений: 254
Гугл дает много ссылок практически с идентичным кодом, как узнать сабж. Например такой:
function  ISAeroEnabled: Boolean;
type
  _DwmIsCompositionEnabledFunc = function(IsEnabled: PBoolean): HRESULT; stdcall;
var
  Flag                       : Boolean;
  DllHandle                  : THandle;
  OsVersion                  : TOSVersionInfo;
  DwmIsCompositionEnabledFunc: _DwmIsCompositionEnabledFunc;
begin
  Result:=False;
  ZeroMemory(@OsVersion, SizeOf(OsVersion));
  OsVersion.dwOSVersionInfoSize := SizeOf(TOSVERSIONINFO);

  if ((GetVersionEx(OsVersion)) and (OsVersion.dwPlatformId = VER_PLATFORM_WIN32_NT) and (OsVersion.dwMajorVersion >= 6)) then 
  begin
      DllHandle := LoadLibrary('dwmapi.dll');
      if DllHandle <> 0 then begin
        @DwmIsCompositionEnabledFunc := GetProcAddress(DllHandle, 'DwmIsCompositionEnabled');
        if (@DwmIsCompositionEnabledFunc <> nil) then
        begin
          if DwmIsCompositionEnabledFunc(@Flag) = S_OK then
            Result:=Flag;
        end;

        FreeLibrary(DllHandle);
      end;
  end;
end;


Казалось бы ничего такого, что должно вызвать проблемы нет. Но, этот код иногда срабатывает нормально, а иногда приводит к крешу приложения. Try-except-ы не помогают. Может кто-то уже встречался с такой проблемой и знает другие способы узнать сабж.
6 дек 11, 17:20    [11715055]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать включен ли Aero в Window 7/Vista  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 9740
_DwmIsCompositionEnabledFunc = function(IsEnabled: PBOOL): HRESULT; stdcall;
А еще лучше
_DwmIsCompositionEnabledFunc = function(out IsEnabled: BOOL): HRESULT; stdcall;
6 дек 11, 17:28    [11715158]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать включен ли Aero в Window 7/Vista  [new]
zark
Member

Откуда: Киев
Сообщений: 254
_Vasilisk_,

спасибо, так тоже пробовал, та же проблема. Найти бы другой способ....
6 дек 11, 18:22    [11715728]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать включен ли Aero в Window 7/Vista  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 9740
zark
спасибо, так тоже пробовал, та же проблема. Найти бы другой способ....
Не верю. Ошибка у Вас именно в этом. Объявите функцию именно так
_DwmIsCompositionEnabledFunc = function(out IsEnabled: BOOL): HRESULT; stdcall;
и все
6 дек 11, 19:11    [11716156]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать включен ли Aero в Window 7/Vista  [new]
Maxim Rusov
Member

Откуда: Москва-Питер
Сообщений: 2387
_Vasilisk_
Не верю. Ошибка у Вас именно в этом. Объявите функцию именно так и все

Это маловероятно. Boolean переменная на стеке занимает те же 4 байта что и LongBool. Т.ч. проблем с этим быть не должно...
6 дек 11, 19:14    [11716175]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать включен ли Aero в Window 7/Vista  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 9740
Maxim Rusov
Это маловероятно. Boolean переменная на стеке занимает те же 4 байта что и LongBool. Т.ч. проблем с этим быть не должно...
А куда адрес такого булеана показывает? на первый байт или последний?
6 дек 11, 19:30    [11716294]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать включен ли Aero в Window 7/Vista  [new]
Maxim Rusov
Member

Откуда: Москва-Питер
Сообщений: 2387
На первый, конечно. У нас же little-endian.
6 дек 11, 19:41    [11716357]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать включен ли Aero в Window 7/Vista  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 9740
Maxim Rusov
На первый, конечно. У нас же little-endian.
На последний. Дамп стека примерно такой получается для Boolean
0: R
1: R
2: R
3: V
и для BOOL
0: V
1: V
2: V
3: V
(R - reserved, V - непосредственно значение). Вроде как по 4 байта. НО! адрес переменной Boolean будет 3, а BOOL - 0. Теперь функция получает некоторый адрес и считает, что ей передали указатель на 4 байта. Т.е. для BOOL будут использованы байты 0-3, а для Boolean: 3-6. Разницу видишь?
6 дек 11, 19:51    [11716439]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать включен ли Aero в Window 7/Vista  [new]
Maxim Rusov
Member

Откуда: Москва-Питер
Сообщений: 2387
_Vasilisk_,

Не тормози. Младший байт - в младших адресах.
6 дек 11, 19:58    [11716483]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать включен ли Aero в Window 7/Vista  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 9740
Maxim Rusov
Не тормози. Младший байт - в младших адресах.
Перед тем как ответить специально проверил. Байт булеана в стеке лежит в старшем адресе
6 дек 11, 20:08    [11716547]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать включен ли Aero в Window 7/Vista  [new]
__Avenger__
Member

Откуда:
Сообщений: 1956
dwmapi.pas, Delphi XE:
function DwmIsCompositionEnabled(var pfEnabled: BOOL): HResult; stdcall;
6 дек 11, 22:01    [11717259]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать включен ли Aero в Window 7/Vista  [new]
Maxim Rusov
Member

Откуда: Москва-Питер
Сообщений: 2387
Вообще, признаю, был не прав. Boolean (byte, word) не выравниваются в стеке. Несколько byte подряд получают соседние адреса. Плохо, на самом деле, так как ухудшается быстродействие... Проверял на D5, может на новых по другому...
6 дек 11, 22:14    [11717341]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать включен ли Aero в Window 7/Vista  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 9740
Это нормальное поведение. Пример
TRec1 = record
  F1: Byte;
end;

TRec2 = record
  F1: Byte;
  F2: Integer;
end;

TRec3 = record
  F1: Byte;
  F2: Byte;
  F3: Integer;
end;

TRec4 = record
  F1: Byte;
  F2: Integer;
  F3: Byte;
end;

SizeOf(TRec1) = 1;
SizeOf(TRec2) = 8;
SizeOf(TRec3) = 8;
SizeOf(TRec4) = 12;
это с выравниванием по границе 4 байт
6 дек 11, 22:55    [11717650]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать включен ли Aero в Window 7/Vista  [new]
Квейд
Member

Откуда: Kyiv, Ukraine
Сообщений: 4991
zark
Гугл дает много ссылок практически с идентичным кодом, как узнать сабж. Например такой:
function  ISAeroEnabled: Boolean;
type
  _DwmIsCompositionEnabledFunc = function(IsEnabled: PBoolean): HRESULT; stdcall;
var
  Flag                       : Boolean;
  DllHandle                  : THandle;
  OsVersion                  : TOSVersionInfo;
  DwmIsCompositionEnabledFunc: _DwmIsCompositionEnabledFunc;
begin
  Result:=False;
  ZeroMemory(@OsVersion, SizeOf(OsVersion));
  OsVersion.dwOSVersionInfoSize := SizeOf(TOSVERSIONINFO);

  if ((GetVersionEx(OsVersion)) and (OsVersion.dwPlatformId = VER_PLATFORM_WIN32_NT) and (OsVersion.dwMajorVersion >= 6)) then 
  begin
      DllHandle := LoadLibrary('dwmapi.dll');
      if DllHandle <> 0 then begin
        @DwmIsCompositionEnabledFunc := GetProcAddress(DllHandle, 'DwmIsCompositionEnabled');
        if (@DwmIsCompositionEnabledFunc <> nil) then
        begin
          if DwmIsCompositionEnabledFunc(@Flag) = S_OK then
            Result:=Flag;
        end;

        FreeLibrary(DllHandle);
      end;
  end;
end;


Казалось бы ничего такого, что должно вызвать проблемы нет. Но, этот код иногда срабатывает нормально, а иногда приводит к крешу приложения. Try-except-ы не помогают. Может кто-то уже встречался с такой проблемой и знает другие способы узнать сабж.
Этот код не приводит к крешу приложения, ищи причину в другом месте.
6 дек 11, 23:21    [11717776]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать включен ли Aero в Window 7/Vista  [new]
Maxim Rusov
Member

Откуда: Москва-Питер
Сообщений: 2387
_Vasilisk_
Это нормальное поведение.

Выравнивание в структурах управляется опцией {$Align}. А вот выравнивание переменных на стеке - ничем не управляется (вроде). В общем по мне - такая упаковка весьма сомнительна. Получается что эффективность кода сильно зависит от того в каком порядке описаны локальные переменные. Фигня с.
6 дек 11, 23:33    [11717842]     Ответить | Цитировать Сообщить модератору
 Re: Как узнать включен ли Aero в Window 7/Vista  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 9740
Maxim Rusov,

На самом деле все правильно. Четырехбайтовые переменные выравниваются по границе четырех байт, двухбайтовые - двух, однобайтовые не выравниваются. Хочешь оптимальности - BOOL и Integer тебе в помощь
7 дек 11, 00:31    [11718074]     Ответить | Цитировать Сообщить модератору
Все форумы / Delphi Ответить