From 1109badbf7ade0bd6647654302a6ef5e1bb8fee2 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Wed, 6 Nov 2013 15:29:23 +0000 Subject: Actman 30 merged with Awk's git-svn-id: http://svn.miranda-ng.org/main/trunk@6806 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Actman30/sparam.pas | 708 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 708 insertions(+) create mode 100644 plugins/Actman30/sparam.pas (limited to 'plugins/Actman30/sparam.pas') diff --git a/plugins/Actman30/sparam.pas b/plugins/Actman30/sparam.pas new file mode 100644 index 0000000000..e29d375ae4 --- /dev/null +++ b/plugins/Actman30/sparam.pas @@ -0,0 +1,708 @@ +unit sparam; + +interface + +uses windows,iac_global; + +const + ACF_PARNUM = $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_PARNUM or ACF_UNICODE or + ACF_CURRENT or ACF_RESULT or + ACF_PARAM or ACF_STRUCT; + ACF_TEMPLATE = $00000800; + ACF_SCRIPT_PARAM = $00001000; + // dummy + ACF_STRING = 0; + + 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 + +function CreateParamBlock(parent:HWND;x,y,width:integer):THANDLE; +procedure ClearParamFields(Dialog: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; + +procedure ClearParam (flags:dword; var param); +function DuplicateParam(flags:dword; var sparam,dparam):dword; + +procedure PreProcess(flags:dword;var l_param:LPARAM;const WorkData:tWorkData); + +function CreateResultBlock(parent:HWND;x,y,width:integer):THANDLE; +procedure ClearResultFields(Dialog: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; + +{$include i_sparam_const.inc} +{$resource sparam.res} + +const + ptNumber = 0; + ptString = 1; + ptUnicode = 2; + ptCurrent = 3; + ptResult = 4; + ptParam = 5; + ptStruct = 6; + +const + sresInt = 0; + sresString = 1; + sresWide = 2; + sresStruct = 3; + +//----- Processing functions ----- + +procedure PreProcess(flags:dword;var l_param:LPARAM;const WorkData:tWorkData); +var + tmp1:pWideChar; +begin + with WorkData do + begin + if (flags and ACF_STRUCT)<>0 then + begin + l_param:=uint_ptr(MakeStructure(pAnsiChar(l_param),Parameter,LastResult,ResultType)) + end + else if (flags and ACF_PARAM)<>0 then + begin + l_param:=Parameter; + end + else if (flags and ACF_RESULT)<>0 then + begin + l_param:=LastResult; + end + else if (flags and ACF_CURRENT)<>0 then + begin + l_param:=WndToContact(WaitFocusedWndChild(GetForegroundwindow){GetFocus}); + end + else + begin + if (flags and ACF_SCRIPT_PARAM)<>0 then + l_param:=uint_ptr(ParseVarString(pWideChar(l_param),Parameter)); + + tmp1:=pWideChar(l_param); + if (flags and ACF_PARNUM)=0 then + begin + if (flags and ACF_UNICODE)=0 then + WideToAnsi(tmp1,pAnsiChar(l_param),MirandaCP) + else + StrDupW(pWideChar(l_param),tmp1); + end + else + l_param:=NumToInt(tmp1); + + if (flags and ACF_SCRIPT_PARAM)<>0 then + mFreeMem(tmp1); + end; + end; +end; + +procedure PostProcess(flags:dword;var l_param:LPARAM; var WorkData:tWorkData); +var + code:integer; + len:integer; + pc:pAnsiChar; +begin + if (flags and ACF_STRUCT)<>0 then + begin + with WorkData do + begin + LastResult:=GetStructureResult(l_param,@code,@len); + case code of +{ + SST_LAST: begin + result:=LastResult; + end; +} + SST_PARAM: begin //?? + LastResult:=Parameter; + ResultType:=rtInt; + end; + SST_BYTE,SST_WORD,SST_DWORD, + SST_QWORD,SST_NATIVE: begin + ResultType:=rtInt; + end; + SST_BARR: begin + StrDup(pAnsiChar(pc),pAnsiChar(LastResult),len); + AnsiToWide(pAnsiChar(pc),PWideChar(LastResult),MirandaCP); + mFreeMem(pAnsiChar(pc)); + ResultType:=rtWide; + end; + SST_WARR: begin + StrDupW(pWideChar(LastResult),pWideChar(LastResult),len); + ResultType:=rtWide; + end; + SST_BPTR: begin + AnsiToWide(pAnsiChar(LastResult),pWideChar(LastResult),MirandaCP); + ResultType:=rtWide; + end; + SST_WPTR: begin + StrDupW(pWideChar(LastResult),pWideChar(LastResult)); + ResultType:=rtWide; + end; + end; + FreeStructure(l_param); + l_param:=0; + end + end; +end; + +//----- Dialog functions ----- + +procedure MakeParamTypeList(wnd:HWND); +begin + SendMessage(wnd,CB_RESETCONTENT,0,0); + InsertString(wnd,ptNumber ,'number value'); + InsertString(wnd,ptString ,'ANSI string'); + InsertString(wnd,ptUnicode,'Unicode string'); + InsertString(wnd,ptCurrent,'current contact'); + InsertString(wnd,ptResult ,'last result'); + InsertString(wnd,ptParam ,'parameter'); + InsertString(wnd,ptStruct ,'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:=ptCurrent + else if StrCmp(buf,'parameter' )=0 then result:=ptParam + else if StrCmp(buf,'result' )=0 then result:=ptResult + else if StrCmp(buf,'structure' )=0 then result:=ptStruct + else if StrCmp(buf,'Unicode text')=0 then result:=ptUnicode + else result:=ptString; +end; + +// get line from template +function GetParamLine(src:pAnsiChar;dst:pWideChar;var ltype:integer):pAnsiChar; +var + pp,pc:pAnsiChar; + savechar:AnsiChar; + j:integer; +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:=ptNumber; + 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=ptStruct then + break + else + p:=pc; + until pc=nil; + end + else + result:=ptNumber; + SendMessage(wnd,CB_SETCURSEL,0,0); +end; + +procedure ClearParamFields(Dialog:HWND); +var + wnd:HWND; +begin + ShowWindow(GetDlgItem(Dialog,IDC_STRUCT),SW_HIDE); + wnd:=GetDlgItem(Dialog,IDC_EDIT_PAR); + ShowEditField (wnd,SW_SHOW); + EnableEditField(wnd,true); + SendMessage (wnd,CB_RESETCONTENT,0,0); + SetEditFlags (wnd,EF_ALL,0); + CB_SelectData(Dialog,IDC_FLAG_PAR,ptNumber); +end; + +function ParamDlgResizer(Dialog:HWND;lParam:LPARAM;urc:PUTILRESIZECONTROL):int; cdecl; +begin + case urc^.wId of + IDC_FLAG_PAR: result:=RD_ANCHORX_WIDTH or RD_ANCHORY_TOP; //RD_ANCHORX_RIGHT + IDC_EDIT_PAR: result:=RD_ANCHORX_WIDTH or RD_ANCHORY_TOP; + IDC_STRUCT: result:=RD_ANCHORX_WIDTH or RD_ANCHORY_TOP; + IDC_STAT_PAR: result:=RD_ANCHORX_LEFT or RD_ANCHORY_TOP; +// IDC_CLOSE: result:=RD_ANCHORX_WIDTH or RD_ANCHORY_TOP; + else + result:=0; + end; +end; + +function DlgParamProc(Dialog:HWnd;hMessage:uint;wParam:WPARAM;lParam:LPARAM):lresult; stdcall; +var + wnd,wnd1:HWND; + i:integer; + pcw:pWideChar; + pc:pAnsiChar; + urd:TUTILRESIZEDIALOG; +begin + result:=0; + + case hMessage of + WM_DESTROY: begin + pc:=pAnsiChar(GetWindowLongPtrW(GetDlgItem(Dialog,IDC_STRUCT),GWLP_USERDATA)); + mFreeMem(pc); + end; + + WM_INITDIALOG: begin + MakeEditField(Dialog,IDC_EDIT_PAR); + + MakeParamTypeList(GetDlgItem(Dialog,IDC_FLAG_PAR)); + end; + + WM_SIZE: begin + FillChar(urd,SizeOf(TUTILRESIZEDIALOG),0); + urd.cbSize :=SizeOf(urd); + urd.hwndDlg :=Dialog; + urd.hInstance :=hInstance; + urd.lpTemplate:=MAKEINTRESOURCEA('IDD_SPARAM'); + urd.lParam :=0; + urd.pfnResizer:=@ParamDlgResizer; + CallService(MS_UTILS_RESIZEDIALOG,0,tlparam(@urd)); + 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=ptStruct then + begin + ShowEditField(wnd ,SW_HIDE); + ShowWindow (wnd1,SW_SHOW); + end + else + begin + ShowEditField(wnd ,SW_SHOW); + ShowWindow (wnd1,SW_HIDE); + + if i in [ptCurrent,ptResult,ptParam] then + EnableEditField(wnd,false) + else + begin + if i=ptNumber then + begin + pcw:='0'; + SendMessageW(wnd,WM_SETTEXT,0,TLParam(pcw)); + end; + EnableEditField(wnd,true); + end; + end; + end; + end; + end; + end; + end; + end; +end; + +//----- Common interface functions ----- + +function CreateParamBlock(parent:HWND;x,y,width:integer):THANDLE; +var + rc,rc1:TRECT; +begin + SetRect(rc,x,y,x+width,y+0{dlgheight}); + MapDialogRect(parent,rc); + + result:=CreateDialogW(hInstance,'IDD_SPARAM',parent,@DlgParamProc); + GetClientRect(result,rc1); + SetWindowPos(result,0, + x,y{rc.left,rc.top},rc.right-rc.left,rc1.bottom-rc1.top, + SWP_NOZORDER); +end; + +// if separate +function DestroyBlock(block:pointer):integer; +begin + result:=0; +end; + +function SetParamValue(Dialog:HWND;flags:dword;value:pointer):boolean; +var + wnd,wnd1:HWND; + pc:pAnsiChar; + vtype:integer; +begin + result:=true; +//?? Check for "Apply" activation + + 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:=ptParam; + end + else if (flags and ACF_RESULT)<>0 then + begin + SendMessageW(wnd,WM_SETTEXT,0,LPARAM(TranslateW('Last result'))); + EnableWindow(wnd,false); + vtype:=ptResult; + end + else if (flags and ACF_CURRENT)<>0 then + begin + SendMessageW(wnd,WM_SETTEXT,0,LPARAM(TranslateW('Current user'))); + EnableWindow(wnd,false); + vtype:=ptCurrent; + end + else if (flags and ACF_STRUCT)<>0 then + begin + vtype:=ptStruct; + + 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_PARNUM)<>0 then + begin + vtype:=ptNumber; + SendMessageW(wnd,WM_SETTEXT,0,LPARAM(value)); + end + else if (flags and ACF_UNICODE)<>0 then + begin + vtype:=ptUnicode; + SendMessageW(wnd,WM_SETTEXT,0,LPARAM(value)); + end + else + begin + vtype:=ptString; + 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); +end; + +function GetParamValue(Dialog:HWND;var flags:dword;var value:pointer):boolean; +var + wnd:HWND; +begin + result:=true; + flags:=0; + value:=nil; + wnd:=GetDlgItem(Dialog,IDC_EDIT_PAR); + case CB_GetData(GetDlgItem(Dialog,IDC_FLAG_PAR)) of + ptParam: begin + flags:=flags or ACF_PARAM + end; + ptResult: begin + flags:=flags or ACF_RESULT + end; + ptCurrent: begin + flags:=flags or ACF_CURRENT + end; + ptNumber: begin + flags:=flags or ACF_PARNUM; + value:=GetDlgText(wnd); + end; + ptStruct: begin + flags:=flags or ACF_STRUCT; + StrDup(pAnsiChar(value), + pAnsiChar(GetWindowLongPtrW(GetDlgItem(Dialog,IDC_STRUCT),GWLP_USERDATA))); + end; + ptUnicode: begin + flags:=flags or ACF_UNICODE; + value:=GetDlgText(wnd); + end; + ptString: value:=GetDlgText(wnd); + end; + if (GetEditFlags(wnd) and EF_SCRIPT)<>0 then + flags:=flags or ACF_SCRIPT_PARAM; +end; + +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 + ptNumber: begin + flags:=flags or ACF_PARNUM; + StrDupW(pWideChar(dparam),pWideChar(@tmpdst)); + end; + ptString: begin + flags:=flags or ACF_STRING; + StrDupW(pWideChar(dparam),pWideChar(@tmpdst)); + end; + ptUnicode: begin + flags:=flags or ACF_UNICODE; + StrDupW(pWideChar(dparam),pWideChar(@tmpdst)); + end; + ptStruct: begin + flags:=flags or ACF_STRUCT; + StrDup(pAnsiChar(dparam),pAnsiChar(sparam)+10); //10=StrLen('structure|') + end; + ptCurrent: flags:=flags or ACF_CURRENT; + ptResult : flags:=flags or ACF_RESULT; + ptParam : 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_PARNUM)<>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; + +//----- result block ----- + +procedure MakeResultTypeList(wnd:HWND); +begin + SendMessage(wnd,CB_RESETCONTENT,0,0); + InsertString(wnd,sresInt ,'Integer'); + InsertString(wnd,sresString,'String'); + InsertString(wnd,sresWide ,'Wide String'); + InsertString(wnd,sresStruct,'Structure'); + SendMessage(wnd,CB_SETCURSEL,0,0); +end; + +function ResultDlgResizer(Dialog:HWND;lParam:LPARAM;urc:PUTILRESIZECONTROL):int; cdecl; +begin + case urc^.wId of + IDC_RES_TYPE : result:=RD_ANCHORX_WIDTH or RD_ANCHORY_TOP; //RD_ANCHORX_RIGHT + IDC_RES_FREEMEM: result:=RD_ANCHORX_WIDTH or RD_ANCHORY_TOP; + IDC_RES_STAT : result:=RD_ANCHORX_LEFT or RD_ANCHORY_TOP; + IDC_RES_GROUP : result:=RD_ANCHORX_WIDTH or RD_ANCHORY_TOP; + else + result:=0; + end; +end; + +procedure ClearResultFields(Dialog:HWND); +begin + CheckDlgButton(Dialog,IDC_RES_FREEMEM,BST_UNCHECKED); + ShowWindow(GetDlgItem(Dialog,IDC_RES_FREEMEM),SW_HIDE); + CB_SelectData(Dialog,IDC_RES_TYPE,sresInt); +end; + +function DlgResultProc(Dialog:HWnd;hMessage:uint;wParam:WPARAM;lParam:LPARAM):lresult; stdcall; +var + urd:TUTILRESIZEDIALOG; + i:integer; +begin + result:=0; + + case hMessage of + WM_INITDIALOG: begin + MakeResultTypeList(GetDlgItem(Dialog,IDC_RES_TYPE)); + end; + + WM_SIZE: begin + FillChar(urd,SizeOf(TUTILRESIZEDIALOG),0); + urd.cbSize :=SizeOf(urd); + urd.hwndDlg :=Dialog; + urd.hInstance :=hInstance; + urd.lpTemplate:=MAKEINTRESOURCEA('IDD_SRESULT'); + urd.lParam :=0; + urd.pfnResizer:=@ResultDlgResizer; + CallService(MS_UTILS_RESIZEDIALOG,0,tlparam(@urd)); + end; + + WM_COMMAND: begin + case wParam shr 16 of + CBN_SELCHANGE: begin + case loword(wParam) of + IDC_RES_TYPE: begin + case CB_GetData(lParam) of + sresInt,sresStruct: begin + i:=SW_HIDE; + end; + sresString,sresWide: begin + i:=SW_SHOW; + end; + end; + ShowWindow(GetDlgItem(Dialog,IDC_RES_FREEMEM),i); + end; + end; + end; + end; + end; + end; +end; + +function CreateResultBlock(parent:HWND;x,y,width:integer):THANDLE; +var + rc,rc1:TRECT; +begin + SetRect(rc,x,y,x+width,y+0{dlgheight}); + MapDialogRect(parent,rc); + + result:=CreateDialogW(hInstance,'IDD_SRESULT',parent,@DlgResultProc); + GetClientRect(result,rc1); + SetWindowPos(result,0, + x,y{rc.left,rc.top},rc.right-rc.left,rc1.bottom-rc1.top, + SWP_NOZORDER); +end; + +function SetResultValue(Dialog:HWND;flags:dword):integer; +var + btn:integer; +begin + // RESULT + if (flags and ACF_RSTRUCT)<>0 then + result:=sresStruct + else if (flags and ACF_RSTRING)<>0 then + begin + 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:=sresWide + else + result:=sresString; + end + else + begin + result:=sresInt; + end; + CB_SelectData(Dialog,IDC_RES_TYPE,result); +end; + +function GetResultValue(Dialog:HWND):dword; +begin + case CB_GetData(GetDlgItem(Dialog,IDC_RES_TYPE)) of + sresString: begin + result:=ACF_RSTRING; + if IsDlgButtonChecked(Dialog,IDC_RES_FREEMEM)=BST_CHECKED then + result:=result or ACF_RFREEMEM; + end; + sresWide: begin + result:=ACF_RSTRING or ACF_RUNICODE; + if IsDlgButtonChecked(Dialog,IDC_RES_FREEMEM)=BST_CHECKED then + result:=result or ACF_RFREEMEM; + end; + sresStruct: result:=ACF_RSTRUCT; + else + result:=0; + end; + +end; + +end. -- cgit v1.2.3