Имя: Пароль:
1C
1C 7.7
v7: Как подавить мелькание окна отправки на принтер при Таб.Напечатать(0)
0 Злопчинский
 
06.07.18
08:12
..собственно, сабж
?
1 Карст
 
06.07.18
08:48
сохраняй файл и печатай скриптом
2 Ray Zexter
 
06.07.18
09:06
скорее всего никак, это окно - часть Windows GUI. Даже если его прижать, скорее всего оно вылезет иначе.
3 Злопчинский
 
06.07.18
10:20
(1) и каким скриптом печатать сохраненный моксель?
4 Вафель
 
06.07.18
10:21
а чем они плохи? они же фокус не забирают. или ты в фоне печатешь по 1000 страниц?
5 Злопчинский
 
06.07.18
10:24
(4) где-то удобнее вместо перекурочивания печформы отправлять на печать 100 одинаковых печформ в цикле (ну так сложилось исторически). окно и морготит...
6 Вафель
 
06.07.18
10:30
(5) ну так в это время пользователь все равно не работает. А так видно что процесс идет, а не просто висит
7 mehfk
 
06.07.18
10:48
(3) А если из них сгенерить ёкселем pdf-ки ?
8 Злопчинский
 
06.07.18
11:12
(7) излишество явное.
и Йоксель просто так правильные пдфы не сгенерит, совпадающие по разметке с результатом печати мокселя.
9 Djelf
 
06.07.18
13:00
(0) Сомневаюсь что можно. Никаких флагов по этому поводу тут не вижу: https://msdn.microsoft.com/en-us/library/w6afzd4h.aspx
Если кто-то найдет какой флаг нужно установить, могу  собрать йоксель с поддержкой такого поведения.

А как насчет того чтобы печатать через подключение по OLE?
10 Злопчинский
 
06.07.18
13:13
"печатать через подключение по OLE" - ??? не понял.
вопрос в (0) некритичный, но интересный...
11 Волшебник
 
06.07.18
13:14
Да пусть моргает... Пёс с ним
12 Djelf
 
06.07.18
13:27
(10) Через V77.Application, печатать в другой сессии.
13 d4rkmesa
 
06.07.18
13:59
(8) Актуальная платформа 8-ки весьма прилично сохраняет pdf-ки. Другое дело, что смысла в этом нет.
14 MadDAD
 
06.07.18
20:08
(0) Решается патчем MFC42.dll
MFC42.dll : 4613 (?OnFilePrint@CView@@IAEXXZ)  + 0x516 - заменить 05 на 00
15 MadDAD
 
06.07.18
20:39
+(14) https://cloud.mail.ru/public/MC6Y/jVPC762So

Обработка для этого. Нужен DynWrapX.dll
16 Злопчинский
 
07.07.18
00:15
О!
17 Злопчинский
 
07.07.18
00:22
(15) что-то где-то у меня в памяти что есть какие-то разные DynWrapX.dll ..?
18 Salimbek
 
07.07.18
09:22
19 Djelf
 
07.07.18
17:30
(14) Это конечно хорошо, но недостаточно ;(
Этих версий mfc42.dll тьма тьмущая и в какой из них по 0x516 находится 0х05 я пока не нашел.
20 MadDAD
 
07.07.18
18:46
21 MadDAD
 
07.07.18
18:51
(19) сообщение съелось.
Моя обработка на твоей версии MFC отработала?

Надо искать от начала процедуры CView::OnFilePrint() по смещению 0x516. Там вызов CWnd::ShowWindow(nCmdShow), захардкоден параметр SW_SHOW

(17) Я  использовал отсюда - http://forum.script-coding.com/viewtopic.php?id=5341
22 MadDAD
 
07.07.18
18:54
(21) ординал CView::OnFilePrint() - 4613.

Я ищу процедуру по ординалу, беруадрес по смещению  0x516 от найденного и если там 05 - меняю на 0 - SW_HIDE.

Т.е. окно создается, но невидимое.
23 Djelf
 
07.07.18
19:04
(22) Отличное решение!
(19) Заработало на mfc42.dll 6.6.8063.0 от 19.10.2016. Размер 1,08 МБ (1 136 640 байт)
На mfc42.dll (той же версии) в составе W10х64 вылетает.
24 Злопчинский
 
07.07.18
22:26
а оформить это ВК-шкой можно, чтобы тонны скрипта не писать в конфигах?
25 MadDAD
 
08.07.18
01:28
26 Djelf
 
08.07.18
12:13
(24) ВК ПрогрессПечати https://cloud.mail.ru/public/HM9C/MEXK9QY9G (вк, ert, sqc);


(25) Сделал поиском по паттерну "FFFF6A058D"

Если на какой то mfc42.dll не сработает - давайте ее сюда.
27 Злопчинский
 
08.07.18
23:44
(26) Взял, постараюсь завтра запустить в работу
28 MadDAD
 
09.07.18
07:54
(25) MistaReader не постит сообщения.

(24) Я писал что есть уже пропатченная библиотека. Навсегда отключено окно.
29 MadDAD
 
09.07.18
07:55
(26) Круто! от вопроса до готовой ВК - полтора суток :)
30 MadDAD
 
09.07.18
08:07
Кстати есть похожее решение для проблемы обрезанного до 63 символов имени файла в ФС.ВЫбратьФайл().
31 Злопчинский
 
09.07.18
09:35
(29) патамушта правильно поставленный Злопчинским вопрос уже содержит половину ответа!
32 Злопчинский
 
09.07.18
09:58
(30) ??
33 ADirks
 
09.07.18
10:07
(30), (32)
недавно с удивлением наткнулся... почесав репу вспомнил про svcsvc

    svcsvc = СоздатьОбъект("Svcsvc.Service");
    ИмяФайла = svcsvc.SelectFile(0, "", "Картинки|*.jpg;*.jpeg;*.bmp;*.gif;*.tif;*.tiff");
    Если ПустаяСтрока(ИмяФайла) = 1 Тогда
        Возврат;
    КонецЕсли;
34 trad
 
09.07.18
10:10
чтобы не корячить общесистемную mfc42
можно рядом 1cv7s.exe (1cv7.exe) создать папку 1cv7s.exe.local (1cv7.exe.local)
скопировать туда mfc42.dll и надругаться над копией
35 MadDAD
 
09.07.18
12:10
(34) Так оно же для каждого процесса отдельно грузит и при патче, прочие не трогает.
36 MadDAD
 
09.07.18
12:11
(32) Патч SEVEN.dll по смещению 220CDA68,  заменить 34 на 30.

Будет возвращаться полный путь с каталогом, но зато не обрезанный.
37 MadDAD
 
09.07.18
12:17
(36) Заменяем вызов CFileDialog::GetFileName() на CFileDialog::GetPathName().
38 Вафель
 
09.07.18
12:18
(28) Переходи на реакт.миста
39 trad
 
09.07.18
12:19
(35) при патче в памяти - да.
но можно пропатчить и положить отдельно сам файл.
дополнительный бонус - не зависим от исходного файла.
40 MadDAD
 
09.07.18
12:21
(39) Это да. Я обычно просто рядом складываю.
41 Злопчинский
 
10.07.18
03:37
(34) не понял. а что дает что в папке 1cv7.exe.local
будет лежать поруганный mfc42.dll ...?копией
42 Злопчинский
 
10.07.18
03:38
(26) Поставил в продакшен. если сегодня с утра не дернут - то будет ок...
43 trad
 
10.07.18
07:47
(41) дает то, что не надо портить файл в system32
44 MadDAD
 
10.07.18
09:38
(43) Ну почему сразу портить? :) Кому оно нужно, это окошко?
45 trad
 
10.07.18
13:12
(44) mfc42 - системная библиотека. Используется не только 1cv7
46 trad
 
10.07.18
13:13
* не только в 1cv7
47 Злопчинский
 
10.07.18
17:59
(43) а откуда система знает что надо брать файл из ближней папки к 1С?
48 Злопчинский
 
10.07.18
18:00
(26) Пока работает, не жалуются. Экран все равно подмаргивает, но работает все побыстрее...
.
а в чем скрытый смысл ПерегрзитьФорму()...? что-то я не просек...
49 Djelf
 
10.07.18
18:22
(48) А мну запаривает 100 раз нажимать Файл/Открыть ;)

Можно вообще вырубить создание окна и его обновление.
Или вообще переписать код этой процедуры и всю перехватить ее полностью. Исходники то есть... Не то что у 7ки ;(
50 trad
 
10.07.18
20:14
(47) так прописано в алгоритме винапишной функции loadlibray
51 Злопчинский
 
10.07.18
22:20
(50) а откуда система знает что эта пакап ближняя?
52 trad
 
10.07.18
22:44
забей. Не грузись
53 Злопчинский
 
24.07.18
20:02
(42) Работает в продакшене. траблов не наблюдается.
54 Djelf
 
24.07.18
20:15
(53) Спасибо! И что, действительно чуток быстрее?
Мой логист, поковыряв в носу, сказал что он уходит при печати на перекур и ему на скорость глубоко <censored>.
И на wine@etersoft ну очень старая mfs42!
Там другой паттерн, если 0.0001% с ней столкнется то оно и для этого есть ;)
55 Злопчинский
 
24.07.18
20:43
(54) логисту глубоко сенсоред и на наркозависимость от сигарет, так что всяким нарокманом верить не будем на слово!
;-)
56 Злопчинский
 
24.07.18
20:47
(54) Я бы сказал что ощутимо быстрее.
У меня оператор на внедренной 77 WMS отправляет пакетом упаковочные листы на печать. По целому направлению. А направление - 20-30 заказов. В пакете - две отдельные печатные формы/обработки. В итоге - моргает гораздо быстрее.
.
Конечно, это не бог весть какое ускорение/оптимизация и не критично. Но - все должно быть, по возможности, кузяво!
.
Хорошо бы конечно вообще убрать промаргивание основного экрана - фокус туда-сюда скачет, видимо когда окно это делается невидимым...
57 Злопчинский
 
24.07.18
20:48
(54) А можно выложить на ИС (с указанием оригинального авторства) - авось еще кому-нить пригодится?
58 Djelf
 
24.07.18
21:27
(56) Да, оно такое делает. Переводит окно на себя и блокирует все остальное. Чтобы никто не тыкал лишнего.
Потом дергает окна...
Это то я могу увидеть в коде, а вот как убрать чтобы ничего не нарушить...

Знание ассемблера у мну на уровне Z86 Spectrum ;)

Может MadDAD свое кунгфу проявит?
59 MadDAD
 
25.07.18
12:38
(58) Там в процедуре чуть выше по коду есть
"// disable main window while printing & init printing status dialog
AfxGetMainWnd()->EnableWindow(FALSE);"

Можно занопить или заменить FALSE на TRUE.
60 MadDAD
 
25.07.18
12:40
(59)
CView::OnFilePrint() + 0x045A заменить 0 на 1
61 Djelf
 
25.07.18
12:46
(60) Спасибо! Попробую.
62 MadDAD
 
25.07.18
12:50
(61) Паттерн по идее такой

6A 00 E8 B9 0D FC FF 8B C8 E8 7C D2 FF FF


должно стать:
6A 01 E8 B9 0D FC FF 8B C8 E8 7C D2 FF FF
63 Djelf
 
25.07.18
12:56
(62) Не, это не совсем оно. Там то true/false понятно.
Нужно еще вот это заблокировать
AfxGetMainWnd()->EnableWindow();    // enable main window
Кажется именно оно делает мигания!
Вот это я не знаю как запретить ;(
64 MadDAD
 
25.07.18
13:12
(63) Оно и делает, сначала делает AfxGetMainWnd()->EnableWindow(FALSE) а после завершения печати AfxGetMainWnd()->EnableWindow(TRUE)

Я предложил заменить в первом вызове тоже на TRUE, на скорость не повлияет, но мигать не должно.

Второй вариант:

6A 00 E8 B9 0D FC FF 8B C8 E8 7C D2 FF FF


должно стать:
90 90 90 90 90 90 90 90 90 90 90 90 90 90

Не проверял, может что-то поломаться

Или еще так:

6A 00 E8 B9 0D FC FF 8B C8 E8 7C D2 FF FF

должно стать:

EB 0C E8 B9 0D FC FF 8B C8 E8 7C D2 FF FF  - перепрыгиваем получение главного окна и EnableWindow()
65 Djelf
 
25.07.18
13:57
(64) Эх... придется покопаться. Такого паттерна не нашел, хотя уже штук 7 разных mfc накачал.
Ничё... разберемся...
66 MadDAD
 
25.07.18
14:21
(65) В моей версии находится по смещению 0x5D3A5 от начала файла.
Версия файла 6.6.8064.0
Размер 1 137 664 байт
67 MadDAD
 
25.07.18
14:34
(65) Еще вариант

53 E8 50 A2 FE FF 8B C8 E8 11 05 FF FF
Заменить на
EB 0B 50 A2 FE FF 8B C8 E8 11 05 FF FF

Смещение 0x17062

Версия файла
6.2.8073.0
размер 974 848 байт
68 MadDAD
 
25.07.18
15:13
Наковырял.

Паттерны на разных версиях будут разные, т.к. адреса процедур уезжают.

Дейстовать надо примерно так:

EnableWindowAddr = GetProcAddress(hDll,MAKEINTRESOURCE(2642));// "?EnableWindow@CWnd@@QAEHH@Z", Ordinal = 2642
GetMainWndAddr = GetProcAddress(hDll,MAKEINTRESOURCE(6575));//"?AfxGetMainWnd@@YGPAVCWnd@@XZ", Ordinal = 6575

Ищем такой паттерн:
E8 xx xx xx FF 8B C8 E8 yy yy yy FF
^                    ^
Addr1              Addr2

xxxxxx = 0 - (Addr1 + 4 - GetMainWndAddr) - 0xFF0000
yyyyyy = 0 - (Addr2 + 4 - EnableWindowAddr) - 0xFF0000

Если [Addr1 - 2] = 0x6A И [Addr1 - 1] = 0x00 Тогда
    [Addr1 - 2] = 0xEB; [Addr1 - 1] = 0x0C;

Если [Addr1 - 1] = 0x53 Тогда
    [Addr1 - 1] = 0xEB; [Addr1] = 0x0B;

Если не запутался с порядком байт то должно получиться.
69 MadDAD
 
25.07.18
15:15
(68) Addr2 = Addr1 + 7
70 Djelf
 
25.07.18
15:21
(69) Спасибо. Как раз в эту сторону и копал.
Но опята маловато в таком ковырянии ;)
Попробую половить золотую рыбку...
71 MadDAD
 
25.07.18
15:26
(68) Поправочка

xxxxxx = 0 - (Addr1 + 5 - GetMainWndAddr) - 0xFF0000;
yyyyyy = 0 - (Addr2 + 5 - EnableWindowAddr) - 0xFF0000;
72 Djelf
 
25.07.18
17:15
(71) Выловил, пропатчил, мигает ;)

0xEB 0x0C это мы перепрыгиваем AfxGetMainWnd и EnableWindow
А Если [Addr1 - 1] = 0x53 кого мы перепрыгиваем?

Что то еще... боюсь так просто это не поломать.
73 Злопчинский
 
25.07.18
17:38
Я за вами бздю, то есть бдю. слежу, короче.
Как будет тестовый вариант - публикуйте, подсуну в проект.
74 MadDAD
 
25.07.18
18:01
(72)
"А Если [Addr1 - 1] = 0x53 кого мы перепрыгиваем?"

Это у меня нашлось два разных варианта установки параметра для EnableWindow()

Если  [Addr1 - 1] = 0x53, то джамп должен быть короче.

Один вариант:

text:718EDBA5 6A 00                                                           push    0
.text:718EDBA7 E8 B9 0D FC FF                                                  call    ?AfxGetMainWnd@@YGPAVCWnd@@XZ ; AfxGetMainWnd(void)
.text:718EDBAC 8B C8                                                           mov     ecx, eax        ; this
.text:718EDBAE E8 7C D2 FF FF                                                  call    ?EnableWindow@CWnd@@QAEHH@Z ; CWnd::EnableWindow(int)

Вместо PUSH 0 мы делаем  JMP text:718EDBB3


Второй вариант

.text:73DA7056 53                                                              push    ebx             ; int
.text:73DA7057 E8 50 A2 FE FF                                                  call    ?AfxGetMainWnd@@YGPAVCWnd@@XZ ; AfxGetMainWnd(void)
.text:73DA705C 8B C8                                                           mov     ecx, eax        ; this
.text:73DA705E E8 11 05 FF FF                                                   call    ?EnableWindow@CWnd@@QAEHH@Z ; CWnd::EnableWindow(int)    

Вместо push ebx делаем JMP .text:73DA7063


В общем это условие на разные версии библиотеки.

Могу дать готовую патченную версию MFC42 для тестирования.
75 MadDAD
 
25.07.18
18:09
(74) Патченный MFC42

https://cloud.mail.ru/public/3z78/NuUXSCHWW


Не проверял на моргания.
76 Djelf
 
25.07.18
18:10
(74) Да, давай выкладывай патченную.
Вроде дампером памяти сверяю после патча, но всякое возможно.
77 Djelf
 
25.07.18
18:17
(75) У меня тоже самое получается.
Только на не патченной mfc32 может какое то окно всплывать, а 1С остается относительно неподвижной, то на патченной само окно 1С начинает исчезать и появляться. Эффект жутковатый ;)
78 Злопчинский
 
26.07.18
00:45
как будет что-нить готовое для эксплуатации - маячьте
79 MadDAD
 
26.07.18
09:07
80 Djelf
 
26.07.18
10:40
(79) Видео https://cloud.mail.ru/public/GA7i/kS1rpCCd9
Боюсь что придется процедуру печати в ВК затащить.
81 MadDAD
 
26.07.18
11:51
(80) Да, видимо все не так просто.

У меня при этом мелькает соседнее окно :)
82 Djelf
 
26.07.18
12:18
(81) Да, с шашкой наголо не получается...
Там перед
AfxGetMainWnd()->EnableWindow(0);
есть еще
AfxGetMainWnd()->SetFocus();
Может это оно?
83 MadDAD
 
26.07.18
13:19
(82) Если это в моем патченном - то это я наделал. Заменил вызов AfxGetMainWnd()->EnableWindow(0) на  AfxGetMainWnd()->SetFocus()
84 Djelf
 
26.07.18
15:02
(83) А я то гадаю, откуда оно там взялось ;)

(0) Попробуй, в сочетании с ВК, такой запуск формы печати:

Процедура ПриОткрытии()
    Если Форма.МодальныйРежим()=0 Тогда
        Сервис=СоздатьОбъект("Сервис");
        Сервис.ОткрытьПлавающуюФорму("Обработка.Обработка#",,РасположениеФайла());
        СтатусВозврата(0);
        Возврат;
    КонецЕсли;
КонецПроцедуры


Полностью не избавляет, но значительно веселее выглядит.

А можно и через окна:

Окна=СоздатьОбъект("Окна");
Окна.МинимизироватьВТрей(1);
Окна.Минимизировать();
Печать();
Окна.Максимизировать();

Прогресс печати правда не видать, ну и ладно...