Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Определение способа подачи бумаги

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3

Открыть новую тему     Написать ответ в эту тему

Aleksandr N

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Имеется интересная ситуация. Определяем стандартным образом способ подачи бумаги
 
       FillChar(BinValues, SizeOf(BinValues), 0);
       BinCount := DeviceCapabilities(CurrentDevice, CurrentPort, DC_BINS, @BinValues[0], nil);
       if BinCount > 0 then
        begin
         GetMem(BinNames, BinCount * 24 * sizeof(char));
         GetMem(BinValues, BinCount * 24 * sizeof(char));
         try
          DeviceCapabilities(CurrentDevice, CurrentPort, DC_BINNAMES, Pointer(BinNames), nil);
          DeviceCapabilities(CurrentDevice, CurrentPort, DC_BINS, Pointer(BinValues), nil);
          FBins := TStringList.Create;
          for I := 0 to BinCount - 1 do
           begin
            BinName := BinNames^[I];
            FBins.AddObject(BinName, TObject(BinValues^[I]));
           end;
         finally
          FreeMem(BinNames, BinCount * 24 * sizeof(char));
          FreeMem(BinValues, BinCount * 24 * sizeof(char));
         end;
        end;
 
Имеется некий принтер в драйверах которого способы подачи бумаги определены как: "Автоматическое устройство подачи" и "Ручное устройство подачи". При данном способе определения, программа выдаёт только 24 символа:
 

 
Пытался вместо параметра "24" поставить "40". В одном случае это ни к чему не приводило, в другом из этого получилось:
 

 
Вся проблема в том, что при этом программа либо выдаёт ошибку, либо молча вышибается. Поставив это между try except - программа ошибок на экран не выдаёт, но ведёт себя крайне неадекватно.
Вопрос: можно что-то в этом коде исправить чтобы выдавался весь текст. Как я предполагаю в этом случае ошибок быть не должно. Или может есть другой способ определения способа подачи бумаги.
 
P.S. Поставить нормальный драйвер принтера не предлагать - я обратился в ветку по программированию...
 


 
Во многих других модулях так-же. Такая-же история с компонентом печати от "Девок" где этот параметр определяется иначе. Но суть это не изменило... Вот их код:  
 
      BinCount := DeviceCapabilities(CurrentDevice, CurrentPort, DC_BINS, nil, nil);  
      if BinCount > 0 then  
      begin  
        BinValues := AllocMem(BinSize * BinCount);  
        try  
          if DeviceCapabilities(CurrentDevice, CurrentPort, DC_BINS, PChar(BinValues), nil) <> -1 then  
          begin  
            BinNames := AllocMem(BinNameSize * BinCount);  
            try  
              if DeviceCapabilities(CurrentDevice, CurrentPort, DC_BINNAMES, PChar(BinNames), nil) <> -1 then  
              begin  
                FBins := TStringList.Create;  
                for I := 0 to BinCount - 1 do  
                begin  
                  BinName := BinNames^[I];  
                  FBins.AddObject(BinName, TObject(BinValues^[I]));  
                end;  
              end;  
            finally  
              FreeMem(BinNames, BinNameSize * BinCount);  
            end;  
          end;  
        finally  
          FreeMem(BinValues, BinSize * BinCount);  
        end;  
      end;  

Всего записей: 1665 | Зарегистр. 25-02-2008 | Отправлено: 18:24 11-12-2009
data man



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Aleksandr N
 
Не знаю в какой версии Девок вы взяли код, но в 47 - иначе:

Код:
      BinCount := DeviceCapabilities(CurrentDevice, CurrentPort, DC_BINS, nil, nil);
      if BinCount > 0 then
      begin
        BinValues := AllocMem(BinSize * BinCount * SizeOf(Char));
        try
          if DeviceCapabilities(CurrentDevice, CurrentPort, DC_BINS, PChar(BinValues), nil) <> -1 then
          begin
            BinNames := AllocMem(BinNameSize * BinCount * SizeOf(Char));
            try
              if DeviceCapabilities(CurrentDevice, CurrentPort, DC_BINNAMES, PChar(BinNames), nil) <> -1 then
              begin
                FBins := TStringList.Create;
                for I := 0 to BinCount - 1 do
                begin
                  BinName := BinNames^[I];  
                  FBins.AddObject(BinName, TObject(BinValues^[I]));
                end;  
              end;
            finally
              FreeMem(BinNames);
            end;
          end;
        finally
          FreeMem(BinValues);
        end;
      end;
 

 
http://msdn.microsoft.com/en-us/library/dd183552(VS.85).aspx

Цитата:
DC_BINNAMES - Retrieves the names of the printer's paper bins. The pOutput buffer receives an array of string buffers. Each string buffer is 24 characters long and contains the name of a paper bin. The return value indicates the number of entries in the array. The name strings are null-terminated unless the name is 24 characters long. If pOutput is NULL, the return value is the number of bin entries required.


----------
Любой достаточно развитый тролль неотличим от подлинно помешанного на какой-либо идее.
Кекс. Антибиотики. Ламбада.

Всего записей: 1696 | Зарегистр. 13-10-2005 | Отправлено: 18:59 11-12-2009
Aleksandr N

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
data man

Цитата:
в какой версии Девок  

Это точно было в 42, но переодически сверяю код. Может пропустил. Попробую в понедельник т.к. принтер рабочий, а при себе драйверов нет. По-моему и это пробовал.
 
greenpc предложил:
 
procedure GetPaperBins(sl: TStrings; var parName : string);
 type
   TBinName      = array [0..23] of Char;
   TBinNameArray = array [1..High(Integer) div SizeOf(TBinName)] of TBinName;
   PBinnameArray = ^TBinNameArray;
   TBinArray     = array [1..High(Integer) div SizeOf(Word)] of Word;
   PBinArray     = ^TBinArray;
 var
   Device, Driver, Port: array [0..255] of Char;
   hDevMode: THandle;
   i, numBinNames, numBins, temp: Integer;
   pBinNames: PBinnameArray;
   pBins: PBinArray;
 begin
   Printer.PrinterIndex := -1;
   Printer.GetPrinter(Device, Driver, Port, hDevmode);
   parName := Printer.Printers[Printer.PrinterIndex];
   numBinNames := WinSpool.DeviceCapabilities(Device, Port, DC_BINNAMES, nil, nil);
   numBins     := WinSpool.DeviceCapabilities(Device, Port, DC_BINS, nil, nil);
   if numBins <> numBinNames then
   begin
     raise Exception.Create('DeviceCapabilities reports different number of bins and bin names!');
   end;
   if numBinNames > 0 then
   begin
     pBins := nil;
     GetMem(pBinNames, numBinNames * SizeOf(TBinname));
     GetMem(pBins, numBins * SizeOf(Word));
     try
       WinSpool.DeviceCapabilities(Device, Port, DC_BINNAMES, PChar(pBinNames), nil);
       WinSpool.DeviceCapabilities(Device, Port, DC_BINS, PChar(pBins), nil);
       sl.Clear;
       for i := 1 to numBinNames do
       begin
         temp := pBins^[i];
         sl.addObject(pBinNames^[i], TObject(temp));
       end;
     finally
       FreeMem(pBinNames);
       if pBins <> nil then
         FreeMem(pBins);
     end;
   end;
 end;
 
Результат:

При закрытии выдаёт

Всего записей: 1665 | Зарегистр. 25-02-2008 | Отправлено: 20:01 11-12-2009 | Исправлено: Aleksandr N, 20:02 11-12-2009
data man



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Aleksandr N
 
Да я думаю что 24 символа - максимум. Я же привел цитату из MSDN.
Просто в последних DevEx сделана корректировка на юникодные версии Delphi.

----------
Любой достаточно развитый тролль неотличим от подлинно помешанного на какой-либо идее.
Кекс. Антибиотики. Ламбада.

Всего записей: 1696 | Зарегистр. 13-10-2005 | Отправлено: 20:08 11-12-2009 | Исправлено: data man, 20:11 11-12-2009
Aleksandr N

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
data man
Да пускай 24 символа, хоть 10. Главное чтобы программу это не срубало.

Цитата:
Вся проблема в том, что при этом программа либо выдаёт ошибку, либо молча вышибается. Поставив это между try except - программа ошибок на экран не выдаёт, но ведёт себя крайне неадекватно.

Только вот как сделать чтобы всё работало?!?
 
Добавлено:
Тем более никто не гарантирует, что только этот драйвер кривой. Сколько ещё таких может быть... А проблему решать надо...

Всего записей: 1665 | Зарегистр. 25-02-2008 | Отправлено: 21:42 11-12-2009
greenpc

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
data man

Цитата:
Да я думаю что 24 символа - максимум

если перевести правильно, то система выделяет 24 символа на каждый бин
и не важно если название короче (длинее быть не может т.к. ограничение системы) . Т.е. получаем 24*numBins.
_http://support.microsoft.com/kb/82167  
Aleksandr N
а система определяет корректно?

Всего записей: 401 | Зарегистр. 18-04-2003 | Отправлено: 08:38 12-12-2009 | Исправлено: greenpc, 08:57 12-12-2009
Aleksandr N

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
greenpc
Имеешь в виду другими программами? Если да, то из тех программ, которые можно установить и которые показывают в диалоге печати способы подачи бумаги, FastStone Image Viewer показывает так-же. Но ошибок не выдает. Да и Win, по-моему, так-же, но система не падает...
Повторюсь, пускай показывает сколько хочет. Главное чтобы всё работало.
 
Добавлено:
Совсем старый стал
Я-же установил себе этот драйвер.
Сама Win почему-то показывает это иначе
 

 
Во второй половине картинки версия драйвера (кто хочет собственноручно поэкспериментировать).

Всего записей: 1665 | Зарегистр. 25-02-2008 | Отправлено: 13:38 12-12-2009
Aleksandr N

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
greenpc
Интнресно девки пляшут...
До этого я эксперементировал но WinXP без установленных юникодовских шрифтов. Сейчас попробывал на Win7.
При нажатии на кнопку в режиме компиляции три раза выкидавает на:
 

 
При закрытии ошибок не выдает. А если внимательней посмотреть на картинку, видно что не хватает ещё одного символа.
 

 
По-моему это как-то связано со способом выдачи данных системой и шрифтами.
Только как всё это обойти???

Всего записей: 1665 | Зарегистр. 25-02-2008 | Отправлено: 22:14 12-12-2009
data man



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Aleksandr N
Цитата:
Только как всё это обойти???

В зависимости от PChar(BinValues), вставлять свою строку.
В windows.pas это константы вида DMBIN_XXXXXXX
В данном случае DMBIN_AUTO и DMBIN_MANUAL
То есть, примерно так:

Код:
if PChar(BinValues^[I]) = PChar(DMBIN_AUTO) then
  S := 'Автоматическая подача бумаги';
if PChar(BinValues^[I]) = PChar(DMBIN_MANUAL) then
  S := 'Ручная подача бумаги';


----------
Любой достаточно развитый тролль неотличим от подлинно помешанного на какой-либо идее.
Кекс. Антибиотики. Ламбада.

Всего записей: 1696 | Зарегистр. 13-10-2005 | Отправлено: 22:40 12-12-2009
Aleksandr N

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
data man
То есть предлагаешь в независимости от того что производитель заложил в описании этого типа самому выдавать пользователю "Автоматическая подача бумаги" вместо "ХЗ какой способ"? Или я не так понял и предлагаешь проверять надпись в драйвере с "Автоматическая подача бумаги"?
???

Всего записей: 1665 | Зарегистр. 25-02-2008 | Отправлено: 22:50 12-12-2009
data man



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Aleksandr N
Производитель драйвера обязан соблюдать стандарты винды.
И винда же так же делает, пишет свои строки ?

Цитата:
проверять надпись в драйвере

Нет, конечно не строки.
P.S. А способ я в Qt подсмотрел.


----------
Любой достаточно развитый тролль неотличим от подлинно помешанного на какой-либо идее.
Кекс. Антибиотики. Ламбада.

Всего записей: 1696 | Зарегистр. 13-10-2005 | Отправлено: 22:58 12-12-2009 | Исправлено: data man, 23:02 12-12-2009
Aleksandr N

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
data man
Понятно что должен, только "не выходит каменный цветок".
Я всё таки не понял что данный способ делает: Заменяет текст драйвера на свой или Сверяешь свой текст с текстом в драйвере?

Всего записей: 1665 | Зарегистр. 25-02-2008 | Отправлено: 23:06 12-12-2009
data man



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Aleksandr N
 
Да, заменять текст типа подачи бумаги, в зависимости от кода этого типа.
Если за образец взять код из DevEx, то посмотри в отладчике на значения FBins.Objects.

----------
Любой достаточно развитый тролль неотличим от подлинно помешанного на какой-либо идее.
Кекс. Антибиотики. Ламбада.

Всего записей: 1696 | Зарегистр. 13-10-2005 | Отправлено: 23:12 12-12-2009
Aleksandr N

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
data man
Это конечно хорошо, только никто не гарантирует что проблема не возникнет с другим драйвером где может быть запись типа "Автоматический тип подачи бумаги" и т.п.
Проблема стоит не в конкретном драйвере, а в правильном способе обработки таких ситуаций.

Всего записей: 1665 | Зарегистр. 25-02-2008 | Отправлено: 23:17 12-12-2009
data man



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Aleksandr N
 
Ну так для этого и прописаны константы типов подачи !
Если производитель не будет их соблюдать, то как мелкомягкие будут относиться к такому производителю ? Думаю сурово.
В общем, осталось попробовать.

----------
Любой достаточно развитый тролль неотличим от подлинно помешанного на какой-либо идее.
Кекс. Антибиотики. Ламбада.

Всего записей: 1696 | Зарегистр. 13-10-2005 | Отправлено: 23:23 12-12-2009
Aleksandr N

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
data man
Подумаю, попробую. Окончательно всё равно смогу сказать не раньше понедельника...
У кого ещё есть светлые мысли.

Всего записей: 1665 | Зарегистр. 25-02-2008 | Отправлено: 01:54 13-12-2009
Aleksandr N

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
А в Компасе 11 и Win7 вот что показывает:

Всего записей: 1665 | Зарегистр. 25-02-2008 | Отправлено: 22:07 13-12-2009
psa1974



Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Aleksandr N
У меня в системе стоит 9 принтеров (физических и виртуальных)... Самая длинная строка - "автоматический выбор", что не превышает 24 символа. Я тоже склонен полагать, что к твоему принтеру кривые дрова.  
 
Но это лирика, а на практике предлагаю альтернативный вариант .
Смысл в том, что для просто определения текста, описывающего способы подачи бумаги, вообще можно не париться - а читать все с реестра.
Есть 2 ветки:
[HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers\имя принтера\DsDriver]
[HKLM\SYSTEM\CurrentControlSet\Control\Print\Printers\имя принтера\DsDriver]
В обеих прописаны для каждого принтера мультистроковые параметры "printBinNames".
Достаточно их читать и все дела.  
 
ЗЫ: Кстати, рискну предположить, что  тут же можно в случае чего их попробовать подкорректировать. Хотя это надо тщательно проверять - не вылезет ли где каким боком... Вобщем насчет корректировки - типа я тебе ничего не советовал
Также надо определиться зачем существует 2 ветки с одинаковым содержимым... Это - "домашнее задание"
 
ЗЫ-ЗЫ: Ветки я привел применительно к Вин ХР...

Цитата:
А в Компасе 11 и Win7 вот что показывает:

Вот-вот - параметр "printBinNames" мультистроковый, каждый вариант подачи в нем идет в новой строке, а у тебя тут всё читается как одна строка, отчего не знаю, но имхо почитать с реестра - самый ненапряжный и верный способ, без каких-либо программных "прослоек"...
 
Добавлено:
Решил сам твое "домашнее задание":
  • изменение значения параметра в одной ветке приводит к синхронному изменению значения в другой, без разницы, в какой именно производились изменения, отчего я делаю вывод что физически это один и тот же кусок реестра
  • изменение значения параметра "printBinNames" никак не влияет на значения, получаемые методом, реализованным в Девках...
    Таким образом, изменять нельзя, можно только читать, причем все равно из какой ветки.

    ----------
    У программёра есть два состояния: "Втупляю" и "Попёрло"...

  • Всего записей: 438 | Зарегистр. 08-11-2005 | Отправлено: 23:49 13-12-2009 | Исправлено: psa1974, 00:24 14-12-2009
    Aleksandr N

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    psa1974
    То что принтер кривой - я согласен. Но сути это не меняет.
    Про реестр я не подумал.А там вот что написано:
     
    Автоматическое устройств
    Ручное устройство подачи
     
    Но если внимательно почитать мои предыдущие посты, то Win7 в независимости от значений реестра убирается ещё по одному символу.

    Цитата:
    а у тебя тут всё читается как одна строка

    У меня считывается это когда я считываю своей программой. А это считывают сторонние программы. Компас сделан на Delphi и используется стандартный диалог для Delphi. Получается это ошибка метода printBinNames, который и нужно как-то подправить. А считывается этот параметр не из реестра, а наверняка с самого драйвера.

    Всего записей: 1665 | Зарегистр. 25-02-2008 | Отправлено: 02:07 14-12-2009
    psa1974



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Aleksandr N

    Цитата:
    А считывается этот параметр не из реестра, а наверняка с самого драйвера.

    Совершенно верно. Остается вопрос, как попадает значение в реестр - как точная копия значения в драйверах или с помощью той же ф-ции DeviceCapabilities вытягивается при инсталляции...  
    Если первый вариант, то и в дровах у тебя такое-же значение "Автоматическое устройств" длиной в 24 символа и все равно откуда брать значение, но из реестра - без шанса схлопотать эксцепшен; если второй вариант - то все равно лучше юзать значение из реестра, ибо в дровах оно некорректное с точки зрения системы, отсюда и эксцепшены...  
    Ну, безусловно, это мое имхо .
     
    Про вин7: запустил щас скомпиленный экзешник с использованием класса TdxPrintDevice (Девки), у меня в виртуалке на вин7 стоит принтер "Microsoft XPS Document Writer", для него четко выдало: "Автовыбор" (добуквенно, ничего не съелось). Но тут далеко до 23 символов. Хз, может в Вин7 ограничение в 23 символа... Тут уже в одной из тем выяснялись косяки в висте и семерке со шрифтами в окне редактирования edit (сам опыты ставил )... Не исключено, что еще один косяк.
    А каково значение в реестре в Вин7 этих строк? Они тоже длиной в 23 символа?

    ----------
    У программёра есть два состояния: "Втупляю" и "Попёрло"...

    Всего записей: 438 | Зарегистр. 08-11-2005 | Отправлено: 02:54 14-12-2009
    Открыть новую тему     Написать ответ в эту тему

    Страницы: 1 2 3

    Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Определение способа подачи бумаги


    Реклама на форуме Ru.Board.

    Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
    Modified by Ru.B0ard
    © Ru.B0ard 2000-2025

    BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

    Рейтинг.ru