|
v7: Перехват события печати | ☑ | ||
---|---|---|---|---|
0
pofigos
11.10.13
✎
12:30
|
Добрый день.
Прошу помощи, т.к. не понял, как это реализовать. Нужно перехватить событие отправки на печать (кнопкой на панели, сочетанием Ctrl+P или через меню Файл-Печать). Помогите разобраться, что писать в глобальнике, что в модуле документа\обработки. |
|||
1
Naumov
11.10.13
✎
12:36
|
без внешних компонент никак
|
|||
2
mehfk
11.10.13
✎
12:37
|
||||
3
pofigos
11.10.13
✎
12:39
|
(1) Сори, не уточнил.
СписокКомпонент = СоздатьОбъект("СписокЗначений"); СписокКомпонент.ДобавитьЗначение("1cpp.dll"); СписокКомпонент.ДобавитьЗначение("1sqlite.dll"); СписокКомпонент.ДобавитьЗначение("FormEx.dll"); СписокКомпонент.ДобавитьЗначение("SpreadSheet.dll"); СписокКомпонент.ДобавитьЗначение("TurboMD.dll"); Все в последних версиях и обновлено. Исходя из этой темы: http://forum.infostart.ru/forum9/topic39308/ формексом через опу получится. Ориентируюсь на: Печать в 7.7 под SRV2008 (именно этот результат нужен). |
|||
4
mehfk
11.10.13
✎
12:42
|
(3) Еще раз: FormEx ПриПечатиТаблицы
|
|||
5
pofigos
11.10.13
✎
13:01
|
(4) Пробую. Спс, посмотрю на результат и устроит ли.
|
|||
6
mehfk
11.10.13
✎
13:23
|
(5) Если заинтересует - еще есть ВК которая вот так умеет
Процедура ПриСохраненииТабличногоДокумента(ТабДок,ИмяФайла,ТипФайла,ФлагСтандартнойОбработки) Экспорт Сообщить("ТабДок = "+ ТабДок+ ""); Сообщить("ИмяФайла = "+ ИмяФайла+ ""); Сообщить("ТипФайла = "+ ТипФайла+ ""); Сообщить("ФлагСтандартнойОбработки = "+ ФлагСтандартнойОбработки+ ""); КонецПроцедуры ЗагрузитьВнешнююКомпоненту("mox_sheet.dll"); |
|||
7
pofigos
11.10.13
✎
13:52
|
В принципе отловил отправку на печать любым способом.
Применил RWidjets.dll Процедура ПриПолученииКоманды(пКоманда,пЗаблокироватьКоманду) Если пКоманда=57607 Тогда пЗаблокироватьКоманду=1; //Блокируем стандартную обработку ОткрытьФормуМодально("Обработка.Печать",Конт); Если Конт=1 Тогда Флаг=1; КонецЕсли; КонецЕсли; КонецПроцедуры Вопрос возник следующий. Каким образом передать ссылку на печатную форму? |
|||
8
pofigos
11.10.13
✎
14:02
|
Вопрос снят. Проблема решена.
|
|||
9
pofigos
11.10.13
✎
16:51
|
Итого:
Проблема печати на Server 2008 решена. что понадобилось: 1. Все загруженные компоненты в базе. СписокКомпонент.ДобавитьЗначение("1cpp.dll"); СписокКомпонент.ДобавитьЗначение("1sqlite.dll"); СписокКомпонент.ДобавитьЗначение("FormEx.dll"); СписокКомпонент.ДобавитьЗначение("RWidjets.dll"); СписокКомпонент.ДобавитьЗначение("SpreadSheet.dll"); СписокКомпонент.ДобавитьЗначение("TurboMD.dll"); 2. В глобальнике прописал процедуру определения команды: Процедура ПриПолученииКоманды(пКоманда, пЗаблокироватьКоманду) Перем Конт; Сервис = СоздатьОбъект("Сервис"); Версия=Сервис.ВерсияОС(); //Определить версию ОС на сервере. Если Найти(Версия,"Server40")>0 Тогда Если пКоманда=57607 Тогда //Отправка на печать пЗаблокироватьКоманду=1; //Блокируем стандартную обработку Если Сервис.АктивныйКонтекст(Конт) = 1 Тогда ОткрытьФормуМодально("Обработка.Печать",Конт); Если Конт=1 Тогда Флаг=1; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; КонецПроцедуры 3. Создал "Обработка.Печать". Печать в 7.7 под SRV2008 (поледний пост) Перехватывает любую отправку на печать (меню, кнопка на панели, сочетание Ctrl+P). Печать производится из Excel/ Возможно кому-то и пригодится при решении проблемы печати в связке Windows Server 2008 R2 + SQL Server 2008 R2+ 1C 7.7.27 (Solution 7) |
|||
10
mehfk
11.10.13
✎
19:27
|
Что будешь делать с ?
|
|||
11
Злопчинский
11.10.13
✎
21:51
|
нихрена не понял
|
|||
12
mehfk
12.10.13
✎
09:30
|
Пичалька.
|
|||
13
pofigos
12.10.13
✎
17:21
|
(10) в моем случае этого не будет. Порядка 90% печати документов идет через внешние обработки. И вроде как нигде нет прямой печати без вывода диалога
|
|||
14
pofigos
12.10.13
✎
17:27
|
(11) Все просто. Формируется печатная форма (документа, отчета, номенкалтуры... пофиг). Далее пользователь пытается ее распечатать. Перехватываю событие отправки на печать в глобальнике пунктом 2 из (10). Т.к. на данный момент разделение нагрузки контролируется 2008 и 2003 сервером, проверяю Версию ОС, чтобы открывать диалог печати через Excel на 2008 сервере (2003 покажет стандартный). Контекстом передается печатная форма в обработку Печати... ну и собственно печатается. Сохранение временного .xls прописал на папку пользователя. Так же после печати она автоматом удаляется.
На данный момент столкнулся с проблемой системы безопасности в самом Office 2010. Нужно разрешать открытие файлов с небезопасным содержимым. |
|||
15
vcv
12.10.13
✎
20:56
|
Печать штатной таблицы 1С перехватывается легко. А как перехватить печать таблицы Йоксель?
|
|||
16
pofigos
13.10.13
✎
12:44
|
(15) а что передается в контексте при посылке на печать?
|
|||
17
pofigos
13.10.13
✎
13:02
|
Проблема с офисом решена настройкой групповых политик. А именно добавлением надежного пути размещения файлов.
|
|||
18
vcv
13.10.13
✎
13:32
|
(16) А как этот контекст перехватить? FormEx ПриПечатиТаблицы факт печати таблицы Йоксель не перехватывает.
|
|||
19
smaharbA
13.10.13
✎
13:47
|
нужно событие печати или событие нажатия на кнопку (быстрые клавиши) ?
|
|||
20
smaharbA
13.10.13
✎
13:53
|
set wshshell=CreateObject("wscript.shell")
call wshshell.run("%comspec% /c mofcomp -N:root\cimv2 %SystemRoot%\system32\Wbem\Wbemcons.mof&&pause",9,-1) call wshshell.run("%comspec% /c mofcomp -N:root\subscription %SystemRoot%\system32\Wbem\scrcons.mof&&pause",9,-1) Computer="." Set Service = GetObject("winmgmts:\\" & Computer & "\Root\CIMV2") mondel(Service) Set oFilter = Service.Get("__EventFilter").SpawnInstance_ oFilter.Name = "Мой монитор печати" oFilter.QueryLanguage = "WQL" oFilter.Query = "SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_PrintJob'" oFilter.Put_ FolderMon="C:\PrintLog" FileMon=FolderMon & "\Мой монитор печати лог.txt" Set oConsumer = Service.Get("LogFileEventConsumer").SpawnInstance_ oConsumer.Name = "Мой монитор печати лог" oConsumer.FileName = FileMon oConsumer.Text = "Компьютер: %TargetInstance.Name%, Имя принтера: %TargetInstance.Name%, Документ: %TargetInstance.Document%, Пользователь: %TargetInstance.Owner%, Всего страниц: %TargetInstance.TotalPages%, Время печати: %TargetInstance.TimeSubmitted%, Отпечатано страниц: %TargetInstance.PagesPrinted%" oConsumer.Put_ Set oFilter = Service.Get("__EventFilter.Name='Мой монитор печати'") Set oConsumer = Service.Get("LogFileEventConsumer.Name='Мой монитор печати лог'") Set oBinding = Service.Get("__FilterToConsumerBinding").SpawnInstance_ oBinding.Filter = oFilter.Path_ oBinding.Consumer = oConsumer.Path_ oBinding.Put_ SMTP="mail.n-d.ru" From="[email protected]" Too="[email protected]" Subj="""Мои логи печати на "" & now" Body=Subj SendInterval=86400 * 1000 Script="Call SendPost(""" & SMTP & """, """ & Too & """, """ & From & """, " & Subj & ", " & Body & "):" & _ "Function SendPost(strSMTPServer, strTo, strFrom, strSubject, strBody):" & _ " Set iMsg = CreateObject(""CDO.Message""):" & _ " Set iConf = CreateObject(""CDO.Configuration""):" & _ " Set Flds = iConf.Fields:" & _ " Flds.Item(""http://schemas.microsoft.com/cdo/configuration/sendusing"") = 2:" & _ " Flds.Item(""http://schemas.microsoft.com/cdo/configuration/smtpserver"") = strSMTPServer:" & _ " Flds.Item(""http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout"") = 10:" & _ " Flds.Update:" & _ " iMsg.Configuration = iConf:" & _ " iMsg.To = strTo:" & _ " iMsg.From = strFrom:" & _ " iMsg.Subject = strSubject:" & _ " iMsg.TextBody = strBody:" & _ " iMsg.AddAttachment """ & FileMon & """:" & _ " iMsg.Send:" & _ "End Function" Set Service=GetObject("winmgmts:\\" & computer & "\root\subscription") mondel(Service) Set oTimer=Service.Get("__IntervalTimerInstruction").SpawnInstance_ oTimer.IntervalBetweenEvents = SendInterval oTimer.TimerId = "Мой супертаймер" oTimer.Put_ Set oFilter=Service.Get("__EventFilter").SpawnInstance_ oFilter.Name = "Мой отправитель логов печати" oFilter.QueryLanguage = "WQL" oFilter.Query = "SELECT * FROM __TimerEvent WHERE TimerID='Мой супертаймер'" oFilter.Put_ Set oScript=Service.Get("ActiveScriptEventConsumer").SpawnInstance_ oScript.Name = "Мой скрипт отправителя логов печати" oScript.ScriptText = Script oScript.ScriptingEngine = "VBScript" oScript.Put_ Set oFilter = Service.Get("__EventFilter.Name='Мой отправитель логов печати'") Set oConsumer = Service.Get("ActiveScriptEventConsumer.Name='Мой скрипт отправителя логов печати'") Set oBinding=Service.Get("__FilterToConsumerBinding").SpawnInstance_ oBinding.Filter=oFilter.Path_ oBinding.Consumer=oConsumer.Path_ oBinding.Put_ sub mondel(objService) on error resume next for each c in objService.ExecQuery("select * from __EventFilter") if instr(lcase(c.name),"мой") then msgbox c.name c.Delete_ end if next for each c in objService.ExecQuery("select * from __IntervalTimerInstruction") if instr(lcase(c.TimerId),"мой") then msgbox c.TimerId c.Delete_ end if next for each c in objService.ExecQuery("select * from __TimerEvent") if instr(lcase(c.name),"мой") then msgbox c.name c.Delete_ end if next for each c in objService.ExecQuery("select * from LogFileEventConsumer") if instr(lcase(c.name),"мой") then msgbox c.name c.Delete_ end if next for each c in objService.ExecQuery("select * from ActiveScriptEventConsumer") if instr(lcase(c.name),"мой") then msgbox c.name c.Delete_ end if next for each c in objService.ExecQuery("select * from __FilterToConsumerBinding") if instr(lcase(c.Consumer),"мой") then msgbox c.Consumer c.Delete_ end if next on error goto 0 end sub |
|||
21
Злопчинский
13.10.13
✎
16:38
|
это что делает ?
|
|||
22
smaharbA
13.10.13
✎
17:05
|
один раз запущенное, шлет по почте все задания печати ("расшифровку")
нужно только раз запустить и все, после система сама будет отслеживать и посылать по почте, файл можно удалить и забыть про него, убьет этот "монитор" только переустановка системы. |
|||
23
vcv
13.10.13
✎
17:18
|
(20) Великий человек! Обязательно нужно придумать куда это применить!
Но меня интересовало несколько иное - как в рамках 1С перехватить факт печати таблицы Йоксель и сделать разные всякости, нужные для внутреннего документооборота компании. На данный момент всё работает на базе стандартный таблиц 1С и перехвата печати из FormEx, но хочется пользователям дать удобства в виде панели инструментов Йоксель. Но не получается. Вроде как, в каком-то замшелом году, автор Йокселя соглашался с народом, что события перехвата печати и сохранения таблицы полезны и обещал подумать над осуществлением, но, похоже, не сложилось. Есть еще вариант добыть какую-то старую версию RWidjets, которая, по слухам, имеет функционал перехвата команд меню и панелей 1С. Но полностью проблемы это не решает. |
|||
24
Lionee
13.10.13
✎
17:27
|
Олег вернулся уря
|
|||
25
smaharbA
13.10.13
✎
18:34
|
(23) почти то же, что в (20) через обработка ожидания, но будет только факт, отменить печать "маленького" документа не реально
|
|||
26
smaharbA
13.10.13
✎
18:39
|
если выставить в настройках принтеров оставлять задания, то все задания можно получать офлайн через тот же вми в 1с
если нужно онлайн, то либо вк изобретать, либо что то типа set wshshell=CreateObject("wscript.shell") call wshshell.run("%comspec% /c mofcomp -N:root\cimv2 %SystemRoot%\system32\Wbem\Wbemcons.mof&&pause",9,-1) Computer="." FLog="C:\MonPrn.txt" Set Service = GetObject("winmgmts:\\" & Computer & "\Root\CIMV2") Set oFilter = Service.Get("__EventFilter").SpawnInstance_() oFilter.Name = "MonPrnJobLog" oFilter.QueryLanguage = "WQL" oFilter.Query = "SELECT * FROM __InstanceCreationEvent WITHIN 0.2 WHERE TargetInstance ISA 'Win32_PrintJob'" oFilter.Put_ Set oConsumer = Service.Get("LogFileEventConsumer").SpawnInstance_() oConsumer.Name = "MonPrnJobLog" oConsumer.FileName = FLog oConsumer.Text = "Пользователь: %TargetInstance.Owner%, Компьютер: %TargetInstance.HostPrintQueue%, Принтер: %TargetInstance.Name%, Документ: %TargetInstance.Document%, Время печати: %TargetInstance.TimeSubmitted%, Всего страниц: %TargetInstance.TotalPages%" ' Отпечатано страниц: %TargetInstance.PagesPrinted%" oConsumer.Put_ Set oFilter = Service.Get("__EventFilter.Name='MonPrnJobLog'") msgbox oConsumer.Text Set oConsumer = Service.Get("LogFileEventConsumer.Name='MonPrnJobLog'") Set oBinding = Service.Get("__FilterToConsumerBinding").SpawnInstance_() oBinding.Filter = oFilter.Path_ oBinding.Consumer = oConsumer.Path_ oBinding.Put_ выполнить в 1с и парсить полученный лог |
|||
27
smaharbA
13.10.13
✎
20:09
|
Нужны самые полные права
Перем ПринтерПоУмолчанию,ЗаданияПечати,Колонки; //******************************************* Процедура Сформировать() КонецПроцедуры Функция Win32_X(Путь="Win32_process",Фильтр="name='1CV7S.EXE'",Компьютер=".",Поля="*",Действие="") Если ПустоеЗначение(Фильтр)=1 Тогда Ф=""; Иначе Ф= "Where "+Фильтр; КонецЕсли; ТЗ=СоздатьОбъект("ТаблицаЗначений"); Скрипт=СоздатьОбъект("MSScriptControl.ScriptControl"); Скрипт.Language="javascript"; Локатор=СоздатьОбъект("wbemscripting.swbemlocator"); Сервис=Локатор.ConnectServer(Компьютер,"root\cimv2"); Коллекция=Сервис.ExecQuery("Select "+Поля+" from "+Путь+" "+Ф); Если Коллекция.count=0 Тогда ТЗ.НоваяКолонка("Ошибка"); ТЗ.НоваяСтрока(); ТЗ.Ошибка="Ненайдены экземпляры Select "+Поля+" from "+Путь+" "+Ф; Возврат ТЗ; КонецЕсли; Скрипт.AddObject("Коллекция",Коллекция); Перечисленные=Скрипт.Eval("Перечисленные=new Enumerator(Коллекция)"); Перечисленные=Скрипт.Eval("new Enumerator(Коллекция)"); Свойства=Перечисленные.item(0).Properties_; Скрипт.AddObject("Свойства",Свойства); ПеречисленныеСвойства=Скрипт.Eval("new Enumerator(Свойства)"); Пока ПеречисленныеСвойства.atEnd(0)=0 Цикл Стр=ПеречисленныеСвойства.item(0).name; ТЗ.НоваяКолонка(Стр); ПеречисленныеСвойства.moveNext(0); КонецЦикла; Сеть=СоздатьОбъект("Wscript.Network"); Пользователь=Сеть.UserName; Пока Перечисленные.atEnd(0)=0 Цикл Попытка Если ПустаяСтрока(Действие)=0 Тогда Скрипт.Eval("Перечисленные.item(0)."+Действие+";Перечисленные.item(0).Put_();"); КонецЕсли; Исключение Сообщить(ОписаниеОшибки()); КонецПопытки; НС=ТЗ.НоваяСтрока(); Для к=1 По ТЗ.КоличествоКолонок() Цикл Стр=ТЗ.ПолучитьПараметрыКолонки(к); Попытка Тип=Скрипт.Eval("typeof(Перечисленные.item(0).Properties_.Item('"+Стр+"').Value)"); Если Тип="object" Тогда СтрЗнач=Скрипт.Eval("(Перечисленные.item(0).Properties_.Item('"+Стр+"').Value).toString()"); ИначеЕсли Тип="unknown" Тогда СтрЗнач=""; Массив=Скрипт.Eval("new VBArray(Перечисленные.item(0).Properties_.Item('"+Стр+"').Value)"); СтрЗнач=Массив.toArray(0).toString(0); Иначе СтрЗнач=Перечисленные.item(0).Properties_.Item(Стр).Value; КонецЕсли; ТЗ.УстановитьЗначение(НС,Стр,СтрЗнач); Исключение КонецПопытки; КонецЦикла; Перечисленные.moveNext(0); КонецЦикла; Возврат ТЗ; //Предупреждение(Текст); КонецФункции Процедура МониторПечати() Перем ТЗ; Win32_X("win32_printjob","").Выгрузить(ТЗ); Если ТЗ.КоличествоСтрок()>0 Тогда Если (ТЗ.КоличествоСтрок()=1) и (ТЗ.ВидимостьКолонки("Ошибка")=-1) Тогда Иначе ТЗ.ВыбратьСтроки(); Пока ТЗ.ПолучитьСтроку() = 1 Цикл Стр=0; Если ЗаданияПечати.НайтиЗначение(Тз.ПолучитьЗначение(ТЗ.НомерСтроки,1),Стр,1)=0 Тогда ТЗ.ВыбратьСтроку(); Прервать; КонецЕсли; Для Сч=1 По ТЗ.КоличествоКолонок() Цикл Если ТЗ.ПолучитьЗначение(ТЗ.НомерСтроки,ТЗ.ПолучитьПараметрыКолонки(Сч))=ЗаданияПечати.ПолучитьЗначение(Стр,ТЗ.ПолучитьПараметрыКолонки(Сч)) Тогда Продолжить; КонецЕсли; ТЗ.Выгрузить(ЗаданияПечати); ТЗ.ВыбратьСтроку(); Возврат; КонецЦикла; КонецЦикла; КонецЕсли; КонецЕсли; ТЗ.Выгрузить(ЗаданияПечати); КонецПроцедуры // МониторПечати Процедура ПриОткрытии() ТЗ=Win32_X("win32_printer","default=true",,,"KeepPrintedJobs=true"); ПринтерПоУмолчанию=ТЗ.ПолучитьЗначение(1,"name"); Win32_X("win32_printer","",,,"KeepPrintedJobs=true").Выгрузить(ЗаданияПечати); //Microsoft XPS Document Writer Форма.ОбработкаОжидания("МониторПечати",1); КонецПроцедуры // ПриОткрытии |
|||
28
Злопчинский
13.10.13
✎
22:01
|
(27) не найдены экземпляры Select * from win32_printjob
. ??? |
|||
29
smaharbA
13.10.13
✎
22:03
|
(28) это болванка, поправь
|
|||
30
Злопчинский
13.10.13
✎
22:32
|
929) Олегя. я ж - девелопер.. ;-) максимум на что меня хватило - заменить 1cv7s на 1cv7...
|
|||
31
smaharbA
13.10.13
✎
22:36
|
(30) если выдает "Ненайдены экземпляры Select ", нет заданий, далее отправляй на печать и смотри, важна строка
Win32_X("win32_printer","",,,"KeepPrintedJobs=true") задает всем принтерам сохранение заданий (важно в случае этого кода) ссуть простая, задаем принтерам сохранять задания в очереди и с периодичностью сверяем список заданий до и после |
|||
32
smaharbA
13.10.13
✎
22:36
|
в случае отличий выводим на экран
|
|||
33
Злопчинский
13.10.13
✎
22:41
|
(31) спасибо, понятно!
а эти сохраненные задания - они где располагаются и как их чистить или заново включить несохранение заданий..? |
|||
34
smaharbA
13.10.13
✎
22:49
|
(33) визуально - открыть очередь печати принтера, а так это просто файлы в
%systemroot%\system32\spool\printer\ |
|||
35
Злопчинский
13.10.13
✎
22:52
|
так, подвижка получилась..
направил на печать - теперь в таблице отражается это задание ушедещее. отправил еще распечатку - на другой принтер - появилась в таблице вторая строка, нопосле обновлени я- исчезла, осталась только одн астрока от первого задания... - это что значит..? |
|||
36
Злопчинский
13.10.13
✎
22:54
|
по указанному пути вижу вот такое
http://screencast.com/t/NKTybvhXx |
|||
37
smaharbA
13.10.13
✎
22:56
|
(35) у второго принтера не сохранилось значение сохранять задания после печати
|
|||
38
Злопчинский
13.10.13
✎
22:58
|
из кучи отправленных заданий на разыне принтера вижу только одно в таблице http://screencast.com/t/5zZpIh2x1Y
|
|||
39
smaharbA
13.10.13
✎
22:58
|
(36) все верно, по паре файлов, один файл описание очереди, второй данные отправленные на принтер, содержимое второго зависит от языка принтера, ps, pcl, cap и т.д.
|
|||
40
Злопчинский
13.10.13
✎
22:58
|
(37) и чего делать надо..?
|
|||
41
Злопчинский
13.10.13
✎
22:58
|
а почему вторая пара с нулевыми содержимыми..?
|
|||
42
smaharbA
13.10.13
✎
23:00
|
(38) установи вручную на всех сохранение очереди, код сырой
|
|||
43
smaharbA
13.10.13
✎
23:00
|
(41) вот так и зависает спулер )
|
|||
44
Злопчинский
13.10.13
✎
23:01
|
(42) ну ты барин задачи ставишь....
|
|||
45
smaharbA
13.10.13
✎
23:02
|
отрыл эту болванку по случаю сабжа, можно причесать до рабочего варианта
|
|||
46
Злопчинский
13.10.13
✎
23:04
|
ага, поставил у одног из принтеров сохранение - появилось в таблице...
|
|||
47
Злопчинский
13.10.13
✎
23:06
|
(45) надо! надо причесать до рабочего варианта!
ну чтобы вручную "регилось" сохранение заданий после печати (и отдельную процедурку для вкл/выкл параметра "сохранять заданяи после печати" для принетра(передаваемго параметром). . хотя бы уже полезно, что количество напечататнных страниц есть... . |
|||
48
Злопчинский
13.10.13
✎
23:07
|
полезная вещь!!
|
|||
49
Злопчинский
14.10.13
✎
15:18
|
ух ты, работает!! видно кто чего напечатал и в каком количестве...
|
|||
50
Злопчинский
15.10.13
✎
23:15
|
работает, едридмадрид...
сегодня еще бухия разоралась, что техотдел виноват, что расчетные листки (конфиинфа) распечаталась на складской принтер.. - ну что тут сказать - куда напечатали - туда и распечаталась... и в логах данного скрипта это видно (отчего бы не быть видно - если вылезло на чужлй принтер - то и зарегено что вылезло именно на этот принтер). |
|||
51
Злопчинский
15.10.13
✎
23:17
|
а еще можно считать количество распечатанных листов .. чтобы например бумагу домой не тырили.. ;-)
|
|||
52
H A D G E H O G s
15.10.13
✎
23:24
|
Вкину кусман коду, если кому надо - пишите в vk от Ромикса
function ThreadProc(Param: Cardinal): Cardinal; stdcall; var PrintersInfo: array of TPrinterInfo5; I, Needed, Returned: DWORD; hCurrentPrinter: Cardinal; WaitResult: Cardinal; ObjectIndex: Integer; aJobs: array [0 .. 99] of JOB_INFO_1; enumResult: Boolean; cbBuf: Cardinal; PrinterName, JobsName, CompName, UserName: String; APrinterInfo: TPrinterInfo2; ABytesNeeded: DWORD; begin ErrorStatus := 0; EnumPrinters(PRINTER_ENUM_LOCAL, nil, 5, nil, 0, Needed, Returned); SetLength(PrintersInfo, Needed div SizeOf(TPrinterInfo5)); if not EnumPrinters(PRINTER_ENUM_LOCAL, nil, 5, PrintersInfo, Needed, Needed, Returned) then begin ErrorStatus := 1; ErrorDescription := 'Не удалось получить список принтеров!'; exit; end; if Returned < 1 then begin ErrorStatus := 2; ErrorDescription := 'Не найдено не одного принтера!'; exit; end; for I := 0 to Returned - 1 do begin if not OpenPrinter(PrintersInfo[I].pPrinterName, hCurrentPrinter, nil) then Continue; inc(OpenPrintersCount); // SetLength(hOpenPrintersArray, OpenPrintersCount); hOpenPrintersArray[OpenPrintersCount - 1] := hCurrentPrinter; end; if OpenPrintersCount < 1 then begin ErrorStatus := 3; ErrorDescription := 'Не удалось открыть не одного принтера!'; exit; end; while True do begin for I := 0 to OpenPrintersCount - 1 do begin hCurrentPrinter := hOpenPrintersArray[I]; hCurrentChange := FindFirstPrinterChangeNotification(hCurrentPrinter, PRINTER_CHANGE_ADD_JOB, 0, nil); if hCurrentChange = INVALID_HANDLE_VALUE then Continue; inc(OpenChangesCount); hChangesArray[OpenChangesCount - 1] := hCurrentChange; end; WaitResult := WaitForMultipleObjects(OpenChangesCount, @hChangesArray, false, INFINITE); if WaitResult = WAIT_FAILED then begin ErrorStatus := 4; ErrorDescription := 'Не удалось подключить обработчик ожидания!'; exit; end; ObjectIndex := WaitResult - WAIT_OBJECT_0; hCurrentPrinter := hOpenPrintersArray[ObjectIndex]; Needed := 0; enumResult := EnumJobs(hCurrentPrinter, 0, Length(aJobs), 1, @aJobs, SizeOf(aJobs), Needed, Returned); if not enumResult then begin ErrorStatus := 5; ErrorDescription := 'Принтер начал печать, но не удалось получить список работ принтера!'; exit; end; if Returned < 1 then Continue; PrinterName := ''; JobsName := ''; CompName := ''; UserName := ''; for I := 0 to Returned - 1 do begin if PrinterName = '' then PrinterName := aJobs[I].pPrinterName; if CompName = '' then CompName := aJobs[I].pMachineName; if UserName = '' then UserName := aJobs[I].pUserName; JobsName := JobsName + aJobs[I].pDocument; end; GlobalEvent.ExternalEvent('PrintersEvent', 'НачатаПечать', 'Принтер:' + PrinterName + #13#10 + 'Документы:' + JobsName + #13#10 + 'Компьютер:' + CompName + #13#10 + 'Пользователь:' + UserName); for I := 0 to OpenChangesCount - 1 do FindClosePrinterChangeNotification(hChangesArray[I]); OpenChangesCount := 0; end; end; /// ////////////////////////////////////////////////////////////////// function T_vk_object.meth1(mode: TMode): string; var PID: Cardinal; I: Integer; begin case mode of m_rus_name: Result := 'НачатьНаблюдение'; m_eng_name: Result := 'StartWatch'; m_n_params: g_NParams := 0; // Количество параметров функции m_execute: begin meth2(m_execute); GlobalEvent := IEvent; hThread := CreateThread(nil, 0, @ThreadProc, nil, 0, PID); g_Value := 0; end; // case end; end; /// ////////////////////////////////////////////////////////////////// function T_vk_object.meth2(mode: TMode): string; var I: Integer; begin case mode of m_rus_name: Result := 'ЗакончитьНаблюдение'; m_eng_name: Result := 'StopWatch'; m_n_params: g_NParams := 0; // Количество параметров функции m_execute: begin for I := 0 to OpenChangesCount - 1 do FindClosePrinterChangeNotification(hChangesArray[I]); OpenChangesCount := 0; for I := 0 to OpenPrintersCount - 1 do ClosePrinter(hOpenPrintersArray[I]); OpenPrintersCount := 0; TerminateThread(hThread, 0); GlobalEvent := nil; end; end; // case end; |
|||
53
Злопчинский
15.10.13
✎
23:28
|
И чего с этим мне, девелоперу-1снику, делать..? /;-)
|
|||
54
Torquader
16.10.13
✎
00:17
|
А ещё можно свой монитор печати написать и вообще все задания складывать в файлы, а потом фильтровать и печатать только то, что реально нужно.
P.S. RAW-print server даже школьник может написать. |
|||
55
Злопчинский
16.10.13
✎
00:18
|
(54) мне в школу поздно...
|
|||
56
Злопчинский
16.10.13
✎
00:20
|
давно надо бы что-то типа
Рез = Таб.Напечатать(); если Рез = 0 тогда //алярм КонецЕсли . однако же эта многозадачность и прояая фуета такого сабжа зарубили вусмерть |
|||
57
Torquader
16.10.13
✎
01:01
|
(56) Ставишь pdf-принтер и печатаешь - то есть он не напечатать не может - только нужно правильно настраивать, чтобы имя файла присваивалось одно и то же.
Потом этот файл можно "отправлять" на реальный принтер. |
|||
58
Злопчинский
16.10.13
✎
01:11
|
(57) подтверждение того, что пдф напечатался на реальном принтере...?
|
|||
59
vcv
16.10.13
✎
06:20
|
(56) Отключи в свойствах принтера "использование очереди печати" и будет тебе ожидание успеха/ошибки. Осталось только проверить, напечаталось или нет. Но тут, думаю, smaharbA "Великий и Ужасный" :) поможет.
|
|||
60
VladZ
16.10.13
✎
06:44
|
smaharbA не перестает удивлять.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |