/* Miranda IM: the free IM client for Microsoft* Windows* Copyright 2000-2009 Miranda ICQ/IM project, all portions of this codebase are copyrighted to the people listed in contributors.txt. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "..\..\core\commonheaders.h" int LoadAwayMessageSending(void); static HANDLE hAwayMsgMenuItem; static HANDLE hWindowList; struct AwayMsgDlgData { HANDLE hContact; HANDLE hSeq; HANDLE hAwayMsgEvent; }; #define HM_AWAYMSG (WM_USER+10) static INT_PTR CALLBACK ReadAwayMsgDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) { AwayMsgDlgData *dat = (AwayMsgDlgData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch(message) { case WM_INITDIALOG: TranslateDialogDefault(hwndDlg); dat = (AwayMsgDlgData*)mir_alloc(sizeof(AwayMsgDlgData)); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); dat->hContact = (HANDLE)lParam; dat->hAwayMsgEvent = HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_AWAYMSG); dat->hSeq = (HANDLE)CallContactService(dat->hContact, PSS_GETAWAYMSG, 0, 0); WindowList_Add(hWindowList, hwndDlg, dat->hContact); { TCHAR str[256], format[128]; TCHAR* contactName = cli.pfnGetContactDisplayName(dat->hContact, 0); char* szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)dat->hContact, 0); WORD dwStatus = DBGetContactSettingWord(dat->hContact, szProto, "Status", ID_STATUS_OFFLINE); TCHAR* status = cli.pfnGetStatusModeDescription(dwStatus, 0); GetWindowText(hwndDlg, format, SIZEOF(format)); mir_sntprintf(str, SIZEOF(str), format, status, contactName); SetWindowText(hwndDlg, str); GetDlgItemText(hwndDlg, IDC_RETRIEVING, format, SIZEOF(format)); mir_sntprintf(str, SIZEOF(str), format, status); SetDlgItemText(hwndDlg, IDC_RETRIEVING, str); Window_SetProtoIcon_IcoLib(hwndDlg, szProto, dwStatus); } if (dat->hSeq == NULL) { ACKDATA ack = {0}; ack.cbSize = sizeof(ack); ack.hContact = dat->hContact; ack.type = ACKTYPE_AWAYMSG; ack.result = ACKRESULT_SUCCESS; SendMessage(hwndDlg, HM_AWAYMSG, 0, (LPARAM)&ack); } Utils_RestoreWindowPosition(hwndDlg, (HANDLE)lParam, "SRAway", "AwayMsgDlg"); return TRUE; case HM_AWAYMSG: { ACKDATA *ack = (ACKDATA*)lParam; if (ack->hContact != dat->hContact || ack->type != ACKTYPE_AWAYMSG) break; if (ack->result != ACKRESULT_SUCCESS) break; if (dat->hAwayMsgEvent && ack->hProcess == dat->hSeq) { UnhookEvent(dat->hAwayMsgEvent); dat->hAwayMsgEvent = NULL; } #ifdef _UNICODE DBVARIANT dbv; bool unicode = !DBGetContactSetting(dat->hContact, "CList", "StatusMsg", &dbv) && (dbv.type == DBVT_UTF8 || dbv.type == DBVT_WCHAR); DBFreeVariant(&dbv); if (unicode) { DBGetContactSettingWString(dat->hContact, "CList", "StatusMsg", &dbv); SetDlgItemText(hwndDlg, IDC_MSG, dbv.pwszVal); } else #endif SetDlgItemTextA(hwndDlg, IDC_MSG, (const char*)ack->lParam); ShowWindow(GetDlgItem(hwndDlg, IDC_RETRIEVING), SW_HIDE); ShowWindow(GetDlgItem(hwndDlg, IDC_MSG), SW_SHOW); SetDlgItemText(hwndDlg, IDOK, TranslateT("&Close")); break; } case WM_COMMAND: switch(LOWORD(wParam)) { case IDCANCEL: case IDOK: DestroyWindow(hwndDlg); break; } break; case WM_CLOSE: DestroyWindow(hwndDlg); break; case WM_DESTROY: if (dat->hAwayMsgEvent) UnhookEvent(dat->hAwayMsgEvent); Utils_SaveWindowPosition(hwndDlg, dat->hContact, "SRAway", "AwayMsgDlg"); WindowList_Remove(hWindowList, hwndDlg); Window_FreeIcon_IcoLib(hwndDlg); mir_free(dat); break; } return FALSE; } static INT_PTR GetMessageCommand(WPARAM wParam, LPARAM) { HWND hwnd; if (hwnd=WindowList_Find(hWindowList, (HANDLE)wParam)) { SetForegroundWindow(hwnd); SetFocus(hwnd); } else CreateDialogParam(hMirandaInst, MAKEINTRESOURCE(IDD_READAWAYMSG), NULL, ReadAwayMsgDlgProc, wParam); return 0; } static int AwayMsgPreBuildMenu(WPARAM wParam, LPARAM) { CLISTMENUITEM clmi; TCHAR str[128]; char *szProto; szProto=(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0); ZeroMemory(&clmi, sizeof(clmi)); clmi.cbSize = sizeof(clmi); clmi.flags = CMIM_FLAGS | CMIF_NOTOFFLINE | CMIF_HIDDEN | CMIF_TCHAR; if ( szProto != NULL ) { int chatRoom = szProto ? DBGetContactSettingByte((HANDLE)wParam, szProto, "ChatRoom", 0) : 0; if ( !chatRoom ) { int status = DBGetContactSettingWord((HANDLE)wParam, szProto, "Status", ID_STATUS_OFFLINE); mir_sntprintf( str, SIZEOF(str), TranslateT("Re&ad %s Message"), cli.pfnGetStatusModeDescription( status, 0 )); clmi.ptszName = str; if ( CallProtoService( szProto, PS_GETCAPS, PFLAGNUM_1, 0 ) & PF1_MODEMSGRECV ) { if ( CallProtoService( szProto, PS_GETCAPS, PFLAGNUM_3, 0 ) & Proto_Status2Flag( status )) { clmi.flags = CMIM_FLAGS | CMIM_NAME | CMIF_NOTOFFLINE | CMIM_ICON | CMIF_TCHAR; clmi.hIcon = LoadSkinProtoIcon(szProto, status); } } } } CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hAwayMsgMenuItem, ( LPARAM )&clmi ); IconLib_ReleaseIcon(clmi.hIcon, 0); return 0; } static int AwayMsgPreShutdown(WPARAM, LPARAM) { if (hWindowList) WindowList_BroadcastAsync(hWindowList, WM_CLOSE, 0, 0); return 0; } int LoadAwayMsgModule(void) { CLISTMENUITEM mi = { 0 }; hWindowList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); CreateServiceFunction(MS_AWAYMSG_SHOWAWAYMSG, GetMessageCommand); mi.cbSize = sizeof(mi); mi.position = -2000005000; mi.flags = CMIF_NOTOFFLINE; mi.pszName = LPGEN("Re&ad Status Message"); mi.pszService = MS_AWAYMSG_SHOWAWAYMSG; hAwayMsgMenuItem = Menu_AddContactMenuItem(&mi); HookEvent(ME_CLIST_PREBUILDCONTACTMENU, AwayMsgPreBuildMenu); HookEvent(ME_SYSTEM_PRESHUTDOWN, AwayMsgPreShutdown); return LoadAwayMessageSending(); }