{ Parameter: CBN_EDITCHANGE on fields changing, BN_CLICKED on Struct changes Result : CBN_EDITCHANGE on type changing, BN_CLICKED on option changes } unit sparam; interface uses windows, m_api; 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:TMCONTACT):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, 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:TMCONTACT):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 SendMessage(GetParent(Dialog),WM_COMMAND,BN_CLICKED shl 16,Dialog); 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 SendMessage(GetParent(Dialog),WM_COMMAND,CBN_EDITCHANGE shl 16,Dialog); 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.