DreamEdit插件说明(最后更新:2000年4月20日)

下面是DreamEdit的PlugIn程序规范:(其实是DLL,改后缀名为4DE)

说明:所有读取字符串的函数,必须预先分配好足够的内存。

1、保存目录:
现在与Edit有关的PlugIn保存在主程序所在目录的EditPlug子目录下。


2、主程序提供的函数(DreamEdit API)


//表示已经有PlugIn载入。在PlugIn程序的初始化函数(即Initialize)中,必须执行一次。
procedure RegisterCallBack;stdcall;


//得到保存DreamEdit.ini的路径,用于保存跟这个插件有关的配置。
//例如:d:\DreamEdit\DreamEdit.ini
function GetIniFile:PChar;stdcall;


//得到保存DreamEdit的编辑所用PlugIn的路径,现在是DreamEdit目录下的EditPlug子目录。
//为了防止以后目录会变动,请用此函数来获取PlugIn程序所在目录。
//例如:d:\DreamEdit\EditPlug
function GetEditPlugInDirectory:PChar;stdcall;


//得到当前文章的标题
function GetTitle:PChar;stdcall;


//设置当前文章的标题
procedure SetTitle(s:PChar);stdcall;


//以下是编辑用到的函数

//得到编辑窗口文本大小
function GetTextLength:integer;stdcall;


//得到编辑窗口的全部文本
//在调用这个函数之前,先用GetTextLength得到Text的大小,分配好内存,再调用。
function GetText:PChar;stdcall;


//设置编辑窗口的全部文本,实际上是执行了:全选->替换
procedure SetText(s:PChar);stdcall;

//得到编辑窗口所选择的文本的大小
function GetSelTextLength:integer;stdcall;

//得到编辑窗口所选择的文本
//在调用这个函数之前,先用GetSelTextLength得到SelText的大小,分配好内存,再调用。
function GetSelText:PChar;stdcall;

//替换编辑窗口所选择的文本
procedure SetSelText(s:PChar);stdcall;

//得到编辑窗口所选择文本的开始坐标
function GetSelStart:integer;stdcall;

//设置编辑窗口所选择文本的开始坐标
procedure SetSelStart(i:integer);stdcall;

//得到编辑窗口所选择文本的长度
function GetSelLength:integer;stdcall;

//设置编辑窗口所选择文本的长度
procedure SetSelLength(i:integer);stdcall;

//移动编辑窗口到光标可见位置
procedure SetCaretPos;stdcall;

利用SetSelStart,SetSelLength,SetCaretPos可以设定编辑窗口的选择区域,并将
窗口移动到光标可见位置。

3、PlugIn程序规范

下面是一个Base64解码的PlugIn程序实例。
library Decode;
{$R *.RES}//包含了图标信息等,16X16大小,256色。
{$E 4DE} //表示后缀为4DE(For DreamEdit,主程序按照这个后缀来识别是否是PlugIn。

uses
  Windows,
  Classes,
  uTBase64;

type
  TGetString=function:PChar;stdcall;
  TSetString=procedure(s:pchar);stdcall;
  TGetInteger=function:integer;stdcall;
  TSetInteger=procedure(i:integer);stdcall;
  TRegisterCallBack=procedure;stdcall;

type
   PPluginData=^TPluginData;
   TPluginData=packed record
     Count:integer;//PlugIn函数的个数
     Instance:Longint;//用于读取bitmap的HInstance
end;

const
  itProcName=0;
  itName=1;
  itHint=2;
  itInfo=3;
  itResID=4;
var
  AOwner:Integer;
  T:TPluginData;

//初始化PlugIn,返回一个PPluginData。该结构不可改变,它与主程序中使用的结构一致。
//本函数必须存在
function Initialize(Owner:Integer):PPluginData;stdcall;
begin
  AOwner:=Owner;
  T.Count:=2;//表示有几个PlugIn函数可以调用
  T.Instance:=HInstance;
  result:=@T;
  {Add any initialization code here}
  //向主程序注册,表示PlugIn程序初始化完毕
  TRegisterCallBack(GetProcAddress(AOwner,'RegisterCallBack'));
end;

//向主程序传递PlugIn函数的各个参数,本函数必须存在
function RegisterProcs(index,InfoType:integer):Pchar;stdcall;
begin
  result := '';
  case index of
  0:
     case InfoType of
       itProcname:result:='Base64DecodeAll';//第一个PlugIn函数的函数名为Base64DecodeAll,与下面的实现函数名一致
       itName:result:='按Base64解码全部文本';//显示在菜单上的名称
       itHint:result:='按Base64编码方式解码当前整个文本';
       itResID:result:='BITMAP1';//表示该函数的图标,如果为'',则不在快捷方式中出现。
       itInfo:result:='Decode Plugins by Sheng Quanhu';
     end;
  1:
     case InfoType of
       itProcname:result:='Base64DecodeSelected';
       itName:result:='按Base64解码所选文本';
       itHint:result:='按Base64编码方式解码当前所选文本';
       itResID:result:='BITMAP2';
       itInfo:result:='Decode Plugins by Sheng Quanhu';
     end;
  end;
end;

//PlugIn函数
procedure Base64DecodeAll;stdcall;//必须与RegisterProcs中说明的itProcname一致。
var
  s:string;
  Base64:TBase64;
  iResult:byte;
  sDeletedString:string;
  sDecodeString:string;
  iStartPos,iEndPos:integer;
begin
  s := String(TGetString(GetProcAddress(AOwner,'GetText')));

  for iStartPos := 1 to Length(s) do
    if s[iStartPos] in ['A'..'Z','a'..'z','0'..'9','+','/'] then break;

  for iEndPos := Length(s) downto 1 do
    if s[iEndPos] in ['A'..'Z','a'..'z','0'..'9','+','/','='] then break;

  sDeletedString := Copy(s,iEndPos+1,Length(s)-iEndPos);
  s := Copy(s,iStartPos,iEndPos - iStartPos + 1);

  if s <> '' then
  begin
    Base64:=TBase64.Create;
    iResult := Base64.DecodeData(s,sDecodeString);
    case iResult of
      BASE64_OK       :
        begin
          sDecodeString := sDecodeString + sDeletedString;
          TSetString(GetProcAddress(AOwner,'SetText'))(pchar(sDecodeString));
        end;
      BASE64_INVALID  :MessageBox(THandle(0),'输入字符串中带有非法字符','错误',MB_OK);
      BASE64_LENGTH   :MessageBox(THandle(0),'输入字符串长度不是合法的Base64长度(mod 4)','错误',MB_OK);
      BASE64_DATALEFT :MessageBox(THandle(0),'输入字符太多(已经到了编码字符的末端,但输入仍未结束)','错误',MB_OK);
    else
      MessageBox(THandle(0),'无法正确解码','错误',MB_OK);
    end;
    Base64.Free;
  end;
end;

procedure Base64DecodeSelected;stdcall;
var
  s:string;
  Base64:TBase64;
  iResult:byte;
  sDeletedString:string;
  sDecodeString:string;
  iStartPos,iEndPos:integer;
begin
  s := string(TGetString(GetProcAddress(AOwner,'GetSelText')));

  for iStartPos := 1 to Length(s) do
    if s[iStartPos] in ['A'..'Z','a'..'z','0'..'9','+','/'] then break;

  for iEndPos := Length(s) downto 1 do
    if s[iEndPos] in ['A'..'Z','a'..'z','0'..'9','+','/','='] then break;

  sDeletedString := Copy(s,iEndPos+1,Length(s)-iEndPos);
  s := Copy(s,iStartPos,iEndPos - iStartPos + 1);

  if s <> '' then
  begin
    Base64:=TBase64.Create;
    iResult := Base64.DecodeData(s,sDecodeString);
    case iResult of
      BASE64_OK       :
        begin
          sDecodeString := sDecodeString + sDeletedString;
          TSetString(GetProcAddress(AOwner,'SetSelText'))(pchar(sDecodeString));
        end;
      BASE64_INVALID  :MessageBox(THandle(0),'输入字符串中带有非法字符','错误',MB_OK);
      BASE64_LENGTH   :MessageBox(THandle(0),'输入字符串长度不是合法的Base64长度(mod 4)','错误',MB_OK);
      BASE64_DATALEFT :MessageBox(THandle(0),'输入字符太多(已经到了编码字符的末端,但输入仍未结束)','错误',MB_OK);
    else
      MessageBox(THandle(0),'无法正确解码','错误',MB_OK);
    end;
    Base64.Free;
  end;
end;

//导出函数,使得主程序可以调用。
exports
  Base64DecodeAll,Base64DecodeSelected,Initialize,RegisterProcs;

begin
end.

4、PlugIn程序注意事项
  (1)PlugIn程序存放目录为EditPlug,并且不能放在它的子目录中。PlugIn程序用到的文件可以放在子目录中。
  (2)写PlugIn程序是需要注意函数名不能写错,并且要定义为stdcall。
  (3)注意程序最后要把用到的PlugIn函数导出。
   (4) 从主程序函数返回的PChar类型字符串,在PlugIn中应该复制一份以后使用。
   (5) PlugIn的要求为高:16,宽:32,为两个16X16图标大小,其中前16X16图标为可用时的图标,后16X16图标为不可用时的图标。

5、声明
    如果您写了PlugIn程序,请连同源码寄给我一份,确认没有Bug后,将放到我的主页上,并署上您的大名。谢谢。