Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > ОС и железо
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 08.01.2018, 06:44
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,053
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию PowerEnumerate под Win64

Есть такая функция:
Код:
function PowerEnumerate(RootPowerKey : THandle; SchemeGuid : PGUID; SubGroupOfPowerSettingsGuid : PGUID; AccessFlags: POWER_DATA_ACCESSOR; Index: ULONG; var Buffer : TGUID; var BufferSize : DWORD) : DWORD; stdcall; external 'PowrProf.dll';

Вызов:
Код:
procedure TPowerPlansList.GetPowerPlans;
const
  BufferLength : DWORD = 1024;
var
  chGuid : TGUID;
  szGuid : DWORD;
  szName : DWORD;
  chName : PChar;
  stName : String;
  Idx : Integer;
  Ret : Integer;

  PowerPlan : TPowerPlan;

  iEnum : DWORD;
begin
  FItems.Clear;
  Idx := 0;

  szGuid := SizeOf(TGUID);

  GetMem(chName,BufferLength*SizeOf(Char));

  Try
    iEnum := PowerEnumerate(0{Nil},Nil,Nil,ACCESS_SCHEME,Idx,chGuid,szGuid);
    While iEnum = 0 Do
      Begin
        // Reinitialize buffer and buffer size
        // Undocumented in MSDN: even when PowerReadFriendlyName success,
        // it overwrites buffer size
        szName := BufferLength;
        ZeroMemory(chName,BufferLength*SizeOf(Char));

        Ret := PowerReadFriendlyName(Nil,@chGuid,Nil,Nil,PUCHAR(chName),@szName);
        if Ret = 0
          Then stName := StrPas(chName)
          Else
            If Not PowerReadWellKnownFriendlyName(chGuid,stName)
              Then stName := 'Unknown plan';

        PowerPlan.Index := Idx;
        PowerPlan.Guid := chGuid;
        PowerPlan.Name := stName;
        FItems.Add(PowerPlan);

        Inc(Idx);

        iEnum := PowerEnumerate(0{Nil},Nil,Nil,ACCESS_SCHEME,Idx,chGuid,szGuid);
      End;
  Finally
    FreeMem(chName,szName*SizeOf(Char));
  End;
end;

Но тут есть такой момент. Все прекрасно работает под Win32, а под Win64 возвращает ошибку (87, вроде это про неправильный параметр).
Если у кого есть мысль что в этом коде неправильно - подскажите.
Ответить с цитированием
  #2  
Старый 08.01.2018, 10:07
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

Вот на х64 работает, на х32 нет возможности проверить - на виртуалке только WindowsXP, а там и не будет работать:

Код:
function PowerEnumerate(RootPowerKey: HKEY;
  SchemeGuid: PGUID; SubGroupOfPowerSettingsGuid: PGUID;
  AccessFlags: DWORD; Index: ULONG;
  Buffer: Pointer; var BufferSize: DWORD): DWORD;
  stdcall; external 'powrprof.dll';

function PowerReadFriendlyName(
  RootPowerKey: HKEY;
  SchemeGuid: PGUID; SubGroupOfPowerSettingsGuid: PGUID;
  PowerSettingGuid: PGUID;
  Buffer: Pointer; var BufferSize: DWORD
): DWORD; stdcall; external 'powrprof.dll';

const
  ACCESS_SCHEME = 16;

procedure TForm1.FormCreate(Sender: TObject);
var
  Buffer: TGUID;
  BufferSize: DWORD;
  LIndex: ULONG;
  LPowerEnumerate: DWORD;
  BufferName: array [0..$FF] of Char;
begin
  LIndex:=0;
  repeat
    BufferSize:=SizeOf(TGUID);
    LPowerEnumerate:=PowerEnumerate(0, nil, nil, ACCESS_SCHEME,
      LIndex, @Buffer, BufferSize);
    if LPowerEnumerate=ERROR_SUCCESS then
    begin
      Memo1.Lines.Add(GUIDToString(Buffer));
      BufferSize:=Length(BufferName);
      if PowerReadFriendlyName(0, @Buffer, nil, nil,
        @BufferName[0], BufferSize)<>ERROR_SUCCESS then RaiseLastOSError;
        Memo1.Lines.Add(BufferName);
    end;
    Inc(LIndex);
  until LPowerEnumerate<>ERROR_SUCCESS;
end;

Результат:

Цитата:
{381B4222-F694-41F0-9685-FF5BB260DF2E}
Сбалансированная
{8C5E7FDA-E8BF-4A96-9A85-A6E23A8C635C}
Высокая производительность
{A1841308-3541-4FAB-BC81-F71556F20B4A}
Экономия энергии
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #3  
Старый 08.01.2018, 11:16
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,053
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Да, вроде, код такой-же...
Ладно, проверю что там с ULong... это, по факту, единственная разница.

ЗЫ. Я все на 64-бит ОС проверял, просто сборка 32- и 64-бит. 32 работает, а 64 - нет. ОС - Win10, если что...
Ответить с цитированием
  #4  
Старый 08.01.2018, 11:25
Аватар для @Rafa3L
@Rafa3L @Rafa3L вне форума
Начинающий
 
Регистрация: 09.11.2011
Адрес: Москва
Сообщения: 144
Версия Delphi: XE2
Репутация: 11216
По умолчанию

Цитата:
Сообщение от NumLock
Вот на х64 работает...
на х32 аналогичный результат
__________________
Помогаю платно.
Помогаю иногда бесплатно.
Ответить с цитированием
  #5  
Старый 10.01.2018, 02:55
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,053
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Короче, расковыряли.
Оказывается, под 64 бита дефолтный enum не совместим с С кодом, хотя он и с 32 битным не совместим, но там почему-то работает. Либо ставим {$Z4}, либо вообще декларируем как NativeUInt и все работает.
Вот ведь...
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 12:48.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter