summaryrefslogtreecommitdiff
path: root/plugins/Utils.pas/sparam.pas
diff options
context:
space:
mode:
authorAlexey Kulakov <panda75@bk.ru>2014-01-15 21:18:15 +0000
committerAlexey Kulakov <panda75@bk.ru>2014-01-15 21:18:15 +0000
commit56dbdaf5d7855632eeea4cfe820531bc24b09ee0 (patch)
tree172487e562256c6d7d366bd2cae1f3b86d9e91f4 /plugins/Utils.pas/sparam.pas
parent8182b383ff777c41459278bd517e4370c42fd78a (diff)
sync
git-svn-id: http://svn.miranda-ng.org/main/trunk@7671 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/Utils.pas/sparam.pas')
-rw-r--r--plugins/Utils.pas/sparam.pas986
1 files changed, 986 insertions, 0 deletions
diff --git a/plugins/Utils.pas/sparam.pas b/plugins/Utils.pas/sparam.pas
new file mode 100644
index 0000000000..5a686aa4a8
--- /dev/null
+++ b/plugins/Utils.pas/sparam.pas
@@ -0,0 +1,986 @@
+unit sparam;
+
+interface
+
+uses windows;
+
+const
+ // parameter flags
+ ACF_NUMBER = $00000001; // Param is number
+ ACF_UNICODE = $00000002; // Param is Unicode string
+ ACF_CURRENT = $00000004; // Param is ignored, used current user handle
+ // from current message window
+ ACF_RESULT = $00000008; // Param is previous action result
+ ACF_PARAM = $00000010; // Param is Call parameter
+ ACF_STRUCT = $00000020;
+ ACF_PARTYPE = ACF_NUMBER or ACF_UNICODE or
+ ACF_CURRENT or ACF_RESULT or
+ ACF_PARAM or ACF_STRUCT;
+ ACF_SIGNED = $00002000; // for future
+ ACF_TEMPLATE = $00000800;
+ ACF_SCRIPT_PARAM = $00001000;
+ // dummy
+ ACF_STRING = 0;
+ ACF_RNUMBER = 0;
+
+ // result flags
+ ACF_RSTRING = $00010000; // Service result is string
+ ACF_RUNICODE = $00020000; // Service result is Widestring
+ ACF_RSTRUCT = $00040000; // Service result in structure
+ ACF_RFREEMEM = $00080000; // Need to free memory
+ ACF_RHEXNUM = $00100000; // Show number as hex
+ ACF_RSIGNED = $00200000; // Show number as signed
+
+ ACF_RTYPE = ACF_RSTRING or ACF_RUNICODE or
+ ACF_RSTRUCT or ACF_RFREEMEM or
+ ACF_RHEXNUM or ACF_RSIGNED;
+
+ // parameter / result block creation flags
+ ACF_NOSTATIC = $01000000; // No label text in block
+ ACF_NOBORDER = $02000000; // No group border around block
+ ACF_NOSTRUCT = $04000000; // don't add structure as param type
+ ACF_NOVISUAL = $08000000; // don't show number view styles
+
+function CreateParamBlock(parent:HWND;x,y,width:integer;flags:dword=0):THANDLE;
+function ClearParamFields(Dialog:HWND):HWND;
+function FillParam (Dialog:HWND;txt:pAnsiChar):integer;
+function SetParamValue (Dialog:HWND; flags:dword; value:pointer):boolean;
+function GetParamValue (Dialog:HWND;var flags:dword;var value:pointer):boolean;
+function SetParamLabel (Dialog:HWND; lbl:pWideChar):HWND;
+
+procedure ClearParam (flags:dword; var param);
+function DuplicateParam(flags:dword; var sparam,dparam):dword;
+function TranslateParam(param:uint_ptr;flags:dword;hContact:THANDLE):uint_ptr;
+
+function CreateResultBlock(parent:HWND;x,y,width:integer;flags:dword=0):THANDLE;
+function ClearResultFields(Dialog:HWND):HWND;
+function SetResultValue(Dialog:HWND;flags:dword):integer;
+function GetResultValue(Dialog:HWND):dword;
+
+implementation
+
+uses
+ messages,
+ common, editwrapper, wrapper, syswin,
+ m_api, sedit, strans,
+ mirutils;
+
+const
+ IDC_FLAG_PAR = 2150;
+ IDC_EDIT_PAR = 2151;
+ IDC_STRUCT = 2152;
+ IDC_LABEL_PAR = 2153;
+ IDC_GROUP_PAR = 2154;
+
+ IDC_RES_TYPE = 2160;
+ IDC_RES_FREEMEM = 2161;
+ IDC_RES_SIGNED = 2162;
+ IDC_RES_HEXNUM = 2163;
+
+
+procedure InsertString(wnd:HWND;num:dword;str:PAnsiChar);
+var
+ buf:array [0..127] of WideChar;
+begin
+ SendMessageW(wnd,CB_SETITEMDATA,
+ SendMessageW(wnd,CB_ADDSTRING,0,
+ lparam(TranslateW(FastAnsiToWideBuf(str,buf)))),
+ num);
+end;
+
+
+//----- Dialog functions -----
+
+procedure MakeParamTypeList(wnd:HWND; flags:dword);
+begin
+ SendMessage(wnd,CB_RESETCONTENT,0,0);
+ InsertString(wnd,ACF_NUMBER ,'number value');
+ InsertString(wnd,ACF_STRING ,'ANSI string');
+ InsertString(wnd,ACF_UNICODE,'Unicode string');
+ InsertString(wnd,ACF_CURRENT,'current contact');
+ InsertString(wnd,ACF_RESULT ,'last result');
+ InsertString(wnd,ACF_PARAM ,'parameter');
+ if (flags and ACF_NOSTRUCT)=0 then
+ InsertString(wnd,ACF_STRUCT ,'structure');
+ SendMessage(wnd,CB_SETCURSEL,0,0);
+end;
+
+function IsParamNumber(txt:pAnsiChar):boolean;
+begin
+ if (txt[0] in ['0'..'9']) or ((txt[0]='-') and (txt[1] in ['0'..'9'])) or
+ ((txt[0]='$') and (txt[1] in sHexNum)) or
+ ((txt[0]='0') and (txt[1]='x') and (txt[2] in sHexNum)) then
+ result:=true
+ else
+ result:=false;
+end;
+
+// Set parameter type by parameter template
+function FixParam(buf:PAnsiChar):integer;
+begin
+ if StrCmp(buf,'hContact' )=0 then result:=ACF_CURRENT
+ else if StrCmp(buf,'parameter' )=0 then result:=ACF_PARAM
+ else if StrCmp(buf,'result' )=0 then result:=ACF_RESULT
+ else if StrCmp(buf,'structure' )=0 then result:=ACF_STRUCT
+ else if StrCmp(buf,'Unicode text')=0 then result:=ACF_UNICODE
+ else result:=ACF_STRING;
+end;
+
+function FixParamControls(Dialog:HWND;atype:dword):dword;
+var
+ wnd,wnd1:HWND;
+ pcw:pWideChar;
+begin
+ result:=atype;
+
+ wnd :=GetDlgItem(Dialog,IDC_EDIT_PAR);
+ wnd1:=GetDlgItem(Dialog,IDC_STRUCT);
+
+ if atype=ACF_STRUCT then
+ begin
+ ShowEditField(wnd ,SW_HIDE);
+ ShowWindow (wnd1,SW_SHOW);
+ end
+ else
+ begin
+ ShowEditField(wnd ,SW_SHOW);
+ ShowWindow (wnd1,SW_HIDE);
+
+ if atype in [ACF_CURRENT,ACF_RESULT,ACF_PARAM] then
+ EnableEditField(wnd,false)
+ else
+ begin
+ if atype=ACF_NUMBER then //!!
+ begin
+ pcw:='0';
+ SendMessageW(wnd,WM_SETTEXT,0,TLParam(pcw));
+ end;
+ EnableEditField(wnd,true);
+ end;
+
+ end;
+end;
+
+// get line from template
+function GetParamLine(src:pAnsiChar;dst:pWideChar;var ltype:integer):pAnsiChar;
+var
+ pp,pc:pAnsiChar;
+ j:integer;
+ savechar:AnsiChar;
+begin
+ pc:=StrScan(src,'|');
+
+ if pc<>nil then
+ begin
+ savechar:=pc^;
+ pc^:=#0;
+ end;
+
+ if IsParamNumber(src) then
+ begin
+ j:=0;
+ pp:=src;
+ repeat
+ dst[j]:=WideChar(pp^);
+ inc(j); inc(pp);
+ until (pp^=#0) or (pp^=' ');
+ dst[j]:=WideChar(pp^); // anyway, #0 or " " needs
+ if pp^<>#0 then
+ begin
+ dst[j+1]:='-'; dst[j+2]:=' '; inc(j,3);
+ FastAnsitoWideBuf(pp+1,dst+j);
+ StrCopyW(dst+j,TranslateW(dst+j));
+ end;
+ ltype:=ACF_NUMBER;
+ end
+ else
+ begin
+ ltype:=FixParam(src);
+ StrCopyW(dst,TranslateW(FastAnsitoWideBuf(src,dst)));
+ end;
+
+ if pc<>nil then
+ begin
+ pc^:=savechar;
+ inc(pc);
+ end;
+
+ result:=pc;
+end;
+
+// Set parameter value by parameter template
+function FillParam(Dialog:HWND;txt:pAnsiChar):integer;
+var
+ bufw:array [0..2047] of WideChar;
+ wnd:HWND;
+ p,pc:PAnsiChar;
+ ltype:integer;
+begin
+ wnd:=GetDlgItem(Dialog,IDC_EDIT_PAR);
+ SendMessage(wnd,CB_RESETCONTENT,0,0);
+ if (txt<>nil) and (txt^<>#0) then
+ begin
+ result:=-1;
+ p:=txt;
+ repeat
+ pc:=GetParamLine(p,bufw,ltype);
+ if result<0 then
+ result:=ltype;
+ SendMessageW(wnd,CB_ADDSTRING,0,lparam(@bufw));
+
+ if result=ACF_STRUCT then
+ break
+ else
+ p:=pc;
+ until pc=nil;
+ end
+ else
+ result:=ACF_NUMBER;
+ SendMessage(wnd,CB_SETCURSEL,0,0);
+
+ CB_SelectData(GetDlgItem(Dialog,IDC_FLAG_PAR),result);
+ FixParamControls(Dialog,result);
+end;
+
+function ClearParamFields(Dialog:HWND):HWND;
+var
+ wnd:HWND;
+begin
+ wnd:=GetDlgItem(Dialog,IDC_EDIT_PAR);
+ SendMessage (wnd,CB_RESETCONTENT,0,0);
+ SetEditFlags (wnd,EF_ALL,0);
+ CB_SelectData(Dialog,IDC_FLAG_PAR,ACF_NUMBER);
+ FixParamControls(Dialog,ACF_NUMBER);
+ result:=Dialog;
+end;
+
+function DlgParamProc(Dialog:HWnd;hMessage:uint;wParam:WPARAM;lParam:LPARAM):lresult; stdcall;
+var
+ wnd,wnd1:HWND;
+ proc:pointer;
+ pcw:pWideChar;
+ pc,pc1:pAnsiChar;
+ i:integer;
+begin
+ result:=0;
+
+ case hMessage of
+ WM_DESTROY: begin
+ pc:=pAnsiChar(GetWindowLongPtrW(GetDlgItem(Dialog,IDC_STRUCT),GWLP_USERDATA));
+ mFreeMem(pc);
+ end;
+
+ WM_SHOWWINDOW: begin
+ // hide window by ShowWindow function
+ if (lParam=0) and (wParam=0) then
+ begin
+ pc:=pAnsiChar(SetWindowLongPtrW(GetDlgItem(Dialog,IDC_STRUCT),GWLP_USERDATA,0));
+ mFreeMem(pc);
+ end;
+ end;
+
+ WM_COMMAND: begin
+ case wParam shr 16 of
+ CBN_EDITCHANGE,
+ EN_CHANGE: begin
+ SendMessage(GetParent(Dialog),WM_COMMAND,CBN_EDITCHANGE shl 16,Dialog);
+ end;
+
+ CBN_SELCHANGE: begin
+ SendMessage(GetParent(Dialog),WM_COMMAND,CBN_EDITCHANGE shl 16,Dialog);
+ case loword(wParam) of
+ IDC_FLAG_PAR: begin
+ wnd :=GetDlgItem(Dialog,IDC_EDIT_PAR);
+ wnd1:=GetDlgItem(Dialog,IDC_STRUCT);
+
+ i:=CB_GetData(GetDlgItem(Dialog,loword(wParam)));
+
+ if i=ACF_STRUCT then
+ begin
+ ShowEditField(wnd ,SW_HIDE);
+ ShowWindow (wnd1,SW_SHOW);
+ end
+ else
+ begin
+ ShowEditField(wnd ,SW_SHOW);
+ ShowWindow (wnd1,SW_HIDE);
+
+ if i in [ACF_CURRENT,ACF_RESULT,ACF_PARAM] then
+ EnableEditField(wnd,false)
+ else
+ begin
+ if i=ACF_NUMBER then
+ begin
+ pcw:='0';
+ SendMessageW(wnd,WM_SETTEXT,0,TLParam(pcw));
+ end;
+ EnableEditField(wnd,true);
+ end;
+
+ end;
+ end;
+ end;
+ end;
+
+ BN_CLICKED: begin
+ case loword(wParam) of
+ IDC_STRUCT: begin
+ pc:=pAnsiChar(GetWindowLongPtrW(lParam,GWLP_USERDATA));
+//!!!!
+ pc1:=EditStructure(pc{,Dialog});
+ if pc1<>nil then
+ begin
+ mFreeMem(pc);
+ SetWindowLongPtrW(lParam,GWLP_USERDATA,long_ptr(pc1));
+ SendMessage(GetParent(Dialog),WM_COMMAND,BN_CLICKED shl 16,Dialog);
+ end;
+ end;
+ else
+ // can be just edit field wrapper button, no need to react
+ end;
+ end;
+
+ end;
+ end;
+ else
+ proc:=pointer(GetWindowLongPtrW(Dialog,GWLP_USERDATA));
+ result:=CallWindowProc(proc,Dialog,hMessage,wParam,lParam)
+ end;
+end;
+
+//----- Common interface functions -----
+
+function CreateParamBlock(parent:HWND;x,y,width:integer;flags:dword=0):THANDLE;
+var
+ hf:HFONT;
+ group,ctrl:HWND;
+ proc:pointer;
+ rc:TRECT;
+ fullline:bool;
+ gx,dx,dy,xo,yo:integer;
+ ux,uy:integer;
+begin
+ hf:=SendMessageW(parent,WM_GETFONT,0,0);
+ GetUnitSize(parent,ux,uy);
+
+ // block
+ SetRect(rc,x,y,x+width,y+31);
+ dx:=rc.right-rc.left;
+ dy:=rc.bottom-rc.top;
+
+ result:=CreateWindowExW(WS_EX_CONTROLPARENT,'STATIC',nil,WS_CHILD+WS_VISIBLE,
+ x,y,dx,dy, parent,0,hInstance,nil);
+ proc:=pointer(SetWindowLongPtrW(result,GWLP_WNDPROC,long_ptr(@DlgParamProc)));
+ SetWindowLongPtrW(result,GWLP_USERDATA,long_ptr(proc));
+
+ yo:=0;
+
+ // group border
+ if (flags and ACF_NOBORDER)=0 then
+ begin
+ group:=CreateWindowW('BUTTON','Param',WS_CHILD+WS_VISIBLE+WS_GROUP+BS_GROUPBOX,
+ 0,0,dx,dy, result,IDC_GROUP_PAR,hInstance,nil);
+ SendMessageW(group,WM_SETFONT,hf,0);
+ gx:=4;
+ inc(yo,12);
+ end
+ else
+ begin
+ gx:=0;
+ end;
+
+ // label
+ if (flags and ACF_NOSTATIC)=0 then
+ begin
+
+ if width<=150 then
+ begin
+ fullline:=true;
+ rc.bottom:=11*uy div 8;
+ xo:=dx-gx*2;
+ end
+ else
+ begin
+ fullline:=false;
+ rc.bottom:=14*uy div 8; // same as param type combobox
+ xo:=dx div 3;
+ end;
+ ctrl:=CreateWindowW('STATIC','Param type',WS_CHILD+WS_VISIBLE+SS_RIGHT+SS_CENTERIMAGE,
+ gx,yo,xo-gx,rc.bottom, result,IDC_LABEL_PAR,hInstance,nil);
+ SendMessageW(ctrl,WM_SETFONT,hf,0);
+ end
+ else
+ begin
+ fullline:=true;
+ end;
+
+ // param type
+ rc.bottom:=14*uy div 8;
+ if fullline then
+ begin
+ xo:=gx;
+ if (flags and ACF_NOSTATIC)=0 then
+ inc(yo,rc.bottom);
+ end;
+ ctrl:=CreateWindowW('COMBOBOX',nil,WS_CHILD+WS_VISIBLE+WS_VSCROLL+CBS_DROPDOWNLIST+CBS_AUTOHSCROLL,
+ xo+2,yo,dx-xo-gx-2,56, result,IDC_FLAG_PAR,hInstance,nil);
+
+ SendMessageW(ctrl,WM_SETFONT,hf,0);
+ MakeParamTypeList(ctrl,flags);
+ inc(yo,rc.bottom+2);
+
+ // param value
+ rc.bottom:=14*uy div 8;
+
+ ctrl:=CreateWindowW('COMBOBOX',nil,WS_CHILD+WS_VISIBLE+WS_VSCROLL+CBS_DROPDOWN+CBS_AUTOHSCROLL,
+ gx,yo,dx-gx*2,76, result,IDC_EDIT_PAR,hInstance,nil);
+ SendMessageW(ctrl,WM_SETFONT,hf,0);
+ MakeEditField(result,IDC_EDIT_PAR);
+
+ ctrl:=CreateWindowW('BUTTON','Structure',WS_CHILD+WS_VISIBLE+BS_PUSHBUTTON,
+ gx,yo,dx-gx*2,rc.bottom, result,IDC_STRUCT,hInstance,nil);
+ SendMessageW(ctrl,WM_SETFONT,hf,0);
+ inc(yo,rc.bottom+4);
+
+ // resize group and dialog
+ MoveWindow(result,x,y,dx,yo,false);
+ if (flags and ACF_NOBORDER)=0 then
+ MoveWindow(group,0,0,dx,yo,false);
+
+ ClearParamFields(result);
+end;
+
+// if separate
+function DestroyBlock(block:pointer):integer;
+begin
+ result:=0;
+end;
+
+function SetParamLabel(Dialog:HWND; lbl:pWideChar):HWND;
+var
+ wnd:HWND;
+begin
+ result:=Dialog;
+
+ if Dialog=0 then
+ exit;
+
+ wnd:=GetDlgItem(Dialog,IDC_LABEL_PAR);
+ if wnd<>0 then
+ SendMessageW(wnd,WM_SETTEXT,0,LPARAM(lbl))
+ else
+ begin
+ wnd:=GetDlgItem(Dialog,IDC_GROUP_PAR);
+ if wnd<>0 then
+ SendMessageW(wnd,WM_SETTEXT,0,LPARAM(lbl))
+ end;
+end;
+
+function SetParamValue(Dialog:HWND;flags:dword;value:pointer):boolean;
+var
+ wnd,wnd1:HWND;
+ pc:pAnsiChar;
+ pcw:pWideChar;
+ vtype:integer;
+begin
+ if Dialog=0 then
+ begin
+ result:=false;
+ exit;
+ end;
+
+ result:=true;
+
+ wnd:=GetDlgItem(Dialog,IDC_EDIT_PAR);
+ if (flags and ACF_TEMPLATE)<>0 then
+ begin
+ vtype:=FillParam(Dialog,value);
+ end
+ else if (flags and ACF_PARAM)<>0 then
+ begin
+ SendMessageW(wnd,WM_SETTEXT,0,LPARAM(TranslateW('Parameter')));
+ EnableWindow(wnd,false);
+ vtype:=ACF_PARAM;
+ end
+ else if (flags and ACF_RESULT)<>0 then
+ begin
+ SendMessageW(wnd,WM_SETTEXT,0,LPARAM(TranslateW('Last result')));
+ EnableWindow(wnd,false);
+ vtype:=ACF_RESULT;
+ end
+ else if (flags and ACF_CURRENT)<>0 then
+ begin
+ SendMessageW(wnd,WM_SETTEXT,0,LPARAM(TranslateW('Current user')));
+ EnableWindow(wnd,false);
+ vtype:=ACF_CURRENT;
+ end
+ else if (flags and ACF_STRUCT)<>0 then
+ begin
+ vtype:=ACF_STRUCT;
+
+ ShowEditField(wnd,SW_HIDE);
+ wnd1:=GetDlgItem(Dialog,IDC_STRUCT);
+ ShowWindow(wnd1,SW_SHOW);
+ // delete old value
+ pc:=pAnsiChar(GetWindowLongPtrW(wnd1,GWLP_USERDATA));
+ mFreeMem(pc);
+ // set newly allocated
+ SetWindowLongPtrW(wnd1,GWLP_USERDATA,long_ptr(StrDup(pc,pAnsiChar(value))));
+//!!!!!!!!
+ end
+ else if (flags and ACF_NUMBER)<>0 then
+ begin
+ vtype:=ACF_NUMBER;
+ if value=nil then
+ pcw:='0'
+ else
+ pcw:=value;
+ SendMessageW(wnd,WM_SETTEXT,0,LPARAM(pcw));
+ end
+ else if (flags and ACF_UNICODE)<>0 then
+ begin
+ vtype:=ACF_UNICODE;
+ SendMessageW(wnd,WM_SETTEXT,0,LPARAM(value));
+ end
+ else
+ begin
+ vtype:=ACF_STRING;
+ SendMessageW(wnd,WM_SETTEXT,0,LPARAM(value));
+ end;
+ SetEditFlags(wnd,EF_SCRIPT,ord((flags and ACF_SCRIPT_PARAM)<>0));
+
+ CB_SelectData(GetDlgItem(Dialog,IDC_FLAG_PAR),vtype);
+ FixParamControls(Dialog,vtype);
+end;
+
+function GetParamValue(Dialog:HWND;var flags:dword;var value:pointer):boolean;
+var
+ wnd:HWND;
+begin
+ if Dialog=0 then
+ begin
+ result:=false;
+ exit;
+ end;
+
+ result:=true;
+ flags:=0;
+ value:=nil;
+ wnd:=GetDlgItem(Dialog,IDC_EDIT_PAR);
+ case CB_GetData(GetDlgItem(Dialog,IDC_FLAG_PAR)) of
+ ACF_PARAM: begin
+ flags:=flags or ACF_PARAM
+ end;
+ ACF_RESULT: begin
+ flags:=flags or ACF_RESULT
+ end;
+ ACF_CURRENT: begin
+ flags:=flags or ACF_CURRENT
+ end;
+ ACF_NUMBER: begin
+ flags:=flags or ACF_NUMBER;
+ value:=GetDlgText(wnd);
+ end;
+ ACF_STRUCT: begin
+ flags:=flags or ACF_STRUCT;
+ StrDup(pAnsiChar(value),
+ pAnsiChar(GetWindowLongPtrW(GetDlgItem(Dialog,IDC_STRUCT),GWLP_USERDATA)));
+ end;
+ ACF_UNICODE: begin
+ flags:=flags or ACF_UNICODE;
+ value:=GetDlgText(wnd);
+ end;
+ ACF_STRING: value:=GetDlgText(wnd);
+ end;
+ if (GetEditFlags(wnd) and EF_SCRIPT)<>0 then
+ flags:=flags or ACF_SCRIPT_PARAM;
+end;
+
+//----- Additional functions -----
+
+procedure ClearParam(flags:dword; var param);
+begin
+ if (flags and (ACF_CURRENT or ACF_RESULT or ACF_PARAM))=0 then
+ mFreeMem(pointer(param));
+end;
+
+function DuplicateParam(flags:dword; var sparam,dparam):dword;
+var
+ tmpdst:array [0..2047] of WideChar;
+ ltype:integer;
+begin
+ mFreeMem(dparam);
+
+ if (flags and ACF_TEMPLATE)<>0 then
+ begin
+ flags:=flags and not (ACF_TEMPLATE or ACF_PARTYPE);
+ GetParamLine(pAnsiChar(sparam),tmpdst,ltype);
+ case ltype of
+ ACF_NUMBER: begin
+ flags:=flags or ACF_NUMBER;
+ StrDupW(pWideChar(dparam),pWideChar(@tmpdst));
+ end;
+ ACF_STRING: begin
+ flags:=flags or ACF_STRING;
+ StrDupW(pWideChar(dparam),pWideChar(@tmpdst));
+ end;
+ ACF_UNICODE: begin
+ flags:=flags or ACF_UNICODE;
+ StrDupW(pWideChar(dparam),pWideChar(@tmpdst));
+ end;
+ ACF_STRUCT: begin
+ flags:=flags or ACF_STRUCT;
+ StrDup(pAnsiChar(dparam),pAnsiChar(sparam)+10); //10=StrLen('structure|')
+ end;
+ ACF_CURRENT: flags:=flags or ACF_CURRENT;
+ ACF_RESULT : flags:=flags or ACF_RESULT;
+ ACF_PARAM : flags:=flags or ACF_PARAM;
+ end;
+ end
+ else if (flags and (ACF_CURRENT or ACF_RESULT or ACF_PARAM))=0 then
+ begin
+ if (flags and ACF_NUMBER)<>0 then
+ StrDupW(pWideChar(dparam),pWideChar(sparam))
+ else if (flags and ACF_STRUCT)<>0 then
+ StrDup(pAnsiChar(dparam),pAnsiChar(sparam))
+ else if (flags and ACF_UNICODE)<>0 then
+ StrDupW(pWideChar(dparam),pWideChar(sparam))
+ else
+ StrDupW(pWideChar(dparam),pWideChar(sparam));
+ end;
+ result:=flags;
+end;
+
+function TranslateParam(param:uint_ptr;flags:dword;hContact:THANDLE):uint_ptr;
+var
+ tmp1:pWideChar;
+begin
+ if (flags and ACF_SCRIPT_PARAM)<>0 then
+ result:=uint_ptr(ParseVarString(pWideChar(param),hContact));
+
+ tmp1:=pWideChar(result);
+ if (flags and ACF_NUMBER)=0 then
+ begin
+ if (flags and ACF_UNICODE)=0 then
+ WideToAnsi(tmp1,pAnsiChar(result),MirandaCP)
+ else
+ StrDupW(pWideChar(result),tmp1);
+ end
+ else
+ result:=NumToInt(tmp1);
+
+ if (flags and ACF_SCRIPT_PARAM)<>0 then
+ mFreeMem(tmp1);
+end;
+
+//===== result block =====
+
+function ClearResultFields(Dialog:HWND):HWND;
+var
+ w:HWND;
+begin
+ result:=Dialog;
+
+ if Dialog=0 then
+ exit;
+
+ CheckDlgButton(Dialog,IDC_RES_FREEMEM,BST_UNCHECKED);
+ ShowWindow(GetDlgItem(Dialog,IDC_RES_FREEMEM),SW_HIDE);
+ CB_SelectData(Dialog,IDC_RES_TYPE,ACF_RNUMBER);
+
+ w:=GetDlgItem(Dialog,IDC_RES_HEXNUM);
+ if w<>0 then
+ begin
+ ShowWindow(w,SW_SHOW);
+ ShowWindow(GetDlgItem(Dialog,IDC_RES_SIGNED),SW_SHOW);
+ end;
+end;
+
+procedure MakeResultTypeList(wnd:HWND;flags:dword);
+begin
+ SendMessage(wnd,CB_RESETCONTENT,0,0);
+ InsertString(wnd,ACF_RNUMBER ,'number value');
+ InsertString(wnd,ACF_RSTRING ,'ANSI string');
+ InsertString(wnd,ACF_RUNICODE,'Unicode string');
+ if (flags and ACF_NOSTRUCT)=0 then
+ InsertString(wnd,ACF_RSTRUCT ,'structure');
+ SendMessage(wnd,CB_SETCURSEL,0,0);
+end;
+
+function DlgResultProc(Dialog:HWnd;hMessage:uint;wParam:WPARAM;lParam:LPARAM):lresult; stdcall;
+var
+ proc:pointer;
+ wnd:HWND;
+ b:bool;
+ i,j:integer;
+begin
+ result:=0;
+
+ case hMessage of
+ WM_COMMAND: begin
+ case wParam shr 16 of
+ BN_CLICKED: begin
+ case loword(wParam) of
+ IDC_RES_SIGNED: begin
+ if IsDlgButtonChecked(Dialog,IDC_RES_SIGNED)=BST_UNCHECKED then
+ begin
+ b:=true;
+ end
+ else
+ begin
+ b:=false;
+ end;
+ EnableWindow(GetDlgItem(Dialog,IDC_RES_HEXNUM),b);
+ end;
+ IDC_RES_HEXNUM: begin
+ if IsDlgButtonChecked(Dialog,IDC_RES_HEXNUM)=BST_UNCHECKED then
+ begin
+ b:=true;
+ end
+ else
+ begin
+ b:=false;
+ end;
+ EnableWindow(GetDlgItem(Dialog,IDC_RES_SIGNED),b);
+ end;
+ end;
+ end;
+
+ CBN_SELCHANGE: begin
+ case loword(wParam) of
+ IDC_RES_TYPE: begin
+ case CB_GetData(lParam) of
+ ACF_RNUMBER: begin
+ i:=SW_HIDE;
+ j:=SW_SHOW;
+ end;
+ ACF_RSTRUCT: begin
+ i:=SW_HIDE;
+ j:=SW_HIDE;
+ end;
+ ACF_RSTRING,ACF_RUNICODE: begin
+ i:=SW_SHOW;
+ j:=SW_HIDE;
+ end;
+ end;
+ ShowWindow(GetDlgItem(Dialog,IDC_RES_FREEMEM),i);
+ wnd:=GetDlgItem(Dialog,IDC_RES_HEXNUM);
+ if wnd<>0 then
+ begin
+ ShowWindow(wnd,j);
+ ShowWindow(GetDlgItem(Dialog,IDC_RES_SIGNED),j);
+ end;
+ end;
+ end;
+ end;
+ end;
+ end;
+ else
+ proc:=pointer(GetWindowLongPtrW(Dialog,GWLP_USERDATA));
+ result:=CallWindowProc(proc,Dialog,hMessage,wParam,lParam)
+ end;
+end;
+
+function CreateResultBlock(parent:HWND;x,y,width:integer;flags:dword=0):THANDLE;
+var
+ hf:HFONT;
+ ctrl,group:HWND;
+ proc:pointer;
+ rc:TRECT;
+ fullline:bool;
+ dx,dy,yo,gx,xo:integer;
+ ux,uy:integer;
+begin
+ hf:=SendMessageW(parent,WM_GETFONT,0,0);
+ GetUnitSize(parent,ux,uy);
+
+ // block body
+ SetRect(rc,x,y,x+width,y+53);
+ dx:=rc.right-rc.left;
+ dy:=rc.bottom-rc.top;
+
+ result:=CreateWindowExW(WS_EX_CONTROLPARENT,'STATIC',nil,WS_CHILD+WS_VISIBLE,
+ x,y,dx,dy, parent,0,hInstance,nil);
+ proc:=pointer(SetWindowLongPtrW(result,GWLP_WNDPROC,long_ptr(@DlgResultProc)));
+ SetWindowLongPtrW(result,GWLP_USERDATA,long_ptr(proc));
+
+ yo:=0;
+
+ // group border
+ if (flags and ACF_NOBORDER)=0 then
+ begin
+ group:=CreateWindowW('BUTTON','Result',WS_CHILD+WS_VISIBLE+WS_GROUP+BS_GROUPBOX,
+ 0,0,dx,dy, result,0,hInstance,nil);
+ SendMessageW(group,WM_SETFONT,hf,0);
+ gx:=4;
+ inc(yo,12);
+ end
+ else
+ begin
+ gx:=0;
+ end;
+
+ // label
+ if (flags and ACF_NOSTATIC)=0 then
+ begin
+ if width<=150 then
+ begin
+ fullline:=true;
+ rc.bottom:=11*uy div 8;
+ xo:=dx-gx*2;
+ end
+ else
+ begin
+ fullline:=false;
+ rc.bottom:=14*uy div 8; // same as param type combobox
+ xo:=dx div 3;
+ end;
+ ctrl:=CreateWindowW('STATIC','Result type',WS_CHILD+WS_VISIBLE+SS_RIGHT+SS_CENTERIMAGE,
+ gx,yo,xo-gx,rc.bottom, result,IDC_LABEL_PAR,hInstance,nil);
+ SendMessageW(ctrl,WM_SETFONT,hf,0);
+ end
+ else
+ begin
+ fullline:=true;
+ end;
+
+ // result type
+ rc.bottom:=14*uy div 8;
+ if fullline then
+ begin
+ xo:=gx;
+ if (flags and ACF_NOSTATIC)=0 then
+ inc(yo,rc.bottom);
+ end;
+ ctrl:=CreateWindowW('COMBOBOX',nil,WS_CHILD+WS_VISIBLE+WS_VSCROLL+CBS_DROPDOWNLIST+CBS_AUTOHSCROLL,
+ xo+2,yo,dx-xo-gx-2,76, result,IDC_RES_TYPE,hInstance,nil);
+
+ SendMessageW(ctrl,WM_SETFONT,hf,0);
+ MakeResultTypeList(ctrl,flags);
+ inc(yo,rc.bottom+2);
+
+ // 'free memory' checkbox
+ rc.bottom:=11*uy div 8;
+
+ ctrl:=CreateWindowW('BUTTON','Free memory',WS_CHILD+WS_VISIBLE+BS_AUTOCHECKBOX,
+ gx,yo,dx-gx*2,rc.bottom, result,IDC_RES_FREEMEM,hInstance,nil);
+ SendMessageW(ctrl,WM_SETFONT,hf,0);
+ inc(yo,rc.bottom+4);
+
+ if (flags and ACF_NOVISUAL)=0 then
+ begin
+ dec(yo,rc.bottom+4);
+
+ ctrl:=CreateWindowW('BUTTON','Signed',WS_CHILD+WS_VISIBLE+BS_AUTOCHECKBOX,
+ gx,yo,dx-gx*2,rc.bottom, result,IDC_RES_SIGNED,hInstance,nil);
+ SendMessageW(ctrl,WM_SETFONT,hf,0);
+ inc(yo,rc.bottom+2);
+
+ ctrl:=CreateWindowW('BUTTON','As hex',WS_CHILD+WS_VISIBLE+BS_AUTOCHECKBOX,
+ gx,yo,dx-gx*2,rc.bottom, result,IDC_RES_HEXNUM,hInstance,nil);
+ SendMessageW(ctrl,WM_SETFONT,hf,0);
+ inc(yo,rc.bottom+4);
+ end;
+
+ // resize group and dialog
+ MoveWindow(result,x,y,dx,yo,false);
+ if (flags and ACF_NOBORDER)=0 then
+ MoveWindow(group,0,0,dx,yo,false);
+
+ ClearResultFields(result);
+end;
+
+function SetResultValue(Dialog:HWND;flags:dword):integer;
+var
+ w:HWND;
+ btn:cardinal;
+ sh,sh1:integer;
+begin
+ if Dialog=0 then
+ begin
+ result:=ACF_RNUMBER;
+ exit;
+ end;
+
+ // RESULT
+ sh :=SW_HIDE;
+ sh1:=SW_HIDE;
+ w:=GetDlgItem(Dialog,IDC_RES_HEXNUM);
+ if (flags and ACF_RSTRUCT)<>0 then
+ result:=ACF_RSTRUCT
+ else if (flags and (ACF_RSTRING or ACF_RUNICODE))<>0 then
+ begin
+ sh:=SW_SHOW;
+
+ if (flags and ACF_RFREEMEM)<>0 then
+ btn:=BST_CHECKED
+ else
+ btn:=BST_UNCHECKED;
+ CheckDlgButton(Dialog,IDC_RES_FREEMEM,btn);
+
+ if (flags and ACF_RUNICODE)<>0 then
+ result:=ACF_RUNICODE
+ else
+ result:=ACF_RSTRING;
+ end
+ else
+ begin
+ result:=ACF_RNUMBER;
+ if w<>0 then
+ begin
+ sh1:=SW_SHOW;
+ if (flags and ACF_RSIGNED)<>0 then
+ btn:=BST_CHECKED
+ else
+ btn:=BST_UNCHECKED;
+ CheckDlgButton(Dialog,IDC_RES_SIGNED,btn);
+ if (flags and ACF_RHEXNUM)<>0 then
+ btn:=BST_CHECKED
+ else
+ btn:=BST_UNCHECKED;
+ CheckDlgButton(Dialog,IDC_RES_HEXNUM,btn);
+ end;
+ end;
+ ShowWindow(GetDlgItem(Dialog,IDC_RES_FREEMEM),sh);
+ if w<>0 then
+ begin
+ ShowWindow(w,sh1);
+ ShowWindow(GetDlgItem(Dialog,IDC_RES_SIGNED),sh1);
+ end;
+ CB_SelectData(Dialog,IDC_RES_TYPE,result);
+end;
+
+function GetResultValue(Dialog:HWND):dword;
+begin
+ if Dialog=0 then
+ begin
+ result:=ACF_RNUMBER;
+ exit;
+ end;
+
+ case CB_GetData(GetDlgItem(Dialog,IDC_RES_TYPE)) of
+ ACF_RSTRING: begin
+ result:=ACF_RSTRING;
+ if IsDlgButtonChecked(Dialog,IDC_RES_FREEMEM)=BST_CHECKED then
+ result:=result or ACF_RFREEMEM;
+ end;
+ ACF_RUNICODE: begin
+ result:={!!atavizm ACF_RSTRING or }ACF_RUNICODE;
+ if IsDlgButtonChecked(Dialog,IDC_RES_FREEMEM)=BST_CHECKED then
+ result:=result or ACF_RFREEMEM;
+ end;
+ ACF_RSTRUCT: result:=ACF_RSTRUCT;
+ else
+ result:=ACF_RNUMBER;
+ if GetDlgItem(Dialog,IDC_RES_HEXNUM)<>0 then
+ begin
+ if IsDlgButtonChecked(Dialog,IDC_RES_SIGNED)=BST_CHECKED then
+ result:=result or ACF_RSIGNED
+ else if IsDlgButtonChecked(Dialog,IDC_RES_HEXNUM)=BST_CHECKED then
+ result:=result or ACF_RHEXNUM;
+ end;
+ end;
+
+end;
+
+end.