Задать вопрос
mastersoftna
@mastersoftna

Передача HBitmap из dll на Delphi в приложение на C#?

Есть библиотека на Delphi. У нее функция, которая рисует изображение и возвращает его HBitmap:

function TRGOpenHandle(FileName:PAnsiChar; Release:boolean):LongWord; stdcall; export;<br/>
begin<br/>
if FActive then<br/>
 begin<br/>
 try<br/>
 TRG.Clear;<br/>
 TRG.ClearBackground;<br/>
 TRG.LoadFromFile(FileName);<br/>
 TRG.ClearBackground;<br/>
 if Release then result:=TRG.Image.Picture.Bitmap.ReleaseHandle<br/>
 else result:=TRG.Image.Picture.Bitmap.Handle;<br/>
 except on E:Exception do<br/>
 begin<br/>
 MessageBox(0, PAnsiChar(E.Message), 'TRG.DLL', MB_OK + MB_ICONWARNING);<br/>
 FActive:=false;<br/>
 result:=0;<br/>
 end;<br/>
 end;<br/>
 end else<br/>
 begin<br/>
 result:=0;<br/>
 end;<br/>
end;



Если вызывать эту dll из приложения на Delphi, то все работает нормально, изображение отрисовывается. Если вызывать dll из приложения на C#, то изображение неотрисовывается, Image заливается просто белым цветом.


Вызов из C#:

LibWrap.TRGInit();<br/>
 bmp = Bitmap.FromHbitmap((IntPtr)LibWrap.TRGOpenHandle(files[i], false));<br/>
 files[i] = System.IO.Path.GetFileNameWithoutExtension(files[i]);<br/>
 bmp.Save(tiffPath + &quot;\\&quot; + files[i] + &quot;.tif&quot;, System.Drawing.Imaging.ImageFormat.Tiff);



Стоит только добавить в функцию dll вызов модального окна (именно модального), то и в c# все отрисовываетяс отлично. Но работать с постоянно выскакивающими модальными окнами невозможно. Что можно сделать?


Код функции при добавлении вызова модального окна:

function TRGOpenHandle(FileName:PAnsiChar; Release:boolean):LongWord; stdcall; export;<br/>
begin<br/>
if FActive then<br/>
 begin<br/>
 try<br/>
 TRG.Clear;<br/>
 TRG.ClearBackground;<br/>
 TRG.LoadFromFile(FileName);<br/>
Form2.ShowModal;<br/>
 TRG.ClearBackground;<br/>
 if Release then result:=TRG.Image.Picture.Bitmap.ReleaseHandle<br/>
 else result:=TRG.Image.Picture.Bitmap.Handle;<br/>
 except on E:Exception do<br/>
 begin<br/>
 MessageBox(0, PAnsiChar(E.Message), 'TRG.DLL', MB_OK + MB_ICONWARNING);<br/>
 FActive:=false;<br/>
 result:=0;<br/>
 end;<br/>
 end;<br/>
 end else<br/>
 begin<br/>
 result:=0;<br/>
 end;<br/>
end;



Так же отрисовываетяс, но через раз если сделать так:

function TRGOpenHandle(FileName:PAnsiChar; Release:boolean):LongWord; stdcall; export;<br/>
begin<br/>
if FActive then<br/>
 begin<br/>
 try<br/>
 TRG.Clear;<br/>
 TRG.ClearBackground;<br/>
 TRG.LoadFromFile(FileName);<br/>
 TRG.ClearBackground;<br/>
 Application.ModalStarted;<br/>
 Application.HandleMessage;<br/>
 Application.ModalFinished;<br/>
 Application.ProcessMessages;<br/>
 if Release then result:=TRG.Image.Picture.Bitmap.ReleaseHandle<br/>
 else result:=TRG.Image.Picture.Bitmap.Handle;<br/>
 except on E:Exception do<br/>
 begin<br/>
 MessageBox(0, PAnsiChar(E.Message), 'TRG.DLL', MB_OK + MB_ICONWARNING);<br/>
 FActive:=false;<br/>
 result:=0;<br/>
 end;<br/>
 end;<br/>
 end else<br/>
 begin<br/>
 result:=0;<br/>
 end;<br/>
end;



Подскажите как решить эту проблему, или хотя бы как убивать модальное окно программно. В чем может быть загвоздка, почему именно при вызове модального окна все срабатывает, а без него нет?
  • Вопрос задан
  • 3407 просмотров
Подписаться 2 Оценить 1 комментарий
Пригласить эксперта
Ответы на вопрос 3
@korvindest
С модальным окном все понятно, пока оно у вас хоть сколько нибудь висит, объект успевает синхронизироваться и уже отправляется в C# целиком.

Решать это задержкой не вариант, но для теста можете попробовать поставить просто большой wait (или Delay, не помню уже как в делфи называется).

Вы должны убедится, что в момент передачи управления в C# объект в памяти уже содержит то что вы передаете.

Это конечно все предположения, но думаю, что так оно и есть.
Ответ написан
GavriKos
@GavriKos
Можете попробовать такую механику — при вызове функции библиотеки в нее предаете колбек. Когда библиотека точно отрисует картинку (надеюсь, это можно проверить) — она вызовет колбек основного приложения.
Ответ написан
shsweb
@shsweb
Попробуйте вместо вызова модального окна:
for i:=0 to 100 do Application.ProcessMessages;
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы