RUS  ENG 

Проблемы с разработкой плагина

Страницы: 1 2 3 След.
RSS
Проблемы с разработкой плагина
 
Вопрос №1 снимается. Похоже, я нашёл ответ.
 
1. Чтобы сказать о том, отчего возникает access violation, надо конечно видеть код (фрагмент кода), его вызывающий. Посмотрите где именно вылетает, проверьте свой код, нет ли неинициализированных переменных, к которым Вы обращаетесь, проверяйте уазатели возвращаемых объектов на nil, прежде чем обращаться к их свойствам и методам.
Объект Zulu - не создаваемый объект. К нему есть доступ только из плагина.
2. Да, возможна. См. SetEventSink у IPluginConnector.
3. Всплывающее окно браузера БД появляется только в оболочке. В случае собственного приложения Вы можете разместить браузер на форме и связать его с картой, чтобы срабатывала "i", либо сосдать всплывающую форму с ним.
 
Спасибо за ответ!
По поводу 3-го вопроса: окно семантической информации не появляется в оболочке.
 
Если не появляется окно семантической информации по щелчку по объекту, то возможны два варианта:
1. объект - примитив, и база не подключена к примитивам (Карта->Настройка слоя->База данных)
2. объект типовой, и база не подключена к данному типу (тогда см. Слой->Структура слоя)
 
Продолжаю писать плагин в Delphi 7. В onZuluEvent пишу обработку события evMapMouseMove. Через какие параметры onZuluEvent передаются RealX и RealY (если можно, напишите пример кода)? Можете ли прислать перечень передаваемых параметров для каждого события (не совсем понятно: в onZuluEvent параметров всего три, а в событиях может быть использовано больше параметров)?
 
RealX и RealY в событиях OnMapMouseXXX через параметры не передаются. Там в param2 содержаться экранные координаты в окне карты. А RealX и RealY получить можно по экранным через IMapView.GetRealX
IMapView.GetRealY
Список событий коротко описан тут: http://politerm.com.ru/zulu5doc/plugins/onzuluevent.htm
 
Пожалуйста, скажите, что я делаю неправильно в onZuluEvent для получения RealX и RealY? Меня интересуют входные параметры методов IMapView.GetRealX и IMapView.GetRealY:

var
Number: Integer;
Byte1, Byte2: Byte;
begin
if EventID = evMapMouseMove then
begin
Number := VarAsType(Param2, varInteger);
Byte1 := Lo(Number);
Byte2 := Hi(Number);
// Потом Byte1 и Byte2 должны передаваться в IMapView.GetRealX и IMapView.GetRealY
end;
end;
 
Не очень понятно, почему Byte. Экранные координаты не до 255. Они должны быть Word. А так ты их обрезаешь.
Экранный x подставляется в IMapView.GetRealY, а экранный у в IMapView.GetRealX, так как в координатах местности X вверх, а Y вправо.
 
Корректен ли следующий фрагмент кода:

var MapView: IMapView;
. . .
. . .
Document := FConnector.Zulu.ActiveDocument;
if Assigned(Document) and (Document.Type_ = eMapDoc) then
MapView := IMapView(Document.NativeDoc);
 
последняя строчка скорее всего д.б.
MapDoc := IMapDoc(Document.NativeDoc);

Document.NativeDoc в случае карты возвращает объект MapDoc. И, кроме того, я бы не прямо приводил указатель на интерфейс (хотя это сейчас работает), а выполнил бы QueryInterface.
 
Мне нужно получить именно интерфейс IMapView (например, чтобы поработать со свойствами CenterX, CenterY).
 
тогда дальше: MapDoc.Views.Active
 
Уже разобрался. Сделал так (и у меня получилось):

var Document: IDocument;
Map: IMapDoc;
MapView: IMapView;
. . .
. . .
Document := FConnector.Zulu.ActiveDocument;
if Assigned(Document) and (Document.Type_ = eMapDoc) then
begin
Map := IMapDoc(Document.NativeDoc);
MapView := Map.Views.Active;
end;
 
Спасибо!
Теперь другая проблема: не получается запустить плагин из плагина:

var
MyPlug: IPluginConnector;
. . .
. . .
MyPlug := FConnector.Zulu.LocatePlugin('MyPlugin');
if not VarIsNull(MyPlug) then
FConnector.Zulu.LoadPlugin('MyPlugin');
 
погодите, может "if VarIsNull(MyPlug) then" ?
 
Нет, не работает. Я хочу проверить: если плагин не был загружен, тогда отобразить его на экране.
 
Приношу извинения, команды для запуска плагинов заведены у нас в объектной модели, но не реализованы. Постараемся доделать к ближайшему релизу.
 
Обеспечил в плагине (в onZuluEvent) обработку события evMapMouseMove. В этом обработчике в текстовое поле выводятся экранные координаты. Пример кода:

case EventID of
evMapMouseMove:
begin
// Определяем экранные координаты X и Y
// . . .
// Отображаем экранные координаты
Edit1.Text := IntToStr(X) + ‘ ’ + IntToStr(Y);
end;
evMapLButtonDblClk:
begin
if MyLayer.CurrentID<>-1 then
ShowMessage(IntToStr(MyLayer.CurrentID));
end;
end;

После этого, при перемещении по карте, при выполнении метода Map.GoToXY, при установке свойства CurrentID, при щелчке левой кнопкой мыши по карте, а также при изменении размеров плагина, практически постоянно стали появляться сообщения об ошибках:

Zulu 5.2 – обнаружена ошибка. Приложение будет закрыто…

Подпись ошибки:
AppName: zulu.exe AppVer: 5.2.0.2370 ModName: ntdll.dll
ModVer: 5.1.2600.2180 Offset: 00011e5a

Инструкция по адресу «0х73d911c7» обратилась к памяти по адресу «0х00000004». Память не может быть «read».

Когда убираю обработку этого события, плагин работает нормально. В чём тут может быть дело?
 
Посмотрите в отладчике, где именно вылетает, посмотрите стек, какой последняя строчка вашего кода выполнялась, после чего происходит вылет (сам он происходит в ntdll.dll).
 
Получил такую информацию:
Окно CPU: останов произошёл в ntdll.DbgBreakPoint ($7C901231).
Call Stack: ничего нет.
Thread Status: Zulu.exe (8636) (State: Stopped; Status Breakpoint; Location: $7C901231)
Modules: Process 8636 - ntdll.dll (DbgBreakPoint $7C901231)
В самом плагине ошибок нет.
 
К предыдущему сообщению:
В Event Log -
ODS: HEAP[Zulu.exe]: Process Zulu.exe (8636)
ODS: Heap block at 036736E0 modified at 03673738 past requested size of 50 Process Zulu.exe (8636)
 
"В самом плагине ошибок нет." - скорее всего, в нем то и ошибка, без него ж работает.
Пришлите фрагмент кода на evMapMouseMove поподробнее, судя по сообщению об ошибке, у Вас выход за границы массива, после чего и получается вылет в неожиданных местах.
 
procedure TMyPlugin.onZuluEvent(EventID: Integer;
const IUnknown: IUnknown; Param1, Param2, Param3: OleVariant);
var
lpBuffer: PChar;
Code: LongInt;
begin
case EventID of
evMapMouseMove: begin
RadixStr(PChar(VarToStr(Param2)), 10, lpBuffer, 2, Code);
edtNote.Lines.Text := lpBuffer;
end;
evMapLButtonUp:
begin
if MyLayer.CurrentID <> -1 then
txtCurrentID.Text := IntToStr(MyLayer.CurrentID)
else
txtCurrentID.Text := '-1';
end;
end;
end;

// Преобразование числа из одной системы счисления в другую (решение Borland'a)
procedure RadixStr(NumStr : pChar; {исходное число}
Radix : LongInt; {исходная система счисления}
ResultStr : pChar; {возвращаемый результат}
NewRadix : LongInt; {"новая" система счисления}
var ErrorCode : LongInt {возвращаемый код ошибки});
var
RadixChar : array[0..35] of Char;
v : LongInt;
i : LongInt;
p : LongInt;
c : Integer;
begin
if ((Abs(Radix) < 2) or (Abs(Radix) > 36)) then
begin
ErrorCode := p;
Exit;
end;

StrLCopy(ResultStr, NumStr, StrLen(NumStr));

for i := 0 to 35 do
begin
if i <= 9 then
RadixChar[i] := Char(48 + (i))
else
RadixChar[i] := Char(64 + (i - 9))
end;

v := 0;

for i := 0 to (StrLen(ResultStr) - 1) do
begin
ResultStr[i] := UpCase(ResultStr[i]);
p := Pos(ResultStr[i], PChar(@RadixChar)) - 1;
if ((p < 0) or (p >= Abs(Radix))) then
begin
ErrorCode := i;
Exit;
end;
v := v * Abs(Radix) + p;
end;

if v = 0 then
begin
ResultStr := '0';
ErrorCode := 0;
exit;
end
else
begin
i:=0;
repeat
ResultStr[i] := RadixChar[v mod NewRadix];
v := v div NewRadix;
Inc(i)
until v = 0;
if Radix < 0 then
begin
ResultStr[i] := '-';
ResultStr[i + 1] := #0
end
else
ResultStr[i] := #0;
p := StrLen(ResultStr);
for i := 0 to ((p div 2) - 1) do
begin
ResultStr[i] := Char(Byte(ResultStr[i]) xor Byte(ResultStr[(p - i) - 1]));
ResultStr[(p - i) - 1] := Char(Byte(ResultStr[(p - i) - 1]) xor Byte(ResultStr[i]));
ResultStr[i] := Char(Byte(ResultStr[i]) xor Byte(ResultStr[(p - i) - 1]))
end;
ResultStr[p] := #0;
ErrorCode := 0;
end;
end;
 
RadixStr(PChar(VarToStr(Param2)), 10, lpBuffer, 2, Code);
У Вас lpBuffer объявлен как PChar и дальше заполняется,
но он нигде не инициализирован! Как так ?!
 
Вы совершенно правы. Это мой глюк. Прошу прощения за доставленное беспокойство.
Большое Вам спасибо за Вашу неоценимую помощь!
Страницы: 1 2 3 След.