Win API функция
-
- Гуру
- Сообщения: 879
- Зарегистрирован: 17 июн 2010, 23:14
- Репутация: 207
- Откуда: Москва
Win API функция
С наступившим всех!
Буквально на прошедших днях возникла задача. Дописал утилиту для пакетной печати окон, осталось только реализовать выбор принтера для печати. Поскольку МапВасик не имеет функцию возвращения списка принтеров в системе, товарищ посоветовал использовать стандартную WinApi функцию, которая выполняет подобную операцию (стандартный раскрывающийся список с принтерами в окне печати). Она же кстати и используются в большинстве ПО. Собственно вопрос - как подключить подобную функцию, что и где надо добавлять? Поделитесь опытом, кто уже этим занимался.
Если что - MapBasic 7.8
Буквально на прошедших днях возникла задача. Дописал утилиту для пакетной печати окон, осталось только реализовать выбор принтера для печати. Поскольку МапВасик не имеет функцию возвращения списка принтеров в системе, товарищ посоветовал использовать стандартную WinApi функцию, которая выполняет подобную операцию (стандартный раскрывающийся список с принтерами в окне печати). Она же кстати и используются в большинстве ПО. Собственно вопрос - как подключить подобную функцию, что и где надо добавлять? Поделитесь опытом, кто уже этим занимался.
Если что - MapBasic 7.8
-
- Гуру
- Сообщения: 4168
- Зарегистрирован: 15 окт 2010, 08:33
- Репутация: 1107
- Ваше звание: программист
- Откуда: Казань
Re: Win API функция
найдите, в какой DLL системы находится функция, и импортируйте. Интерфейс описан в доках MS VS или MSDNSlinger писал(а):товарищ посоветовал использовать стандартную WinApi функцию
нашел тут следы экспериментов с DLL 15-летней давности, думаю, мало что изменилось ...
Код: Выделить всё
Include "с:\mapbasic\MAPBASIC.DEF"
Declare Sub dll_proc Lib "с:\tmp\mb_dll.dll" Alias "TESTMBDLL" (f As Float,i As Integer)
Call dll_proc(f,i)
-
- Гуру
- Сообщения: 879
- Зарегистрирован: 17 июн 2010, 23:14
- Репутация: 207
- Откуда: Москва
Re: Win API функция
Спасибо за наводку, однако созданием и подключением функций ни разу не занимался, может ли кто подсказать чуть подробнее на эту тему? В справочнике WinAPI нашёл функцию EnumPrinters (ссылка) с кучей аргументов. Что с ними делать и каким образом подключать?
- Aleksandr Dezhin
- Активный участник
- Сообщения: 244
- Зарегистрирован: 03 фев 2010, 10:47
- Репутация: 14
- Откуда: Москва
Re: Win API функция
Если MapBasic это VBA, то проще наверное список принтеров через WMI получить, например как тут: http://technet.microsoft.com/en-us/libr ... 76746.aspx
- asgs
- Участник
- Сообщения: 89
- Зарегистрирован: 04 авг 2010, 06:35
- Репутация: 1
- Контактная информация:
Re: Win API функция
Лично я бы в данном случае написал небольшую DLL на С++ с упрощенной функцией-оберткой для EnumPrinters, поскольку сильно уж много именованных констант используется в флагах, передавать их в MapBasic несколько затруднительно.Slinger писал(а):Спасибо за наводку, однако созданием и подключением функций ни разу не занимался, может ли кто подсказать чуть подробнее на эту тему? В справочнике WinAPI нашёл функцию EnumPrinters (ссылка) с кучей аргументов. Что с ними делать и каким образом подключать?
Пример подключения DLL в MapBasic можно посмотреть здесь: http://asgs.narod.ru/gplprog.html
Лучше в TiffMosaic.
Злобный йожег
-
- Активный участник
- Сообщения: 120
- Зарегистрирован: 14 апр 2011, 13:24
- Репутация: 5
- Откуда: Екатеринбург
Re: Win API функция
ну..., imho, в данном случае дело не в именованных константах (не так уж и много их здесь, да и работа с ними не сложная), а в "хитрой" организации данных в возвращаемом буфере и в тщательно скрываемом умении/неумении MB работать с указателями. С непривычки всю голову переломашь.asgs писал(а):Лично я бы в данном случае написал небольшую DLL на С++ с упрощенной функцией-оберткой для EnumPrinters, поскольку сильно уж много именованных констант используется в флагах, передавать их в MapBasic несколько затруднительно.
Пример подключения DLL в MapBasic можно посмотреть здесь: http://asgs.narod.ru/gplprog.html
Лучше в TiffMosaic.
Пример получения списка установленных принтеров в MB (каюсь - без обработки ошибок):
Код: Выделить всё
include "mapbasic.def"
define PRINTER_ENUM_LOCAL &H00000002
define PRINTER_ENUM_CONNECTIONS &H00000004
define PRINTER_ENUM_NAME &H00000008
type PRINTER_INFO_1
Flags as integer
pDescription as string
pName as string
pComment as string
end type
declare function EnumPrintersA Lib "winspool.drv" (
byval Flags as integer,
byval Name as integer,
byval Level as integer,
buff() as integer,
byval cbBuf as integer,
pcbNeeded as integer,
pcReturned as integer
) as integer
declare function lstrlen Lib "kernel32" (byval c as integer) as integer
declare function lstrcpy Lib "kernel32" (s as string, byval buff as integer) as integer
declare sub PRINTER_INFO_1_convert( buff() as integer, pi() as PRINTER_INFO_1)
declare sub main()
sub main()
CLS
dim r as integer
dim pi() as PRINTER_INFO_1
dim ibuff() as integer
dim i as integer
dim pcbNeeded as integer
dim pcReturned as integer
print "========================================================="
r = EnumPrintersA(PRINTER_ENUM_CONNECTIONS+PRINTER_ENUM_LOCAL, 0, 1, ibuff, 0, pcbNeeded, pcReturned)
print "размер буфера:" + str$(pcbNeeded) + " байт"
redim ibuff(pcbNeeded/4)
r = EnumPrintersA(PRINTER_ENUM_CONNECTIONS+PRINTER_ENUM_LOCAL, 0, 1, ibuff, pcbNeeded, pcbNeeded, pcReturned)
print "количество структур PRINTER_INFO_1:" + str$(pcReturned)
redim pi(pcReturned)
call PRINTER_INFO_1_convert(ibuff, pi)
print "Список установленных принтеров:"
for i = 1 to pcReturned
print str$(i) + ".------------------------------------------------"
print pi(i).Flags
print pi(i).pDescription
print pi(i).pName
print pi(i).pComment
next
end sub
sub PRINTER_INFO_1_convert(buff() as integer, pi() as PRINTER_INFO_1)
dim i, retv as integer
for i = 1 to ubound(pi)
pi(i).Flags = buff(4 * (i - 1) + 1)
pi(i).pDescription = Space$( lstrlen ( buff(4 * (i - 1) + 2 ) ) )
retv = lstrcpy( pi(i).pDescription, buff(4 * (i - 1) + 2))
pi(i).pName = Space$( lstrlen ( buff(4 * (i - 1) + 3 ) ) )
retv = lstrcpy( pi(i).pName , buff(4 * (i - 1) + 3))
pi(i).pComment = Space$( lstrlen ( buff(4 * (i - 1) + 4 ) ) )
retv = lstrcpy( pi(i).pComment, buff(4 * (i - 1) + 4))
next
end sub
Опять же imho...
для поставленной задачи (выбор нужного принтера и, может быть, каких то его параметров) совсем не нужно так извращаться ( ведь придется еще и реализовать диалог выбора, а в случае установки еще каких то свойств для печати еще писать и писать...)
проще так (Вам ведь не нужен именно список - нужен ведь конкретный выбранный принтер):
Код: Выделить всё
Include "mapbasic.def"
Include "menu.def"
dim p_name as string 'имя выбранного принтера
dim hw as integer
Layout ' или Map, или Browser - вспомогательное "документальное" окно, Layout выбран потому, что его наполнять содержанием не обязательно
hw = frontwindow()
Run Menu Command M_FILE_PAGE_SETUP ' стандартный в MI диалог установки параметров печати (и выбора принтера)
' Сохраняем в переменных нужное:
p_name = windowinfo(hw, WIN_INFO_PRINTER_NAME) ' имя принтера
' для последующей установки с помощью оператора Set Window
' ну и еще какие свойства - бумага, ориентация......
close window hw ' теперь окно уже не нужно...
Set Window .... (то что сохранили)
и печатаем
- asgs
- Участник
- Сообщения: 89
- Зарегистрирован: 04 авг 2010, 06:35
- Репутация: 1
- Контактная информация:
Re: Win API функция
Кстати да, второй вариант попроще будет в реализации, как мне кажется.
Злобный йожег
-
- Гуру
- Сообщения: 879
- Зарегистрирован: 17 июн 2010, 23:14
- Репутация: 207
- Откуда: Москва
Re: Win API функция
Всем спасибо за ответы, особенно SergS. Задача полностью решена.
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и 3 гостя