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

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

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

Сообщение ZigZagkms »

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

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

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

Максимальная ширина - 550 пикселов.
Спасибо. это как раз то что нужно было
Забросил, всем спасибо, исходники раздаю кому надо https://github.com/ZigZagkms
$teelR@t
Сообщения: 348
Зарегистрирован: 19:14, 30.03.2008
Откуда: Украина
Контактная информация:

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

Сообщение $teelR@t »

Добрый день!
У меня возникло 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-а (http://commfort.com/ru/forum/viewtopic. ... 307#p15307), я просто взял его за базу для своего плагина, но и чистый плагин от sonic-a тоже не принимает сообщения от сервера + обрезает ник бота и пол женский.

Вариант "перейди назад на 2007 делфи" не принимается. Прошу помоч в сложившейся ситуации :)
Аватара пользователя
DIGGER
Сообщения: 264
Зарегистрирован: 13:46, 15.05.2009

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

Сообщение DIGGER »

Заменяешь в коде свой Pchar на PAnsiChar и многие функции заведутся :)
Дело в том, что в 2010 делфях в отличие от 2007 функция PAnsiChar, не поддерживается.
Утверждение ложно.
$teelR@t
Сообщения: 348
Зарегистрирован: 19:14, 30.03.2008
Откуда: Украина
Контактная информация:

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

Сообщение $teelR@t »

DIGGER писал(а):Заменяешь в коде свой Pchar на PAnsiChar и многие функции заведутся :)
Да нет... Ничего не завелось... Как ничего не получалось от сервера, так и не получается... И ник и пол бота такими же остались...

Код я беру чистый от sonic-а... только перекомпилировал его в 2010 делфях и изменил Pchar на PAnsiChar.
Аватара пользователя
DIGGER
Сообщения: 264
Зарегистрирован: 13:46, 15.05.2009

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

Сообщение DIGGER »

Код в студию. так как вспоминается при Ваших словах только Станиславский))
$teelR@t
Сообщения: 348
Зарегистрирован: 19:14, 30.03.2008
Откуда: Украина
Контактная информация:

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

Сообщение $teelR@t »

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 »

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

strPluginName        : Array [0..254] of char;
Почему не заменили Char на AnsiChar ?
$teelR@t
Сообщения: 348
Зарегистрирован: 19:14, 30.03.2008
Откуда: Украина
Контактная информация:

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

Сообщение $teelR@t »

О, спасибо, не заметил :). Теперь всё заработало :D
Chief
Сообщения: 17
Зарегистрирован: 22:10, 26.07.2007
Откуда: OpenProject

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

Сообщение Chief »

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

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

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

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

Сообщение joub »

Пишу плагин для клиентской части.
Подскажите пожалуйста: как остановить плагин в случаем некого внутреннего сбоя ???
т.е.:по сути вызвать PluginTerminate(), к примеру если при попытки инициализации не удалось определить неких параметров...
а так же в процессе работы...
за ранее спасибо!
Maxim Mirgorodsky
Администратор
Сообщения: 6867
Зарегистрирован: 09:56, 27.06.2005

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

Сообщение Maxim Mirgorodsky »

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

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

Сообщение joub »

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

ах да, и когда планируется выход новое версии системы плагинов ? :))
Аватара пользователя
DIGGER
Сообщения: 264
Зарегистрирован: 13:46, 15.05.2009

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

Сообщение DIGGER »

joub писал(а):а как это исключение вызвать ????
Делением на 0, как вариант.
$teelR@t
Сообщения: 348
Зарегистрирован: 19:14, 30.03.2008
Откуда: Украина
Контактная информация:

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

Сообщение $teelR@t »

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