Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   C++ Funktion nach Delphi (https://www.delphipraxis.net/169952-c-funktion-nach-delphi.html)

mcbain 22. Aug 2012 11:45

C++ Funktion nach Delphi
 
Hallo,
ich habe folgenden C++ Code:

Code:

typedef struct _CARD
   {
   
      // ---------------- 
   
      HDC      hDC;         // Graphical context
      HANDLE   hPrinter;      // Destination Printer
      
      // ----------------
                        // this will be set up with the openCard function
      int      height;         // of the card (see CR80 dimensions)
      int      width;         // idem
      
      // ----------------
      
      BOOL   bNewFontCreated;   // Font management
      HFONT   prevFont;
      HFONT   currFont;
      
      // ----------------
      
      BOOL   bNewPenCreated;      // Pen management
      HPEN   prevPen;
      HPEN   currPen;
            
      // ----------------
      
      DWORD   dwLastError;      // Error Management
      int      bOnError;
      
   } Card, * PCard;

BOOL DriverPrint_OpenCard ( PCard pCard, LPTSTR pPrinterName )
{
   pCard->bNewPenCreated   = FALSE;
   pCard->currPen         = NULL;
   pCard->prevPen         = NULL;
   pCard->bNewFontCreated   = FALSE;
   pCard->currFont         = NULL;
   pCard->prevFont         = NULL;
   pCard->height         = 648;
   pCard->width         = 1016;
   
   // ouverture du printer pour extraction contexte graphique
   
   if ( OpenPrinter( pPrinterName, &(pCard->hPrinter), NULL ) )
   {
      LONG lDVsize = DocumentProperties( NULL, pCard->hPrinter, pPrinterName, NULL, NULL, 0 );
      
      if ( lDVsize )
      {
         LPBYTE   bInDV   = new BYTE[ lDVsize ];
         LPBYTE bOutDV   = new BYTE[ lDVsize ];
         DEVMODE   sDV;
         
         if ( ( bInDV != NULL ) && ( bOutDV != NULL ) )
         {
            lDVsize = DocumentProperties( NULL, pCard->hPrinter, pPrinterName, (PDEVMODE) bOutDV, NULL, DM_COPY );

            if (lDVsize == IDOK)
            {
               if ( IDOK == DocumentProperties(NULL, pCard->hPrinter, pPrinterName, (PDEVMODE)bInDV, (PDEVMODE)bOutDV,
                                       DM_IN_BUFFER | /*DM_IN_PROMPT |*/ DM_OUT_BUFFER))
               {
                  memcpy( &sDV, bInDV, sizeof(DEVMODE) );

                  if ( pCard->hDC = CreateDC( NULL, pPrinterName, NULL, &sDV ) )
                  {
                     DOCINFO dinfo;
                     
                     dinfo.cbSize      = sizeof(DOCINFO);
                     dinfo.lpszDocName   = NULL;
                     dinfo.lpszOutput   = NULL;//"FILE:";
                     dinfo.lpszDatatype   = TEXT("raw");
                     
                     if ( StartDoc( pCard->hDC, &dinfo ) > 0 )
                     {
                        if ( StartPage( pCard->hDC ) <= 0 )
                        {
                           EvoError( pCard, "Error : StartPage Failed \r\n" );
                        }
                     } 
                     else
                     {
                        EvoError( pCard, "Error : StartDoc Failed \r\n" );
                     }
                  }
                  else // from CreateDC
                  {
                     EvoError( pCard , "Error : CreateDC Failed \r\n" );   
                  }
               }
               else // from IDOK == DocumentProperties
               {
                  EvoError( pCard, "Error : DocumentProperties Failed \r\n" );
               }
            }
            else // from (lDVsize == IDOK)
            {
               EvoError( pCard, "Error : DocumentProperties (Copy Request) Failed \r\n" );      
            }
         }
         else // from ( ( bInDV != NULL ) && ( bOutDV != NULL ) )
         {
            EvoError( pCard, "Error : Memory Allocation Failed \r\n" );
         }
         
         // nettoyage
         delete(bInDV);
         delete(bOutDV);
         if ( !ClosePrinter(pCard->hPrinter) )
         {
            EvoError( pCard, "Error : ClosePrinter Failed \r\n" );
         }
      }
      else // from lDVSize
      {
         EvoError( pCard, "Error : DocumentProperties (Size Request) Failed \r\n" );
      }
   } 
   else // openprinter
   {
      EvoError( pCard, "Error : OpenPrinter Failed \r\n" );
   }
   
   return ( !pCard->bOnError );
}
Ich habe den Code folgendermaßen nach Delphi XE 2 portiert:

Code:

 TCard = record
  private
    { Private-Deklarationen }
  public
    hDC: HDC;
    hPrinter: THandle;
    height: Integer;
    width: Integer;
    bNewFontCreated: Bool;
    prevFont: HFONT;
    currFont: HFONT;
    bNewPenCreated: Bool;
    prevPen: HPEN;
    currPen: HPEN;
    dwLastError: LongInt;
    bOnError: Integer;

    { Public-Deklarationen }
  end;

function DriverPrint_OpenCard(pCard: TCard; pPrinterName: lptstr): Bool;
var lDVsize: LONG;
    bInDV, bOutDV: TBytes;
    sdv: PDEVMODE;
    dinfo: DOCINFO;
    test: hdc;
     devA: _devicemodeA;

begin
  pCard.bNewPenCreated := False;
  pCard.currPen := 0;
  pCard.prevPen := 0;
  pCard.bNewFontCreated := False;
  pCard.currFont := 0;
  pCard.prevFont := 0;
  pCard.height := 648;
  pCard.width := 1016;

  pCard.hPrinter := 0;
  if OpenPrinter(pPrinterName,pCard.hPrinter,nil) then
  begin
    lDVsize := DocumentProperties(0,pCard.hPrinter,pPrinterName,nil,nil,0); //im C++ Programm ist lDVsize 166, in Delphi allerdings 220

    if(lDVsize <> 0) then
    begin
      SetLength(bInDV,lDVsize);
      SetLength(bOutDV,lDVsize);

      if (bInDV <> nil) and (bOutDV <> nil) then
      begin
        lDVsize := DocumentProperties(0,pCard.hPrinter,pPrinterName, PDEVMODE(bOutDV),nil,DM_COPY);

        if lDVsize = IDOK then
        begin

          if IDOK = DocumentProperties(0, pCard.hPrinter, pPrinterName, PDEVMODE(bInDV), PDEVMODE(bOutDV),
                                       DM_OUT_BUFFER OR DM_IN_BUFFER) then
          begin
   
             Move(bInDV, sDV, sizeof(DEVMODE) );          

             if pCard.hDC = CreateDC(nil,pPrinterName,nil,sdv) then //Das Delphi Programm läuft bis hierher, aber da CreateDC 0 zurück liefert durchläuft Delphi diese Bedingung nicht mehr
             begin
               dinfo.cbSize := SizeOf(DOCINFO);
               dinfo.lpszDocName := nil;
               dinfo.lpszOutput := nil;
               dinfo.lpszDatatype := 'raw';

               if StartDoc(pCard.hDC, dinfo) > 0 then
                  if StartPage(pCard.hDC) <= 0 then
                     ShowMessage('Error');

               ShowMessage('OK');
             end;
          end;
        end;
      end;

    end;

    ClosePrinter(pCard.hPrinter);

  end;

end;
Ich habe 2 Kommentare im Delphi-Code angegeben wo es zu Problemen kommt.
Hätte jemand einen Vorschlag für mich woran es scheitern könnte? Denke ich bin kurz vor der Lösung.
Vielen Dank.
Gruß
mc

DeddyH 22. Aug 2012 11:52

AW: C++ Funktion nach Delphi
 
Delphi-Quellcode:
pCard.hDC := CreateDC(nil,pPrinterName,nil,sdv);
if pCard.hDC <> 0 then

mcbain 22. Aug 2012 11:57

AW: C++ Funktion nach Delphi
 
Vielen Dank für die schnelle Antwort aber das hat das Problem leider nicht gelöst.
Ich denke das Problem beginnt auch schon früher, da ja lDVsize bei mir 220 ist und in C++ 165.

DeddyH 22. Aug 2012 12:09

AW: C++ Funktion nach Delphi
 
Könnte das mit Ansi/Unicode zusammenhängen?

mcbain 22. Aug 2012 12:26

AW: C++ Funktion nach Delphi
 
Ist durchaus möglich, wenn ich an der 1. Stelle
DocumentPropertiesA(0,pCard.hPrinter,PAnsiChar(pPrinterName), PDEVMODE (bOutDV),nil,DM_COPY);
verwende, dann bekomme ich zumindest hier das gleiche Erbebnis wie in C++.
Aber das andere Problem besteht weiterhin...

DeddyH 22. Aug 2012 12:34

AW: C++ Funktion nach Delphi
 
D.h. CreateDC liefert 0 zurück? Hast Du mal testhalber pPrinterName als PAnsiChar übergeben?

himitsu 22. Aug 2012 12:42

AW: C++ Funktion nach Delphi
 
pPrinterName ist doch lptstr, also PWideChar, seit D2009.

Da sollte der Compiler also bei
Delphi-Quellcode:
DocumentPropertiesA(0,pCard.hPrinter,PAnsiChar(pPrinterName), PDEVMODE(bOutDV),nil,DM_COPY);
rummotzen. :gruebel:

Wie wird denn DriverPrint_OpenCard aufgerufen? (ich würde erstmal dort den Fehler suchen)



Tja, anfangs war fast alles dynamisch programmiert, womit es sich seit D2009 automatisch auf Unicode umstellen sollte ... bis auf
Delphi-Quellcode:
devA: _devicemodeA;


String, Char, PChar, ApiFunktion, Struktur/Record
AnsiString, AnsiChar, PAnsiChar, ApiFunktionA, StrukturA/RecordA
WideString/UnicodeString, WideChar, PWideChar, ApiFunktionW, StrukturW/RecordW

NIEMALS vermischen :!:

Und wie ich es immer wieder prädige: Wertet endlich mal die Rückgabewerte und Fehlermeldungen der Funktionen aus, welche ihr aufruft.
Die sagen euch meistens schon, was ihnen nicht gefällt ... man muß nur drauf hören.

Robotiker 22. Aug 2012 12:45

AW: C++ Funktion nach Delphi
 
Zitat:

Zitat von himitsu (Beitrag 1179346)
NIEMALS vermischen :!:

Das betrifft in diesem Fall auch die Strukturmakros wie DOCINFO. Ich bin mir ziemlich sicher, VC ersetzt die zu DOCINFOA bzw. DOCINFOW, d.h. die sind eventuell auch unterschiedlich.

DeddyH 22. Aug 2012 12:49

AW: C++ Funktion nach Delphi
 
Einen ähnlichen Verdacht habe ich auch, aber ich kenne mich mit den C++-Datentypen nicht gut aus.

Aphton 22. Aug 2012 12:57

AW: C++ Funktion nach Delphi
 
Hab mir nur die Rümpfe angeschaut und weiß nicht ob es evt daran liegt, ABER...
Code:
  BOOL DriverPrint_OpenCard ( PCard pCard, LPTSTR pPrinterName )
Delphi-Quellcode:
  function DriverPrint_OpenCard(pCard: TCard; pPrinterName: lptstr): Bool;
..
"PCard pCard" <> "pCard: TCard"

Richtig:
"PCard pCard"
= "pCard: PCard" (wobei PCard = ^TCard)
= "var pCard: TCard"


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:32 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