|
Вызов окна WPF из Delphi
|
|||
---|---|---|---|
#18+
Задача. Имеется приложение, написанное на Delphi (разработчик, сторонний, но контакты с ним есть). Требуется расширить функциональность приложения, добавив некоторый модуль C# (будет писаться нами). Предполагаемое взаимодействие выглядит так: пишем dll на шарпе, а в дельфийском приложении разработчики добавляют кнопку, которая будет вызывать метод из dll с нужными параметрами. Сложность в том, что шарповый модуль во время работы должен взаимодействовать с пользователем через свои WPF-окна. Причем эти окна должны иметь «модальное» поведение по отношению к приложению (т.е. пока эти окна не закроются, управление обратно в дельфийское приложение не должно возвращаться). Поиски в сети привели к следующему коду запуска WPF-окна: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
И все бы хорошо (окно по дельфийской кнопке запускается, обратно, без закрытия окна, не пускает), но есть маленькая ложка дегтя: при перетаскивании окна остаются некрасивые артефакты (см. приложенный рисунок). После закрытия окна и возврата в основное приложение, они исчезают, но осадочек остается… Через это вопрос: можно ли как-нибудь избавиться от этих артефактов, при этом не передавая управление дельфи раньше времени? А может есть более другой способ вызова модального окна WPF из дельфи? Дополнительная информация:
... |
|||
:
Нравится:
Не нравится:
|
|||
20.12.2021, 07:35 |
|
Вызов окна WPF из Delphi
|
|||
---|---|---|---|
#18+
у вас в запускаемом методе бесконечный цикл, в котором дельфя ожидает закрытия окна, потому и не работает. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.12.2021, 10:35 |
|
Вызов окна WPF из Delphi
|
|||
---|---|---|---|
#18+
Colt, Ну, во-первых, я бы не рекомендовал вызывать CLR через статические экспорты. Лучше использовать COM и взаимодействовать через COM-интерфейсы и COM-маршаллинг. Самый главный плюс такого подхода - на стороне неуправляемого кода можно через COM-интерфейс держать указатель на managed-объект с его состоянием. Хитрого тут ничего нет, просто в сборке объявляем public-интерфейс с COMVisible=True, реализуем его в public-классе c public-конструктором без параметров. Сборку и класс в системе регистрировать не нужно. Далее в дельфи подключаем юнит JclDotNet из библиотеки JCL, инстанциируем CLR-хост, создаем домен, грузим в него сборку, и создаем экземпляр класса, полученный Variant приводим к интерфейсу, и работаем через него (перед этим библиотеку типов дотнетовской dll нужно импортировать в дельфийский юнит, стандартная операция чеhез Component->Import Component). Во-вторых, как показать диалоговое окно, модальное по отношению к нативному окну - здесь стандартно используется WindowInteropHelper: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172.
... |
|||
:
Нравится:
Не нравится:
|
|||
20.12.2021, 11:12 |
|
Вызов окна WPF из Delphi
|
|||
---|---|---|---|
#18+
Roman Mejtes, в том-то и неувязка, что дельфя ничего не может сделать пока я работаю со своим окном (и это меня устраивает), но обратная сторона палки, что дельфя в это время и свое окно отрисовать нормально не может (и это расстраивает). Сон Веры Павловны, спасибо за указание более другого пути, сейчас буду пробовать. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.12.2021, 12:40 |
|
Вызов окна WPF из Delphi
|
|||
---|---|---|---|
#18+
Colt, нужно заблокировать окно и вернуть управление. ну и ты вызываешь Show, а не ShowDialog, не верен, что это блокирует основное окно, но вообще стоит попробовать ... |
|||
:
Нравится:
Не нравится:
|
|||
20.12.2021, 13:11 |
|
Вызов окна WPF из Delphi
|
|||
---|---|---|---|
#18+
И ведь вот что интересно, вот такой примитивный код отрабатывает прекрасно: Код: c# 1. 2. 3. 4. 5. 6. 7.
А вот, если брать такой: Код: c# 1. 2. 3. 4. 5. 6. 7.
То вываливается ошибка (см. рисунок) на вызове ShowDialog Может (в отличии от WinForm) WPF надо как-то предварительно проинициализировать? ... |
|||
:
Нравится:
Не нравится:
|
|||
20.12.2021, 13:56 |
|
Вызов окна WPF из Delphi
|
|||
---|---|---|---|
#18+
... в дополнение к предыдущему. Я потому и начал заморачиваться с дополнительными потоками, что в них WPF-окошко создается и работает (просто не совсем красиво), а напрямую - нет. Но, может я перемудрил, и надо просто как-то объяснить WPF, что можно работать и в основном потоке? WinForms же как-то смог. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.12.2021, 13:58 |
|
Вызов окна WPF из Delphi
|
|||
---|---|---|---|
#18+
Colt Может (в отличии от WinForm) WPF надо как-то предварительно проинициализировать? https://www.sql.ru/forum/1328336/flt-invalid-operation-c0000090-pri-vyzove-double-isnan-double-nan-v-winxp У меня с учетом изложенного по ссылке (перед вызовом операции сохраняем и переопределяем регистры FPU, после операции восстанавливаем) всё работает в основном потоке, и вполне нормально. И да, показ окна - это не единственный вариант возникновения такой ошибки, в общем случае она без правильного выставления регистров может вылететь где и на чём угодно. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.12.2021, 14:29 |
|
Вызов окна WPF из Delphi
|
|||
---|---|---|---|
#18+
Сон Веры Павловны, спасибо! Кажется это оно и есть ... |
|||
:
Нравится:
Не нравится:
|
|||
20.12.2021, 14:55 |
|
Вызов окна WPF из Delphi
|
|||
---|---|---|---|
#18+
Вроде все срослось. Большое спасибо тем, кто направлял на путь истинный. Примерный итог выглядит так: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32.
Примечание: Видимо в режиме отладки студия как-то хитро работает с потоками. Через это, если не делать некую (эмпирической длинны) задержку, то флаги на сопроцессор не успевают прописаться. В "боевом" режиме такого замечено не было. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.12.2021, 06:52 |
|
|
Start [/forum/topic.php?fid=21&fpage=1&tid=1440230]: |
0ms |
get settings: |
20ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
58ms |
get topic data: |
13ms |
get forum data: |
2ms |
get page messages: |
286ms |
get tp. blocked users: |
3ms |
others: | 13ms |
total: | 415ms |
0 / 0 |