Технология создания плагинов и программ-дополнений

Здесь обсуждаются графические оболочки, боты, языковые файлы и другие дополнения к CommFort 4.
ZigZagkms
Сообщения: 109
Зарегистрирован: 08:23, 11.12.2008
Откуда: Комсомольск-на-Амуре
Контактная информация:

Re: Технология создания плагинов и программ-дополнений

Сообщение ZigZagkms » 09:02, 16.05.2010

Maxim Mirgorodsky писал(а):В таком случае Вам нужно самостоятельно в плагине производить масштабирование.

Ограничения по размерам изображений в зависимости от соответствующей опции:

Маленькие не более 15000 пикселов.
Средние не более 50000 пикселов.
Большие не более 100000 пикселов.
Очень большие не более 200000 пикселов.

Максимальная ширина - 550 пикселов.


Спасибо. это как раз то что нужно было
Забросил, всем спасибо, исходники раздаю кому надо https://github.com/ZigZagkms

$teelR@t
Сообщения: 348
Зарегистрирован: 19:14, 30.03.2008
Откуда: Украина
Контактная информация:

Re: Технология создания плагинов и программ-дополнений

Сообщение $teelR@t » 04:16, 27.05.2010

Добрый день!
У меня возникло 2 проблемы.
1. Делал плагин для сервера на Delphi 2007 - всё нормально работало, обновился на 2010 - перестал получать ответы на запросы от серверной части :(. Получается, что плагин запускается, выполняется функция PluginInit, в которой вызывается форма для показа, на ней кнопка и поле Memo, по щелчку на кнопке вызывается FCommFortProcess(FdwPluginID, 41, 0, 0), где

Код: Выделить всё

TtypeCommFortProcess = function(dwPluginID : DWORD; dwMessageID : DWORD; bMessage : PCHAR; dwMessageLength : DWORD) : BYTE; stdcall;
и
FCommFortProcess : TtypeCommFortProcess;

затем я поставил простейшее отображение окошка ShowMessage('asd') при вызове сервером функции

Код: Выделить всё

function PluginProcess(dwMessageID : DWORD; bMessage : PString; dwMessageLength : DWORD) : BYTE;


В 2007-ом Delphi всё работало, а вот в 2010 не работает :(. Не понимаю, или вообще серверу не передаётся запрос или передаётся, но принять его плагин не может :(.
2. Имя бота, создаваемого плагином обрезается до одного первого символа и пол становится женским. Таже самая ситуация - на 2007-ом делфи ничего не обрезалось, а пол ставился на мужской, а на 2010 вылез вот такой косяк :( .

Моё предположение - проблема с кодировками. Дело в том, что в 2010 делфях в отличие от 2007 функция PAnsiChar, не поддерживается. Похоже кодировка Ansi теперь не поддерживается. Хотя в коде варируют только Pchar и просто char. Кстати плагин я решил откомпилить плагин от sonic-а (viewtopic.php?p=15307#p15307), я просто взял его за базу для своего плагина, но и чистый плагин от sonic-a тоже не принимает сообщения от сервера + обрезает ник бота и пол женский.

Вариант "перейди назад на 2007 делфи" не принимается. Прошу помоч в сложившейся ситуации :)

Аватара пользователя
DIGGER
Сообщения: 264
Зарегистрирован: 13:46, 15.05.2009

Re: Технология создания плагинов и программ-дополнений

Сообщение DIGGER » 11:19, 27.05.2010

Заменяешь в коде свой Pchar на PAnsiChar и многие функции заведутся :)

Дело в том, что в 2010 делфях в отличие от 2007 функция PAnsiChar, не поддерживается.

Утверждение ложно.

$teelR@t
Сообщения: 348
Зарегистрирован: 19:14, 30.03.2008
Откуда: Украина
Контактная информация:

Re: Технология создания плагинов и программ-дополнений

Сообщение $teelR@t » 11:32, 27.05.2010

DIGGER писал(а):Заменяешь в коде свой Pchar на PAnsiChar и многие функции заведутся :)


Да нет... Ничего не завелось... Как ничего не получалось от сервера, так и не получается... И ник и пол бота такими же остались...

Код я беру чистый от sonic-а... только перекомпилировал его в 2010 делфях и изменил Pchar на PAnsiChar.

Аватара пользователя
DIGGER
Сообщения: 264
Зарегистрирован: 13:46, 15.05.2009

Re: Технология создания плагинов и программ-дополнений

Сообщение DIGGER » 13:13, 27.05.2010

Код в студию. так как вспоминается при Ваших словах только Станиславский))

$teelR@t
Сообщения: 348
Зарегистрирован: 19:14, 30.03.2008
Откуда: Украина
Контактная информация:

Re: Технология создания плагинов и программ-дополнений

Сообщение $teelR@t » 14:57, 27.05.2010

comm_form.pas

Код: Выделить всё

unit comm_form;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, comm_info, comm_func, ExtCtrls;

type
  TCForm = class(TForm)
    CheckBox1: TCheckBox;
    LabeledEdit1: TLabeledEdit;
    LabeledEdit2: TLabeledEdit;
    CheckBox2: TCheckBox;
    Button1: TButton;
    Memo1: TMemo;
    Button2: TButton;
    Memo2: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    FCommFortProcess : TtypeCommFortProcess;
    FdwPluginID      : DWORD;
  public
    property CommFortProcess : TtypeCommFortProcess read FCommFortProcess write FCommFortProcess;
    property dwPluginID : DWORD read FdwPluginID write FdwPluginID;
  end;

var
  CForm: TCForm;

implementation

{$R *.dfm}

procedure TCForm.Button1Click(Sender: TObject);
var msg: TStringStream;
begin
  if CheckBox2.Checked then
    msg:=StatusToChannel(LabeledEdit1.Text, LabeledEdit2.Text)
  else
    msg:=MsgToChannel(LabeledEdit1.Text, LabeledEdit2.Text);
  FCommFortProcess(FdwPluginID, 20, PAnsiChar(msg.DataString), msg.InstanceSize);
end;

procedure TCForm.Button2Click(Sender: TObject);
begin
  FCommFortProcess(FdwPluginID, 41, 0, 0);
end;

end.


comm_info.pas

Код: Выделить всё

unit comm_info;

interface

uses Windows;

type
  TPluginInfo = packed record
    strPluginName        : Array [0..254] of char;
    strPluginDescription : Array [0..254] of char;
    strPluginVersion     : Array [0..254] of char;
  end;   
  PPluginInfo = ^TPluginInfo;

  TBotUserInfo = packed record
    strBotName    : Array [0..254] of char;
    strBotPasswor : Array [0..254] of char;
    bIsFemale     : boolean;
  end;
  PBotUserInfo = ^TBotUserInfo;

  TtypeCommFortProcess = function(dwPluginID : DWORD; dwMessageID : DWORD; bMessage : PAnsiCHAR; dwMessageLength : DWORD) : BYTE; stdcall;

const
PM_PLUGIN_SNDMSG_PUB          = 20; //plugin -> commfort: Опубликовать сообщение в канал: Число(режим)+текст(канал)+текст(сообщение) Режимы: 0 - текст опубликован обычно 1 - текст опубликован состоянием (F9)
PM_PLUGIN_USERS_GET           = 41; //plugin -> commfort: Запросить список подключенных пользователей
PM_PLUGIN_MSG_PRIV            = 60; //commfort -> plugin: Сообщение в приват: Пользователь()+число(режим)+текст(сообщение) Режимы: 0 - текст опубликован обычно 1 - текст опубликован состоянием (F9)
PM_PLUGIN_USERS_LIST          = 91; //commfort -> plugin: Список подключенных пользователей (ответ на запрос с ID=41): Число(количество подключенных пользователей)+пользователь()*количество подключенных пользователей
  PRE_PLUGIN_MSG                = 0;  //commfort -> plugin: Премодерация сообщений
  PRE_PLUGIN_THEME              = 1;  //commfort -> plugin: Премодерация тем
  PRE_PLUGIN_ANNOUNCMENT        = 2;  //commfort -> plugin: Премодерация объявлений

implementation

end.


comm_plugin.pas

Код: Выделить всё

unit comm_plugin;

interface

uses Windows, SysUtils, Classes, comm_info, comm_form, comm_func;

const
  PLU_NAME     = 'test';
  PLU_DESC     = 'test';
  PLU_VER      = '1';

  BOT_NAME     = 'test';
  BOT_PASS     = '123';
  BOT_ISFEMALE = FALSE;

var dwPluginID      : DWORD;
    CommFortProcess : TtypeCommFortProcess;
    CForm           : TCForm;

function PluginInit(dwThisPluginID : DWORD; plInfo : PPluginInfo; botInfo : PBotUserInfo; func1 : TtypeCommFortProcess) : BYTE; cdecl; stdcall;
function PluginTerminate : BYTE; cdecl; stdcall;
function PluginProcess(dwMessageID : DWORD; bMessage : PString; dwMessageLength : DWORD) : BYTE; cdecl; stdcall;
function Premoderation(dwMessageID : DWORD; bMessage : PAnsiCHAR; dwMessageLength : PDWORD) : boolean; cdecl; stdcall;

exports PluginInit, PluginTerminate, PluginProcess, Premoderation;

implementation

function PluginInit(dwThisPluginID : DWORD; plInfo : PPluginInfo; botInfo : PBotUserInfo; func1 : TtypeCommFortProcess) : BYTE;
begin
  dwPluginID := dwThisPluginID;
  //При инициализации планину присваивается идентификатор
   //его необходимо обязательно сохранить, и указывать
   //в качестве первого параметра при пересылке сообщений программе

  plInfo^.strPluginName        := PLU_NAME;
  plInfo^.strPluginDescription := PLU_DESC;
  plInfo^.strPluginVersion     := PLU_VER;
  //Заполняем структуру информации о плагине
   //Обязательно необходимо указать версию CommFort server для которой
   //предназначен планин

  botInfo^.strBotName          := BOT_NAME;
  botInfo^.strBotPasswor       := BOT_PASS;
  botInfo^.bIsFemale           := BOT_ISFEMALE;
  //Заполняем авторизационные данные виртуального пользователя,
   //от имени которого будет действовать плагин.

  CommFortProcess              := func1;
  //указываем функцию обратного вызова,
   //с помощью которой можно будет отправлять команды программе

  CForm                        := TCForm.Create(nil);
  CForm.CommFortProcess        := @CommFortProcess;
  CForm.dwPluginID             := dwPluginID;
  CForm.Show;

  result                       := 0;
end;

function PluginTerminate : BYTE;
begin
  //данная функция вызывается при завершении работы программы
  if Assigned(CForm) then FreeAndNil(CForm);
  result := 0;
end;

function PluginProcess(dwMessageID : DWORD; bMessage : PString; dwMessageLength : DWORD) : BYTE;
var msg: TStringStream;
    name, ip, male, channel, text: string;
    I, J, N: integer;
begin
  //Функция приема данных от программы к плагину
   //Параметры:
   //dwMessageID - идентификатор блока данных
   //bMessage - указатель на данные
   //dwMessageLength - указатель на переменную содержащую объем данных в байтах

   //Возвращаемое значение:
   //на данный момент не используется
  result := 0;

  case dwMessageID of
    PM_PLUGIN_MSG_PUB : begin
                          msg := TStringStream.Create(String(bMessage));
                          msg.Size := dwMessageLength;
                          msg.Position := 0;
                          msg.Read(I,4);
                          name := msg.ReadString(I);
                          msg.Read(I,4);
                          ip := msg.ReadString(I);
                          msg.Read(I,4);
                          if I=0 then male:='мальчик'
                          else if I=1 then male:='девочка';
                          msg.Read(I,4);
                          channel := msg.ReadString(I);
                          msg.Read(I,4);
                          msg.Read(I,4);
                          text := msg.ReadString(I);
                          CForm.Memo2.Lines.Add(name+'('+ip+' / '+male+'):'+text);
                        end;

    PM_PLUGIN_USERS_LIST : begin
                             CForm.Memo1.Clear;
                             msg := TStringStream.Create(String(bMessage));
                             msg.Size := dwMessageLength;
                             msg.Position := 0;
                             msg.Read(N,4);
                             for J:=1 to N do
                              begin
                                msg.Read(I,4);
                                name := msg.ReadString(I);
                                msg.Read(I,4);
                                ip := msg.ReadString(I);
                                msg.Read(I,4);
                                if I=0 then male:='мальчик'
                                else if I=1 then male:='девочка';
                                CForm.Memo1.Lines.Add(name+'('+ip+' / '+male+')');
                              end;
                           end;
  end;
end;

function Premoderation(dwMessageID : DWORD; bMessage : PAnsiCHAR; dwMessageLength : PDWORD) : boolean;
begin
  //Функция для премодерации. в качестве параметров используются:
   //dwMessageID - идентификатор сообщения
   //bMessage - указатель на данные, содержащие сообщение
   //dwMessageLength - указатель на переменную содержащую объем данных сообщения в байтах

   //Возвращаемые значения:
   //FALSE - изменение сообщения не требуется
   //TRUE - необходимо изменить сообщение

   //максимальный объем буфера bMessage - 40000 байт

   //Если установить чекбокс, то
   //все сообщения которые будут публиковаться в том же
   //канале где присутствует виртуальный пользователь плагина
   //будут заменяться на "xxx". Темы при их изменении
   //будут заменяться на "yyy", а публикуемые объявления
   //будут заменяться на "zzz".
  result:=FALSE;
  if CForm.CheckBox1.Checked=FALSE then exit;
  case dwMessageID of
    PRE_PLUGIN_MSG         : begin
                              bMessage[0]:='x';
                              bMessage[1]:='x';
                              bMessage[2]:='x';
                              dwMessageLength^:=3;
                              result:=TRUE;
                             end;
    PRE_PLUGIN_THEME       : begin
                              bMessage[0]:='y';
                              bMessage[1]:='y';
                              bMessage[2]:='y';
                              dwMessageLength^:=3;
                              result:=TRUE;
                             end;
    PRE_PLUGIN_ANNOUNCMENT : begin
                              bMessage[0]:='z';
                              bMessage[1]:='z';
                              bMessage[2]:='z';
                              dwMessageLength^:=3;
                              result:=TRUE;
                             end;
  end;
end;

end.

Аватара пользователя
DIGGER
Сообщения: 264
Зарегистрирован: 13:46, 15.05.2009

Re: Технология создания плагинов и программ-дополнений

Сообщение DIGGER » 16:26, 27.05.2010

Код: Выделить всё

strPluginName        : Array [0..254] of char;

Почему не заменили Char на AnsiChar ?

$teelR@t
Сообщения: 348
Зарегистрирован: 19:14, 30.03.2008
Откуда: Украина
Контактная информация:

Re: Технология создания плагинов и программ-дополнений

Сообщение $teelR@t » 16:34, 27.05.2010

О, спасибо, не заметил :). Теперь всё заработало :D


Chief
Сообщения: 17
Зарегистрирован: 22:10, 26.07.2007
Откуда: OpenProject

Возможность добавлять элемент в меню клиента

Сообщение Chief » 13:56, 31.05.2010

Здравствуйте, Максим.

Возникла необходимость реализовать одну функцию, но с помощью текущей функциональности клиентских плагинов это довольно неудобно. Насколько возможна реализация функции добавления новых элементов в меню клиента и панели инструментов?

Спасибо.

joub
Сообщения: 30
Зарегистрирован: 01:30, 02.04.2010

Re: Технология создания плагинов и программ-дополнений

Сообщение joub » 03:44, 06.06.2010

Пишу плагин для клиентской части.
Подскажите пожалуйста: как остановить плагин в случаем некого внутреннего сбоя ???
т.е.:по сути вызвать PluginTerminate(), к примеру если при попытки инициализации не удалось определить неких параметров...
а так же в процессе работы...
за ранее спасибо!

Maxim Mirgorodsky
Администратор
Сообщения: 6731
Зарегистрирован: 09:56, 27.06.2005
Благодарил (а): 1 раз

Re: Технология создания плагинов и программ-дополнений

Сообщение Maxim Mirgorodsky » 17:20, 07.06.2010

Плагин автоматически останавливается в случае возникновения исключений (ошибок). Возможность остановки изнутри не предусмотрена. Возможно, реализуем в системе плагинов к 5.00.

joub
Сообщения: 30
Зарегистрирован: 01:30, 02.04.2010

Re: Технология создания плагинов и программ-дополнений

Сообщение joub » 21:49, 07.06.2010

Maxim Mirgorodsky писал(а):Плагин автоматически останавливается в случае возникновения исключений (ошибок). Возможность остановки изнутри не предусмотрена. Возможно, реализуем в системе плагинов к 5.00.

а как это исключение вызвать ????
ии что будет если в: PluginInit, PluginProcess в Return засунуть значение отличное от 0 ???

ах да, и когда планируется выход новое версии системы плагинов ? :))

Аватара пользователя
DIGGER
Сообщения: 264
Зарегистрирован: 13:46, 15.05.2009

Re: Технология создания плагинов и программ-дополнений

Сообщение DIGGER » 14:46, 08.06.2010

joub писал(а):а как это исключение вызвать ????

Делением на 0, как вариант.

$teelR@t
Сообщения: 348
Зарегистрирован: 19:14, 30.03.2008
Откуда: Украина
Контактная информация:

Re: Технология создания плагинов и программ-дополнений

Сообщение $teelR@t » 17:39, 09.06.2010

А мне никто не подскажет что это за событие для плагинов сервера "изменение имени пользователя" с ID - 75. Чё-то я меняю имя пользователя в его карточке и ничего не вызывается. Ник же изменить нельзя тоже вроде...
Последний раз редактировалось $teelR@t 03:03, 10.06.2010, всего редактировалось 1 раз.

Закрыто