Autor Beitrag
C++arsten
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 79



BeitragVerfasst: Di 19.07.05 00:41 
Hallo,
mit folgendem Codeschnipsel stelle ich fest, welche Druckerschächte bei einem beliebigen Drucker vorhanden sind:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
procedure GetBinnames(aStringList: TStrings);
const
    druckername = 'HP LaserJet 2100 PCL6';
type
    TBinName = array [0..23of Char;
  TBinNameArray = array [1..99of TBinName;
  PBinnameArray = ^TBinNameArray;
  TBinArray = array [1..99of Word;
  PBinArray = ^TBinArray;
var
  szDevice, szDriver, szPort : array[0..255of Char;
  hDevMode                   : THandle;
  i, iBinNames, iBins        : Integer;
  pBinNames                  : PBinnameArray;
  pBins                      : PBinArray;
begin
  for i := 0 to Printer.Printers.Count-1 do begin
      if Pos(druckername, Printer.Printers[i]) <> 0 then begin
       Printer.PrinterIndex := i;
       Break;
        end;
    end;
  Printer.PrinterIndex := i;
  Printer.GetPrinter(szDevice, szDriver, szPort, hDevmode);
  iBinNames := DeviceCapabilities(szDevice, szPort, DC_BINNAMES, nilnil);
  if iBinNames > 0 then begin
     GetMem(pBinNames, iBinNames * Sizeof(TBinname));
     GetMem(pBins, iBins * Sizeof(Word));
     try
      DeviceCapabilities(szDevice, szPort, DC_BINNAMES, PChar(pBinNames), nil);
        DeviceCapabilities(szDevice, szPort, DC_BINS, PChar(pBins), nil);
        aStringList.Clear;
        for i := 1 to iBinNames do
            aStringList.Add(Format('%s (%d)',[pBinNames^[i], pBins^[i]]));
       finally
         FreeMem(pBinNames );
         if pBins <> nil then
           FreeMem(pBins);
     end;
    end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
    GetBinNames(Memo1.Lines);
end;


und das sind die Warnungen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
[Warnung] Unit1.pas(76): Unsicherer Typ 'PChar'
[Warnung] Unit1.pas(76): Unsicherer Typ 'PChar'
[Warnung] Unit1.pas(180): Unsicherer Code 'GetMem'
[Warnung] Unit1.pas(181): Unsicherer Code 'GetMem'
[Warnung] Unit1.pas(183): Unsicherer Typ 'PChar'
[Warnung] Unit1.pas(184): Unsicherer Typ 'PChar'
[Warnung] Unit1.pas(189): Unsicherer Code 'FreeMem'
[Warnung] Unit1.pas(191): Unsicherer Code 'FreeMem'
[Warnung] Unit1.pas(181): Variable 'iBins' ist möglicherweise nicht initialisiert worden


Beim Starten unter Delphi 7 gibst nen Absturz EAccessViolation. Unter Delpi 5 läuft der Code.
Kann mir jemand sagen, warum?!?

Danke.

Moderiert von user profile iconraziel: Code- durch Delphi-Tags ersetzt.
Sprint
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 849



BeitragVerfasst: Di 19.07.05 02:21 
ausblenden Delphi-Quelltext
1:
GetMem(pBins, iBins * Sizeof(Word));					

iBins hat keinen Wert. Darum auch die Warnung: [Warnung] Unit1.pas(181): Variable 'iBins' ist möglicherweise nicht initialisiert worden

Die anderen Warnungen kannst du unter Projekt-->Option-->Compiler-Meldung abstellen.

_________________
Ciao, Sprint.
C++arsten Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 79



BeitragVerfasst: Di 19.07.05 09:19 
Dagegen wäre dann aber einzuwenden, dass das Programm unter Delphi 5 läuft. Die von dir angesprochene Warnung wirft Delphi 5 auch raus, aber das Programm stürzt nicht wie bei Delphi 7 bei dieser Zeile
ausblenden Quelltext
1:
aStringList.Add(Format('%s (%d)',[pBinNames^[i], pBins^[i]]));					

ab (die angesprochene EAccessViolation Exception).
Stefan.Buchholtz
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 612

WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
BeitragVerfasst: Di 19.07.05 09:44 
Weil du iBins nicht initialisiert hast, ist der Wert von iBins zufällig und hängt davon ab, was der vorher ausgeführte Code auf dem Stack hinterlassen hat. Dass das unter Delphi 5 funktioniert hat, würde ich mal als Zufall abhaken - dann lag da eben etwas sinnvolles auf dem Stack.
iBinNames ist doch die Anzahl der Druckerschächte. Du musst also die Zeile nur so abändern:

ausblenden Delphi-Quelltext
1:
GetMem(pBins, iBinNames * Sizeof(Word));					


Nicht ausprobiert, sollte aber gehen.

Stefan
C++arsten Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 79



BeitragVerfasst: Di 19.07.05 10:04 
Prima, es läuft.
Danke.