C ++ to Delphi: переменная в цикле FOR с назначенным объявлением - PullRequest
6 голосов
/ 13 июня 2019

Что является эквивалентом в Delphi для этого for цикла вокруг ChildWindowFromPoint() из этого кода C ++:

HWND  hWnd;
POINT point;

...

for (HWND currHwnd = hWnd;;)
{
    hWnd = currHwnd;
    ScreenToClient(currHwnd, &point);
    currHwnd = ChildWindowFromPoint(currHwnd, point);
    if (!currHwnd || currHwnd == hWnd)
        break;
}

Моя попытка была такая, но я не уверен, что это правильно:

var
  hWndWindow, currHwnd: HWND;
  MousePoint: TPoint;

...

while True do
begin
  currHwnd := hWndWindow;
  hWndWindow := currHwnd;
  ScreenToClient(currHwnd, MousePoint);
  currHwnd := ChildWindowFromPoint(currHwnd, MousePoint);

  if (currHwnd = 0) or (currHwnd = hWndWindow) then
    Break;
end;

1 Ответ

10 голосов
/ 13 июня 2019

Ваш перевод почти правильный, но вы допустили одну ошибку. Вам необходимо переместить начальное назначение currHwnd за пределы цикла while:

var
  hWndWindow, currHwnd: HWND;
  MousePoint: TPoint;

...

currHwnd := hWndWindow; // <-- moved here!
while True do
begin
  hWndWindow := currHwnd;
  ScreenToClient(currHwnd, MousePoint);
  currHwnd := ChildWindowFromPoint(currHwnd, MousePoint);

  if (currHwnd = 0) or (currHwnd = hWndWindow) then
    Break;
end;

За for цикл на cppreference.com:

формальный синтаксис:

attr (необязательно) для ( условие инициализации условие (необязательно) ; iteration_expression (опция) ) оператор

неофициальный синтаксис:

attr (необязательно) для ( объявление или выражение (необязательно) ; объявление или выражение (необязательно) ; выражение (необязательно) ) выражение

attr (C ++ 11) - любое количество атрибутов

init-Statement - либо

  • оператор выражения (который может быть нулевым оператором";")

  • простое объявление, обычно объявление переменной счетчика цикла с инициализатором, но оно может объявлять произвольное множество переменных

    Обратите внимание, что любой оператор init должен заканчиваться точкой с запятой; именно поэтому он часто неофициально описывается как выражение или объявление, за которым следует точка с запятой.

условие - либо

  • выражение, которое контекстуально можно преобразовать в bool. Это выражение вычисляется перед каждой итерацией, и если оно возвращает false, цикл завершается.

  • объявление одной переменной с инициализатором в скобках или равно. инициализатор вычисляется перед каждой итерацией, и если значение объявленной переменной преобразуется в false, цикл завершается.

iteration_expression - любое выражение, которое выполняется после каждой итерации цикла и перед повторной оценкой условие . Как правило, это выражение, которое увеличивает счетчик цикла

оператор - любой оператор, обычно составной оператор, который является телом цикла

Объяснение

Приведенный выше синтаксис создает код, эквивалентный:

{
    init_statement 
    while ( condition ) { 
        statement 
        iteration_expression ; 
    }
}

При этом я бы перевел цикл C ++ в цикл Delphi repeat..until (и написал бы код C ++ для использования цикла do..while):

HWND hWnd;
POINT point;

...

HWND currHwnd = hWnd;
do
{
    hWnd = currHwnd;
    ScreenToClient(currHwnd, &point);
    currHwnd = ChildWindowFromPoint(currHwnd, point);
}
while (currHwnd && currHwnd != hWnd);
var
  hWndWindow, currHwnd: HWND;
  MousePoint: TPoint;

...

currHwnd := hWndWindow;
repeat
  hWndWindow := currHwnd;
  ScreenToClient(currHwnd, MousePoint);
  currHwnd := ChildWindowFromPoint(currHwnd, MousePoint);
until (currHwnd = 0) or (currHwnd = hWndWindow);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...