-
Кто нибудь боролся с ограничением по длине?
Если длинное имя принтера, то DC не создается.
FPrnDC := Windows.CreateDC(nil, PChar(FPrinterName), nil, PDevMode);
FPrnDC всегда ноль, а если короткое, то все в порядке.
-
через \\??\ попробуй (правда не уверен что с принтерами работает, бо длинных имен для них ни разу не видел :)
-
а чем отличается короткое имя принтера от длинного?
-
> junglecat (03.05.14 22:50) [2]
> а чем отличается короткое имя принтера от длинного?
не влазит в MAX_PATH, с которым не умеет работать CreateFile, в отличие от Zw...
-
> [3] Rouse_ © (03.05.14 22:55)
а контекст устройства разве создается через CreateFile?
-
> junglecat (03.05.14 22:56) [4]
> > [3] Rouse_ © (03.05.14 22:55)
>
> а контекст устройства разве создается через CreateFile?
А ты теплое с мягким не путаешь? :) Чтобы создать контекст, нужно иметь описатель...
-
типа того, что сначала открывается принтер путем CreateFile, а потом для его хэндла создается контекст?
ну, логично в принципе...
-
Абсолютно верно, только не принтер а его символьная ссылка, а потому уже далее...
-
Узнать длинное имя у системы могу. В моем случае это 'HP LaserJet P2015 Series UPD PCL 6'. Отослать системе длинное имя тоже получается, а передать структуру PDeviceModeW не выходит. Выдает ERROR_INVALID_PARAMETER 87 (The parameter is incorrect.) или ERROR_INSUFFICIENT_BUFFER 122 (The data area passed to a system call is too small) в случае если вместо структуры ставишь nil.
-
Хм, это не длинное имя...
Накидай тестовый пример, завтра по удаленке на нашем тестовом стенде попробую посотреть.
-
Разобрался. Если кому надо:
Procedure TWinPrinter.CreateDC;
var
PDevMode: PDeviceModeW;
begin
Self.DeleteDC;
GetMem(PDevMode, SizeOf(_DeviceModeW));
PDevMode^ := FInfo2_Array[FPrinterIndex].pDevMode;
FPrnDC := Windows.CreateDC(nil, PWideChar(FInfo2_Array[FPrinterIndex].pPrinterName), nil, @PDevMode);
ShowMessage(IntToStr(GetLastError));
FreeMem(PDevMode);
end;
Чекнешься с юникодом :)
-
а ты имя передаешь в dmDeviceName? у него ограничение CCHDEVICENAME = 32
-
FInfo2_Array[FPrinterIndex] это у меня массив данных PPrinterInfo2W полученный при EnumPrinters. Microsoft рекомендует создать локальный массив.
-
junglecat (03.05.14 23:34) [11]
Не в dmDeviceName, а через указатели.
//Копирую в локальную переменную
PrinterInfo_2.pPrinterName := PChar(PrnInfo^.pPrinterName);
а PrnInfo возвращается через EnumPrinters.
-
Rouse_ © (03.05.14 23:32) [9]
34 символа. 2 не помещаются.
На самом деле проблема решена. см [10].
Всем спасибо!
ненавижуюникод!
-
Из-за этого приходится такие простыни писать:
PrinterInfo_2.pServerName := PChar(PrnInfo^.pServerName);
PrinterInfo_2.pPrinterName := PChar(PrnInfo^.pPrinterName);
PrinterInfo_2.pDriverName := PChar(PrnInfo^.pDriverName);
PrinterInfo_2.pPortName := PChar(PrnInfo^.pPortName);
PrinterInfo_2.pShareName := PChar(PrnInfo^.pShareName);
PrinterInfo_2.pComment := PChar(PrnInfo^.pComment);
PrinterInfo_2.pLocation := PChar(PrnInfo^.pLocation);
with PrinterInfo_2.pDevMode do
begin
dmDeviceName := PrnInfo.pDevMode^.dmDeviceName;
dmSpecVersion := PrnInfo.pDevMode^.dmSpecVersion;
dmDriverVersion := PrnInfo.pDevMode^.dmDriverVersion;
dmSize := PrnInfo.pDevMode^.dmSize;
dmDriverExtra := PrnInfo.pDevMode^.dmDriverExtra;
dmFields := PrnInfo.pDevMode^.dmFields;
dmOrientation := PrnInfo.pDevMode^.dmOrientation;
dmPaperSize := PrnInfo.pDevMode^.dmPaperSize;
dmPaperLength := PrnInfo.pDevMode^.dmPaperLength;
dmPaperWidth := PrnInfo.pDevMode^.dmPaperWidth;
dmScale := PrnInfo.pDevMode^.dmScale;
dmCopies := PrnInfo.pDevMode^.dmCopies;
dmDefaultSource := PrnInfo.pDevMode^.dmDefaultSource;
dmPrintQuality := PrnInfo.pDevMode^.dmPrintQuality;
dmColor := PrnInfo.pDevMode^.dmColor;
dmDuplex := PrnInfo.pDevMode^.dmDuplex;
dmYResolution := PrnInfo.pDevMode^.dmYResolution;
dmTTOption := PrnInfo.pDevMode^.dmTTOption;
dmCollate := PrnInfo.pDevMode^.dmCollate;
dmFormName := PrnInfo.pDevMode^.dmFormName;
dmLogPixels := PrnInfo.pDevMode^.dmLogPixels;
dmBitsPerPel := PrnInfo.pDevMode^.dmBitsPerPel;
dmPelsWidth := PrnInfo.pDevMode^.dmPelsWidth;
dmPelsHeight := PrnInfo.pDevMode^.dmPelsWidth;
dmDisplayFlags := PrnInfo.pDevMode^.dmDisplayFlags;
dmDisplayFrequency := PrnInfo.pDevMode^.dmDisplayFrequency;
dmICMMethod := PrnInfo.pDevMode^.dmICMMethod;
dmICMIntent := PrnInfo.pDevMode^.dmICMIntent;
dmMediaType := PrnInfo.pDevMode^.dmMediaType;
dmDitherType := PrnInfo.pDevMode^.dmDitherType;
dmICCManufacturer := PrnInfo.pDevMode^.dmICCManufacturer;
dmICCModel := PrnInfo.pDevMode^.dmICCModel;
dmPanningWidth := PrnInfo.pDevMode^.dmPanningWidth;
dmPanningHeight := PrnInfo.pDevMode^.dmPanningHeight;
end;
PrinterInfo_2.pSepFile := PChar(PrnInfo^.pSepFile);
PrinterInfo_2.pPrintProcessor := PChar(PrnInfo^.pPrintProcessor);
PrinterInfo_2.pDataType := PChar(PrnInfo^.pDatatype);
PrinterInfo_2.pParameters := PChar(PrnInfo^.pParameters);
PrinterInfo_2.SecurityDescriptor := PrnInfo^.pSecurityDescriptor;
PrinterInfo_2.Attributes := PrnInfo^.Attributes;
PrinterInfo_2.Priority := PrnInfo^.Priority;
PrinterInfo_2.DefaultPriority := PrnInfo^.DefaultPriority;
PrinterInfo_2.StartTime := PrnInfo^.StartTime;
PrinterInfo_2.UntilTime := PrnInfo^.UntilTime;
PrinterInfo_2.Status := PrnInfo^.Status;
PrinterInfo_2.sJobs := PrnInfo^.cJobs;
PrinterInfo_2.AveragePPM := PrnInfo^.AveragePPM;
-
> dmk © (03.05.14 23:44) [15]
> Из-за этого приходится такие простыни писать:
Это ты зря :)
-
А как скопировать? Просто через move не получится. Это же непоследовательный массив указателей. Приходится все выдирать по одному :( Может я чего не понимаю? Подскажите пожалуйста!!!
-
Так ты код-то покажи.
Маленькую демку сваргань и скажи под какой дельфей компилишь.
Зачем такие портянки то выкладывать?
-
Демку не получится. Много кода.
Писал для совместимости с юникодом. Проект старый еще во времена D7 жил.
Суть в поддержке длинных строк. Delphi XE6. Пока поставил trial. Думаю брать/не брать?!?
Изначально идея была в создании динамического массива с длинными именами, что сначала и сделал, а потом возникла надобность в правке параметров: ориентация, разрешение и т.п. Т.к. к классу прикручен собственный диалог настроек, решил на будущее (а вдруг!) могут понадобится доп данные из структур PRINTER_INFO_2 и DEVMODE. Поэтому к динамическому массиву из юникод-имен добавил такую простыню, но массив уже не динамический, а простая декларация array[0..9] of PRINTER_INFO_2. Вот и думаю, а надо ли оно?!