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

Здесь обсуждаются графические оболочки, боты, языковые файлы и другие дополнения к CommFort 4.
Аватара пользователя
VIRUS
Сообщения: 174
Зарегистрирован: 13:15, 23.11.2008

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

Сообщение VIRUS »

Вопрос к вам Maxim Mirgorodsky(просто интересно :) ). Зачем к объявлении указателей на функции

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

typedef BYTE __stdcall (*typeClCommFortProcess)(DWORD dwPluginID, DWORD dwMessageID, BYTE * bMessage, DWORD dwMessageLength);
typedef DWORD __stdcall (*typeClGetData)(DWORD dwDataID, BYTE * bBuffer, DWORD dwBufferSize);
Вы использовали соглашение __stdcall? Ведь вы в функцию

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

 BYTE __stdcall PluginInit(DWORD dwThisPluginID, sPluginInfo *plInfo, [color=#FF0000]typeClCommFortProcess func1[/color], [color=#FF0000]typeClGetData func2[/color])
передаете грубо говоря "чистый адрес" функций.
Пользователь думает, что в килобайте 1000 байт, а программист думает, что в километре 1024 метра.
Аватара пользователя
VIRUS
Сообщения: 174
Зарегистрирован: 13:15, 23.11.2008

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

Сообщение VIRUS »

Сделал две функции: одна для отправки сообщений клиенту, другая для приема (мучаю плагины :) )

Вот функция для отправки сообщения, работает все на отлично.

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

TStringStream *OutMsgToChannel(AnsiString Channel,AnsiString Text)
{
        int i,*pi=&i;

        TStringStream *msg=new TStringStream("");
        msg->Position=0;
        i=Channel.Length();
        msg->Write(pi,4);
        msg->WriteString(Channel);
        i=Text.Length();
        msg->Write(pi,4);
        msg->WriteString(Text);

        return msg;
}
А вот функция для разбора сообщений не работает:

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

void InMsgToChannel(BYTE * bMessage, DWORD dwMessageLength)
{
        AnsiString user_name,user_ip,channel,text;
        int i,*pi=&i;

        TStringStream *msg=new TStringStream((char*)bMessage); // ошибка видимо тут, когда я в конструктор передаю указатель на массив BYTE, а потом его пытаюсь преобразовать
        msg->Size=dwMessageLength;
        msg->Position=0;
        msg->Read(pi,4);
        user_name=msg->ReadString(i);
        msg->Read(pi,4);
        user_ip=msg->ReadString(i);
        msg->Read(pi,4);
        channel=msg->ReadString(i);
        msg->Read(pi,4);
        text=msg->ReadString(i);

        ShowMessage(user_name+","+user_ip+","+channel+","+text);

        delete msg;
}
Может кто-то сталкивался с таким?
Пользователь думает, что в килобайте 1000 байт, а программист думает, что в километре 1024 метра.
mw
Сообщения: 120
Зарегистрирован: 15:42, 03.11.2007

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

Сообщение mw »

VIRUS писал(а):Вопрос к вам Maxim Mirgorodsky(просто интересно :) ). Зачем к объявлении указателей на функции

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

typedef BYTE __stdcall (*typeClCommFortProcess)(DWORD dwPluginID, DWORD dwMessageID, BYTE * bMessage, DWORD dwMessageLength);
typedef DWORD __stdcall (*typeClGetData)(DWORD dwDataID, BYTE * bBuffer, DWORD dwBufferSize);
Вы использовали соглашение __stdcall? Ведь вы в функцию

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

 BYTE __stdcall PluginInit(DWORD dwThisPluginID, sPluginInfo *plInfo, [color=#FF0000]typeClCommFortProcess func1[/color], [color=#FF0000]typeClGetData func2[/color])
передаете грубо говоря "чистый адрес" функций.
а как насчет порядка передачи аргументов в памяти и способа очистки памяти при возврате из функции?
Maxim Mirgorodsky
Администратор
Сообщения: 6869
Зарегистрирован: 09:56, 27.06.2005

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

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

els писал(а):Всем привет!
Возникла проблема.
Не отображается диалог настроек. Диалог создаю средствами студии.
Вызываю таким образом:

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

void	__stdcall	PluginShowOptions	()
{
	DialogBox(NULL, MAKEINTRESOURCE(IDD_DIALOG1), NULL, OptionsDlgProc);
}
В отдельном простейшем приложении диалог созданный таким же образом отлично отображается.
Кто-нибудь писал плагины с диалогами на MSVS C++?
Кнопка запуска диалога в опциях программы при этом активна?
Maxim Mirgorodsky
Администратор
Сообщения: 6869
Зарегистрирован: 09:56, 27.06.2005

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

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

Vary писал(а):часами перечитывать форум, разгребать код нул-плагина, приложение к нему, и изучать примеры предоставленные -=SJ=- и dv(за что им огромное спасибо))
Плагины до сих пор работали в тестовом режиме. К выпуску следующей версии справочная информация по плагинам будет модернизирована.
Аватара пользователя
VIRUS
Сообщения: 174
Зарегистрирован: 13:15, 23.11.2008

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

Сообщение VIRUS »

Жаль, что не получилась короче функция для разбора сообщения. Вот(может кто-то укоротит :) ):

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

void InMsgToChannel(BYTE * bMessage)
{

        int i=0; AnsiString str;

        i=*bMessage;
        char *user_name=new char[i];
        bMessage+=4;
        strncpy(user_name,bMessage,i);
        str=user_name;
        ShowMessage(str);

        bMessage+=i;
        i=*bMessage;
        char *user_ip=new char[i];
        bMessage+=4;
        strncpy(user_ip,bMessage,i);
        str=user_ip;
        ShowMessage(str);

        bMessage+=i;
        i=*bMessage;
        char *channel=new char[i];
        bMessage+=4;
        strncpy(channel,bMessage,i);
        str=channel;
        ShowMessage(str);

        bMessage+=i;
        i=*bMessage;
        char *text=new char[i];
        bMessage+=4;
        strncpy(text,bMessage,i);
        str=text;
        ShowMessage(str);

        delete []user_name;
        delete []user_ip;
        delete []channel;
        delete []text;

}
Может кому то пригодится.
Пользователь думает, что в килобайте 1000 байт, а программист думает, что в километре 1024 метра.
Vary
Сообщения: 10
Зарегистрирован: 01:00, 04.07.2009

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

Сообщение Vary »

Maxim Mirgorodsky писал(а):К выпуску следующей версии справочная информация по плагинам будет модернизирована.
Вот за это большое спасибо) а если еще подробные сообщения об ошибках/запретах в events то вообще супер
Maxim Mirgorodsky
Администратор
Сообщения: 6869
Зарегистрирован: 09:56, 27.06.2005

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

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

а если еще подробные сообщения об ошибках
Клиент и сервер 4.30 выводит информацию о том при обработке сообщения с каким ID произошла ошибка. И в случае если ошибка произошла во время старта или остановки - тоже выводится соответствующая информация.
Аватара пользователя
supermet
Сообщения: 245
Зарегистрирован: 02:35, 19.07.2009

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

Сообщение supermet »

VIRUS писал(а):Сделал две функции: одна для отправки сообщений клиенту, другая для приема (мучаю плагины :) )

. . .

Может кто-то сталкивался с таким?
Если убрать строчку

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

 msg->Size=dwMessageLength; 
, то все должно заработать. По крайней мере в Delphi у меня в этом была проблема.
Последний раз редактировалось supermet 12:57, 17.08.2009, всего редактировалось 1 раз.
els
Сообщения: 9
Зарегистрирован: 15:16, 10.11.2007

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

Сообщение els »

Maxim Mirgorodsky писал(а):Кнопка запуска диалога в опциях программы при этом активна?
Да, активна. По нажатию ничего не происходит.
els
Сообщения: 9
Зарегистрирован: 15:16, 10.11.2007

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

Сообщение els »

VIRUS
Могу предложить свой вариант:

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

//commfortstream.h
#pragma once

#include <windows.h>
#include <string>

namespace	cms
{
	class CommFortStream
	{
	protected:
		char		*_buffer;
		unsigned	_pos;
	public:
		CommFortStream	();

		CommFortStream &	operator >>	(std::string &str);
		CommFortStream &	operator >>	(DWORD &num);
		void					Assign        (char *buffer);
	};
}

//commfortstream.cpp
#include "commfortstream.h"

cms::CommFortStream::CommFortStream()
: _buffer(0), _pos(0)
{
}

void	cms::CommFortStream::Assign(char *buffer)
{
	_buffer = buffer;
	_pos = 0;
}

cms::CommFortStream &	cms::CommFortStream::operator >>(DWORD &num)
{
	memcpy((char *)&num, _buffer + _pos, 4);
	_pos += 4;

	return *this;
}

cms::CommFortStream &	cms::CommFortStream::operator >>(std::string &str)
{
	DWORD length = 0;
	(*this) >> length;
	str.insert(0, _buffer + _pos, length);
	_pos += length;

	return *this;
}
Использовать, например, так:

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

char	__stdcall	PluginProcess		(DWORD messageid, char *message, DWORD messagelength)
{
	string name, ip, channel, text;
	switch (messageid)
	{
	case CHANNEL_MESSAGE:
		plugin.Assign(message);
		plugin >> name >> ip >> channel >> text;
		if (channel == "123" && text == "съешь малины")
			...
		break;
	default:
		break;
	}
	return 0;
}
Аватара пользователя
gomelchanin
Сообщения: 151
Зарегистрирован: 14:09, 13.04.2007
Откуда: ГОМЕЛЬ

1

Сообщение gomelchanin »

Вопрос к разработчикам: с помощью плагина можно очищать окно чата на клиенте где он установлен? нужно на серверной машине. если можно то как подскажите авторам настоящих и будущих програм дополнений.
commfort.nostra.by 9740
Аватара пользователя
VIRUS
Сообщения: 174
Зарегистрирован: 13:15, 23.11.2008

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

Сообщение VIRUS »

supermet и els спс за код. Я тоже в долгу не останусь :), вот, что намутил с TStringStream:

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

Message InMsgToChannel(BYTE *bMessage, DWORD dwMessageLength)
{

        int i;

        for (int j=0;j<dwMessageLength;j++)
                if(bMessage[j]==0)
                        bMessage[j]=1;

        TStringStream *mess=new TStringStream((char*)bMessage);

        mess->Seek(0,soFromBeginning);
        mess->Size=dwMessageLength;
        i=*bMessage;
        mess->Seek(4,soFromCurrent);
        msg.user_name=mess->ReadString(i);
        bMessage+=4+i;
        i=*bMessage;
        mess->Seek(4,soFromCurrent);
        msg.user_ip=mess->ReadString(i);
        bMessage+=4+i;
        i=*bMessage;
        mess->Seek(4,soFromCurrent);
        msg.channel=mess->ReadString(i);
        bMessage+=4+i;
        i=*bMessage;
        mess->Seek(4,soFromCurrent);
        msg.text=mess->ReadString(i);

        delete mess;

        return msg;

}
Если убрать строчку
Код:
msg->Size=dwMessageLength;
, то все должно заработать.
Не в этом дело, потом уже дошло :lol: , что функции для работы с текстом в языке С++ не могут читать строки за NULL-символом, в Delphi это возможно.
Пользователь думает, что в килобайте 1000 байт, а программист думает, что в километре 1024 метра.
Vary
Сообщения: 10
Зарегистрирован: 01:00, 04.07.2009

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

Сообщение Vary »

Maxim Mirgorodsky писал(а):Клиент и сервер 4.30 выводит информацию...
пытался как-то раз отослать сообщение плагином, не получилось, а комфорт и молчит что это оказывается из-за того что у меня нет права на рассылку массовых сообщений( потом только понял в чем дело было.
Maxim Mirgorodsky
Администратор
Сообщения: 6869
Зарегистрирован: 09:56, 27.06.2005

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

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

els писал(а):Да, активна. По нажатию ничего не происходит.
Значит адрес этой функции определяется программой. В чем-то другом проблема.
gomelchanin писал(а):Вопрос к разработчикам: с помощью плагина можно очищать окно чата на клиенте где он установлен? нужно на серверной машине. если можно то как подскажите авторам настоящих и будущих програм дополнений.
Нет.
Закрыто