• dmk © (03.05.14 20:13) [0]
    Кто нибудь боролся с ограничением по длине?
    Если длинное имя принтера, то DC не создается.
    FPrnDC := Windows.CreateDC(nil, PChar(FPrinterName), nil, PDevMode);
    FPrnDC всегда ноль, а если короткое, то все в порядке.
  • Rouse_ © (03.05.14 22:46) [1]
    через \\??\ попробуй (правда не уверен что с принтерами работает, бо длинных имен для них ни разу не видел :)
  • junglecat (03.05.14 22:50) [2]
    а чем отличается короткое имя принтера от длинного?
  • Rouse_ © (03.05.14 22:55) [3]

    > junglecat   (03.05.14 22:50) [2]
    > а чем отличается короткое имя принтера от длинного?

    не влазит в MAX_PATH, с которым не умеет работать CreateFile, в отличие от Zw...
  • junglecat (03.05.14 22:56) [4]
    > [3] Rouse_ ©   (03.05.14 22:55)

    а контекст устройства разве создается через CreateFile?
  • Rouse_ © (03.05.14 23:00) [5]

    > junglecat   (03.05.14 22:56) [4]
    > > [3] Rouse_ ©   (03.05.14 22:55)
    >
    > а контекст устройства разве создается через CreateFile?

    А ты теплое с мягким не путаешь? :) Чтобы создать контекст, нужно иметь описатель...
  • junglecat (03.05.14 23:02) [6]
    типа того, что сначала открывается принтер путем CreateFile, а потом для его хэндла создается контекст?
    ну, логично в принципе...
  • Rouse_ © (03.05.14 23:04) [7]
    Абсолютно верно, только не принтер а его символьная ссылка, а потому уже далее...
  • dmk © (03.05.14 23:25) [8]
    Узнать длинное имя у системы могу. В моем случае это '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.
  • Rouse_ © (03.05.14 23:32) [9]
    Хм, это не длинное имя...
    Накидай тестовый пример, завтра по удаленке на нашем тестовом стенде попробую посотреть.
  • dmk © (03.05.14 23:33) [10]
    Разобрался. Если кому надо:

    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;


    Чекнешься с юникодом :)
  • junglecat (03.05.14 23:34) [11]
    а ты имя передаешь в dmDeviceName? у него ограничение CCHDEVICENAME = 32
  • dmk © (03.05.14 23:35) [12]
    FInfo2_Array[FPrinterIndex] это у меня массив данных PPrinterInfo2W полученный при EnumPrinters. Microsoft рекомендует создать локальный массив.
  • dmk © (03.05.14 23:39) [13]
    junglecat   (03.05.14 23:34) [11]
    Не в dmDeviceName, а через указатели.

    //Копирую в локальную переменную
    PrinterInfo_2.pPrinterName := PChar(PrnInfo^.pPrinterName);

    а PrnInfo возвращается через EnumPrinters.
  • dmk © (03.05.14 23:43) [14]
    Rouse_ ©   (03.05.14 23:32) [9]
    34 символа. 2 не помещаются.
    На самом деле проблема решена. см [10].

    Всем спасибо!

    ненавижуюникод!
  • dmk © (03.05.14 23:44) [15]
    Из-за этого приходится такие простыни писать:
           //Собираем данные о принтере
           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;

  • Rouse_ © (03.05.14 23:58) [16]

    > dmk ©   (03.05.14 23:44) [15]
    > Из-за этого приходится такие простыни писать:

    Это ты зря :)
  • dmk © (04.05.14 00:04) [17]
    А как скопировать? Просто через move не получится. Это же непоследовательный массив указателей. Приходится все выдирать по одному :( Может я чего не понимаю? Подскажите пожалуйста!!!
  • Rouse_ © (04.05.14 00:06) [18]
    Так ты код-то покажи.
    Маленькую демку сваргань и скажи под какой дельфей компилишь.  
    Зачем такие портянки то выкладывать?
  • dmk © (04.05.14 00:36) [19]
    Демку не получится. Много кода.
    Писал для совместимости с юникодом. Проект старый еще во времена D7 жил.
    Суть в поддержке длинных строк. Delphi XE6. Пока поставил trial. Думаю брать/не брать?!?
    Изначально идея была в создании динамического массива с длинными именами, что сначала и сделал, а потом возникла надобность в правке параметров: ориентация, разрешение и т.п. Т.к. к классу прикручен собственный диалог настроек, решил на будущее (а вдруг!) могут понадобится доп данные из структур PRINTER_INFO_2 и DEVMODE. Поэтому к динамическому массиву из юникод-имен добавил такую простыню, но массив уже не динамический, а простая декларация array[0..9] of PRINTER_INFO_2. Вот и думаю, а надо ли оно?!
  • dmk © (04.05.14 02:01) [20]
    В общем ошибка непонятно где.
    GetPrinter() возвращает одну информацию, а EnumPrinters другую.

    Если брать указатели возвращенные функцией EnumPrinters, то структура Devmode воспринимается системой, а если взять Devmode полученной от GetPrinter, а потом изменить ее и подсунуть обратно системе, то системе не нравится такая структура. Вот и прикол.

    Правильное название возвращенное EnumPrinters:
    http://i55.fastpic.ru/big/2014/0504/11/d1e8eb36ab44477a2f0285d2ea58f211.jpg

    НЕ правильное название возвращенное GetPrinter:
    http://i55.fastpic.ru/big/2014/0504/93/39116696f3388ba7718d6bab4bd73393.jpg

    Если Devmode от Enumprinters сохранить, то система берет измененную структуру, а если подсунуть от GetPrinter, то не принимает.
  • dmk © (04.05.14 02:09) [21]
    Поэтому и возникла идея сохранять все структуры во время EnumPrinters :(
  • dmk © (04.05.14 02:10) [22]
    Поэтому и возникла идея сохранять все структуры во время EnumPrinters :(
  • junglecat (04.05.14 12:18) [23]
    а GetPrinter(8) то же самое вернет?
  • dmk © (04.05.14 14:03) [24]
    junglecat   (04.05.14 12:18) [23]
    Если через VCL.TPrinter.GetPrinter, то да, вернет не полное имя.
    Или в дровах HP ошибка или microsoft.

    В общем решил оставить подготовку массивов при EnumPriners. Кода много, зато работает без проблем.
  • junglecat (04.05.14 14:13) [25]
    > [24] dmk ©   (04.05.14 14:03)

    нет, я имел в виду винапишную GetPrinter, через структуру PRINTER_INFO_8
  • dmk © (04.05.14 14:17) [26]
    junglecat   (04.05.14 14:13) [25]
    Через WinApi то же самое. Правильно только через EnumPrinters.
  • dmk © (04.05.14 14:20) [27]
    junglecat   (04.05.14 14:13) [25]
    Извиняюсь! У меня идет через PRINTER_INFO_2. Там в составе есть DevMode.
  • junglecat (04.05.14 14:25) [28]
    а в PRINTER_INFO_8 это единственное поле
  • dmk © (04.05.14 15:12) [29]
    junglecat   (04.05.14 14:25) [28]

    Попробовал через PRINTER_INFO_8 - то же самое. Структура не нравится системе в случае длинного имени принтера. Если короткое, то все отлично.
    Оставляю пока структуру из EnumPrinters. Бред !(O.o)!
  • dmk © (06.05.14 17:33) [30]
    Разобрался. Ошибка в приведении типов была. PPrinterInfo2 и PPrinterInfo2W. Стек рушился, если приводил старый тип PPrinterInfo2. Сейчас все нормально.
Есть новые Нет новых   [134427   +34][b:0][p:0.003]