Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Cpp > Pas (https://www.delphipraxis.net/111058-cpp-pas.html)

Nils_13 28. Mär 2008 17:59


Cpp > Pas
 
Hi,

ich muss einen Cpp-Code übersetzen und habe Probleme mit den gegebenen Typen.
Extreme Probleme macht mir die Übersetzung von einem LPVOID und CHAR_INFO. Was ich ebensowenig herausfinden konnte ist, was ein &... bedeutet. Ich wusste einfach nicht, was ich da Google fragen sollte. Ich habe im unteren Code (Pascal) die problematischen Zeilen markiert und die Fehlermeldung dazugeschrieben. Hier die beiden Codes:
Code:
#include <windows.h>
#include <stdio.h>
 
VOID main(void)

    HANDLE hStdout, hNewScreenBuffer;
    SMALL_RECT srctReadRect;
    SMALL_RECT srctWriteRect;
    CHAR_INFO chiBuffer[160]; // [2][80];
    COORD coordBufSize;
    COORD coordBufCoord;
    BOOL fSuccess;
 
    // Get a handle to the STDOUT screen buffer to copy from and
    // create a new screen buffer to copy to.
 
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    hNewScreenBuffer = CreateConsoleScreenBuffer( 
       GENERIC_READ |           // read/write access
       GENERIC_WRITE,
       0,                      // not shared
       NULL,                   // default security attributes
       CONSOLE_TEXTMODE_BUFFER, // must be TEXTMODE
       NULL);                  // reserved; must be NULL
    if (hStdout == INVALID_HANDLE_VALUE || 
            hNewScreenBuffer == INVALID_HANDLE_VALUE)
    {
        printf("CreateConsoleScreenBuffer (%d)\n", GetLastError());
        return;
    }
 
    // Make the new screen buffer the active screen buffer.
 
    if (! SetConsoleActiveScreenBuffer(hNewScreenBuffer) )
    {
        printf("SetConsoleActiveScreenBuffer (%d)\n",
            GetLastError());
        return;
    }
 
    // Set the source rectangle.
 
    srctReadRect.Top = 0;   // top left: row 0, col 0 
    srctReadRect.Left = 0;
    srctReadRect.Bottom = 1; // bot. right: row 1, col 79 
    srctReadRect.Right = 79;
 
    // The temporary buffer size is 2 rows x 80 columns.
 
    coordBufSize.Y = 2;
    coordBufSize.X = 80;
 
    // The top left destination cell of the temporary buffer is
    // row 0, col 0.
 
    coordBufCoord.X = 0;
    coordBufCoord.Y = 0;
 
    // Copy the block from the screen buffer to the temp. buffer.
 
    fSuccess = ReadConsoleOutput( 
       hStdout,       // screen buffer to read from
       chiBuffer,     // buffer to copy into
       coordBufSize,  // col-row size of chiBuffer
       coordBufCoord, // top left dest. cell in chiBuffer
       &srctReadRect); // screen buffer source rectangle
    if (! fSuccess)
    {
        printf("ReadConsoleOutput (%d)\n", GetLastError());
        return;
    }
 
    // Set the destination rectangle.
 
    srctWriteRect.Top = 10;   // top lt: row 10, col 0 
    srctWriteRect.Left = 0;
    srctWriteRect.Bottom = 11; // bot. rt: row 11, col 79 
    srctWriteRect.Right = 79;
 
    // Copy from the temporary buffer to the new screen buffer.
 
    fSuccess = WriteConsoleOutput( 
        hNewScreenBuffer, // screen buffer to write to
        chiBuffer,       // buffer to copy from
        coordBufSize,    // col-row size of chiBuffer
        coordBufCoord,   // top left src cell in chiBuffer
        &srctWriteRect); // dest. screen buffer rectangle
    if (! fSuccess)
    {
        printf("WriteConsoleOutput (%d)\n", GetLastError());
        return;
    }
    Sleep(5000);
 
    // Restore the original active screen buffer.
 
    if (! SetConsoleActiveScreenBuffer(hStdout))
    {
        printf("SetConsoleActiveScreenBuffer (%d)\n",
            GetLastError());
        return;
    }
}
Nützliches:
Code:
HANDLE WINAPI CreateConsoleScreenBuffer(
  __in       DWORD dwDesiredAccess,
  __in       DWORD dwShareMode,
  __in_opt   const SECURITY_ATTRIBUTES* lpSecurityAttributes,
  __in       DWORD dwFlags,
  __reserved LPVOID lpScreenBufferData
);
Delphi-Quellcode:
procedure TfrmMain.Button1Click(Sender: TObject);
var hStdout, hNewScreenBuffer  : THandle;
    srctReadRect, srctWriteRect : TRect;
    coordBufSize, coordBufCoord : TPoint;
    fSuccess                   : Boolean;
    CHAR_INFO chiBuffer[160]; // [2][80]; <--
begin
  hStdout := GetStdHandle(STD_OUTPUT_HANDLE);
  hNewScreenBuffer := CreateConsoleScreenBuffer(GENERIC_READ, GENERIC_WRITE, nil, 0, CONSOLE_TEXTMODE_BUFFER, 0); <-- [Fehler] Unit1.pas(34): Inkompatible Typen: 'Integer' und 'Pointer' >>> siehe "Nützliches"

  if (hStdout = INVALID_HANDLE_VALUE) or (hNewScreenBuffer = INVALID_HANDLE_VALUE) then
    raise Exception.Create('CreateConsoleScreenBuffer: '+IntToStr(GetLastError));

  if not SetConsoleActiveScreenBuffer(hNewScreenBuffer) then
    raise Exception.Create('SetConsoleActiveScreenBuffer: '+IntToStr(GetLastError));

  srctReadRect.Top   := 0; // top left: row 0, col 0
  srctReadRect.Left  := 0;
  srctReadRect.Bottom := 1; // bottom right: row 1, col 79
  srctReadRect.Right := 79;
  // The temporary buffer size is 2 rows x 80 columns
  coordBufSize.Y := 2;
  coordBufSize.X := 80;
  // The top left destination cell of the temporary buffer is
  // row 0, col 0.
  coordBufCoord.X := 0;
  coordBufCoord.Y := 0;

  // Copy the block from the screen buffer to the temp. buffer.
  fSuccess := ReadConsoleOutput(hStdout, chiBuffer, coordBufSize, coordBufCoord, ^srctReadRect); <-- hierfür müsste ich CHAR_INFO übersetzen können, abgesehen davon könnte es noch mehr Ärger in dieser Zeile geben
  if not fSuccess then
    raise Exception.Create('ReadConsoleOutput: '+IntToStr(GetLastError));

  // Set the destination rectangle.
  srctWriteRect.Top   := 10;   // top lt: row 10, col 0
  srctWriteRect.Left  := 0;
  srctWriteRect.Bottom := 11; // bot. rt: row 11, col 79
  srctWriteRect.Right := 79;

  // Copy from the temporary buffer to the new screen buffer.
  fSuccess := WriteConsoleOutput(hNewScreenBuffer, chiBuffer, coordBufSize, coordBufCoord, ^srctWriteRect); <-- hierfür müsste ich CHAR_INFO übersetzen können, abgesehen davon könnte es noch mehr Ärger in dieser Zeile geben
  if not fSuccess then
    raise Exception.Create('WriteConsoleOutput: '+IntToStr(GetLastError));
  Sleep(5000); // Nötig ????

  // Restore the original active screen buffer.
  if not SetConsoleActiveScreenBuffer(hStdout)
    raise Exception.Create('SetConsoleActiveScreenBuffer: '+IntToStr(GetLastError));
end;

bigg 28. Mär 2008 18:05

Re: Cpp > Pas
 
Das '&' in C ist das @ in Pascal.

jbg 28. Mär 2008 18:17

Re: Cpp > Pas
 
CHAR_INFO ist in Windows.pas deklariert. Du kannst dabei auch den Alias TCharInfo nutzen.

Integer=0 => Pointer=nil

*srctReadRect ist bei Delphi srctReadRect^ (das Dächen ist hinten und nicht wie bei C/C++ vorne)


Zitat:

Sleep(5000); // Nötig ????
Das kommt darauf an, ob du es brauchst. Im C Programm wird es benutzt, damit das Programm beim Debuggen nicht sofort beendet wird.

jbg 28. Mär 2008 18:19

Re: Cpp > Pas
 
Zitat:

GetStdHandle(STD_OUTPUT_HANDLE);
Hat deine Anwendung denn auch ein Konsolenfenster?

wido 28. Mär 2008 18:21

Re: Cpp > Pas
 
Ahja, sollst ja auch was lernen bei:

Code:
CHAR_INFO chiBuffer[160]; // [2][80]; <--
Ist ein einfaches Array aus CHAR_INFO. Die Übersetzung lautet entsprechend einfach:

Delphi-Quellcode:
chiBuffer                  : array[0..159] of CHAR_INFO;
Code:
hNewScreenBuffer := CreateConsoleScreenBuffer(GENERIC_READ, GENERIC_WRITE, nil, 0, CONSOLE_TEXTMODE_BUFFER, 0); <-- [Fehler] Unit1.pas(34): Inkompatible Typen: 'Integer' und 'Pointer' >>> siehe "Nützliches"
Schau im Original Code. Da steht GENERIC_READ | GENERIC_WRITE und nicht GENERIC_READ, GENERIC_WRITE. | ist in C die Bitweise or Verknüpfung, entsprechend wird daraus:

Delphi-Quellcode:
hNewScreenBuffer := CreateConsoleScreenBuffer(GENERIC_READ or GENERIC_WRITE, 0, nil, CONSOLE_TEXTMODE_BUFFER, nil);
Auf die anderen Fehler wurdest ja bereits hingewiesen. Entsprechend hier mal das komplette Machwerk:

Delphi-Quellcode:
program Project2;

{$APPTYPE CONSOLE}

uses
  sysutils, windows;

var hStdout, hNewScreenBuffer  : THandle;
    srctReadRect, srctWriteRect : _SMALL_RECT;
    coordBufSize, coordBufCoord : _COORD;
    fSuccess                   : Boolean;
    chiBuffer                  : array[0..159] of CHAR_INFO; // [2][80]; <--
begin
  hStdout := GetStdHandle(STD_OUTPUT_HANDLE);
  hNewScreenBuffer := CreateConsoleScreenBuffer(GENERIC_READ or GENERIC_WRITE, 0, nil, CONSOLE_TEXTMODE_BUFFER, nil);

  if (hStdout = INVALID_HANDLE_VALUE) or (hNewScreenBuffer = INVALID_HANDLE_VALUE) then
    raise Exception.Create('CreateConsoleScreenBuffer: '+IntToStr(GetLastError));

  if not SetConsoleActiveScreenBuffer(hNewScreenBuffer) then
    raise Exception.Create('SetConsoleActiveScreenBuffer: '+IntToStr(GetLastError));

  srctReadRect.Top   := 0; // top left: row 0, col 0
  srctReadRect.Left  := 0;
  srctReadRect.Bottom := 1; // bottom right: row 1, col 79
  srctReadRect.Right := 79;
  // The temporary buffer size is 2 rows x 80 columns
  coordBufSize.Y := 2;
  coordBufSize.X := 80;
  // The top left destination cell of the temporary buffer is
  // row 0, col 0.
  coordBufCoord.X := 0;
  coordBufCoord.Y := 0;

  // Copy the block from the screen buffer to the temp. buffer.
  fSuccess := ReadConsoleOutput(hStdout, @chiBuffer[0], coordBufSize, coordBufCoord, srctReadRect);
  if not fSuccess then
    raise Exception.Create('ReadConsoleOutput: '+IntToStr(GetLastError));

  // Set the destination rectangle.
  srctWriteRect.Top   := 10;   // top lt: row 10, col 0
  srctWriteRect.Left  := 0;
  srctWriteRect.Bottom := 11; // bot. rt: row 11, col 79
  srctWriteRect.Right := 79;

  // Copy from the temporary buffer to the new screen buffer.
  fSuccess := WriteConsoleOutput(hNewScreenBuffer, @chiBuffer[0], coordBufSize, coordBufCoord, srctWriteRect);
  if not fSuccess then
    raise Exception.Create('WriteConsoleOutput: '+IntToStr(GetLastError));
  Sleep(5000); // Nötig ????

  // Restore the original active screen buffer.
  if not SetConsoleActiveScreenBuffer(hStdout) then
    raise Exception.Create('SetConsoleActiveScreenBuffer: '+IntToStr(GetLastError));
  readln;
end.
Compiled, macht aber gar nichts. Was sollte denn passieren? Hab keine Lust mich durch die API Dokumentation zu wühlen.

jbg 28. Mär 2008 18:32

Re: Cpp > Pas
 
Zitat:

Zitat von wido
Was sollte denn passieren?

http://msdn.microsoft.com/library/de...attributes.asp

Nils_13 28. Mär 2008 18:34

Re: Cpp > Pas
 
Zitat:

Zitat von jbg
Zitat:

GetStdHandle(STD_OUTPUT_HANDLE);
Hat deine Anwendung denn auch ein Konsolenfenster?

Nein. Dann geht das so also nicht. Hast du irgendeine Idee, wie man dennoch an die Ausgabe rankommen könnte ? Mein Ziel ist es ja, ein Programm wie TurboPascal in ein Fenster umzuleiten.
@wido: Danke, ich hätte vieles noch von früher (hatte mal etwas mit Cpp zu tun) wissen müssen, aber einiges geht dann doch wieder verloren.

An alle: Wir müssen nun aufpassen, dass wir das andere Thema nicht mit diesem vermischen. Deshalb wäre mein Vorschlag, dass wir nun falls es nichts mit der Übersetzung zu tun hat im anderen Thread weitermachen. Sonst wird das zu unübersichtlich.

turboPASCAL 28. Mär 2008 18:44

Re: Cpp > Pas
 
Zitat:

Zitat von Nils_13
Code:
Sleep(5000); // Nötig ????

Delphi-Quellcode:
program STDINOUT_DMO;

uses
  Windows,
  Messages,
  SysUtils;

procedure Main;
var
  hStdout, hNewScreenBuffer: THANDLE;
  srctReadRect: TSMALLRECT;
  srctWriteRect: TSMALLRECT;
  chiBuffer: array [0..160] of TCHARINFO; // [2]*[80];
  coordBufSize: TCOORD;
  coordBufCoord: TCOORD;
  fSuccess: BOOL;
begin
    // Get a handle to the STDOUT screen buffer to copy from and
    // create a new screen buffer to copy to.

    hStdout := GetStdHandle(STD_OUTPUT_HANDLE);
    hNewScreenBuffer := CreateConsoleScreenBuffer(
       GENERIC_READ or         // read/write access
       GENERIC_WRITE,
       0,                      // not shared
       nil,                    // default security attributes
       CONSOLE_TEXTMODE_BUFFER, // must be TEXTMODE
       nil);                   // reserved; must be NULL

    if (hStdout = INVALID_HANDLE_VALUE) or
       (hNewScreenBuffer = INVALID_HANDLE_VALUE) then
    begin
      WriteLn(format('CreateConsoleScreenBuffer (%d)', [GetLastError]));
      exit;
    end;

    // Make the new screen buffer the active screen buffer.

    if not SetConsoleActiveScreenBuffer(hNewScreenBuffer) then
    begin
      WriteLn(format('SetConsoleActiveScreenBuffer (%d)', [GetLastError]));
      exit;
    end;

    // Set the source rectangle.

    srctReadRect.Top := 0;   // top left: row 0, col 0
    srctReadRect.Left := 0;
    srctReadRect.Bottom := 1; // bot. right: row 1, col 79
    srctReadRect.Right := 79;

    // The temporary buffer size is 2 rows x 80 columns.

    coordBufSize.Y := 2;
    coordBufSize.X := 80;

    // The top left destination cell of the temporary buffer is
    // row 0, col 0.

    coordBufCoord.X := 0;
    coordBufCoord.Y := 0;

    // Copy the block from the screen buffer to the temp. buffer.

    fSuccess := ReadConsoleOutput(
       hStdout,       // screen buffer to read from
       @chiBuffer[0], // buffer to copy into
       coordBufSize,  // col-row size of chiBuffer
       coordBufCoord, // top left dest. cell in chiBuffer
       srctReadRect); // screen buffer source rectangle
    if not fSuccess then
    begin
      WriteLn(format('SetConsoleActiveScreenBuffer (%d)', [GetLastError]));
      exit;
    end;

    // Set the destination rectangle.

    srctWriteRect.Top := 10;   // top lt: row 10, col 0
    srctWriteRect.Left := 0;
    srctWriteRect.Bottom := 11; // bot. rt: row 11, col 79
    srctWriteRect.Right := 79;

    // Copy from the temporary buffer to the new screen buffer.

    fSuccess := WriteConsoleOutput(
        hNewScreenBuffer, // screen buffer to write to
        @chiBuffer[0],   // buffer to copy from
        coordBufSize,    // col-row size of chiBuffer
        coordBufCoord,   // top left src cell in chiBuffer
        srctWriteRect);  // dest. screen buffer rectangle
    if not fSuccess then
    begin
      WriteLn(format('WriteConsoleOutput (%d)', [GetLastError]));
      exit;
    end;
    Sleep(5000); // <--<<

    // Restore the original active screen buffer.

    if not SetConsoleActiveScreenBuffer(hStdout) then
    begin
      WriteLn(format('SetConsoleActiveScreenBuffer (%d)', [GetLastError]));
      exit;
    end;
end;

BEGIN
  AllocConsole;
  Main;
  FreeConsole;
END.
Für das Demo ja. Es dient zur visualisierung des Demos ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:25 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz