summaryrefslogtreecommitdiff
path: root/plugins/Actman/i_action.inc
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/Actman/i_action.inc')
-rw-r--r--plugins/Actman/i_action.inc952
1 files changed, 952 insertions, 0 deletions
diff --git a/plugins/Actman/i_action.inc b/plugins/Actman/i_action.inc
new file mode 100644
index 0000000000..1dd9719d35
--- /dev/null
+++ b/plugins/Actman/i_action.inc
@@ -0,0 +1,952 @@
+{Action code}
+const
+ rtInt = 1;
+ rtWide = 2;
+
+const
+ SST_BYTE = 0;
+ SST_WORD = 1;
+ SST_DWORD = 2;
+ SST_QWORD = 3;
+ SST_NATIVE = 4;
+ SST_BARR = 5;
+ SST_WARR = 6;
+ SST_BPTR = 7;
+ SST_WPTR = 8;
+ SST_LAST = 9;
+ SST_PARAM = 10;
+
+const
+ protostr = '<proto>';
+
+const
+ BufferSize = 8192;
+
+function DBRW(act:pHKAction;hContact:THANDLE;avalue:uint_ptr;
+ last,restype:uint_ptr):uint_ptr;
+var
+ buf ,buf1 :array [0..127] of AnsiChar;
+ sbuf:array [0..127] of AnsiChar;
+ module,setting:pAnsiChar;
+ tmp:pWideChar;
+ tmpa,tmpa1:pAnsichar;
+begin
+ module :=act^.dbmodule;
+ setting:=act^.dbsetting;
+
+ with act^ do
+ begin
+ if restype=rtWide then
+ FastWideToAnsiBuf(pWideChar(last),@sbuf)
+ else
+ IntToStr(sbuf,last);
+
+ if (flags2 and ACF2_RW_MVAR)<>0 then module :=ParseVarString(module ,hContact,sbuf);
+ if (flags2 and ACF2_RW_SVAR)<>0 then setting:=ParseVarString(setting,hContact,sbuf);
+ StrCopy(buf,module);
+ StrReplace(buf,protostr,GetContactProtoAcc(hContact));
+
+ StrReplace(buf,'<last>',sbuf);
+ StrCopy(buf1,setting);
+ StrReplace(buf1,'<last>',sbuf);
+
+ if (flags2 and ACF2_RW_TVAR)<>0 then
+ pWideChar(avalue):=ParseVarString(pWideChar(avalue),hContact,@sbuf);
+
+ if ((flags and ACF_DBUTEXT)=0) and
+ ((flags2 and ACF2_RW_TVAR)<>0) then
+ begin
+ tmp:=pWideChar(avalue);
+ avalue:=StrToInt(tmp);
+ mFreeMem(tmp);
+ end;
+
+ if (flags and ACF_DBDELETE)<>0 then
+ begin
+ result:=DBDeleteSetting(hContact,buf,setting);
+ end
+ else if (flags and ACF_DBWRITE)<>0 then
+ begin
+ if (flags and ACF_DBANSI)=ACF_DBANSI then
+ begin
+ WideToAnsi(pWideChar(avalue),tmpa,MirandaCP);
+ DBWriteString(hContact,buf,buf1,tmpa);
+ mFreeMem(tmpa);
+ if (flags2 and ACF2_RW_TVAR)=0 then
+ StrDupW(pWideChar(avalue),pWideChar(avalue));
+ end
+ else if (flags and ACF_DBBYTE )=ACF_DBBYTE then DBWriteByte(hContact,buf,setting,avalue)
+ else if (flags and ACF_DBWORD )=ACF_DBWORD then DBWriteWord(hContact,buf,setting,avalue)
+ else if (flags and ACF_DBUTEXT)=ACF_DBUTEXT then
+ begin
+ DBWriteUnicode(hContact,buf,buf1,pWideChar(avalue));
+ if (flags2 and ACF2_RW_TVAR)=0 then
+ StrDupW(pWideChar(avalue),pWideChar(avalue));
+ end
+ else DBWriteDWord(hContact,buf,setting,avalue);
+
+ result:=avalue;
+ end
+ else
+ begin
+ if (flags and ACF_DBANSI)=ACF_DBANSI then
+ begin
+ WideToAnsi(pWideChar(avalue),tmpa1,MirandaCP);
+ tmpa:=DBReadString(hContact,buf,buf1,tmpa1);
+ AnsiToWide(tmpa,PWideChar(result),MirandaCP);
+ mFreeMem(tmpa1);
+ mFreeMem(tmpa);
+
+ if (flags2 and ACF2_RW_TVAR)<>0 then
+ mFreeMem(avalue);
+ end
+ else if (flags and ACF_DBBYTE )=ACF_DBBYTE then result:=DBReadByte(hContact,buf,setting,avalue)
+ else if (flags and ACF_DBWORD )=ACF_DBWORD then result:=DBReadWord(hContact,buf,setting,avalue)
+ else if (flags and ACF_DBUTEXT)=ACF_DBUTEXT then
+ begin
+ result:=uint_ptr(DBReadUnicode(hContact,buf,buf1,pWideChar(avalue)));
+ if (flags2 and ACF2_RW_TVAR)<>0 then
+ mFreeMem(avalue);
+ end
+ else result:=DBReadDWord(hContact,buf,setting,avalue);
+
+ end;
+ if (flags2 and ACF2_RW_MVAR)<>0 then mFreeMem(module);
+ if (flags2 and ACF2_RW_SVAR)<>0 then mFreeMem(setting);
+ end;
+end;
+
+function OpenContact(hContact:THANDLE):THANDLE;
+begin
+ ShowContactDialog(hContact);
+{
+ if CallService(MS_DB_CONTACT_IS,hContact,0)<>0 then
+ begin
+ if ServiceExists(MS_MSG_CONVERS)<>0 then
+ begin
+ CallService(MS_MSG_CONVERS,hContact,0)
+ end
+ else
+ CallService(MS_MSG_SENDMESSAGE,hContact,0)
+ end;
+}
+ result:=hContact;
+end;
+
+function replany(var str:pWideChar;aparam:LPARAM;alast:pWideChar):boolean;
+var
+ buf:array [0..31] of WideChar;
+ tmp:pWideChar;
+begin
+ if StrScanW(str,'<')<>nil then
+ begin
+ result:=true;
+ mGetMem(tmp,2048);
+ StrCopyW(tmp,str);
+ StrReplaceW(tmp,'<param>',IntToStr(buf,aparam));
+ StrReplaceW(tmp,'<last>' ,alast);
+
+ str:=tmp;
+ end
+ else
+ result:=false;
+end;
+
+function RunProgram(act:pHKAction;aparam:LPARAM;alast:pWideChar):dword;
+var
+ tmp,tmpp,lpath:PWideChar;
+ replPrg ,replArg :PWideChar;
+ replPrg1,replArg1:PWideChar;
+ pd:LPARAM;
+ vars1,vars2,prgs,argss:boolean;
+begin
+ with act^ do
+ begin
+
+ replPrg:=prgname;
+ prgs :=replany(replPrg,aparam,alast);
+
+ replArg:=args;
+ argss :=replany(replArg,aparam,alast);
+
+ if ((flags2 and ACF2_PRG_PRG)<>0) or
+ ((flags2 and ACF2_PRG_ARG)<>0) then
+ begin
+ pd:=WndToContact(WaitFocusedWndChild(GetForegroundwindow){GetFocus});
+ if (pd=0) and (CallService(MS_DB_CONTACT_IS,aparam,0)<>0) then
+ pd:=aparam;
+ end;
+
+ if (flags2 and ACF2_PRG_ARG)<>0 then
+ begin
+ vars2:=true;
+ tmp :=ParseVarString(replArg,pd,alast);
+ end
+ else
+ begin
+ vars2:=false;
+ tmp :=replArg;
+ end;
+
+ if (flags2 and ACF2_PRG_PRG)<>0 then
+ begin
+ vars1:=true;
+ tmpp :=ParseVarString(replPrg,pd,alast);
+ end
+ else
+ begin
+ vars1:=false;
+ tmpp:=replPrg;
+ end;
+
+ if StrScanW(tmpp,'%')<>nil then
+ begin
+ mGetMem(replPrg1,8192*SizeOf(WideChar));
+ ExpandEnvironmentStringsW(tmpp,replPrg1,8191);
+ if vars1 then mFreeMem(tmpp);
+ if prgs then mFreeMem(replPrg);
+ tmpp :=replPrg1;
+ prgs :=false;
+ vars1:=true;
+ end;
+ if StrScanW(tmp,'%')<>nil then
+ begin
+ mGetMem(replArg1,8192*SizeOf(WideChar));
+ ExpandEnvironmentStringsW(tmp,replArg1,8191);
+ if vars2 then mFreeMem(tmp);
+ if argss then mFreeMem(replArg);
+ tmp :=replArg1;
+ argss:=false;
+ vars2:=true;
+ end;
+
+ if (flags and ACF_CURPATH)=0 then
+ lpath:=ExtractW(tmpp,false)
+ else
+ lpath:=nil;
+
+ if (flags and ACF_PRTHREAD)<>0 then
+ time:=0
+ else if time=0 then
+ time:=INFINITE;
+ result:=ExecuteWaitW(tmpp,tmp,lpath,show,time,@pd);
+
+ if vars2 then mFreeMem(tmp);
+ if vars1 then mFreeMem(tmpp);
+
+ if prgs then mFreeMem(replPrg);
+ if argss then mFreeMem(replArg);
+ end;
+ mFreeMem(lpath);
+end;
+{
+function MakeStructure(txt:pWideChar;aparam,alast:LPARAM;
+ var code,alen:integer;var ofs:int_ptr; restype:integer=rtInt):pointer; forward;
+procedure FreeStructure(var struct;descr:pWideChar); forward;
+}
+function RunService(act:pHKAction;LastResult,Param:LPARAM;var restype:dword):uint_ptr;
+var
+ res:int_ptr;
+ buf:array [0..255] of AnsiChar;
+ cc:integer;
+ lservice:pAnsiChar;
+ lwparam,llparam:LPARAM;
+ tmp1,tmp2:pWideChar;
+ code,len:integer;
+begin
+ result:=uint_ptr(-1);
+
+ lservice:=act^.service;
+ lwparam :=act^.wparam;
+ llparam :=act^.lparam;
+ with act^ do
+ begin
+ if (flags2 and ACF2_SRV_SRVC)<>0 then
+ lservice:=ParseVarString(lservice,Param);
+
+ StrCopy(buf,lservice);
+ if StrPos(lservice,protostr)<>nil then
+ if CallService(MS_DB_CONTACT_IS,Param,0)=0 then
+ begin
+ if (flags2 and ACF2_SRV_SRVC)<>0 then
+ mFreeMem(lservice);
+ exit
+ end
+ else
+ StrReplace(buf,protostr,GetContactProtoAcc(Param));
+
+ if ServiceExists(buf)<>0 then
+ begin
+
+ cc:=-1;
+
+ tmp1:=nil;
+ tmp2:=nil;
+ code:=-1;
+ if (flags and ACF_WSTRUCT)<>0 then
+ begin
+ lwparam:=twParam(MakeStructure(pAnsiChar(lwparam),Param,LastResult,restype))
+ end
+ else if (flags and ACF_WPARAM)<>0 then
+ begin
+ lwparam:=Param;
+ end
+ else if (flags and ACF_WRESULT)<>0 then
+ begin
+ lwparam:=LastResult;
+ end
+ else if (flags and ACF_WCURRENT)<>0 then
+ begin
+ cc:=WndToContact(WaitFocusedWndChild(GetForegroundwindow){GetFocus});
+ lwparam:=cc;
+ end
+ else if (flags2 and ACF2_SRV_WPAR)<>0 then
+ begin
+ if (flags and ACF_WPARNUM)=0 then
+ begin
+ if (flags and ACF_WUNICODE)=0 then
+ lwparam:=uint_ptr(ParseVarString(pAnsiChar(lwparam),Param))
+ else
+ lwparam:=uint_ptr(ParseVarString(pWideChar(lwparam),Param))
+ end
+ else
+ begin
+ tmp1:=ParseVarString(pWideChar(lwparam),Param);
+ lwparam:=StrToInt(tmp1);
+ end;
+ end;
+
+ if (flags and ACF_LSTRUCT)<>0 then
+ begin
+ llparam:=tlParam(MakeStructure(pAnsiChar(llparam),Param,LastResult,restype))
+ end
+ else if (flags and ACF_LPARAM)<>0 then
+ begin
+ llparam:=Param;
+ end
+ else if (flags and ACF_LRESULT)<>0 then
+ begin
+ llparam:=LastResult;
+ end
+ else if (flags and ACF_LCURRENT)<>0 then
+ begin
+ if cc<>-1 then
+ llparam:=cc
+ else
+ llparam:=WndToContact(WaitFocusedWndChild(GetForegroundwindow){GetFocus});
+ end
+ else if (flags2 and ACF2_SRV_LPAR)<>0 then
+ begin
+ if (flags and ACF_LPARNUM)=0 then
+ begin
+ if (flags and ACF_LUNICODE)=0 then
+ llparam:=uint_ptr(ParseVarString(pAnsiChar(llparam),Param))
+ else
+ llparam:=uint_ptr(ParseVarString(pWideChar(llparam),Param))
+ end
+ else
+ begin
+ tmp2:=ParseVarString(pWideChar(llparam),Param);
+ llparam:=StrToInt(tmp2);
+ end;
+ end;
+
+ res:=CallServiceSync(buf,lwparam,llparam);
+ result:=res;
+ if (flags and ACF_STRING)<>0 then
+ begin
+//!! delete old or not?
+ if (flags and ACF_UNICODE)=0 then
+ begin
+ AnsiToWide(pAnsiChar(res),pWideChar(result),MirandaCP);
+ if (flags2 and ACF2_FREEMEM)<>0 then
+ mFreeMem(pAnsiChar(res));
+ end
+ else if (flags2 and ACF2_FREEMEM)=0 then
+ StrDupW(pWideChar(result),pWideChar(res));
+ restype:=rtWide;
+ end
+ else if (flags and ACF_STRUCT)=0 then
+ restype:=rtInt;
+
+ if (flags and ACF_WSTRUCT)<>0 then
+ begin
+ if (flags and ACF_STRUCT)<>0 then
+ begin
+ result:=GetStructureResult(lwparam,@code,@len);
+ case code of
+ SST_LAST: begin
+ result:=LastResult;
+ end;
+ SST_PARAM: begin
+ result:=Param;
+ restype:=rtInt;
+ end;
+ SST_BYTE,SST_WORD,SST_DWORD,
+ SST_QWORD,SST_NATIVE: begin
+ restype:=rtInt;
+ end;
+ SST_BARR: begin
+{
+ mGetMem(pAnsiChar(res),len+1);
+ StrCopy(pAnsiChar(res),pAnsiChar(ofs),len);
+}
+ StrDup(pAnsiChar(res),pAnsiChar(result),len);
+ AnsiToWide(pAnsiChar(res),PWideChar(result),MirandaCP);
+ mFreeMem(pAnsiChar(res));
+ restype:=rtWide;
+ end;
+ SST_WARR: begin
+{
+ mGetMem(pWideChar(result),len+2);
+ len:= len div 2;
+ StrCopyW(pWideChar(result),pWideChar(ofs),len);
+}
+ StrDupW(pWideChar(result),pWideChar(result),len);
+ restype:=rtWide;
+ end;
+ SST_BPTR: begin
+ AnsiToWide(pAnsiChar(result),pWideChar(result),MirandaCP);
+ restype:=rtWide;
+ end;
+ SST_WPTR: begin
+ StrDupW(pWideChar(result),pWideChar(result));
+ restype:=rtWide;
+ end;
+ end;
+ end;
+ code:=SST_UNKNOWN;
+ FreeStructure(lwparam);
+ res:=result;
+ end
+ else if (flags2 and ACF2_SRV_WPAR)<>0 then
+ begin
+ if (flags and ACF_LPARNUM)=0 then
+ mFreeMem(pAnsiChar(lwparam))
+ else
+ mFreeMem(tmp1);
+ end;
+
+ if (flags and ACF_LSTRUCT)<>0 then
+ begin
+ if (flags and ACF_STRUCT)<>0 then
+ begin
+ result:=GetStructureResult(llparam,@code,@len);
+ case code of
+ SST_LAST: begin
+ result:=LastResult;
+ end;
+ SST_PARAM: begin
+ result:=Param;
+ restype:=rtInt;
+ end;
+ SST_BYTE,SST_WORD,SST_DWORD,
+ SST_QWORD,SST_NATIVE: begin
+ restype:=rtInt;
+ end;
+ SST_BARR: begin
+{
+ mGetMem(pAnsiChar(res),len+1);
+ StrCopy(pAnsiChar(res),pAnsiChar(ofs),len);
+}
+ StrDup(pAnsiChar(res),pAnsiChar(result),len);
+ AnsiToWide(pAnsiChar(res),PWideChar(result),MirandaCP);
+ mFreeMem(pAnsiChar(res));
+ restype:=rtWide;
+ end;
+ SST_WARR: begin
+{
+ mGetMem(pWideChar(result),len+2);
+ len:= len div 2;
+ StrCopyW(pWideChar(result),pWideChar(ofs),len);
+}
+ StrDupW(pWideChar(result),pWideChar(result),len);
+ restype:=rtWide;
+ end;
+ SST_BPTR: begin
+ AnsiToWide(pAnsiChar(result),pWideChar(result),MirandaCP);
+ restype:=rtWide;
+ end;
+ SST_WPTR: begin
+ StrDupW(pWideChar(result),pWideChar(result));
+ restype:=rtWide;
+ end;
+ end;
+ end;
+ code:=SST_UNKNOWN;
+ FreeStructure(llparam);
+ res:=result;
+ end
+ else if (flags2 and ACF2_SRV_LPAR)<>0 then
+ begin
+ if (flags and ACF_LPARNUM)=0 then
+ mFreeMem(pAnsiChar(llparam))
+ else
+ mFreeMem(tmp2);
+ end;
+
+ if (flags and (ACF_INSERT or ACF_MESSAGE or ACF_POPUP))<>0 then
+ begin
+ if restype=rtInt then
+ begin
+ if (flags and ACF_HEX)<>0 then
+ IntToHex(pWideChar(@buf),result)
+ else if ((flags and ACF_SIGNED)<>0) and (res<0) then
+ begin
+ pWideChar(@buf)[0]:='-';
+ IntToStr(PWideChar(@buf)+1,-result);
+ end
+ else
+ IntToStr(pWideChar(@buf),result);
+ res:=int_ptr(@buf);
+ end
+ else
+ res:=result;
+ end;
+
+ if (flags and ACF_INSERT )<>0 then SendMessageW(WaitFocusedWndChild(GetForegroundwindow){GetFocus},EM_REPLACESEL,0,res);
+ if (flags and ACF_POPUP )<>0 then ShowPopupW(PWideChar(res));
+ if (flags and ACF_MESSAGE)<>0 then MessageBoxW(0,PWideChar(res),'',0);
+
+ end;
+ if (flags2 and ACF2_SRV_SRVC)<>0 then
+ mFreeMem(lservice);
+ end;
+end;
+
+procedure PasteClipboard(dst:pWideChar);
+var
+ p:pWideChar;
+ fh:tHandle;
+begin
+ if StrPosW(dst,'^v')<>nil then
+ begin
+{
+ p:=PasteFromClipboard(false);
+ StrReplaceW(dst,'^v',p);
+ mFreeMem(p);
+}
+ if OpenClipboard(0) then
+ begin
+ fh:=GetClipboardData(cf_UnicodeText);
+ p:=GlobalLock(fh);
+ StrReplaceW(dst,'^v',p);
+ GlobalUnlock(fh);
+ CloseClipboard;
+ end
+ end
+end;
+
+type
+ trec = record
+ text:PAnsiChar;
+ one, two:integer;
+ end;
+
+function GetFileString(fname:PAnsiChar;linenum:integer):pWideChar;
+var
+ pc,FileBuf,CurLine:PAnsiChar;
+ f:THANDLE;
+ NumLines, j:integer;
+begin
+ f:=Reset(fname);
+ if f<>INVALID_HANDLE_VALUE then
+ begin
+ j:=FileSize(f);
+ mGetMem(FileBuf,j+1);
+ BlockRead(f,FileBuf^,j);
+ while (FileBuf+j)^<' ' do dec(j);
+ (FileBuf+j+1)^:=#0;
+ CloseHandle(f);
+ pc:=FileBuf;
+ CurLine:=pc;
+ NumLines:=1;
+ while pc^<>#0 do // count number of lines
+ begin
+ if pc^=#13 then
+ begin
+ if linenum=NumLines then
+ break;
+ inc(pc);
+ if pc^=#10 then
+ inc(pc);
+ inc(NumLines);
+ CurLine:=pc;
+ end
+ else
+ inc(pc);
+ end;
+ if (linenum>NumLines) or (linenum=0) then //ls - lastline
+ else if linenum<0 then
+ begin
+ randomize;
+ linenum:=random(NumLines)+1;
+ pc:=FileBuf;
+ NumLines:=1;
+ CurLine:=pc;
+ repeat
+ if (pc^=#13) or (pc^=#0) then
+ begin
+ if linenum=NumLines then
+ break;
+ if pc^<>#0 then
+ begin
+ inc(pc);
+ if pc^=#10 then
+ inc(pc);
+ end;
+ inc(NumLines);
+ CurLine:=pc;
+ end
+ else
+ inc(pc);
+ until false;
+ end;
+ pc^:=#0;
+ StrReplace(CurLine,'\n',#13#10);
+ StrReplace(CurLine,'\t',#09);
+ AnsiToWide(CurLine,result,CP_ACP);
+ mFreeMem(FileBuf);
+ end
+ else
+ result:=nil;
+end;
+
+function Split(buf:PWideChar;macro:PWideChar;var r:trec):integer;
+type
+ tconv = packed record
+ case boolean of
+ false: (res:int);
+ true: (lo,hi:word);
+ end;
+var
+ i:integer;
+ p,pp,lp:pWideChar;
+ ls:array [0..511] of WideChar;
+begin
+ result:=0;
+ i:=StrIndexW(buf,macro);
+ if i>0 then
+ begin
+ dec(i);
+ p:=buf+i+StrLenW(macro);
+ pp:=p;
+ while (p^<>#0) and (p^<>')') do
+ inc(p);
+ ls[0]:=#0;
+ if p^<>#0 then // correct syntax
+ begin
+ lp:=ls;
+ while (pp<>p) and (pp^<>',') do // filename
+ begin
+ lp^:=pp^;
+ inc(lp);
+ inc(pp);
+ end;
+ lp^:=#0;
+ WideToAnsi(ls,r.text,MirandaCP);
+ r.one:=-1;
+ r.two:=-1;
+ if pp^=',' then
+ begin
+ inc(pp);
+ r.one:=StrToInt(pp);
+ while (pp<>p) and (pp^<>',') do inc(pp);
+ if pp^=',' then
+ begin
+ inc(pp);
+ r.two:=StrToInt(pp);
+ end;
+ end;
+ tconv(result).lo:=p-buf-i+1; // length
+ tconv(result).hi:=i; // position
+ end;
+ end;
+end;
+
+procedure PasteFileString(dst:pWideChar);
+var
+ i:integer;
+ lp:pWideChar;
+ buf:array [0..511] of AnsiChar;
+ r:trec;
+begin
+ repeat
+ i:=Split(dst,'^f(',r);
+ if i>0 then
+ begin
+ StrDeleteW(dst,i shr 16,loword(i));
+ ConvertFileName(r.text,buf);
+// CallService(MS_UTILS_PATHTOABSOLUTE,dword(r.text),dword(@buf));
+ lp:=GetFileString(@buf,r.one);
+ if lp<>nil then
+ begin
+ StrInsertW(lp,dst,i shr 16);
+ mFreeMem(lp);
+ end;
+ end
+ else
+ break;
+ until false;
+end;
+
+procedure PasteSelectedText(wnd:hwnd;dst:pWideChar);
+var
+ sel:integer;
+ buf:pWideChar;
+begin
+ if (StrPosW(dst,'^s')<>nil) and (wnd<>0) then
+ begin
+ sel:=SendMessageW(wnd,EM_GETSEL,0,0);
+ if loword(sel)=(sel shr 16) then
+ StrReplaceW(dst,'^s',nil)
+ else
+ begin
+ buf:=GetDlgText(wnd,false);
+//!! next line was active. why?
+// SendMessageW(wnd,WM_GETTEXT,4095,dword(@buf));
+ buf[sel shr 16]:=#0;
+ StrReplaceW(dst,'^s',buf+loword(sel));
+ mFreeMem(buf);
+ end;
+ end;
+end;
+
+function CheckAuto(dst:pWideChar):bool;
+var
+ p:PWideChar;
+begin
+ result:=false;
+ if dst<>nil then
+ begin
+ p:=StrEndW(dst);
+ if (p-dst)>2 then
+ begin
+ dec(p,2);
+ if (p^='^') and ((p+1)^='a') then
+ begin
+ result:=true;
+ p^:=#0;
+ end;
+ end;
+ end;
+end;
+
+function InsertText(act:pHKAction;param:LPARAM;last:pWideChar):uint_ptr;
+var
+ tmp:PWideChar;
+ blob,p:PAnsiChar;
+ w:PWideChar;
+ hContact:THANDLE;
+ wnd:HWND;
+ fexist,autosend:bool;
+ dbei:TDBEVENTINFO;
+ i:cardinal;
+ cp:integer;
+ fh:THANDLE;
+ lstr:pWideChar;
+ llen:integer;
+ buf:array [0..31] of WideChar;
+ b,b1:array [0..MAX_PATH] of AnsiChar;
+begin
+ result:=uint_ptr(last);
+ with act^ do
+ begin
+ if (flags and ACF_CLIPBRD)<>0 then
+ begin
+ if (flags and ACF_COPYTO)<>0 then
+ CopyToClipboard(last,false)
+ else
+ result:=uint_ptr(PasteFromClipboard(false));
+ exit;
+ end;
+
+ hContact:=0;
+ if (flags and ACF_FILE)=0 then
+ begin
+ wnd:=WaitFocusedWndChild(GetForegroundWindow){GetFocus};
+ if wnd<>0 then
+ hContact:=WndToContact(wnd);
+ end
+ else
+ wnd:=0;
+
+ if hContact=0 then
+ begin
+ if CallService(MS_DB_CONTACT_IS,param,0)<>0 then
+ hContact:=param;
+ end;
+
+ if (flags and (ACF_FILE or ACF_FAPPEND or ACF_FWRITE))<>ACF_FILE then
+ begin
+ mGetMem (w ,BufferSize*SizeOf(WideChar));
+ FillChar(w^,BufferSize*SizeOf(WideChar),0);
+ StrCopyW(w,text);
+ PasteClipboard(w); // ^v
+ PasteFileString(w); // ^f
+ PasteSelectedText(wnd,w); // ^s
+ autosend:=CheckAuto(w); // ^a
+ StrReplaceW(w,'^l',last); // ^l
+ StrReplaceW(w,'^h',IntToHex(buf,StrToInt(last))); // ^h
+ StrReplaceW(w,'^t',#9); // ^t
+ StrReplaceW(w,'^e',nil); // ^e
+ end
+ else
+ autosend:=false;
+
+ if (flags2 and ACF2_TXT_TEXT)<>0 then
+ begin
+ tmp:=ParseVarString(w,hContact,last);
+ mFreeMem(w);
+ w:=tmp;
+ end;
+
+ if (flags and ACF_FILE)<>0 then
+ begin
+ cp:=0;
+ if (flags and ACF_ANSI)=ACF_ANSI then cp:=1
+ else if (flags and (ACF_UTF8 or ACF_SIGN))=ACF_UTF8 then cp:=2
+ else if (flags and (ACF_UTF8 or ACF_SIGN))=ACF_SIGN then cp:=4
+ else if (flags and (ACF_UTF8 or ACF_SIGN))=(ACF_UTF8 or ACF_SIGN) then cp:=3;
+
+ if (flags2 and ACF2_TXT_FILE)<>0 then
+ tmp:=ParseVarString(tfile,hContact,last)
+ else
+ tmp:=tfile;
+
+ if (flags and (ACF_FAPPEND or ACF_FWRITE))<>0 then
+ begin
+ case cp of
+ 1: begin
+ llen:=StrLen(WideToAnsi(w,pAnsiChar(lstr),MirandaCP));
+ end;
+ 2,3: begin
+ llen:=StrLen(WideToUTF8(w,pAnsiChar(lstr)));
+ end;
+ else
+ lstr:=w;
+ llen:=StrLenW(lstr)*SizeOf(WideChar);
+ end;
+ end
+ else
+ llen:=0;
+
+ fexist:=FileExists(tmp);
+ if fexist and ((flags and ACF_FAPPEND)<>0) then
+ begin
+ fh:=Append(tmp);
+ if fh<>THANDLE(INVALID_HANDLE_VALUE) then
+ begin
+ BlockWrite(fh,lstr^,llen);
+ end;
+ if (cp<>0) and (cp<>4) then
+ mFreeMem(lstr);
+ end
+ else if ((flags and ACF_FWRITE)<>0) or
+ (not fexist and ((flags and ACF_FAPPEND)<>0)) then
+ begin
+ fh:=ReWrite(tmp);
+ if fh<>THANDLE(INVALID_HANDLE_VALUE) then
+ begin
+ if cp=3 then
+ begin
+ i:=SIGN_UTF8;
+ BlockWrite(fh,i,3); // UTF8 sign
+ end
+ else if cp=4 then
+ begin
+ i:=SIGN_UNICODE;
+ BlockWrite(fh,i,2); // UTF16 sign
+ end;
+
+ BlockWrite(fh,lstr^,llen);
+ if (cp<>0) and (cp<>4) then
+ mFreeMem(lstr);
+ end;
+ end
+ else
+ begin
+ if StrPosW(tmp,'://')<>nil then // remote
+ begin
+ GetTempPathA(MAX_PATH,b);
+ GetTempFileNameA(b,'wat',GetCurrentTime,b1);
+ GetFile(FastWideToAnsiBuf(tmp,b),b1);
+ if tmp<>tfile then
+ mFreeMem(tmp);
+ FastAnsiToWide(b1,tmp);
+ end
+ else
+ b1[0]:=#0;
+ fh:=Reset(tmp);
+ if fh<>THANDLE(INVALID_HANDLE_VALUE) then
+ begin
+ i:=GetFSize(tmp);
+ mGetMem (w ,i+SizeOf(WideChar));
+ FillChar(w^,i+SizeOf(WideChar),0);
+ BlockRead(fh,w^,i);
+ if (flags and ACF_ANSI)<>0 then
+ begin
+ AnsiToWide(pAnsiChar(w),lstr,MirandaCP);
+ mFreeMem(w);
+ w:=lstr;
+ end
+ else if (flags and ACF_UTF8)<>0 then
+ begin
+ if (pdword(w)^ and $FFFFFF)=SIGN_UTF8 then
+ p:=pAnsiChar(w)+3
+ else
+ p:=pAnsiChar(w);
+ mFreeMem(w);
+ UTF8ToWide(p,w);
+ end
+ else
+ ChangeUnicode(w);
+ end;
+ if b1[0]<>#0 then
+ DeleteFileA(b1);
+ end;
+ if fh<>THANDLE(INVALID_HANDLE_VALUE) then
+ CloseHandle(fh);
+ if tmp<>tfile then
+ mFreeMem(tmp);
+ end;
+
+ result:=uint_ptr(w);
+
+ if (flags and ACF_FILE)=0 then
+ begin
+ if autosend then
+ begin
+ if hContact=0 then exit;
+ p:=GetContactProtoAcc(hContact);
+ cp:=DBReadDWord(hContact,'Tab_SRMsg','ANSIcodepage',MirandaCP);
+ if DBReadByte(hContact,p,'ChatRoom',0)<>1 then
+ begin
+ i:=WideToCombo(w,blob,cp);
+ // if CallContactService(hContact,PSS_MESSAGEW,0,dword(blob))=
+ // ACKRESULT_FAILED then
+ CallContactService(hContact,PSS_MESSAGE,PREF_UNICODE,tlparam(blob));
+ dbei.cbSize :=sizeof(dbei);
+ dbei.cbBlob :=i;
+ dbei.pBlob :=pByte(blob);
+ dbei.eventType:=EVENTTYPE_MESSAGE;
+ dbei.timestamp:=GetCurrentTime;
+ dbei.szModule :=p;
+ dbei.flags :=DBEF_SENT;
+ CallService(MS_DB_EVENT_ADD,hContact,tlparam(@dbei));
+ mFreeMem(blob);
+ end
+ else
+ SendToChat(hContact,w);
+ end
+ else
+ begin
+ GetWindowThreadProcessId(GetForegroundWindow,@i);
+ if (i=GetCurrentProcessId) and (wnd<>0) then
+ SendMessageW(wnd,EM_REPLACESEL,1,tlparam(w))
+ else
+ SendString(0,w);
+ end;
+ end;
+ end;
+end;