0

印刷しているPDFのドキュメントプロパティを収集する次の関数があります。何らかの理由で、Delphi 7(XPを実行)では、これはうまく機能します...しかし、Windows7を使用してDelphiXEで再コンパイルしようとすると、関数は常に失敗して終了するようです... dwRet = IDOK

dwNeededDelphi 7での私のオブジェクトがであることに気づきました7332、そしてXEではそれはです4294967295!!

これをすばやく修正する方法はありますか?

Function TPrintPDF.GetPrinterDevMode ( pDevice: PChar ): PDevMode;
Var
  pDevModeVar : PDevMode;
  pDevModeVar2 : PDevMode;
  dwNeeded : DWord;
  dwRet : DWord;
Begin

  { Start by opening the printer }
  If (Not OpenPrinter (pDevice, PrinterHandle, Nil))
    Then Result := Nil;

  { Step 1: Allocate a buffer of the correct size }
  dwNeeded := DocumentProperties (0,
                         PrinterHandle, { Handle to our printer }
                         pDevice, { Name of the printer }
                         pDevModevar^, { Asking for size, so these are not used }
                         pDevModeVar^,
                         0); { Zero returns buffer size }

  GetMem (pDevModeVar, dwNeeded);

  { Step 2: Get the default DevMode for the printer }
  dwRet := DocumentProperties (0,
                 PrinterHandle,
                 pDevice,
                 pDevModeVar^, { The address of the buffer to fill }
                 pDevModeVar2^, { Not using the input buffer }
                 DM_OUT_BUFFER); { Have the output buffer filled }

  { If failure, cleanup and return failure }
  If (dwRet <> IDOK) Then Begin
    FreeMem (pDevModeVar);
    ClosePrinter (PrinterHandle);
    Result := Nil;
  End;

  { Finished with the printer }
  ClosePrinter (PrinterHandle);

  { Return the DevMode structure }
  Result := pDevModeVar;

End; { GetPrinterDevMode Function }
4

2 に答える 2

2

これが私があなたのコードで見ることができる問題です:

  1. の戻り値DocumentPropertiesは、符号付き32ビット整数です。として宣言されていLONGます。負の値はエラーが発生したことを意味し、それがあなたに起こっていることです。値を符号なし整数に詰め込んだため、負の値は表示されません。残念ながら、XEは宣言に失敗しLONGます。したがって、Integer代わりに使用するようにコードを変更してください。
  2. DocumentProperties返品時にエラーをチェックしません。エラーが発生した場合は、負の値が返されます。必ず確認してください。
  3. 4番目と5番目のパラメーターでランダムなガベージをに渡しますDocumentPropertiesnil初めて呼び出すときに、両方のパラメーターを渡すことができると思いますDocumentPropertiesnilを設定したことがないので、関数を呼び出すときに両方とも5番目のパラメーターを渡すことができますDM_IN_BUFFER
  4. エラーが発生した場合は、に設定Resultnilますが、残りの関数の実行を続行します。そうしないでください。関数を終了するには、exitを呼び出します。に割り当てると、Cのような言語のようにResult実行が終了することはありません。return
  5. ブロックを使用して、try/finallyを確実に呼び出しますCloseHandleCloseHandleそれはあなたが一度だけ書くことを可能にします。
于 2012-07-31T19:28:15.037 に答える
0

これがDavidが提案した解決策です...Davidに感謝します!

{ ---------------------------------------------------------------------------- }

Function TPrintPDF.GetPrinterDevMode                           (         pDevice: PChar                ): PDevMode;


Var
   pDevModeVar       : PDevMode;
   pDevModeVar2      : PDevMode;
   dwNeeded          : Long64;
   dwRet             : Long64;


Begin

  Result := Nil;

  { Start by opening the printer }
  If (OpenPrinter (pDevice, PrinterHandle, Nil)) Then Begin

    Try

      { Step 1: Allocate a buffer of the correct size }
      dwNeeded := DocumentProperties (0,
                                      PrinterHandle,  { Handle to our printer }
                                      pDevice,        { Name of the printer   }
                                      Nil,            { Asking for size, so these are not used }
                                      Nil,
                                      0);             { Zero returns buffer size }

      { Exit if this fails }
      If (dwNeeded < 0)
        Then Exit;

      GetMem (pDevModeVar, dwNeeded);


      { Step 2: Get the default DevMode for the printer }
      dwRet := DocumentProperties (0,
                                   PrinterHandle,
                                   pDevice,
                                   pDevModeVar^,      { The address of the buffer to fill }
                                   pDevModeVar2^,     { Not using the input buffer }
                                   DM_OUT_BUFFER);    { Have the output buffer filled }


      { If failure, cleanup and return failure }
      If (dwRet <> IDOK) Then Begin
        FreeMem (pDevModeVar);
        ClosePrinter (PrinterHandle);
        Result := Nil;
      End;


    { Finished with the printer }
    Finally
      ClosePrinter (PrinterHandle);
    End; { Try }

    { Return the DevMode structure }
    Result := pDevModeVar;

  End; { If we could open the printer }


End; { GetPrinterDevMode Function }
于 2012-07-31T19:16:20.390 に答える