View previous topic :: View next topic |
Author |
Message |
tonyy
Joined: 13 May 2013 Posts: 5
|
(Separately) Posted: Mon May 13, 2013 14:16 Post subject: ошибка при написании wdx плагина |
|
|
Уважаемые участники форума!
нужна помощь. не могу найти ошибку, из-за которой не работает плагин.
вот код:
Code: |
{$E wdx}
library Segd1Inf1;
uses
Windows,
SysUtils,
ContPlug,
Usegdread,
Classes;
const
_DetectString: PAnsiChar = 'EXT="segd"';
_FieldsNum = 3;
_Fields: array[0.._FieldsNum-1] of PAnsiChar = (
'prof ',
'piket ',
'data ');
procedure ContentGetDetectString(DetectString: PAnsiChar; maxlen: integer); stdcall;
begin
lstrcpynA(DetectString, _DetectString,maxlen);
end;
function ContentGetSupportedField(FieldIndex: integer; FieldName: PAnsiChar;
Units: PAnsiChar; maxlen: integer): integer; stdcall;
begin
if FieldIndex in [0..High(_Fields)] then
begin
lstrcpynA(FieldName,_Fields[FieldIndex],maxlen);
strcopy(Units,'');
Result := FT_STRING;
end else Result := ft_NoMoreFields;
end;
function ContentGetValueW(fn: PWideChar; FieldIndex, UnitIndex: integer;
FieldValue: PWideChar; MaxLen, Flags: integer): integer; stdcall;
var
s: AnsiString;
ext: string;
begin
if (FieldIndex<0) or (FieldIndex >= _FieldsNum) then
begin Result:= FT_NOSUCHFIELD; Exit end;
ext:= LowerCase(ExtractFileExt(fn));
if (Flags and CONTENT_DELAYIFSLOW)>0 then
if (ext<>'') then begin Result:= FT_DELAYED; Exit end;
s:= segdread(fn, FieldIndex);
if s=''
then
Result:= FT_FIELDEMPTY
else
begin
lstrcpynW(FieldValue, PWideChar(Widestring(s)), MaxLen);
Result:= FT_STRINGW;
end;
end;
function ContentGetValue(fn: PAnsiChar; FieldIndex, UnitIndex: integer;
FieldValue: PWideChar; MaxLen, Flags: integer): integer; stdcall;
begin
//Result := ContentGetValueW(PWideChar(WideString(fn)), FieldIndex, UnitIndex, FieldValue, MaxLen, Flags);
Result:=ft_fieldempty;
end;
exports
ContentGetDetectString,
ContentGetSupportedField,
ContentGetValueW,
ContentGetValue;
end.
{$R *.res}
begin
end.
|
надеюсь на конструктивную помощь. это мой первый плагин. буду благодарен любой помощи. |
|
Back to top |
|
|
CaptainFlint
Joined: 14 Dec 2004 Posts: 6151 Location: Москва
|
(Separately) Posted: Mon May 13, 2013 16:57 Post subject: |
|
|
Для начала хорошо бы описать, как именно проявляется "неработа" плагина. Что значит "не работает"? Не устанавливается? Устанавливается, но не выводится в списке WDX-плагинов? Выводится, но не показывает список полей? Показывает, но неправильно?.. _________________ Почему же, ё-моё, ты нигде не пишешь "ё"? |
|
Back to top |
|
|
tonyy
Joined: 13 May 2013 Posts: 5
|
(Separately) Posted: Mon May 13, 2013 21:52 Post subject: |
|
|
он устанавливается. выводится в списке wdx плагинов появляются название поле, а вот сами значения не появляются |
|
Back to top |
|
|
MVV
Joined: 15 Oct 2009 Posts: 4811 Location: Ростов-Дон
|
(Separately) Posted: Mon May 13, 2013 22:10 Post subject: |
|
|
Code: | Result:=ft_fieldempty; |
Типа, дядя Коммандир, всё ок, поле пустое... Для теста уже возвращай строчку текстовую какую-нибудь, или число. Впрочем, если есть юникодовская версия функции, тотал (современный) не будет вызывать ансишную.
А юникодовская функция вообще ничего не делает, если нет флага CONTENT_DELAYIFSLOW. А должна. В документации написано как раз, что второй раз функция вызывается без этого флага, как раз в тот момент, когда надо возвращать значение.
Советую сначала отладить плагин без фоновой обработки, обрабатывая поля напрямую. Когда заработает - тогда уже переключаться на обработку в фоне.
Добавлено спустя 6 минут:
А, это некорректные отступы сбивают с толку...
Непонятно, кстати, зачем вызывать segdread для пустого расширения. Ведь эта пара строк завершает функцию только при первом проходе И непустом расширении. При первом проходе и пустом расширении функция продолжит работу.
Code: | if (Flags and CONTENT_DELAYIFSLOW)>0 then
if (ext<>'') then begin Result:= FT_DELAYED; Exit end;
|
Очень рекомендую подключать отладчик к тоталу и отлаживать плагин на ходу, сразу будет понятно, где что не так работает. На худой конец, отображать мессейджбоксы из функции. По коду похоже, что s пустая... Опять же, для тестов можно повозвращать строки/числа.
Кстати, если s - ансишная строка, необязательно её в юникод конвертить перед возвратом тоталу, он прекрасно поймет, если вернуть ему ансишную с результатом FT_STRING. _________________ TCFS2 + TCFS2Tools: Полноэкранный режим и многое другое (обсуждение)
WINCMD.RU: AskParam, CopyTree, NTLinks, Sudo, VirtualPanel… |
|
Back to top |
|
|
CaptainFlint
Joined: 14 Dec 2004 Posts: 6151 Location: Москва
|
(Separately) Posted: Tue May 14, 2013 00:46 Post subject: |
|
|
Вопрос на засыпку: а зачем имена полей плагина завершаются пробелами? Я сразу и не заметил… Я вовсе не уверен, что Тотал вообще умеет такое нормально кушать. Так что первым делом нужно эти пробелы убить, а тестовые колонки в Тотале пересоздать. И если по-прежнему содержимое будет пустым, то надо либо пошаговой отладкой проходить, как предложил MVV, либо комментировать всё содержимое функции ContentGetValueW, заменять её простейшей реализацией (например, безусловным заполнением константной строкой, без всяких segdread и отложенных выполнений), ну и последовательно приводить к желаемому виду, постоянно проверяя, работает ли код после очередного шага. _________________ Почему же, ё-моё, ты нигде не пишешь "ё"? |
|
Back to top |
|
|
tonyy
Joined: 13 May 2013 Posts: 5
|
(Separately) Posted: Tue May 14, 2013 17:47 Post subject: |
|
|
пробелы убрал. проблему это не решило, к сожалению.
как провести пошаговую отладку подключаясь к тоталу? |
|
Back to top |
|
|
ProgMan13
Joined: 19 Aug 2009 Posts: 334
|
(Separately) Posted: Tue May 14, 2013 19:21 Post subject: |
|
|
Отступы действительно дикие, тотал спокойно обрабатывает поля с такими пробелами, вызова функции отложенного выполнения в приведённом примере нет, код рабочий.
Code: | if (Flags and CONTENT_DELAYIFSLOW)>0 then
if (ext<>'') then begin Result:= FT_DELAYED; Exit end; |
Перед Exit должен быть вызов типа MyThreadedFunction, а её нет. Эти две строчки - фэйк - их закомментировать.
Несколько лет назад на форуме поднималась тема про расширения файлов в DetectString. Расширение должно быть написано прописными буквами Так что надо поменять
_DetectString: PAnsiChar = 'EXT="segd"';
на
_DetectString: PAnsiChar = 'EXT="SEGD"';
Перекомпилировать и переустановить(!) плагин.
Я не знаю, правильно ли работает функция segdread, но чтобы проверить работу плагина просто заменить
s:= segdread(fn, FieldIndex);
на
s:= 'TEST'; |
|
Back to top |
|
|
MVV
Joined: 15 Oct 2009 Posts: 4811 Location: Ростов-Дон
|
(Separately) Posted: Tue May 14, 2013 19:38 Post subject: |
|
|
tonyy,
Укажи в качестве отлаживаемого в среде разработки процесса тотал, запускаемый с конфигом, который грузит дебаг-версию плагина, по идее можно будет отлаживать. В Visual Studio так прекрасно работает.
ProgMan13 wrote: | Перед Exit должен быть вызов типа MyThreadedFunction, а её нет. Эти две строчки - фэйк - их закомментировать. |
Это еще зачем? По-моему, те строчки выполняют вполне определенную задачу - сообщают тоталу на первом (основном) проходе, что обработка затянется, и что нужно вызвать функцию во втором (фоновом) проходе. _________________ TCFS2 + TCFS2Tools: Полноэкранный режим и многое другое (обсуждение)
WINCMD.RU: AskParam, CopyTree, NTLinks, Sudo, VirtualPanel… |
|
Back to top |
|
|
ProgMan13
Joined: 19 Aug 2009 Posts: 334
|
(Separately) Posted: Tue May 14, 2013 20:04 Post subject: |
|
|
MVV wrote: | Это еще зачем? По-моему, те строчки выполняют вполне определенную задачу - сообщают тоталу на первом (основном) проходе, что обработка затянется, и что нужно вызвать функцию во втором (фоновом) проходе. |
Хм, да это моё видение. Функция не возвращает никаких данных быстро, слишком специализированная (файлы "segd"). Вызов этой функции в фоне не должен залочить TC, как я понимаю, - тогда согласен.
Тогда добавить Enter/LeaveCriticalSection? |
|
Back to top |
|
|
MVV
Joined: 15 Oct 2009 Posts: 4811 Location: Ростов-Дон
|
(Separately) Posted: Tue May 14, 2013 20:32 Post subject: |
|
|
Критическая секция нужна только при необходимости обращения к общим глобальным ресурсам, которых тут не наблюдается.
В основном потоке функция работает со своими параметрами и завершается.
В фоновом выполняет какие-то операции, это один поток, никто не будет вызывать её одновременно больше 1 раза, поэтому проблем не будет, даже если segdread использует глобальные объекты. _________________ TCFS2 + TCFS2Tools: Полноэкранный режим и многое другое (обсуждение)
WINCMD.RU: AskParam, CopyTree, NTLinks, Sudo, VirtualPanel… |
|
Back to top |
|
|
ProgMan13
Joined: 19 Aug 2009 Posts: 334
|
(Separately) Posted: Tue May 14, 2013 20:45 Post subject: |
|
|
MVV wrote: | В фоновом выполняет какие-то операции, это один поток, никто не будет вызывать её одновременно больше 1 раза, поэтому проблем не будет, даже если segdread использует глобальные объекты. | Ладно, стоит думать, что Кристиан всё сделал как надо. Но если на другой панели эта функция будет вызвана для другого файла или файла с пустым расширением? |
|
Back to top |
|
|
MVV
Joined: 15 Oct 2009 Posts: 4811 Location: Ростов-Дон
|
(Separately) Posted: Tue May 14, 2013 23:41 Post subject: |
|
|
На другой панели это будет либо основной поток, либо тот же фоновый (у тотала только один фоновый поток для загрузки контентных полей).
В любом случае, критическая секция должна быть настолько мала, насколько это возможно. Поэтому если ей где-то и место, то в недрах функции segdread (и то только в моменты обращения к глобальным объектам, и то не факт, что нужна), но уж точно не на всю ContentGetValueW. _________________ TCFS2 + TCFS2Tools: Полноэкранный режим и многое другое (обсуждение)
WINCMD.RU: AskParam, CopyTree, NTLinks, Sudo, VirtualPanel… |
|
Back to top |
|
|
tonyy
Joined: 13 May 2013 Posts: 5
|
(Separately) Posted: Wed May 15, 2013 14:19 Post subject: |
|
|
спасибо большое за помощь. вот что у меня получилось и что более менее работает. хочется узнать, если здесь возможность для улучшения. нет ли тут некорректностей?
Code: |
{$E wdx}
library Segd1Inf1;
uses
Windows,
SysUtils,
ContPlug,
Usegdread,
Classes;
const
_DetectString: PAnsiChar = 'EXT="SEGD"';
_FieldsNum = 3;
_Fields: array[0.._FieldsNum-1] of PAnsiChar = (
'prof',
'piket',
'data');
procedure ContentGetDetectString(DetectString: PAnsiChar; maxlen: integer); stdcall;
begin
lstrcpynA(DetectString, _DetectString,maxlen);
end;
function ContentGetSupportedField(FieldIndex: integer; FieldName: PAnsiChar;
Units: PAnsiChar; maxlen: integer): integer; stdcall;
begin
if FieldIndex in [0..High(_Fields)] then
begin
lstrcpynA(FieldName,_Fields[FieldIndex],maxlen);
strcopy(Units,'');
Result := FT_STRING;
end else Result := ft_NoMoreFields;
end;
function ContentGetValue(fn: pchar; FieldIndex, UnitIndex: integer;
FieldValue: PByte; MaxLen, Flags: integer): integer; stdcall;
var
s:AnsiString;
begin
s:= segdread(fn, FieldIndex);
Strlcopy (PAnsiChar (Fieldvalue),PAnsiChar(s),maxlen-1);
result:=ft_string;
end;
exports
ContentGetDetectString,
ContentGetSupportedField,
ContentGetValue;
end.
|
проверку на расширение 'segd' я сделал в модуле segdread.
еще у меня есть вопросы по поводу функции ContentGetDetectString зачем она нужна и на сколько критично, если ее убрать?
а также по поводу функции ContentGetValueW - в чем ее отличие от ContentGetValue. есть ли смысл делать все таки через ContentGetValueW? |
|
Back to top |
|
|
CaptainFlint
Joined: 14 Dec 2004 Posts: 6151 Location: Москва
|
(Separately) Posted: Wed May 15, 2013 15:27 Post subject: |
|
|
tonyy wrote: | вот что у меня получилось и что более менее работает. |
То есть выходит, что вся проблема была лишь в том, что segdread требует имя файла в ANSI?..
tonyy wrote: | еще у меня есть вопросы по поводу функции ContentGetDetectString зачем она нужна и на сколько критично, если ее убрать? |
Зачем она нужна, описано в документации по написанию плагинов. Если кратко, позволяет отфильтровать файлы, заведомо плагином неподдерживаемые.
tonyy wrote: | а также по поводу функции ContentGetValueW - в чем ее отличие от ContentGetValue. есть ли смысл делать все таки через ContentGetValueW? |
Отличие очевидно: в поддержке юникодных имён. Если попадётся SEGD-файл с юникодным именем, то Тотал не сможет его обработать через плагин, если не будет функции ContentGetValueW.
Если для функции segdread есть аналог, умеющий работать с такими файлами, то лучше сделать ContentGetValueW; если нет, то проще оставить ContentGetValue, чтобы не тратить ресурсы на перекодировку. _________________ Почему же, ё-моё, ты нигде не пишешь "ё"? |
|
Back to top |
|
|
MVV
Joined: 15 Oct 2009 Posts: 4811 Location: Ростов-Дон
|
(Separately) Posted: Wed May 15, 2013 15:27 Post subject: |
|
|
ContentGetValueW - юникодная. Соответственно, плюс в том, что понимает файлы с путями, содержащими всякие там иероглифы и просто символы разных кодовых страниц.
ContentGetDetectString нужна, чтобы тотал автоматом определял строку детектирования. Если функции не будет, строку придется прописывать вручную. Если строки не будет, плагин будет работать для всех файлов, а не только определенных. _________________ TCFS2 + TCFS2Tools: Полноэкранный режим и многое другое (обсуждение)
WINCMD.RU: AskParam, CopyTree, NTLinks, Sudo, VirtualPanel… |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|