• Добро пожаловать на Форум пользователей ПО АСКОН. Пожалуйста, авторизуйтесь.
 

Уважаемые пользователи,

Хотим проинформировать вас о режиме работы регистрации на нашем сайте.

Зарегистрироваться возможно в рабочие дни, с 8:00 до 20:00 (мск).

Если у вас возникнут вопросы или потребуется дополнительная информация, не стесняйтесь обращаться к нашей службе поддержки. Вы можете связаться с нами по указанным контактным данным на нашем сайте.

Благодарим вас за понимание и сотрудничество. Мы ценим ваше терпение и стремимся предоставить вам лучший опыт использования нашего сервиса.

С уважением,
Команда Ascon

Модуль замены диалога C#

Автор uiq, 15.02.12, 21:32:06

« назад - далее »

0 Пользователи и 2 гостей просматривают эту тему.

uiq

Здравствуйте, пытаюсь написать модуль замены на c# для лоцмана, который просто выдает сообщение при вызове,
на с++ отлично работает, но на с# лоцман выдает "no argument for format '%s'"
думаю решение элементарно, но найти его не могу к сожалению)

Chaa


uiq

public static int ChangeCreateDialogEx(IntPtr Apphandle,IntPtr Clienthandle,IntPtr ptbuffer,long mode)
{
Messagebox.Show("test");
return 1;
}
перед mode еще 1 параметр типа long, название забыл)

Chaa

Вам нужно добиться того, чтобы ваша DLL на C# экспортировала функцию ChangeCreateDialogEx. Стандартными средствами этого не сделать. Есть разные инструменты, например https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports или http://winch.pinkbile.com/wiki/index.php/Main/Dlltool.

uiq

я этого добился, правив IL код и успешно написал плагин для создания собственного  меню, где экспортировалось 4 функции, потому я думаю проблема в другом

Chaa

Попробуйте для начала объявить функцию как:
public static int ChangeCreateDialogEx(IntPtr AppHandle, IntPtr ClientHandle, IntPtr Buffer, int IDLink, int Mode)
так как long в C# размером в 64 бита, а в Delphi LongInt размером 32 бита.
У себя проверить не могу, так как работаю на Лоцмане 8.5, а замена диалога создания появилась только в 9-м.

uiq

такую же ошибку выдает(
вот код ошибки если поможет чем...
                                                                                                 
Класс ошибки: EConvertError
Сообщение ошибки: No argument for format '%s'.
Адрес ошибки: 0040C26A
------------------------------------------------------------------------------
Стек вызовов, создан 17.02.2012 16:39:02
(0000B265){Loodsman.exe} [0040C265] SysUtils.ConvertErrorFmt + $19
(0000D874){Loodsman.exe} [0040E874] SysUtils.FormatError + $4C
(0000DA77){Loodsman.exe} [0040EA77] SysUtils.FormatBuf + $1A7
(0000D960){Loodsman.exe} [0040E960] SysUtils.FormatBuf + $90
(0000E0C4){Loodsman.exe} [0040F0C4] SysUtils.FmtStr + $54
(000043FA){Loodsman.exe} [004053FA] System.@HandleOnException + $12E
(0000F7EA){Loodsman.exe} [004107EA] SysUtils.EncodeTime + $1E
(0002BAEE){Loodsman.exe} [0042CAEE] Classes.TList.Remove + $6
(0002B7E0){Loodsman.exe} [0042C7E0] Classes.TList.Clear + $10
(0002B78B){Loodsman.exe} [0042C78B] Classes.TList.Destroy + $F
(000021F8){Loodsman.exe} [004031F8] System.@FreeMem + $4
(00003C10){Loodsman.exe} [00404C10] System.TObject.FreeInstance + $C
(00004036){Loodsman.exe} [00405036] System.@ClassDestroy + $2
(00132644){Loodsman.exe} [00533644] JclDebug.TJclStackInfoList.Destroy + $4C
(0002C19C){Loodsman.exe} [0042D19C] Classes.TThreadList.UnlockList + $4
(00131ED4){Loodsman.exe} [00532ED4] JclDebug.TJclGlobalStackList.AddObject + $84
(001324CB){Loodsman.exe} [005334CB] JclDebug.JclCreateStackList + $3B
(00132462){Loodsman.exe} [00533462] JclDebug.DoExceptionStackTrace + $76
(00133279){Loodsman.exe} [00534279] JclDebug.DoExceptNotify + $5D
(0012CC7B){Loodsman.exe} [0052DC7B] JclHookExcept.TNotifierItem.DoNotify + $43
(0009FF5A){Loodsman.exe} [004A0F5A] ascTranslator.TranslateString + $FE
(00004D94){Loodsman.exe} [00405D94] System.@NewAnsiString + $C
(0009FE34){Loodsman.exe} [004A0E34] ascTranslator._TS + $28
(0000E04E){Loodsman.exe} [0040F04E] SysUtils.Format + $A
(007C23B6){Loodsman.exe} [00BC33B6] dkCommon.TdkFrame.RunOther + $256
(007C2314){Loodsman.exe} [00BC3314] dkCommon.TdkFrame.RunOther + $1B4
(0035F072){Loodsman.exe} [00760072] LogonUser.TfrmLogonUser.rbtNTAutorizationClick + $66
(007C27D3){Loodsman.exe} [00BC37D3] dkCommon.TdkFrame.ShowNativeDialog + $117
(006A0D29){Loodsman.exe} [00AA1D29] dfrTree.TdkTree.actTreeCreateExecute + $D1
(000389DF){Loodsman.exe} [004399DF] Classes.TBasicAction.Execute + $F
(00086B5D){Loodsman.exe} [00487B5D] ActnList.TContainedAction.Execute + $31
(00087824){Loodsman.exe} [00488824] ActnList.TCustomAction.Execute + $50
(000388AB){Loodsman.exe} [004398AB] Classes.TBasicActionLink.Execute + $13
(001CF3F7){Loodsman.exe} [005D03F7] dxBar.TdxBarItem.DoClick + $5F
(001CF369){Loodsman.exe} [005D0369] dxBar.TdxBarItem.DirectClick + $39
(001D2D56){Loodsman.exe} [005D3D56] dxBar.TdxBarItemControl.ControlUnclick + $15E
(001D49E4){Loodsman.exe} [005D59E4] dxBar.TdxBarButtonControl.ControlUnclick + $50
(001C001F){Loodsman.exe} [005C101F] dxBar.TCustomdxBarControl.WMLButtonUp + $14B
(0008F707){Loodsman.exe} [00490707] Controls.TControl.WndProc + $2BB
(002D7690){Loodsman.exe} [006D8690] cxContainer.ApplicationGetMessageMsgHookProc + $98
(0009307C){Loodsman.exe} [0049407C] Controls.TWinControl.IsControlMouseMsg + $60
(00093569){Loodsman.exe} [00494569] Controls.TWinControl.WndProc + $499
(001C0936){Loodsman.exe} [005C1936] dxBar.ProcessMouseMessage + $A
(001C0B70){Loodsman.exe} [005C1B70] dxBar.TCustomdxBarControl.WndProc + $204
(00092CF4){Loodsman.exe} [00493CF4] Controls.TWinControl.MainWndProc + $2C
(00039080){Loodsman.exe} [0043A080] Classes.StdWndProc + $14
(001BAA24){Loodsman.exe} [005BBA24] dxBar.TdxBarPopupMenu.Popup + $200
(001BAAB7){Loodsman.exe} [005BBAB7] dxBar.TdxBarPopupMenu.PopupFromCursorPos + $1B
(0069EAF1){Loodsman.exe} [00A9FAF1] dfrTree.TdkTree.trvMainContextPopup + $139
(00090C02){Loodsman.exe} [00491C02] Controls.TControl.DoContextPopup + $26
(00090B54){Loodsman.exe} [00491B54] Controls.TControl.WMContextMenu + $BC
(000971A8){Loodsman.exe} [004981A8] Controls.TWinControl.WMContextMenu + $6C
(0008F707){Loodsman.exe} [00490707] Controls.TControl.WndProc + $2BB
(0007EFFD){Loodsman.exe} [0047FFFD] Forms.TraverseClients + $61
(002D70AD){Loodsman.exe} [006D80AD] cxContainer.ApplicationCallWndProcHookProc + $7D
(00093569){Loodsman.exe} [00494569] Controls.TWinControl.WndProc + $499
(0008F394){Loodsman.exe} [00490394] Controls.TControl.Perform + $24
(000935A2){Loodsman.exe} [004945A2] Controls.TWinControl.DefaultHandler + $2E
(00090BD1){Loodsman.exe} [00491BD1] Controls.TControl.WMContextMenu + $139
(000971A8){Loodsman.exe} [004981A8] Controls.TWinControl.WMContextMenu + $6C
(0008F707){Loodsman.exe} [00490707] Controls.TControl.WndProc + $2BB
(001A981F){Loodsman.exe} [005AA81F] dxBar.dxBarWndProcHook + $22F
(0002F2BF){Loodsman.exe} [004302BF] Classes.TStream.GetPosition + $B
(00093569){Loodsman.exe} [00494569] Controls.TWinControl.WndProc + $499
(0020D020){Loodsman.exe} [0060E020] dxDockControl.dxDockingWndProcHook + $2C
(0007F086){Loodsman.exe} [00480086] Forms.ProcessUpdate + $1A
(00499E56){Loodsman.exe} [0089AE56] ElTree.TElTreeView.WndProc + $16A
(00092CF4){Loodsman.exe} [00493CF4] Controls.TWinControl.MainWndProc + $2C
(00039080){Loodsman.exe} [0043A080] Classes.StdWndProc + $14
(002D70AD){Loodsman.exe} [006D80AD] cxContainer.ApplicationCallWndProcHookProc + $7D
(0009364B){Loodsman.exe} [0049464B] Controls.TWinControl.DefaultHandler + $D7
(000900AC){Loodsman.exe} [004910AC] Controls.TControl.WMRButtonUp + $C
(004A6A68){Loodsman.exe} [008A7A68] ElTree.TElTreeView.WMRButtonUp + $38
(0008F707){Loodsman.exe} [00490707] Controls.TControl.WndProc + $2BB
(002D7690){Loodsman.exe} [006D8690] cxContainer.ApplicationGetMessageMsgHookProc + $98
(00093569){Loodsman.exe} [00494569] Controls.TWinControl.WndProc + $499
(0009307C){Loodsman.exe} [0049407C] Controls.TWinControl.IsControlMouseMsg + $60
(00093569){Loodsman.exe} [00494569] Controls.TWinControl.WndProc + $499
(00499E56){Loodsman.exe} [0089AE56] ElTree.TElTreeView.WndProc + $16A
(00092CF4){Loodsman.exe} [00493CF4] Controls.TWinControl.MainWndProc + $2C
(00039080){Loodsman.exe} [0043A080] Classes.StdWndProc + $14
(0009F242){Loodsman.exe} [004A0242] RtlVclOptimize.DMTSearch + $2A
(000825E0){Loodsman.exe} [004835E0] Forms.TApplication.ProcessMessage + $FC
(0008261A){Loodsman.exe} [0048361A] Forms.TApplication.HandleMessage + $A
(0008283A){Loodsman.exe} [0048383A] Forms.TApplication.Run + $96
(007EDF19){Loodsman.exe} [00BEEF19] Loodsman.Loodsman + $1C9
------------------------------------------------------------------------------

Chaa

Сообщение об ошибке не сильно помогает. Оно говорит нам, что Лоцман попытался загрузить модуль замены и выполнить его, но по какой-то причине это не удалось, и при формировании сообщения об ошибке произошла ошибка уже в самом Лоцмане.
Попробуйте загрузить свой модуль в утилиту depends.exe (входит в состав Platform SDk) и посмотреть, экспортирует ли она функцию ChangeCreateDialogEx на самом деле.

l2qwe

Доброе время суток.
Пробую сделать не модуль замены а простой плагин, Dependency Walker видит InitUserDLLCom и PgiCheckMenuItemCom.
Но плагин всё равно не подключается к Лоцману(
"Не удалось подключить модуль.
Возможно, файл не существует либо имеет неверный формат."
Проект во вложении.
Для компиляции нужно исправит. настройки проекта->События построения
"X:\source\Visual\ExportDll\ExportDll.exe" "$(TargetPath)"
на пут куда распакуется  ExportDll и должен быть установлен Framework 4 (существовать c:\Windows\Microsoft.NET\Framework\v4.0.30319\ilasm.exe и c:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\NETFX 4.0 Tools\ildasm.exe)


l2qwe


Chaa

Описание LoodsmanAddMenuCom на Delphi выглядит примерно так:
TLoodsmanAddMenuCom = record
    stMenu: array [0..MAX_TEXT_LENGTH-1] of AnsiChar;
    stFunction: array [0..MAX_TEXT_LENGTH-1] of AnsiChar;
end;

Поэтому на C# должно быть что-то вроде:
public struct TLoodsmanAddMenuCom {
    byte stMenu[255];
    byte stFunction[255];
}

Вызов new LoodsmanAddMenuCom() не нужен, Лоцман сам выделяет память под нужное кол-во структур TLoodsmanAddMenuCom. Их кол-во возвращает первый вызов InitUserDLLCom.
Функция InitUserDLLCom возвращает кол-во элементов меню, которое она хочет добавить.У вас возвращает 0.
В PgiCheckMenuItemCom лучше вместо string использовать byte*, строки в C# наверняка юникодные.
public static bool PgiCheckMenuItemCom(byte* AFunction, Loodsman.IPluginCall APluginCall)