Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ to Delphi: variable in FOR loop with assigned declaration

What is the equivalent in Delphi for this for loop around ChildWindowFromPoint() from this C++ code:

HWND  hWnd;
POINT point;

...

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

My attempt was this, but I'm not sure that it is right:

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;
like image 221
BrowJr Avatar asked Dec 22 '22 22:12

BrowJr


1 Answers

Your translation is almost correct, but you did make one mistake. You need to move the initial assignment of currHwnd outside of the while loop:

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;

Per for loop on cppreference.com:

formal syntax:

attr(optional) for ( init-statement condition(optional) ; iteration_expression(optional) ) statement

informal syntax:

attr(optional) for ( declaration-or-expression(optional) ; declaration-or-expression(optional) ; expression(optional) ) statement

attr(C++11) - any number of attributes

init-statement - either

  • an expression statement (which may be a null statement ";")

  • a simple declaration, typically a declaration of a loop counter variable with initializer, but it may declare arbitrary many variables

    Note that any init-statement must end with a semicolon ;, which is why it is often described informally as an expression or a declaration followed by a semicolon.

condition - either

  • an expression which is contextually convertible to bool. This expression is evaluated before each iteration, and if it yields false, the loop is exited.

  • declaration of a single variable with a brace-or-equals initializer. the initializer is evaluated before each iteration, and if the value of the declared variable converts to false, the loop is exited.

iteration_expression - any expression, which is executed after every iteration of the loop and before re-evaluating condition. Typically, this is the expression that increments the loop counter

statement - any statement, typically a compound statement, which is the body of the loop

Explanation

The above syntax produces code equivalent to:

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

That being said, I would have translated the C++ loop into a Delphi repeat..until loop (and written the C++ code to use a do..while loop):

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);
like image 119
Remy Lebeau Avatar answered Jan 22 '23 05:01

Remy Lebeau