unit iac_contact; interface implementation uses windows, messages, commctrl, m_api, global, iac_global, common, mircontacts, dlgshare, syswin, inouttext, wrapper, mirutils, dbsettings; {$include i_cnst_contact.inc} {$resource iac_contact.res} const ACF_KEEPONLY = $00000001; // keep contact handle in Last, don't show window ACF_GETACTIVE = $00000002; // try to get contact from active window const ioKeepOnly = 'keeponly'; ioWindow = 'window'; type tContactAction = class(tBaseAction) private contact:TMCONTACT; public constructor Create(uid:dword); // 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; //----- Support functions ----- constructor tContactAction.Create(uid:dword); begin inherited Create(uid); contact:=0; end; { function tContactAction.Clone:tBaseAction; begin result:=tContactAction.Create(0); Duplicate(result); tContactAction(result).contact:=contact; end; } //----- Object realization ----- function tContactAction.DoAction(var WorkData:tWorkData):LRESULT; var wnd:HWND; begin ClearResult(WorkData); if (flags and ACF_GETACTIVE)<>0 then begin wnd:=WaitFocusedWndChild(GetForegroundWindow){GetFocus}; if wnd<>0 then contact:=WndToContact(wnd) else contact:=0; end else if (flags and ACF_KEEPONLY)=0 then ShowContactDialog(contact); WorkData.LastResult:=contact; WorkData.ResultType:=rtInt; result:=0; end; procedure tContactAction.Load(node:pointer;fmt:integer); begin inherited Load(node,fmt); case fmt of 0: if (flags and ACF_GETACTIVE)=0 then contact:=LoadContact(DBBranch,node); 1: begin contact:=ImportContact(HXML(node)); if StrToInt(xmlGetAttrValue(HXML(node),ioKeepOnly))=1 then flags:=flags or ACF_KEEPONLY; if StrToInt(xmlGetAttrValue(HXML(node),ioWindow))=1 then flags:=flags or ACF_GETACTIVE; end; end; end; function ExportContactText(node:tTextExport;hContact:TMCONTACT):integer; var proto,uid:pAnsiChar; cws:TDBVARIANT; p1:pAnsiChar; p:pWideChar; is_chat:boolean; begin result:=0; proto:=Proto_GetBaseAccountName(hContact); if proto<>nil then begin is_chat:=IsChat(hContact); if is_chat then begin p:=DBReadUnicode(hContact,proto,'ChatRoomID'); node.AddTextW('id',p); mFreeMem(p); result:=1; end else begin uid:=pAnsiChar(CallProtoService(proto,PS_GETCAPS,PFLAG_UNIQUEIDSETTING,0)); if DBReadSetting(hContact,proto,uid,@cws)=0 then begin result:=1; node.AddDWord('ctype',cws._type); case cws._type of DBVT_BYTE : node.AddDWord('id',cws.bVal); DBVT_WORD : node.AddDWord('id',cws.wVal); DBVT_DWORD : node.AddDWord('id',cws.dVal); DBVT_ASCIIZ: begin node.AddText('id',cws.szVal.A); // ansi to utf end; DBVT_UTF8 : begin node.AddText('id',cws.szVal.A); end; DBVT_WCHAR : node.AddTextW('id',cws.szVal.W); DBVT_BLOB : begin p1:=mir_base64_encode(cws.pbVal,cws.cpbVal); node.AddText('id',p1); mir_free(p1); end; end; end; DBFreeVariant(@cws); end; if result<>0 then begin node.AddText('protocol',proto); node.AddFlag('ischat' ,is_chat); end; end; end; procedure tContactAction.Save(node:pointer;fmt:integer); begin inherited Save(node,fmt); case fmt of 0: if (flags and ACF_GETACTIVE)=0 then SaveContact(contact,DBBranch,node); 13: begin tTextExport(node).AddFlag('keeponly' ,(flags or ACF_KEEPONLY )<>0); tTextExport(node).AddFlag('getactive',(flags or ACF_GETACTIVE)<>0); ExportContactText(tTextExport(node),contact); end; end; end; //----- Dialog realization ----- procedure ClearFields(Dialog:HWND); begin CheckDlgButton(Dialog,IDC_CNT_KEEP,BST_UNCHECKED); CheckDlgButton(Dialog,IDC_CNT_GET ,BST_UNCHECKED); end; function DlgProc(Dialog:HWND;hMessage:uint;wParam:WPARAM;lParam:LPARAM):LRESULT; stdcall; var wnd:HWND; bb:boolean; begin result:=0; case hMessage of WM_INITDIALOG: begin TranslateDialogDefault(Dialog); wnd:=GetDlgItem(Dialog,IDC_CNT_REFRESH); OptSetButtonIcon(wnd,ACI_REFRESH); SendMessage(wnd,BUTTONADDTOOLTIP,TWPARAM(TranslateW('Refresh')),BATF_UNICODE); OptFillContactList(GetDlgItem(Dialog,IDC_CONTACTLIST)); end; WM_ACT_SETVALUE: begin ClearFields(Dialog); with tContactAction(lParam) do begin if (flags and ACF_GETACTIVE)<>0 then begin bb:=false; CheckDlgButton(Dialog,IDC_CNT_GET,BST_CHECKED); end else begin bb:=true; if (flags and ACF_KEEPONLY)<>0 then CheckDlgButton(Dialog,IDC_CNT_KEEP,BST_CHECKED); SendDlgItemMessage(Dialog,IDC_CONTACTLIST,CB_SETCURSEL, FindContact(GetDlgItem(Dialog,IDC_CONTACTLIST),contact),0); end; EnableWindow(GetDlgItem(Dialog,IDC_CNT_REFRESH),bb); EnableWindow(GetDlgItem(Dialog,IDC_CONTACTLIST),bb); EnableWindow(GetDlgItem(Dialog,IDC_CNT_KEEP ),bb); end; end; WM_ACT_RESET: begin ClearFields(Dialog); EnableWindow(GetDlgItem(Dialog,IDC_CNT_REFRESH),true); EnableWindow(GetDlgItem(Dialog,IDC_CONTACTLIST),true); EnableWindow(GetDlgItem(Dialog,IDC_CNT_KEEP ),true); end; WM_ACT_SAVE: begin with tContactAction(lParam) do begin contact:=SendDlgItemMessage(Dialog,IDC_CONTACTLIST,CB_GETITEMDATA, SendDlgItemMessage(Dialog,IDC_CONTACTLIST,CB_GETCURSEL,0,0),0); if IsDlgButtonChecked(Dialog,IDC_CNT_KEEP)=BST_CHECKED then flags:=flags or ACF_KEEPONLY; end; end; WM_COMMAND: begin case wParam shr 16 of CBN_SELCHANGE: SendMessage(GetParent(GetParent(Dialog)),PSM_CHANGED,0,0); BN_CLICKED: begin case loword(wParam) of IDC_CNT_GET: begin bb:=IsDlgButtonChecked(Dialog,IDC_CNT_GET)=BST_UNCHECKED; EnableWindow(GetDlgItem(Dialog,IDC_CNT_REFRESH),bb); EnableWindow(GetDlgItem(Dialog,IDC_CONTACTLIST),bb); EnableWindow(GetDlgItem(Dialog,IDC_CNT_KEEP ),bb); end; IDC_CNT_REFRESH: begin OptFillContactList(GetDlgItem(Dialog,IDC_CONTACTLIST)); exit; end; end; SendMessage(GetParent(GetParent(Dialog)),PSM_CHANGED,0,0); end; end; end; WM_HELP: begin result:=1; end; end; end; //----- Export/interface functions ----- var vc:tActModule; function CreateAction:tBaseAction; begin result:=tContactAction.Create(vc.Hash); end; function CreateDialog(parent:HWND):HWND; begin result:=CreateDialogW(hInstance,'IDD_ACTCONTACT',parent,@DlgProc); end; procedure Init; begin vc.Next :=ModuleLink; vc.Name :='Contact'; vc.Dialog :=@CreateDialog; vc.Create :=@CreateAction; vc.Icon :='IDI_CONTACT'; vc.Hash :=0; ModuleLink :=@vc; end; begin Init; end.