Вызов функций Win 32 API в 1C

13.09.10

Разработка - Универсальные функции

Эксперименты с функциями Win 32 API в 1C

А для чего это нужно? ЭКСПЕРИМЕНТЫ!

Конечно же 1С не предоставляет пользователю возможность использования функций Win 32 API. Такую возможность можно решить при помощи ActiveX OLE-клиента такого как dynwrap.dll или dynwrapx.dll, причем dynwrapх.dll намного интересен своими возможностями.

Немного истории: Библиотека dynwrap.dll является результатом труда нескольких разработчиков и была выпущена 10 лет назад. Основное предназначение вызов функций Win 32 API в WHS скриптах. В сентябре 2008 года появился новый расширенный вариант библиотеки dynwrapх.dll, на примере использования которой мы и остановимся.

Пример использования библиотеки для посылки сообщения в mailslot\messngr аля Net Send:

Для начала ее зарегистрируем:
regsvr32.exe <путь-к-компоненту>\dynwrapx.dll - для всех пользователей.
regsvr32.exe /i <путь-к-компоненту>\dynwrapx.dll - для текущего пользователя.

Используем в 1С - Wrap = CreateObject("DynamicWrapperX"); далее регистрируем вызовы функций

Wrap.Register("KERNEL32.DLL", "CreateFile", "i=sllllll", "r=l");
Wrap.Register("KERNEL32.DLL", "WriteFile", "i=lllll", "r=l");
Wrap.Register("KERNEL32.DLL", "CloseHandle", "i=l", "r=l");

Инициализируем переменные

  GENERIC_READ = 2147483648;
  GENERIC_WRITE = 1073741824;
  FILE_SHARE_READ = 1;
  FILE_SHARE_WRITE = 2;
  OPEN_EXISTING = 3;
  FILE_ATTRIBUTE_NORMAL = 128;
  MessageText = AnsiToOem("Всем ПРИВЕТ!");
  AddFrom = AnsiToOem("От друзей");
  AddTo = "SERVER";
  MailslotName = "\\" + AddTo+"\mailslot\messngr";
  Если Wrap<>0 Тогда
  hFile = Wrap.CreateFile(MailslotName, GENERIC_WRITE, FILE_SHARE_READ, 0, 
  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  Если hFile>0 Тогда
  // структура MSG должна быть 
  // FromName + CHR(0) + ToComp + CHR(0) + MSG + CHR(0) + CHR(0)
  // длина не более 424 символов
  MSG = Wrap.Space(425);

Обязательно запоминаем ссылку на переменную
  pStr = Wrap.StrPtr(MSG);
  BytesBeSend = 0;
  Для i=1 По СтрДлина(AddFrom) Цикл
    Wrap.NumPut(КодСимв(Сред(AddFrom,i,1)),pStr,BytesBeSend,"b");
    BytesBeSend = BytesBeSend +1;
  КонецЦикла;  
  Wrap.NumPut(0,pStr,BytesBeSend,"b");
  BytesBeSend = BytesBeSend +1;
  Для i=1 По СтрДлина(AddTo) Цикл
    Wrap.NumPut(КодСимв(Сред(AddTo,i,1)),pStr,BytesBeSend,"b");
    BytesBeSend = BytesBeSend +1;
  КонецЦикла;
  Wrap.NumPut(0,pStr,BytesBeSend,"b");
  BytesBeSend = BytesBeSend +1;  
  Для i=1 По СтрДлина(MessageText) Цикл
    КодС = КодСимв(Сред(MessageText,i,1));
    Wrap.NumPut(КодС,pStr,BytesBeSend,"b");
    BytesBeSend = BytesBeSend +1;
  КонецЦикла;  
  Wrap.NumPut(0,pStr,BytesBeSend,"b");
  ByesBeSend = BytesBeSend +1;
  Wrap.NumPut(0,pStr,BytesBeSend,"b");
  BytesBeSend = BytesBeSend +1;  
  cbWritten = " ";
  pcbWritten = Wrap.StrPtr(cbWritten);
  fResult = Wrap.WriteFile(hFile, pStr, BytesBeSend, pcbWritten, 0);
  Wrap.CloseHandle(hFile);
  Если fResult=1 Тогда
    cbWritten = Wrap.NumGet(pcbWritten,0,"l");
    Если cbWritten>0 Тогда
      Сообщить("Сообщение доставлено");
    Иначе
      Сообщить("Сообщение не отправлено");
    КонецЕсли;
  КонецЕсли;

Вот и все сообщение отправили или не отправили :-) самое главное при использовании функций возвращающих или передаваемых значения пользоваться структурами передачи/приема в данном примере передается указатель на строку содержащую 3 раздела От Кому Сообщение после каждого символ 0 и в конце лидирующий 0. Такую структуру создать штатными средствами 1С "очень сложно".

Это только один из примеров. В библиотека MSDN можно найти множество полезных функций.

Данный пример позволяет реализацию функции "копирования файлов" при чем как показала практика максимальная скорость достигается применение буфера данных 65535 байт при этом возможно отслеживание копирования (%, различные прогресс-бары, докачка) и конечно не забываем про разгрузку процессора 1 мс.

Пример №2 Получение абсолютных координат окна

Регистрируем функцию

Wrap.Register("USER32.DLL", "GetWindowRect", "i=lp", "r=l");
1 параметр дескриптор окна (его можно найти как минимум по 2 параметрам 1 заголовок, 2 класс) или при помощи ВК FormEx (респект! разработчикам)
2 ссылка на структуру Rect (типа)
typedef struct _RECT
{
  LONG left;
  LONG top;
  LONG right;
  LONG bottom;
} RECT, *PRECT;

в 1с будет немного кузяво
Rect = Wrap.Space(256); // необходимо 4 DWord
Обязательно сохраняем указатель на переменную
pStr = Wrap.StrPtr(Rect);
Wrap.GetWindowRect(ДискрипторОкна, Rect);
Учитывая что такой тип данных в 1С не существует, то Rect 1С убила - но идем по сохраненному указателю
и вычитываем Rect только так
left = Wrap.NumGet(pStr,0,"l");
top = Wrap.NumGet(pStr,4,"l");
right = Wrap.NumGet(pStr,8,"l");
bottom = Wrap.NumGet(pStr,12,"l");

Не забываем, что мы получили абсолютные координаты окна (компонента формы и тп) далее мы можем размер окна изменить (как минимум 3 способа Win 32 API + FormEx).

 Чуть позже рассмотрим пример как же все таки обработать внешнее событие если окно не имеет фокуса или открыто выпадающее меню на форме (созданное разными вариантами в тч и штатном - ВыбратьЗначение)

См. также

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Благодаря этим пяти строчкам можно больше не заморачиваться с загрузкой из внешних файлов. Пользуюсь везде, всегда и постоянно.

21.05.2024    18722    dimanich70    81    

141

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    3974    3    John_d    11    

57

Универсальные функции Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    16230    atdonya    23    

56

Универсальные функции Программист Платформа 1С v8.3 Бесплатно (free)

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    5360    ke.92@mail.ru    16    

65

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    14169    YA_418728146    7    

166

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    3456    53    progmaster    8    

4

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    18310    164    sapervodichka    112    

135
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. seermak 665 22.12.08 07:48 Сейчас в теме
>Это только один из примеров. В библиотека MSDN можно найти множество полезных функций
продолжайте....
2. Душелов 4018 22.12.08 09:26 Сейчас в теме
Продолжайте, продолжайте!.. :)
3. MrDen 435 22.12.08 10:03 Сейчас в теме
Спасибо продолжим на примере 1С работа с окном получение координат окна
4. Yasen 490 22.12.08 11:14 Сейчас в теме
5. tormozit 7225 22.12.08 11:21 Сейчас в теме
(4) Да не. Пока в фреймворк не влезем, не увидим ничего полезного с координатами. Нормально идентифицировать элементы управления и окна через WINAPI не получится.
6. Yasen 490 22.12.08 11:26 Сейчас в теме
(5) Я о том, что тебе надо было имя хоста узнавать через API
А про идентификацию элементов согласен.
7. tormozit 7225 22.12.08 11:29 Сейчас в теме
(6) Так через dynwrap я уже сделал бы, но админ права всю малину портят.
9. MrDen 435 22.12.08 11:34 Сейчас в теме
(7) я тоже использовал dynwrap.dll но в нем нет возможности вычитывать память по указателю увы :-( а по поводу прав можно попробовать стартануть задачу от системы
8. MrDen 435 22.12.08 11:31 Сейчас в теме
(5) С фреймворком не пробовал но 1С Spy++ получение информации об окнах классах сделать несложно допустим перебором получение стилей окна и классов стиля и установка отрабатывает нормально, конечно бы хотелось и перехват сообщений окна :-)
создам приложение фреймворка и посмотрю MS Spy++, что выдаст
11. MrDen 435 23.12.08 09:23 Сейчас в теме
(5) приложения на фреймворке нормально определяются окна классы стили
(10) а кто мешает дочернему окну послать SendMessage? и потом все таки не стоит забывать, что это 1С :-) и ньянсов много например Drag&Drop у дочернего окна не установлено на прием только у главного окна но кто мешает установить
Теперь внимание как установить перехватчик сообщения окна или компонента окна? Надо попробовать
12. Fuego 463 23.12.08 09:53 Сейчас в теме
(11) речь моя не о том, что я хочу послать сообщение, а о том, что я хочу его перехватить и обработать в своих интересах.
13. MrDen 435 23.12.08 10:07 Сейчас в теме
(12) вот это уже интереснее с этим действительно проблемы но есть GetMessage другой вопрос куда его сунуть вот тут нужны эксперименты. Не считаю, что это "невозможно".
На всяк случай есть вариант изменения параметра окна без прорисовки, а прорисовку делаеш сам. Тут не стоит забывать, что сторонние окна в 1С сами обрабатывают сообщения, например Grid из Vtools.
14. Fuego 463 23.12.08 13:37 Сейчас в теме
(13) GetMessage используется для других целей:

Код
   hWnd = CreateWindow(...
   ....
   ....

   ShowWindow( hWnd, nCmdShow );

   while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0 ) 
   {
      if (bRet == -1)
      {
         // handle the error and possibly exit
      }
      else
      {
         TranslateMessage( &msg );
         DispatchMessage( &msg );
      }
   }

   return;
Показать полностью


Тут организовывается цикл, в котором DispatchMessage() отправляет сообщения на обработку в CallBack окна. Но ведь в том-то и проблема - Этот цикл может и не отправлять в CallBack сообщения. Ведь есть возможность вообще отработать их по-своему, и программисту никто не запрещает делать этого... А ещё можно сделать Hook-процедуры, которые вообще даже в цикл дочернего окна не пропустят сообщения.
15. MrDen 435 23.12.08 14:05 Сейчас в теме
(14) BOOL GetMessage (LPMSG lpMsg, // указатель на структуру
HWND hWnd, // указатель окна чьи сообщения нужно обрабатывать
UINT wMsgFilterMin, // номер мимимального сообщения для выборки
UINT wMsgFilterMax // номер максимального сообщения для выборки);
несомненно можно сделать лучше поток который будет ждать сообщение,
а такой цикл завесит форму 1С
по поводу HOOK это самый правильный вариант, но как его реализовать в 1С?
Резюмируем:
1 - Задача получить сообщение(я) окну, выбрать то что надо
2 - передать управление дальше или нет (хук)
20. Fuego 463 23.12.08 17:04 Сейчас в теме
(15) НООК я через ВК организовывал. В бардаке не могу найти уже написанный код.
27. vdv2701 91 17.02.20 13:41 Сейчас в теме
(5) Есть идеи как можно идентифицировать элементы управления? Буду очень благодарен.
10. Fuego 463 22.12.08 20:43 Сейчас в теме
Фигня это всё. Ничего путнего не добьёшься с врапперами в 1С. Чё там врапперы - я непосредственно в класс окон влезал с перехватчиками сообщений, но там всё через ... (стандартный интерфейс) у них сделано. Все чайлды на паренте отрабатываюца, и чайлду уже тока WM_PAINT приходит.
16. MrDen 435 23.12.08 14:13 Сейчас в теме
извиняюсь не завесит форму :-)
17. vip 23.12.08 14:41 Сейчас в теме
to mrden
Если так свербит попраграммить, пиши ВК на нормальном языке, не извращайся ты с врапом. Больно смотреть.
Нагородили семь бочек арестантов.
18. MrDen 435 23.12.08 14:59 Сейчас в теме
to vip ВК всегда выход :-) если не получится то так и придется
19. Fuego 463 23.12.08 17:03 Сейчас в теме
Кстати, я где-то брался писать ВК на чистом Win32API, но чёта лень было обёртку писать под IDispatch. ATL меня полностью не устраивает. Да и чистый код шустрее работает :) Есть такая обёртка? (pure C++/Win32API)

А лучше бы на самом деле путёвые функции включить в ВК, и не париться с врапперами :)
21. artbear 1563 24.12.08 07:01 Сейчас в теме
(19) А в чем проблема использования ATL/MFC ?
На чистом АПИ слишком много деталей описывать нужно :(
22. Fuego 463 24.12.08 13:25 Сейчас в теме
(21) да так, хочется знать, что в моём коде нет непонятных идей мелкософтовских программеров. А на чистом API я стал писать, когда захотел глубже понять программирование :) Больше практики получил. А теперь привык уже.
23. ksma 09.12.09 22:17 Сейчас в теме
24. markers 277 20.09.10 11:37 Сейчас в теме
Я конечно извиняюсь что встреваю :) Но нет ли у кого-нибудь простенького примера COM объекта с исходниками на Delphi? Очень хочется, а мозга понять как сделать не хватает по видимому.... Заранее спасибо!
25. AlexanderKai 20.11.14 09:55 Сейчас в теме
Зарегистрировал. При создании DynamicWrapperX = Новый COMОбъект("DynamicWrapperX.2") вылетает с ошибкой "Класс не зарегистрирован". Никто не сталкивался?
26. пользователь 13.11.15 16:04
Сообщение было скрыто модератором.
...
Оставьте свое сообщение