2015-09-08 5 views
2

Я пытаюсь напечатать серию меток на принтере Zebra S4M, по какой-то причине высота страницы, похоже, застряла на 5 см, и мне нужно, чтобы она составляла 6,8 см.Printer.GetPrinter вызывает исключение в Delphi XE2

Я пытаюсь установить размер бумаги, используя следующий код

var 
    FDevice: PChar; 
    FDriver: PChar; 
    FPort: PChar; 
    DeviceMode: THandle; 
    DevMode: PDeviceMode; 
begin 
    {to get a current printer settings} 
    Printer.GetPrinter(FDevice, FDriver, FPort, DeviceMode); 
    {lock a printer device} 
    DevMode := GlobalLock(DeviceMode); 
    DevMode^.dmPaperSize := 0; 
    DevMode^.dmPaperWidth := fBaseSettings.Width; 
    DevMode^.dmPaperLength := fBaseSettings.Height; 
    Printer.SetPrinter(FDevice, FDriver, FPort, DeviceMode); 
    {unlock a device} 
    GlobalUnlock(DeviceMode); 
end; 

где fBaseSettings содержит размеры целевой метки (помимо всего прочего), но я получаю сообщение об ошибке Project SPXLabels.exe raised exception class $C0000005 with message 'access violation at 0x00rred82: write of address 0x59212b17

I не вижу, что я делаю неправильно! Любая помощь очень ценится.

+0

Пожалуйста, вы можете сообщить сообщение об ошибке истинной. Пожалуйста, не подделывайте это! Спросите себя также, почему вы не проверяли ошибки. Вы на 100% уверены, что 'GlobalLock' всегда возвращает действительный указатель? Гарантируют ли документы? Или возможно, что 'DevMode' может быть' nil'? Почему люди не проверяют ошибки? Это культура копирования/вставки, сначала запустите, подумайте позже. –

+1

Это истинное сообщение об ошибке! как и для GlobalLock/Unlock, он не доходит так далеко, что не работает в заявлении Printer.GetPrinter! – Paul

+0

'0x00rred82' выглядит не так. Если это действительно сообщение об ошибке, то происходит что-то очень странное! –

ответ

4

FDevice, FDriver и FPort являются указателями на строку, которую вы передаете, чтобы вернуть данные. Таким образом, вы должны сначала разрешить память для этого.

попробовать это

var 
    FDevice, FDriver, FPort: string; 
begin 
    SetLength(FDevice, 200); 
    SetLength(FDriver, 200); 
    SetLength(FPort, 200); 
    {to get a current printer settings} 
    Printer.GetPrinter(PChar(FDevice), PChar(FDriver), PChar(FPort), DeviceMode); 
+0

Вам нужно придать тип на PChar, если вы используете String ... или вы можете просто использовать ' FDevice, FDriver, FPort: array [0..255] of char' ... нет необходимости в 'SetLength' таким образом. – GabrielF

+0

Спасибо Larsdk, это всегда очевидно, что вас укусит в заднице! – Paul

+0

Gah, не могу поверить, что я этого не заметил! Конечно, вам нужно найти лучший способ выработать требуемые длины. А проще ли статические буферы? –