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后,将放到我的主页上,并署上您的大名。谢谢。