28 апреля 2015 г.

Задачка №18Б

Это вторая часть задачки №18. Что не так с этим кодом?

procedure TForm1.Button1Click(Sender: TObject);

  function EnumWindowsProc(const AWnd: HWND; const AParam: LPARAM): BOOL; stdcall;
  var
    Wnd: HWND;
  begin
    Wnd := HWND(AParam);
    if AWnd = Wnd then
      Result := True
    else
      Result := False;
  end;

var
  Wnd: HWND;
begin
  Wnd := Handle;
  EnumWindows(@EnumWindowsProc, LPARAM(Wnd));
end;

Ответ будет (автоматически) опубликован через две недели.

Читать далее: бонус-задачка специально для _Rouse.

11 комментариев :

  1. функция перечисления должна быть вынесена из области видимости класса?

    ОтветитьУдалить
  2. 1. использование промежуточной переменной ну нужно (она все равно будет выкинута оптимизатором)
    2. практически гарантированно на первой же проверке выполнение EnumWindowsProc завершится по результату False
    Больше вроде заковык нет.

    ОтветитьУдалить
    Ответы
    1. Т.е. вообще можно написать вот так:

      procedure TForm1.Button1Click(Sender: TObject);

      function EnumWindowsProc(const AWnd: HWND; const AParam: LPARAM): BOOL; stdcall;
      begin
      Result := AWnd = HWND(AParam);
      end;

      begin
      EnumWindows(@EnumWindowsProc, LPARAM(Handle));
      end;

      А этот код чистый.

      Удалить
    2. А модификатор const не попортит картину?

      Удалить
    3. Не должен (иначе я вообще перстану все понимать :).
      Накатал анализ твоей задачки: http://alexander-bagel.blogspot.ru/2015/04/18-gunsmoker.html
      Будет смешно если ошибка даже не там где я смотрел :)

      Удалить
    4. Где-то я когда-то читал, что const передаётся по значению, если значение до 4х байт. Но не знаю, как оно ведёт себя в x64.. не привычно видеть его тут.

      Удалить
    5. Ну если в 64 битах оно идет со ссылке (с учетом что PTR лезет в регистр что там что там) - то видимо это нюанс.
      Я просто щас не могу на триалке ХЕ8 собрать 64 битный проект - почему-то требует у меня какой-то дебаг сервер запущенный на 64211 порту. Завтра на работе проверю.
      В принципе это реально первая здравая мысль, с учетом первой части вопроса :)

      Удалить
    6. проверил, const не влияет на асм код, что в 64 битах что в 32

      Удалить
    7. Все разобрался CONST не при чем, дело именно в 64 битах и в том что EnumWindowsProc находится внутри TForm1.Button1Clic (параметры AWnd и AParam приходят не верно :)

      Удалить
    8. За информацию по const - спасибо :)
      А то у меня 64х битная винда только на виртуалке, и компилятор 64х битный я не ставил (пока) принципиально.

      Удалить
    9. Незачто.
      Я, кстати, дополнил статью об анализе задачи (причины - следствия) ругательства по первому варианту кода и концовку разбора второго со стороны реверса.
      Думаю, пока полный ответ не опубликован (а думаю он будет в три строчки :), можно ознакомиться
      http://alexander-bagel.blogspot.ru/2015/04/18-gunsmoker.html

      Удалить

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и (опционально) ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

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