powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Использование CommonDialog без .OCX – проблема с методом ShowPrinter
6 сообщений из 6, страница 1 из 1
Использование CommonDialog без .OCX – проблема с методом ShowPrinter
    #36561056
awl100Alex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Требуется помощь профессионалов!

В своем проекте viewer появилась необходимость использовать CommonDialog для стандартных операций (ShowFont, ShowPrinter и т.д.). Чтобы не таскать за приложением OCX, решил воспользоваться кодами, работающими с comdlg32.dll напрямую...
здесь и здесь .
Все нужные мне методы из этих примеров работают без видимых глюков, кроме метода ShowPrinter.

Суть проблемы в следующем:
При вызове метода ShowPrinter, сначала выполняется инициализация отображения формы диалога печати, выставляются нужные флаги и т.д.
Затем вызывается сама форма RetValue = PrintDlg(PD).
Пользователь производит настройки печати и выбирает принтер, например,
Microsoft Office Document Image Writer, нажимает «Ок».
Далее в процедуре происходит получение структуры DEVMODE (DM) выбранного принтера и его настроек из памяти через
CopyMemory DM, ByVal lpDevMode, Len(DM) - вот именно здесь происходит глюк. Заключается он в том, что CopyMemory копирует в ячейку dmDeviceName...
Код: plaintext
1.
2.
3.
4.
Const CCHDEVICENAME =  32 
Private Type DEVMODE
    dmDeviceName As String * CCHDEVICENAME
    ...
End Type
только 30(!) символов, то есть – вместо «Microsoft Office Document Image Writer» получаем - « Microsoft Office Document Imag ». При этом значение константы CCHDEVICENAME не играет НИКАКОЙ роли!
Из-за этого далее по контексту кода естественно не выполняется условие:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
NewPrinterName = UCase$(Left(DM.dmDeviceName, InStr(DM.dmDeviceName, vbNullChar) -  1 ))
       If Printer.DeviceName <> NewPrinterName Then
          For Each objPrinter In Printers
              If UCase$(objPrinter.DeviceName) = NewPrinterName Then
               Set Printer = objPrinter
              End If
          Next
End If 
и объект Printer остается Default. :(

Подобная проблема безуспешно решалась на других форумах ...
и на этом , в том числе...
А так же, что самое удивительное, на официальном сайте Microsoft ...
где dmDeviceName уже описан, как байтовый массив
Код: plaintext
dmDeviceName( 1  To CCHDEVICENAME) As Byte
все так же значение CCHDEVICENAME роли не играет.
Все эти примеры возвращают одни и те же обрезанные длинные имена принтеров.

Может быть кто-нибудь из ГУРУ сможет объяснить что это за хрень?! И как с ней бороться?

Прилагаю фрагмент проекта только с самим ShowPrinter, все лишнее убрал.
...
Рейтинг: 0 / 0
Использование CommonDialog без .OCX – проблема с методом ShowPrinter
    #36561153
Фотография Konst_One
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
set default printer

ps
см про winnt
...
Рейтинг: 0 / 0
Использование CommonDialog без .OCX – проблема с методом ShowPrinter
    #36561496
SoftParanoik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В данном случае следует анализировать не DEVMODE а DEVNAMES:

Код: plaintext
1.
2.
3.
4.
       CopyMemory DN, ByVal lpDevName, Len(DN)
       Dim Buf() As String
       Buf = Split(DN.extra, vbNullChar)
       MsgBox Mid(Buf( 1 ),  2 )
...
Рейтинг: 0 / 0
Использование CommonDialog без .OCX – проблема с методом ShowPrinter
    #36561640
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
awl100AlexМожет быть кто-нибудь из ГУРУ сможет объяснить что это за хрень?! В MSDN четко написано: Note that this name may be truncated to fit in the dmDeviceName array.

CCHDEVICENAME информационная константа, она сообщает разработчику, сколько символов возвращает поле, а не указывает функции, что делать.
...
Рейтинг: 0 / 0
Использование CommonDialog без .OCX – проблема с методом ShowPrinter
    #36561656
awl100Alex,

В дополнение к сказанному Antonariy-ем, в том же MSDN ситуация описана и дана рекомендация , см. Remarks. В переводе на ваш (неаккуратно порезанный) код: извлекайте информацию из DN, а не DM.
...
Рейтинг: 0 / 0
Использование CommonDialog без .OCX – проблема с методом ShowPrinter
    #36564367
awl100Alex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо всем за помощь!
Отдельная благодарность SoftParanoik за конкретную помощь!
Теперь все работает, как надо.

Выкладываю исправленный код с поправкой от SoftParanoik , для всех, кто столкнется с подобной проблемой.
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Использование CommonDialog без .OCX – проблема с методом ShowPrinter
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]