unit iac_messagebox; interface implementation uses editwrapper, windows, messages, commctrl, m_api, global, iac_global, wrapper, mirutils, common, dbsettings; {$include i_cnst_message.inc} {$resource iac_messagebox.res} const ACF_MSG_TTL = $00000001; ACF_MSG_TXT = $00000002; const opt_msgtitle = 'msgtitle'; opt_msgtext = 'msgtext'; opt_boxopts = 'boxopts'; const ioTitle = 'title'; ioText = 'text'; ioType = 'type'; ioArgVariable = 'argvariables'; ioVariables = 'variables'; type tMessageAction = class(tBaseAction) private msgtitle:pWideChar; msgtext :pWideChar; boxopts :uint; public constructor Create(uid:dword); destructor Destroy; override; // function Clone:tBaseAction; override; function DoAction(var WorkData:tWorkData):LRESULT; override; procedure Save(node:pointer;fmt:integer); override; procedure Load(node:pointer;fmt:integer); override; end; //----- Object realization ----- constructor tMessageAction.Create(uid:dword); begin inherited Create(uid); msgtext :=nil; msgtitle:=nil; boxopts :=0; end; destructor tMessageAction.Destroy; begin mFreeMem(msgtitle); mFreeMem(msgtext); inherited Destroy; end; { function tMessageAction.Clone:tBaseAction; begin result:=tMessageAction.Create(0); Duplicate(result); StrDupW(tMessageAction(result).msgtext ,msgtext); StrDupW(tMessageAction(result).msgtitle,msgtitle); tMessageAction(result).boxopts:=boxopts; end; } function tMessageAction.DoAction(var WorkData:tWorkData):LRESULT; var i:integer; buf:array [0..31] of WideChar; tmpc:pWideChar; // LastResult value tmpc1,tmpc2:pWideChar; // title/text after LastResult insertion tmpcv1,tmpcv2:pWideChar; // title/text after Variables processing begin result:=0; if WorkData.ResultType=rtWide then tmpc:=pWidechar(WorkData.LastResult) else begin IntToStr(buf,WorkData.LastResult); tmpc:=@buf; end; // LastResult if StrPosW(msgtitle,'')<>nil then begin mGetMem(tmpc1,8192); StrCopyW(tmpc1,msgtitle); StrReplaceW(tmpc1,'',tmpc); end else tmpc1:=msgtitle; if StrPosW(msgtext,'')<>nil then begin mGetMem(tmpc2,8192); StrCopyW(tmpc2,msgtext); StrReplaceW(tmpc2,'',tmpc); end else tmpc2:=msgtext; // Variables if (flags and ACF_MSG_TTL)<>0 then tmpcv1:=ParseVarString(tmpc1,WorkData.Parameter,tmpc) else tmpcv1:=tmpc1; if (flags and ACF_MSG_TXT)<>0 then tmpcv2:=ParseVarString(tmpc2,WorkData.Parameter,tmpc) else tmpcv2:=tmpc2; i:=MessageBoxW(0,tmpcv2,tmpcv1,boxopts); // Keep old result just if has single OK button if (boxopts and $0F)<>MB_OK then begin ClearResult(WorkData); WorkData.ResultType:=rtInt; WorkData.LastResult:=i; end; if tmpcv1<>tmpc1 then mFreeMem(tmpcv1); if tmpcv2<>tmpc2 then mFreeMem(tmpcv2); if tmpc1 <>msgtitle then mFreeMem(tmpc1); if tmpc2 <>msgtext then mFreeMem(tmpc2); end; procedure tMessageAction.Load(node:pointer;fmt:integer); var section: array [0..127] of AnsiChar; pc: pAnsiChar; begin inherited Load(node,fmt); case fmt of 0: begin pc:=StrCopyE(section,pAnsiChar(node)); StrCopy(pc,opt_msgtitle); msgtitle:=DBReadUnicode(0,DBBranch,section); StrCopy(pc,opt_msgtext ); msgtext :=DBReadUnicode(0,DBBranch,section); StrCopy(pc,opt_boxopts ); boxopts :=DBReadDword (0,DBBranch,section); // v2 = byte end; 1: begin StrDupW(msgtitle,xmlGetAttrValue(HXML(node),ioTitle)); StrDupW(msgtext,xmlGetText(HXML(node))); boxopts:=StrToInt(xmlGetAttrValue(HXML(node),ioType)); if StrToInt(xmlGetAttrValue(HXML(node),ioArgVariable))=1 then flags:=flags or ACF_MSG_TXT; if StrToInt(xmlGetAttrValue(HXML(node),ioVariables ))=1 then flags:=flags or ACF_MSG_TTL; end; end; end; procedure tMessageAction.Save(node:pointer;fmt:integer); var section: array [0..127] of AnsiChar; pc: pAnsiChar; begin inherited Save(node,fmt); case fmt of 0: begin pc:=StrCopyE(section,pAnsiChar(node)); StrCopy(pc,opt_msgtitle); DBWriteUnicode(0,DBBranch,section,msgtitle); StrCopy(pc,opt_msgtext ); DBWriteUnicode(0,DBBranch,section,msgtext); StrCopy(pc,opt_boxopts ); DBWriteDWord (0,DBBranch,section,boxopts); end; { 1: begin end; } 13: begin end; end; end; //----- Dialog realization ----- procedure SetMBRadioIcon(Dialog:HWND;h:THANDLE;id:dword;icon:uint_ptr); begin SendDlgItemMessage(Dialog,id,BM_SETIMAGE,IMAGE_ICON, LoadImage(h,MAKEINTRESOURCE(icon),IMAGE_ICON,16,16,0{LR_SHARED})); // SendDlgItemMessage(Dialog,id,BM_SETIMAGE,IMAGE_ICON,LoadIcon(0,icon)); end; procedure SetMBRadioIcons(Dialog:HWND); var h:THANDLE; begin h:=LoadLibrary('user32.dll'); // SetMBRadioIcon(IDC_MSGI_NONE,IDI_); //? SetMBRadioIcon(Dialog,h,IDC_MSGI_ERROR,103{IDI_HAND}); SetMBRadioIcon(Dialog,h,IDC_MSGI_QUEST,102{IDI_QUESTION}); SetMBRadioIcon(Dialog,h,IDC_MSGI_WARN ,101{IDI_EXCLAMATION}); SetMBRadioIcon(Dialog,h,IDC_MSGI_INFO ,104{IDI_ASTERISK}); FreeLibrary(h); end; procedure ClearFields(Dialog:HWND); begin CheckDlgButton(Dialog,IDC_MSG_RTL ,BST_UNCHECKED); CheckDlgButton(Dialog,IDC_MSG_RIGHT,BST_UNCHECKED); CheckDlgButton(Dialog,IDC_MSGB_OK ,BST_UNCHECKED); CheckDlgButton(Dialog,IDC_MSGB_OC ,BST_UNCHECKED); CheckDlgButton(Dialog,IDC_MSGB_ARI,BST_UNCHECKED); CheckDlgButton(Dialog,IDC_MSGB_YNC,BST_UNCHECKED); CheckDlgButton(Dialog,IDC_MSGB_YN ,BST_UNCHECKED); CheckDlgButton(Dialog,IDC_MSGB_RC ,BST_UNCHECKED); CheckDlgButton(Dialog,IDC_MSGI_NONE ,BST_UNCHECKED); CheckDlgButton(Dialog,IDC_MSGI_ERROR,BST_UNCHECKED); CheckDlgButton(Dialog,IDC_MSGI_QUEST,BST_UNCHECKED); CheckDlgButton(Dialog,IDC_MSGI_WARN ,BST_UNCHECKED); CheckDlgButton(Dialog,IDC_MSGI_INFO ,BST_UNCHECKED); end; function DlgProc(Dialog:HWND;hMessage:uint;wParam:WPARAM;lParam:LPARAM):LRESULT; stdcall; const NoProcess:boolean=true; begin result:=0; case hMessage of WM_INITDIALOG: begin TranslateDialogDefault(Dialog); MakeEditField(Dialog,IDC_MSG_TITLE); MakeEditField(Dialog,IDC_MSG_TEXT); SetMBRadioIcons(Dialog); end; WM_ACT_SETVALUE: begin NoProcess:=true; ClearFields(Dialog); with tMessageAction(lParam) do begin SetDlgItemTextW(Dialog,IDC_MSG_TITLE,msgtitle); SetDlgItemTextW(Dialog,IDC_MSG_TEXT ,msgtext); SetEditFlags(Dialog,IDC_MSG_TITLE,EF_SCRIPT,ord((flags and ACF_MSG_TTL)<>0)); SetEditFlags(Dialog,IDC_MSG_TEXT ,EF_SCRIPT,ord((flags and ACF_MSG_TXT)<>0)); if (boxopts and MB_RTLREADING)<>0 then CheckDlgButton(Dialog,IDC_MSG_RTL ,BST_CHECKED); if (boxopts and MB_RIGHT )<>0 then CheckDlgButton(Dialog,IDC_MSG_RIGHT,BST_CHECKED); case boxopts and $0F of MB_OKCANCEL : CheckDlgButton(Dialog,IDC_MSGB_OC ,BST_CHECKED); MB_ABORTRETRYIGNORE : CheckDlgButton(Dialog,IDC_MSGB_ARI,BST_CHECKED); MB_YESNOCANCEL : CheckDlgButton(Dialog,IDC_MSGB_YNC,BST_CHECKED); MB_YESNO : CheckDlgButton(Dialog,IDC_MSGB_YN ,BST_CHECKED); MB_RETRYCANCEL : CheckDlgButton(Dialog,IDC_MSGB_RC ,BST_CHECKED); // MB_CANCELTRYCONTINUE: else CheckDlgButton(Dialog,IDC_MSGB_OK,BST_CHECKED); end; case boxopts and $F0 of MB_ICONERROR : CheckDlgButton(Dialog,IDC_MSGI_ERROR,BST_CHECKED); MB_ICONQUESTION : CheckDlgButton(Dialog,IDC_MSGI_QUEST,BST_CHECKED); MB_ICONWARNING : CheckDlgButton(Dialog,IDC_MSGI_WARN ,BST_CHECKED); MB_ICONINFORMATION: CheckDlgButton(Dialog,IDC_MSGI_INFO ,BST_CHECKED); else CheckDlgButton(Dialog,IDC_MSGI_NONE,BST_CHECKED); end; end; NoProcess:=false; end; WM_ACT_RESET: begin NoProcess:=true; ClearFields(Dialog); SetDlgItemTextW(Dialog,IDC_MSG_TITLE,nil); SetDlgItemTextW(Dialog,IDC_MSG_TEXT ,nil); SetEditFlags(Dialog,IDC_MSG_TITLE,EF_ALL,0); SetEditFlags(Dialog,IDC_MSG_TEXT ,EF_ALL,0); CheckDlgButton(Dialog,IDC_MSGB_OK ,BST_CHECKED); CheckDlgButton(Dialog,IDC_MSGI_NONE,BST_CHECKED); NoProcess:=false; end; WM_ACT_SAVE: begin with tMessageAction(lParam) do begin {mFreeMem(msgtitle); }msgtitle:=GetDlgText(Dialog,IDC_MSG_TITLE); {mFreeMem(msgtext ); }msgtext :=GetDlgText(Dialog,IDC_MSG_TEXT); if (GetEditFlags(Dialog,IDC_MSG_TITLE) and EF_SCRIPT)<>0 then flags:=flags or ACF_MSG_TTL; if (GetEditFlags(Dialog,IDC_MSG_TEXT ) and EF_SCRIPT)<>0 then flags:=flags or ACF_MSG_TXT; if IsDlgButtonChecked(Dialog,IDC_MSG_RTL )=BST_CHECKED then boxopts:=boxopts or MB_RTLREADING; if IsDlgButtonChecked(Dialog,IDC_MSG_RIGHT)=BST_CHECKED then boxopts:=boxopts or MB_RIGHT; if IsDlgButtonChecked(Dialog,IDC_MSGB_OC )=BST_CHECKED then boxopts:=boxopts or MB_OKCANCEL else if IsDlgButtonChecked(Dialog,IDC_MSGB_ARI)=BST_CHECKED then boxopts:=boxopts or MB_ABORTRETRYIGNORE else if IsDlgButtonChecked(Dialog,IDC_MSGB_YNC)=BST_CHECKED then boxopts:=boxopts or MB_YESNOCANCEL else if IsDlgButtonChecked(Dialog,IDC_MSGB_YN )=BST_CHECKED then boxopts:=boxopts or MB_YESNO else if IsDlgButtonChecked(Dialog,IDC_MSGB_RC )=BST_CHECKED then boxopts:=boxopts or MB_RETRYCANCEL else{if IsDlgButtonChecked(Dialog,IDC_MSGB_OK )=BST_CHECKED then}boxopts:=boxopts or MB_OK; if IsDlgButtonChecked(Dialog,IDC_MSGI_ERROR)=BST_CHECKED then boxopts:=boxopts or MB_ICONHAND else if IsDlgButtonChecked(Dialog,IDC_MSGI_QUEST)=BST_CHECKED then boxopts:=boxopts or MB_ICONQUESTION else if IsDlgButtonChecked(Dialog,IDC_MSGI_WARN )=BST_CHECKED then boxopts:=boxopts or MB_ICONWARNING else if IsDlgButtonChecked(Dialog,IDC_MSGI_INFO )=BST_CHECKED then boxopts:=boxopts or MB_ICONINFORMATION ;//else if IsDlgButtonChecked(Dialog,IDC_MSGI_NONE)=BST_CHECKED then ; end; end; WM_COMMAND: begin case wParam shr 16 of EN_CHANGE, BN_CLICKED: if not NoProcess then SendMessage(GetParent(GetParent(Dialog)),PSM_CHANGED,0,0); end; end; WM_HELP: begin MessageBoxW(0, TranslateW( 'Text replacing'#13#10+ 'by last result'#13#10#13#10+ 'Returns:'#13#10+ '--------'#13#10+ 'OK'#9'= 1'#13#10+ 'CANCEL'#9'= 2'#13#10+ 'ABORT'#9'= 3'#13#10+ 'RETRY'#9'= 4'#13#10+ 'IGNORE'#9'= 5'#13#10+ 'YES'#9'= 6'#13#10+ 'NO'#9'= 7'#13#10+ 'CLOSE'#9'= 8'), TranslateW('MessageBox'),0); result:=1; end; end; end; //----- Export/interface functions ----- var vc:tActModule; function CreateAction:tBaseAction; begin result:=tMessageAction.Create(vc.Hash); end; function CreateDialog(parent:HWND):HWND; begin result:=CreateDialogW(hInstance,'IDD_ACTMESSAGEBOX',parent,@DlgProc); end; procedure Init; begin vc.Next :=ModuleLink; vc.Name :='MessageBox'; vc.Dialog :=@CreateDialog; vc.Create :=@CreateAction; vc.Icon :='IDI_MESSAGE'; vc.Hash :=0; ModuleLink :=@vc; end; begin Init; end.