|
||
| Правила | Регистрация | Пользователи | Сообщения за день | | Поиск | | Справка по форуму | Файлообменник | |
|
Поиск в этой теме |
16.02.2023, 17:10 | #1 | |
Почему не удается подключить GDIplus.dll к VBA?
Регистрация: 14.12.2008
Сообщений: 1,079
|
||
Просмотров: 3257
|
|
||||
Почитай какого типа dll можно использовать в VBA - вопросы отпадут.
__________________
Сообщество программистов Autodesk в СНГ - техническая поддержка |
||||
|
||||
Регистрация: 10.08.2013
Сообщений: 11,052
|
даже в древней версии .Net Framework 1.1 (выпущенной 20 лет назад) есть классы, реализующие поддержку вызова API функций графического интерфейса для рисования. В VBA за эти годы ничего не изменилось - все ручками, ручками)
----- добавлено через ~35 мин. ----- Например, в VBA начертить эллипс на форме Код:
Последний раз редактировалось Сергей812, 18.02.2023 в 01:53. |
|||
|
||||
Регистрация: 14.12.2008
Сообщений: 1,079
|
Удалось начертить линии на UserForm, посмотрите файл Excel.
Но проблема теперь заключается в том, что начальная точка отсчета находится в левом ВЕРХНЕМ углу и ось Y направлена вниз. Есть функция TranslateTransform, которая переносит точку начала координат в другую точку. Попытался применить эту функцию в коде и появляется ошибка что "Функция не найдена в gdiplus.dll". Как исправить эту ошибку? |
|||
|
||||
Регистрация: 14.12.2008
Сообщений: 1,079
|
Немного поменял декларацию функции TranslateTransform согласно описанию данной функции на сайте Microsoft. Добавил пользовательский тип Status, (посмотрите картинки)
Но при вызове функции опять появляется таже ошибка Код:
Правильно ли решение, что параметр "optional" можно не описывать при декларации функции? |
|||
|
||||
Регистрация: 14.12.2008
Сообщений: 1,079
|
Удалось запустить метод TranslateTransform поместив вызов в функцию вычерчивания линии:
Код:
Функция вызывается нормально, правда ничего не делает и возвращает состояние "сбой при выполнении". Изменить ТЕКСТОВЫЙ режим черчения на форме (начало координат слева сверху) на ИЗОМЕТРИЧЕСКИЙ (начало координат слева снизу) не получается. Есть ли возможность настроить ИЗОМЕТРИЧЕСКИЙ режим черчения на UserForm VBA? И еще: Получается что при рисовании каждой линии создается новый объект Grafix который вычерчивает эту линию на форме и потом этот объект удаляется, а линия остается. А в какой контейнер записывается эта линия? Так как при рисовании следующей линии предыдущие не пропадают с экрана. Мне в будущем надо будет постоянно вызывать этот контейнер для отрисовки, так как надо показывать ДИНАМИЧЕСКУЮ отрисовку линии на форме. То есть пока не указана конечная точка линии, на форме должна всегда чертиться, поверх всех остальных линий, линия от начальной точки до курсора мышки. То есть при перемещении мышки по форме в методе MouseMove надо перерисовывать картинку на форме и поверх этой картинки чертить линию от начальной точки до курсора мышки. Как вызвать метод перерисовки формы, чтобы заново чертились все линии до момента черчения новой линии? Эти задачи надо решить для удобства черчения на UserForm. Есть ли способ решения этих задач? |
|||
|
||||
Регистрация: 10.08.2013
Сообщений: 11,052
|
|
|||
|
||||
Инженер-философ Регистрация: 24.04.2019
Хабаровск
Сообщений: 1,875
|
Не спец по Gdi+ и бейсику, но когда-то писал простые программы WinApi на пурсике, что-то еще смутно помню .
Цитата:
Еще важно: WinApi не освобождает память самостоятельно, как VB. Всю очистку нужно делать вручную. Есть вызов CreateDC - нужен и DeleteDC; есть GetDC - нужен ReleaseDC, и т.д. для всех остальных объектов - окон, перьев и т.п.; в справке по функциям WinApi всегда в примечаниях указывают соответствующую функцию очистки. Количество создающих функций должно точно соответствовать количеству удаляющих, иначе в программе начнет течь память; иногда даже Windows можно заглючить своими действиями. Сейчас в программе функция hdc(), которая запрашивает контекст, вызывается много раз, а освобождающая ReleaseDC - редко. Очевидно, форма держит в памяти картинку со всеми начерченными линиями, и показывает ее на экране, когда надо. В чистом WinApi такой халявы нет, там обязательно в ответ на событие WM_PAINT нужно рисовать все, что должно быть видно в окне, иначе вместо картинки будут видны обрывки чужих окон. Придется очищать форму и рисовать по ней заново - сначала все старые линии, потом новую. Известно, что скорость рисования через функции WinApi невысокая, от этого при рисовании экран будет сильно мигать. И есть стандартный трюк с двойной буферизацией, чтобы это мигание убрать. WinApi поддерживает этот трюк через специальные функции:
Код:
Кстати, есть еще фунция CreateDIBSection - она создает картинку поверх массива байтов. В чистом C можно этот массив редактировать впрямую, тем самым рисуя на картинке попиксельно, скорость по сравнению с Gdi получается на порядки выше. Не знаю, можно ли этот трюк провернуть в VB. Цитата:
|
|||
|
||||
Регистрация: 10.08.2013
Сообщений: 11,052
|
это было актуально лет так *-цать назад. Сейчас неизвестно, что больше будет тормозить - API GDI или сам VBA) Да и перерисовывать надо не всю форму, а лишь рабочий холст. Что опять же в VBA потребует приделывания очередных костылей. Слезать с VBA, в общем, надо) В приложении пример рисовалки на .Net Winforms (поставить вершину - левая кнопка мыши, завершить рисование - правая, Ctrl+Z тоже прикручена) - и без оптимизации "движка" не лагает заметно. Все сделано стандартными средствами ЯП.
|
|||
|
||||
Инженер-философ Регистрация: 24.04.2019
Хабаровск
Сообщений: 1,875
|
Посмотрел - мои старые тестовые программки работают как и в стародавние времена: небуферизованный вывод мигает, буферизованный не мигает, доступ к массиву пикселей дает гладкий попиксельный рендер в реальном времени. Но у меня тесты посложенее были, там проволочные объекты крутились, и перерисовывать надо было все линии в новом положении, а не только последний сегмент. Так в небуферизованной версии вся картика мигает, как тут в Net-примере мигает последний сегмент.
А как там перерисовка последнего сегмента сделана? Как он исчезает из предыдущего положения и появляется в новом, восстанавливая ранее закрашенную часть картинки? |
|||
|
||||
Регистрация: 10.08.2013
Сообщений: 11,052
|
Цитата:
т.е. просто заново перерисовываются все линии на холсте (PicturesBox). А последний сегмент дорисовывается - если стоит флаг рисования линии и курсор мыши находится над холстом: тогда от последней фиксированной точки до позиции мыши. А чуть "лагает" - просто гистерезис сделан на пару координатных единиц смещения мыши, чтобы перерисовку по каждому чиху не дергало. ----- добавлено через ~15 мин. ----- собственно весь код, где: WorkCanvas - PicturesBox ака холст OutDrawCoor - метка вывода координат мыши SelectPenColorCBox - комбобокс цвета линии SelectPenWidthCBox - комбобокс толщины линии DrawLineBtn - кнопка рисования линии ClearWorkCanvasBtn - кнопка очистки холста Код:
Последний раз редактировалось Сергей812, 19.02.2023 в 12:54. |
|||
|
||||
Инженер-философ Регистрация: 24.04.2019
Хабаровск
Сообщений: 1,875
|
Цитата:
Когда в WinApi обрабатывается перерисовка, приходится сначала заливать форму фоном, а потом рисовать поверх линии - вот в этот момент и происходит моргание: форма то чисто белая, то на ней уже линии. А буферизация просто выводит новую картинку поверх старой, и мигания не видно, потому что оно на скрытой буферной картинке происходит, и видно только как старая картинка просто мгновенно заменяется новой. А тут все выглядит так, будто старые линии остаются как были, а перерисовывается только последняя, потому и мигает. То есть выглядит так, как будто тут уже есть оптимизация - оптимизированы старые линии. Вот и итересно, почему не мигают старые линии? Должны или мигать все, или не мигать никто. На словах тяжело объяснить. Разницу "мигает - не мигает " лучше видно на моих примерах, во вложении: Пара кубиков. В меню в параметрах на современном железе надо число сторон поставить побольше, штук 20. Вращать клавишами-стрелками, или полосами прокрутки. 1. Кубик без буферизации. 2. Кубик с буферизацией. 3. Простейший калейдоскоп - загрузить картинку и двигать область в левом окне. Подсказки в заголовке, настройки в меню. А в NET - примере старые линии рисуются, как у меня кубик версии 2, а последний сегмент - как кубик версии 1. В чем фокус?! |
|||
|
||||
Инженер-философ Регистрация: 24.04.2019
Хабаровск
Сообщений: 1,875
|
А сейчас все как надо. Никто не мигает - ни старые линии, ни новые.
Кстати, гугель подсказывает, что в Net - формах из коробки поддерживается двойная буферизация. Не могу вспомнить, в старом VB (не VBA) было ли свойство DoubleBuffered у форм, или я его только где-то в Net видел? |
|||
|
||||
Регистрация: 10.08.2013
Сообщений: 11,052
|
Цитата:
----- добавлено через ~5 мин. ----- если есть сильное желание копнуть "вглубь" - исходной код того же класса Graphics, через который в моем примере проводится отрисовка линий. Последний раз редактировалось Сергей812, 19.02.2023 в 14:21. |
|||
|
||||
Инженер-философ Регистрация: 24.04.2019
Хабаровск
Сообщений: 1,875
|
В моих примерах нет проблем с быстродействием, есть проблемы с мерцанием в версии без буферизации. В первой версии мерцание есть даже в маленьком кубике, даже при одиночных нажатиях клавиш. А во второй - нет даже в больших кубиках, у которых явно тормозит прорисовка.
В NET форме есть свойство DoubleBuffered? Его можно выставить в False? Если от этого начнется мерцание, значит, NET просто автоматически делает то, что мне приходилось делать вручную. И тогда в VB тоже придется делать вручную, потому что у него нет такой фишки. |
|||
|
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
не удается подключить "автоматическое фланцевое соединение"( AutoCAD Plant 3D 2019)? | Q_qq | Вертикальные решения на базе AutoCAD | 1 | 24.09.2021 16:59 |
Почему выдает ошибку "не удается найти обозначение детали" из миникаталога ?AutoCAD Plant 3D2019 | Q_qq | Вертикальные решения на базе AutoCAD | 4 | 24.09.2021 16:42 |
Можно ли подключить бытовые сантехнические приборы к К3? | Viarina | Водоснабжение и водоотведение | 5 | 16.10.2014 09:22 |
Почему при расчёте в Robote простой схемы эпюра My получается неправильной? | МишаИнженер | Robot | 13 | 02.03.2010 12:26 |
Почему двутавр 90Б1 высота 893мм ? | dextron3 | Разное | 33 | 11.03.2009 23:31 |