/* "Spam Filter"-Plugin for Miranda IM Copyright 2003-2006 Heiko Herkenrath 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 ("SpamFilter-License.txt"); if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // -- Includes #include "common.h" // -- Variables: Events/Services HANDLE hHookOptInit = NULL; HANDLE hHookDbSettingChangedOpt = NULL; // -- Defines: Self-defined dialog messages #define SFM_ENABLE_SUBCTRLS (WM_APP+121) // wParam=lParam=0 #define SFM_REMOVE_SPAMDEFINITIONFILE (WM_APP+122) // wParam=(int)listIndex, lParam=0 // -- Structs struct WORDSLISTBOXADDITEMPARAMS { POINT ptPos; WCHAR* pszTitle; WCHAR* pszNewItem; }; // ----------------------------------------- BOOL CALLBACK DlgProcSpamFilterOpt(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { /* #if defined(UNICODE) case WM_NOTIFYFORMAT: { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)NFR_UNICODE); return TRUE; } #endif */ case WM_INITDIALOG: { hwndSpamFilterOpt = hwndDlg; /* #if defined(UNICODE) // Convert DlgProc to Unicode (IsWindowUnicode returns true after this call -> see docs) SetWindowLongPtrW(hwndDlg, DWLP_DLGPROC, (LONG_PTR)DlgProcSpamFilterOpt); #endif */ // Init treeview (TVS_CHECKBOXES style is too buggy [it behaves incorrect when space pressed on sections], so self-implementing checkboxes) // The treeview does checkboxes exactly the same as it is done here TreeView_SetImageList(GetDlgItem(hwndDlg, IDC_TREEVIEW_MESSAGETYPES), LoadSystemCheckboxImageList(), TVSIL_STATE); // Translate dialog TranslateDialogDefault(hwndDlg); // Set font { HFONT hUnderlinedFont; LOGFONT lf; GetObject((HFONT)SendDlgItemMessage(hwndDlg, IDC_CHECKBOX_ADVERTISMENTFILTER, WM_GETFONT, 0, 0), sizeof(lf), &lf); lf.lfUnderline = TRUE; hUnderlinedFont = CreateFontIndirect(&lf); SendDlgItemMessage(hwndDlg, IDC_CHECKBOX_ADVERTISMENTFILTER, WM_SETFONT, (WPARAM)hUnderlinedFont, 0); SendDlgItemMessage(hwndDlg, IDC_CHECKBOX_DISLIKEDMESSAGEFILTER, WM_SETFONT, (WPARAM)hUnderlinedFont, 0); SendDlgItemMessage(hwndDlg, IDC_CHECKBOX_ROBOTFILTER, WM_SETFONT, (WPARAM)hUnderlinedFont, 0); } // Init file name control { RECT rc; // Set icon and resize button SendDlgItemMessage(hwndDlg, IDC_BUTTON_LOGBROWSE, BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)LoadSystemIcon(IDB_STD_SMALL_COLOR, STD_FILEOPEN)); SetWindowPos(GetDlgItem(hwndDlg, IDC_BUTTON_LOGBROWSE), NULL, 0, 0, 20, 20, SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW); // Transform into file edit browse combo control MakePathEditCtrl(GetDlgItem(hwndDlg, IDC_EDITBOX_LOGFILE), GetDlgItem(hwndDlg, IDC_BUTTON_LOGBROWSE)); if (GetClientRect(GetDlgItem(hwndDlg, IDC_BUTTON_OPENLOG), &rc)) SetWindowPos(GetDlgItem(hwndDlg, IDC_BUTTON_OPENLOG), NULL, 0, 0, (rc.right-rc.left), (rc.bottom-rc.top)+2*GetSystemMetrics(SM_CYBORDER), SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW); // Forwarding all file drag/drops of spam filter options to the file edit // (child windows of childs seem not to receive that message...) DragAcceptFiles(hwndDlg, (BOOL)SendMessage(GetParent(hwndDlg), PSM_ISEXPERT, 0, 0)); } // Load log file from database { DBVARIANT dbv; if(DBGetContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_LOGFILE, &dbv) == 0) // If existant { SetDlgItemText(hwndDlg, IDC_EDITBOX_LOGFILE, dbv.ptszVal); DBFreeVariant(&dbv); } else { // Nothing specified, display default log filename and path WCHAR szLogFile[MAX_PATH]; PConstructLocalPath(szLogFile, CSIDL_EXT_EXECUTABLE, LOGS_SUBDIRECTORY, DEFAULT_LOGFILE, NULL); PMakePathPretty(szLogFile, PC_ABSOLUTERELATIVE); SetDlgItemText(hwndDlg, IDC_EDITBOX_LOGFILE, szLogFile); } } // Init checkboxes CheckDlgButton(hwndDlg, IDC_CHECKBOX_ADVERTISMENTFILTER, (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENTFILTER, (BYTE)DEFAULT_SETTING_ADVERTISMENTFILTER) ? BST_CHECKED : BST_UNCHECKED)); CheckDlgButton(hwndDlg, IDC_CHECKBOX_DISLIKEDMESSAGEFILTER, (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGEFILTER, (BYTE)DEFAULT_SETTING_DISLIKEDMESSAGEFILTER) ? BST_CHECKED : BST_UNCHECKED)); CheckDlgButton(hwndDlg, IDC_CHECKBOX_ROBOTFILTER, (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ROBOTFILTER, (BYTE)DEFAULT_SETTING_ROBOTFILTER) ? BST_CHECKED : BST_UNCHECKED)); CheckDlgButton(hwndDlg, IDC_CHECKBOX_POPUP, IsPopupAvailable(TRUE) ? DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_POPUP, (BYTE)(DEFAULT_SETTING_POPUP ? BST_CHECKED : BST_UNCHECKED)) : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_CHECKBOX_AUTOADDSPAMMERS, DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_AUTOADDSPAMMERS, (BYTE)(DEFAULT_SETTING_AUTOADDSPAMMERS ? BST_CHECKED : BST_UNCHECKED)) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_CHECKBOX_LOGGING, (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_LOGGING, (BYTE)DEFAULT_SETTING_LOGGING) ? BST_CHECKED : BST_UNCHECKED)); // Check/Uncheck radio buttons: // Delete/Mark read? CheckRadioButton(hwndDlg, IDC_RADIO_MARKREADMSG, IDC_RADIO_DELETEMSG, (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_BEHAVIOUR, (BYTE)DEFAULT_SETTING_BEHAVIOUR) == 1) ? IDC_RADIO_MARKREADMSG : IDC_RADIO_DELETEMSG); // Init sub control state SendMessage(hwndDlg, SFM_ENABLE_SUBCTRLS, 0, 0); SendMessage(hwndDlg, SFM_REBUILD_MSGTYPES, 0, 0); SendMessage(hwndDlg, SFM_CHECK_AUTOIGNORE, 0, 0); PostMessage(hwndDlg, SFM_VALIDATE_LOGFILENAME, 0, 0); return TRUE; } case SFM_ENABLE_SUBCTRLS: { BOOL bStatus; // IDC_CHECKBOX_ADVERTISMENTFILTER BOOL bStatusRobotFilter = (IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_ROBOTFILTER) == BST_CHECKED); BOOL bStatusChainFilter = (IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_DISLIKEDMESSAGEFILTER) == BST_CHECKED); BOOL bStatusAdvertismentFilter = (IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_ADVERTISMENTFILTER) == BST_CHECKED); bStatus = bStatusAdvertismentFilter || bStatusChainFilter || bStatusRobotFilter; EnableDlgItem(hwndDlg, IDC_BUTTON_ADVERTISMENTFILTER, bStatusAdvertismentFilter); EnableDlgItem(hwndDlg, IDC_BUTTON_DISLIKEDMESSAGEFILTER, bStatusChainFilter); EnableDlgItem(hwndDlg, IDC_BUTTON_ROBOTFILTER, bStatusRobotFilter); EnableDlgItem(hwndDlg, IDC_GROUP_BEHAVIOUR, bStatus); EnableDlgItem(hwndDlg, IDC_RADIO_MARKREADMSG, bStatus); EnableDlgItem(hwndDlg, IDC_RADIO_DELETEMSG, bStatus); EnableDlgItem(hwndDlg, IDC_GROUP_IGNORE, bStatus); EnableDlgItem(hwndDlg, IDC_CHECKBOX_AUTOADDSPAMMERS, bStatus); EnableDlgItem(hwndDlg, IDC_GROUP_LOGGING, bStatus); EnableDlgItem(hwndDlg, IDC_CHECKBOX_LOGGING, bStatus); EnableDlgItem(hwndDlg, IDC_GROUP_MESSAGETYPES, bStatus); EnableDlgItem(hwndDlg, IDC_TEXT_MESSAGETYPES, bStatus); EnableDlgItem(hwndDlg, IDC_TREEVIEW_MESSAGETYPES, bStatus); EnableDlgItem(hwndDlg, IDC_CHECKBOX_POPUP, IsPopupAvailable(TRUE) ? bStatus: FALSE); // Auto Ignore SetSpinCtrlRange(GetDlgItem(hwndDlg, IDC_SPIN_ALLOWEDSPAMMESSAGES), bStatusRobotFilter?1:0, 999, DBGetContactSettingWord(NULL, DB_MODULE_NAME, DB_SETTING_ALLOWEDSPAMMESSAGES, (DWORD)DEFAULT_SETTING_ALLOWEDSPAMMESSAGES), FALSE); bStatus = (IsWindowEnabled(GetDlgItem(hwndDlg,IDC_CHECKBOX_AUTOADDSPAMMERS)) && (IsDlgButtonChecked(hwndDlg,IDC_CHECKBOX_AUTOADDSPAMMERS) == BST_CHECKED)); EnableDlgItem(hwndDlg, IDC_TEXT_ALLOWEDSPAMMESSAGES, bStatus); EnableDlgItem(hwndDlg, IDC_EDITBOX_ALLOWEDSPAMMESSAGES, bStatus); EnableDlgItem(hwndDlg, IDC_SPIN_ALLOWEDSPAMMESSAGES, bStatus); // Logging bStatus = (IsWindowEnabled(GetDlgItem(hwndDlg,IDC_CHECKBOX_LOGGING)) && (IsDlgButtonChecked(hwndDlg,IDC_CHECKBOX_LOGGING) == BST_CHECKED)); EnableDlgItem(hwndDlg, IDC_EDITBOX_LOGFILE, bStatus); EnableDlgItem(hwndDlg, IDC_BUTTON_LOGBROWSE, bStatus); return TRUE; } case SFM_REBUILD_MSGTYPES: { HWND hwndTreeView = GetDlgItem(hwndDlg, IDC_TREEVIEW_MESSAGETYPES); HIMAGELIST hImageList; unsigned int u; char* pszSetting; TVINSERTSTRUCT tvis; BOOL bUseSections; HTREEITEM hItem; MESSAGETYPEDESC* pmtd; int iCmpResult; // Clear treeview TreeView_DeleteAllItems(hwndTreeView); if (InSendMessage()) ReplyMessage(TRUE); // Check if only one section is installed // -> if only one section is installed it is not necessary to show the section EnterCriticalSection(&csMsgTypes); // thread safety bUseSections = !IsOnlyOneMsgTypeSectionRegistered(); // New image list hImageList = TreeView_GetImageList(hwndTreeView, TVSIL_NORMAL); if (hImageList) ImageList_Destroy(hImageList); hImageList = ImageList_Create(GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON), (IsWinVerXPPlus()?ILC_COLOR32:ILC_COLOR16)|ILC_MASK, uMsgTypesCount, bUseSections?uMsgTypesCount:0); // includes msgtype and section images TreeView_SetImageList(hwndTreeView, hImageList, TVSIL_NORMAL); // Add items to treeview if (pamtdMsgTypes) { for (u=0; upszSection) == 0) { tvis.hParent = hItem; break; } } // Section does not yet exist: add it first if (!tvis.hParent) { tvis.item.mask = TVIF_TEXT|TVIF_STATE|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE; tvis.item.pszText = pamtdMsgTypes[u].ptszSectionDescription; tvis.item.stateMask = TVIS_BOLD|TVIS_EXPANDED|TVIS_STATEIMAGEMASK; tvis.item.state = TVIS_BOLD|TVIS_EXPANDED|INDEXTOSTATEIMAGEMASK(0); // no checkbox for sections tvis.item.lParam = (LPARAM)u; tvis.item.iImage = ImageList_AddIcon(hImageList, (pamtdMsgTypes[u].hSectionIcon ? pamtdMsgTypes[u].hSectionIcon : LoadSkinnedIcon(SKINICON_OTHER_MIRANDA)) ); tvis.item.iSelectedImage = tvis.item.iImage; // else the wrong icon will be shown when selected // Position new section using position numbers (lowest first) tvis.hInsertAfter = TVI_FIRST; for (hItem=TreeView_GetRoot(hwndTreeView); hItem; hItem=TreeView_GetNextSibling(hwndTreeView, hItem)) { pmtd = GetDataFromTreeViewItem(hwndTreeView, hItem); if (pmtd) { if (pamtdMsgTypes[u].iSectionPosition > pmtd->iSectionPosition) { tvis.hInsertAfter = hItem; // Colliding numbers are sorted alphabetically } else if (pamtdMsgTypes[u].iSectionPosition == pmtd->iSectionPosition) { int iCmpResult; iCmpResult = CompareString(GetThreadLocale(), 0, pamtdMsgTypes[u].ptszSectionDescription, -1, pmtd->ptszSectionDescription, -1); // or: LOCALE_USER_DEFAULT if (iCmpResult != 0) iCmpResult -= 2; // see docs if (iCmpResult >= 0) tvis.hInsertAfter = hItem; } else { // iteration pos is larger than new item pos // (or reached "Other" section) // -> found out where to sort in break; } } } tvis.hParent = TreeView_InsertItem(hwndTreeView, &tvis); } } pszSetting = GetMsgTypeSettingName(pamtdMsgTypes[u].pszSection, pamtdMsgTypes[u].pszName); if (!pszSetting) continue; tvis.item.mask = TVIF_TEXT|TVIF_STATE|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE; tvis.item.pszText = pamtdMsgTypes[u].ptszDescription; tvis.item.stateMask = TVIS_STATEIMAGEMASK; tvis.item.state = INDEXTOSTATEIMAGEMASK(DBGetContactSettingByte(NULL, DB_MODULE_NAME_MSGTYPES, pszSetting, (BYTE)!(pamtdMsgTypes[u].dwFlags&MTDF_DEFAULTDISABLED))?2:1); tvis.item.lParam = (LPARAM)u; if ((int)pamtdMsgTypes[u].hIcon < 0) tvis.item.iImage = ImageList_AddIcon(hImageList, LoadSkinnedIcon((-1)*(int)pamtdMsgTypes[u].hIcon)); else tvis.item.iImage = ImageList_AddIcon(hImageList, pamtdMsgTypes[u].hIcon ? pamtdMsgTypes[u].hIcon : (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_DEFAULT), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED)); tvis.item.iSelectedImage = tvis.item.iImage; // else the wrong icon will be shown when selected mir_free(pszSetting); // Position new item using position numbers (lowest first) tvis.hInsertAfter = TVI_FIRST; for (hItem=TreeView_GetChild(hwndTreeView, tvis.hParent); hItem; hItem=TreeView_GetNextSibling(hwndTreeView, hItem)) { pmtd = GetDataFromTreeViewItem(hwndTreeView, hItem); if (pmtd) { if (pamtdMsgTypes[u].iPosition > pmtd->iPosition) { tvis.hInsertAfter = hItem; // Colliding numbers are sorted alphabetically } else if (pamtdMsgTypes[u].iPosition == pmtd->iPosition) { iCmpResult = CompareString(GetThreadLocale(), 0, pamtdMsgTypes[u].ptszDescription, -1, pmtd->ptszDescription, -1); // or: LOCALE_USER_DEFAULT if (iCmpResult != 0) iCmpResult -= 2; // see docs if (iCmpResult >= 0) tvis.hInsertAfter = hItem; } else { // Iteration pos is larger than new item pos // -> found out where to sort in break; } } } TreeView_InsertItem(hwndTreeView, &tvis); } } LeaveCriticalSection(&csMsgTypes); // thread safety return TRUE; } case SFM_CHECK_AUTOIGNORE: { EnableDlgItem(hwndDlg, IDC_BUTTON_RESETAUTOIGNORE, (CallService(MS_SPAMFILTER_RESETAUTOIGNORE, (WPARAM)TRUE, 0) > 0)); return TRUE; } case SFM_VALIDATE_LOGFILENAME: { const WCHAR* aszFileExtensions[] = {_T(".txt"), _T(".log"), _T(".csv"), _T(".xml"), _T("."), _T(""), NULL}; const WCHAR* aszContentTypes[] = {_T("text/plain"), _T("text/xml"), _T("application/xml"), NULL}; WCHAR szLogFile[MAX_PATH]; DWORD dwPathFlags; BOOL bIsValid; GetDlgItemText(hwndDlg, IDC_EDITBOX_LOGFILE, szLogFile, ARRAYSIZE(szLogFile)); dwPathFlags = PMakePathUsable(szLogFile); // Make sure the correct xml file extension is specified if (PathMatchSpec(szLogFile, _T("*.xsl"))) PathRenameExtension(szLogFile, _T(".xml")); bIsValid = PIsValidFile(szLogFile, aszFileExtensions, ARRAYSIZE(aszFileExtensions), aszContentTypes, ARRAYSIZE(aszContentTypes)); PMakePathPretty(szLogFile, dwPathFlags); SetDlgItemText(hwndDlg, IDC_EDITBOX_LOGFILE, szLogFile); EnableDlgItem(hwndDlg, IDC_BUTTON_OPENLOG, bIsValid); return TRUE; } case WM_DROPFILES: { // Forward do log edit (child windows of childs can not receive that message) PostMessage(GetDlgItem(hwndDlg, IDC_EDITBOX_LOGFILE), uMsg, wParam, lParam); return TRUE; } case WM_DESTROY: { HIMAGELIST hImgLst; // Free font DeleteObject((HFONT)SendDlgItemMessage(hwndDlg, IDC_CHECKBOX_ADVERTISMENTFILTER, WM_GETFONT, 0, 0)); // Destroy tree view imagelist since it does not get destroyed automatically (see msdn docs) hImgLst = TreeView_GetImageList(GetDlgItem(hwndDlg, IDC_TREEVIEW_MESSAGETYPES), TVSIL_STATE); if (hImgLst) { TreeView_SetImageList(GetDlgItem(hwndDlg, IDC_TREEVIEW_MESSAGETYPES), NULL, TVSIL_STATE); // Avoiding Access Violation in CommonControls DLL ImageList_Destroy(hImgLst); } hImgLst = TreeView_GetImageList(GetDlgItem(hwndDlg, IDC_TREEVIEW_MESSAGETYPES), TVSIL_NORMAL); if (hImgLst) { TreeView_SetImageList(GetDlgItem(hwndDlg, IDC_TREEVIEW_MESSAGETYPES), NULL, TVSIL_NORMAL); // Avoiding Access Violation in CommonControls DLL ImageList_Destroy(hImgLst); } // Destroy open icon DestroyIcon((HICON)SendDlgItemMessage(hwndDlg, IDC_BUTTON_LOGBROWSE, BM_GETIMAGE, (WPARAM)IMAGE_ICON, 0)); hwndSpamFilterOpt = NULL; return TRUE; } case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_BUTTON_ADVERTISMENTFILTER: { CallService(MS_SPAMFILTER_SHOWFILTERDIALOG, (WPARAM)hwndDlg, (LPARAM)SFT_ADVERTISMENT_FILTER); // Do not activate "Apply" button return FALSE; } case IDC_BUTTON_DISLIKEDMESSAGEFILTER: { CallService(MS_SPAMFILTER_SHOWFILTERDIALOG, (WPARAM)hwndDlg, (LPARAM)SFT_DISLIKEDMESSAGES_FILTER); // Do not activate "Apply" button return FALSE; } case IDC_BUTTON_ROBOTFILTER: { CallService(MS_SPAMFILTER_SHOWFILTERDIALOG, (WPARAM)hwndDlg, (LPARAM)SFT_ROBOT_FILTER); // Do not activate "Apply" button return FALSE; } case IDC_BUTTON_LOGBROWSE: { WCHAR szLogFile[MAX_PATH]; WCHAR szInitialDir[MAX_PATH]; WCHAR szDefaultLogFile[MAX_PATH]; BOOL bDefaultDirUsed, bDefaultFileUsed; BOOL bFileChanged; DWORD dwPathFlags; int iIndexAll, iIndexOther; OPENFILENAME ofn; // Set focus on editbox SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDC_EDITBOX_LOGFILE), (LPARAM)TRUE); // Get chosen log file GetDlgItemText(hwndDlg, IDC_EDITBOX_LOGFILE, szLogFile, ARRAYSIZE(szLogFile)); dwPathFlags = PMakePathUsable(szLogFile); // Construct default log file PConstructLocalPath(szDefaultLogFile, CSIDL_EXT_EXECUTABLE, LOGS_SUBDIRECTORY, DEFAULT_LOGFILE, NULL); // Check if default file gets used if ((lstrlen(szLogFile) == 0) || (PathFindFileName(szLogFile) == szLogFile)) { // Using default dir if nothing specified mir_sntprintf(szLogFile, ARRAYSIZE(szLogFile), _T("%s"), szDefaultLogFile); bDefaultDirUsed = bDefaultFileUsed = TRUE; } else { bDefaultDirUsed = bDefaultFileUsed = (StrCmpI(szLogFile, szDefaultLogFile) == 0); } // Using default file name when no file given if ( (lstrlen(PathFindFileName(szLogFile)) == 0) || PathIsDirectory(szLogFile)) { PathAppend(szLogFile, PathFindFileName(szDefaultLogFile)); bDefaultFileUsed = TRUE; } // Split file name { mir_sntprintf(szInitialDir, ARRAYSIZE(szInitialDir), _T("%s"), szLogFile); // Get file name mir_sntprintf(szLogFile, ARRAYSIZE(szLogFile), _T("%s"), PathFindFileName(szInitialDir)); // Get initial dir PathRemoveFileSpec(szInitialDir); } // Initialize OPENFILENAME structure ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = (IsWinVerNT() && !IsWinVer2000Plus()) ? OPENFILENAME_SIZE_VERSION_400 : sizeof(ofn); // backward compatibility for NT4 ofn.hwndOwner = hwndDlg; ofn.Flags = OFN_ENABLESIZING|OFN_EXPLORER | OFN_LONGNAMES|OFN_HIDEREADONLY|OFN_NOREADONLYRETURN|OFN_OVERWRITEPROMPT; // also possible: OFN_DONTADDTORECENT, OFN_CREATEPROMPT ofn.lpstrFile = szLogFile; ofn.nMaxFile = ARRAYSIZE(szLogFile); ofn.lpstrTitle = TranslateT("Select Log File"); ofn.lpstrDefExt = CharNext(PathFindExtension(DEFAULT_LOGFILE)); // Make sure the initial directory exists if (SUCCEEDED(PPreparePathForWrite(hwndDlg, szInitialDir, !bDefaultDirUsed, FALSE))) ofn.lpstrInitialDir = szInitialDir; // File Filter { STRINGLIST* pslFilter = SLNewList(); SLAddItemPair(pslFilter, TranslateT("Log Files (*.log)"), _T("*.log")); SLAddItemPair(pslFilter, TranslateT("Text Files (*.txt)"), _T("*.txt")); SLAddItemPair(pslFilter, TranslateT("Comma Separated Values Files (*.csv)"), _T("*.csv")); SLAddItemPair(pslFilter, TranslateT("XML Files (*.xml; *.xsl)"), _T("*.xml; *.xsl")); iIndexAll = SLAddItemPair(pslFilter, TranslateT("All Logging Files (*.log; *.txt; *.csv; *.xml)"), _T("*.log; *.txt; *.csv; *.xml")); iIndexOther = SLAddItemPair(pslFilter, TranslateT("All Files (*.*)"), _T("*.*")); ofn.lpstrFilter = SLConvertToString(pslFilter, NULL, FALSE, TRUE, NULL); SLFreeList(pslFilter); } // Default selected index if ( PathMatchSpec(szLogFile, _T("*.log")) || PathMatchSpec(szLogFile, _T("*.txt")) || PathMatchSpec(szLogFile, _T("*.csv")) || PathMatchSpec(szLogFile, _T("*.xml")) ) { // Show "all logging files" to show the user the possibilities ofn.nFilterIndex = (iIndexAll/2)+1; // filter index is 1 based } else { // Select "All files" ofn.nFilterIndex = (iIndexOther/2)+1; // filter index is 1 based } // Show browse file dialog bFileChanged = GetSaveFileName(&ofn); SLFreeReturn((WCHAR*)ofn.lpstrFilter); if (bFileChanged) { PMakePathPretty(szLogFile, dwPathFlags); SetDlgItemText(hwndDlg, IDC_EDITBOX_LOGFILE, szLogFile); // Re-Set focus on editbox PostMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDC_EDITBOX_LOGFILE), (LPARAM)TRUE); PostMessage(hwndDlg, SFM_VALIDATE_LOGFILENAME, 0, 0); } else { PostMessage(hwndDlg, SFM_VALIDATE_LOGFILENAME, 0, 0); // Do not activate "Apply" button return FALSE; } break; } case IDC_BUTTON_OPENLOG: { WCHAR szLogFile[MAX_PATH]; GetDlgItemText(hwndDlg, IDC_EDITBOX_LOGFILE, szLogFile, ARRAYSIZE(szLogFile)); PMakePathUsable(szLogFile); if ((int)ShellExecute(hwndDlg, _T("open"), szLogFile, NULL, NULL, SW_SHOWNORMAL) <= 32) EnableDlgItem(hwndDlg, IDC_BUTTON_OPENLOG, FALSE); // Do not activate "Apply" button return FALSE; } case IDC_BUTTON_RESETAUTOIGNORE: { // Show message box before doing reset if (MessageBoxEx(hwndDlg, TranslateT("Are you sure that the Auto Ignore counters shall really be reset?\r\n\r\nSpammers that are not already ignored will then not be remembered any longer."), TranslateT("Reset Auto Ignore"), MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON1, LANGIDFROMLCID(GetThreadLocale())) == IDYES) EnableDlgItem(hwndDlg, IDC_BUTTON_RESETAUTOIGNORE, (CallService(MS_SPAMFILTER_RESETAUTOIGNORE, (WPARAM)FALSE, 0) != 0) ); // Do not activate "Apply" button return FALSE; } case IDC_BUTTON_SHOWSPAMMERS: { CallService(MS_SPAMFILTER_SHOWFILTERDIALOG, (WPARAM)hwndDlg, (LPARAM)SFTEXF_SPAMMERS_INFO); // Do not activate "Apply" button return FALSE; } case IDC_CHECKBOX_AUTOADDSPAMMERS: case IDC_CHECKBOX_LOGGING: case IDC_CHECKBOX_ADVERTISMENTFILTER: case IDC_CHECKBOX_DISLIKEDMESSAGEFILTER: case IDC_CHECKBOX_ROBOTFILTER: { PostMessage(hwndDlg, SFM_ENABLE_SUBCTRLS, 0, 0); break; } case IDC_EDITBOX_LOGFILE: { switch (HIWORD(wParam)) { case EN_CHANGE: { EnableDlgItem(hwndDlg, IDC_BUTTON_OPENLOG, FALSE); break; } case EN_KILLFOCUS: { PostMessage(hwndDlg, SFM_VALIDATE_LOGFILENAME, 0, 0); break; } } // fall through } case IDC_EDITBOX_ALLOWEDSPAMMESSAGES: { if (HIWORD(wParam) != EN_SETFOCUS) { // Do not activate "Apply" button return FALSE; } break; } } // Send message to activate "Apply" button... PostMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); return FALSE; } case WM_NOTIFY: { LPNMHDR pnmhdr = (LPNMHDR)lParam; switch (pnmhdr->idFrom) { case IDC_TREEVIEW_MESSAGETYPES: { switch (pnmhdr->code) { case TVN_KEYDOWN: { switch (((NMTVKEYDOWN*)lParam)->wVKey) { case VK_SPACE: { if (TreeView_GetSelection(pnmhdr->hwndFrom)) { ToggleTreeViewItemState(pnmhdr->hwndFrom, TreeView_GetSelection(pnmhdr->hwndFrom)); // Send message to activate "Apply" button... PostMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); } // Prevent default processing SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)FALSE); return TRUE; } } break; } case NM_CLICK: { TVHITTESTINFO hti; // Get click position GetCursorPos(&hti.pt); ScreenToClient(pnmhdr->hwndFrom, &hti.pt); // Check if click was on state icon if (TreeView_HitTest(pnmhdr->hwndFrom, &hti)) if (hti.flags&TVHT_ONITEMSTATEICON) { ToggleTreeViewItemState(pnmhdr->hwndFrom, hti.hItem); // Send message to activate "Apply" button... PostMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); } return TRUE; } } break; } case 0: { switch (pnmhdr->code) { case PSN_EXPERTCHANGED: // Expert mode checkbox checked/unchecked { BOOL bNewState = (BOOL)lParam; // Accept files (when log file edit control is visible) DragAcceptFiles(hwndDlg, bNewState); return TRUE; } case PSN_APPLY: // When "Apply"/"OK" pressed in options dialog then save changes { BOOL bFilterState = ( (IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_DISLIKEDMESSAGEFILTER) == BST_CHECKED) || (IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_ADVERTISMENTFILTER) == BST_CHECKED) || (IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_ROBOTFILTER) == BST_CHECKED) ); // Save filter state DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENTFILTER, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_ADVERTISMENTFILTER) == BST_CHECKED)); DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGEFILTER, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_DISLIKEDMESSAGEFILTER) == BST_CHECKED)); DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ROBOTFILTER, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_ROBOTFILTER) == BST_CHECKED)); // Save popup state if (IsPopupAvailable(TRUE)) { BOOL bPopupState = (IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_POPUP) == BST_CHECKED); DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_POPUP, (BYTE)bPopupState); SetPopupMenuItem(bPopupState, !bFilterState); } // Save Auto Ignore DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_AUTOADDSPAMMERS, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_AUTOADDSPAMMERS) == BST_CHECKED)); DBWriteContactSettingWord(NULL, DB_MODULE_NAME, DB_SETTING_ALLOWEDSPAMMESSAGES, (WORD)GetDlgItemInt(hwndDlg, IDC_EDITBOX_ALLOWEDSPAMMESSAGES, NULL, FALSE)); // Save behaviour DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_BEHAVIOUR, (BYTE)((IsDlgButtonChecked(hwndDlg, IDC_RADIO_MARKREADMSG) == BST_CHECKED) ? 1 : 2)); // Save log file { WCHAR szLogFile[MAX_PATH]; GetDlgItemText(hwndDlg, IDC_EDITBOX_LOGFILE, szLogFile, ARRAYSIZE(szLogFile)); DBWriteContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_LOGFILE, szLogFile); // Save activation of logging DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_LOGGING, (BYTE)((lstrlen(szLogFile) > 0) ? (IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_LOGGING) == BST_CHECKED) : FALSE)); } // Save message types { HWND hwndTreeView = GetDlgItem(hwndDlg, IDC_TREEVIEW_MESSAGETYPES); MESSAGETYPEDESC* pmtd; HTREEITEM hSectionItem; HTREEITEM hItem; char* pszSetting; for (hSectionItem=TreeView_GetRoot(hwndTreeView); hSectionItem; hSectionItem=TreeView_GetNextSibling(hwndTreeView, hSectionItem)) for (hItem=TreeView_GetChild(hwndTreeView, hSectionItem); hItem; hItem=TreeView_GetNextSibling(hwndTreeView, hItem)) { EnterCriticalSection(&csMsgTypes); // thread safety pmtd = GetDataFromTreeViewItem(hwndTreeView, hItem); if (pmtd) { // Save setting pszSetting = GetMsgTypeSettingName(pmtd->pszSection, pmtd->pszName); if (!pszSetting) continue; DBWriteContactSettingByte(NULL, DB_MODULE_NAME_MSGTYPES, pszSetting, (BYTE)((TreeView_GetItemState(hwndTreeView, hItem, TVIS_STATEIMAGEMASK)&INDEXTOSTATEIMAGEMASK(2))?TRUE:FALSE)); mir_free(pszSetting); } LeaveCriticalSection(&csMsgTypes); // thread safety } } return FALSE; } } // switch code break; } } // switch idFrom break; } } return FALSE; } BOOL CALLBACK DlgProcConfigureAdvertismentFilter(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: { hwndAdvertismentFilter = hwndDlg; // Translate dialog TranslateDialogDefault(hwndDlg); // Make group headings bold { HFONT hBoldFont; LOGFONT lf; GetObject((HFONT)SendDlgItemMessage(hwndDlg, IDC_GROUP_BADWORDS, WM_GETFONT, 0, 0), sizeof(lf), &lf); lf.lfWeight = FW_BOLD; hBoldFont = CreateFontIndirect(&lf); SendDlgItemMessage(hwndDlg, IDC_GROUP_BADWORDS, WM_SETFONT, (WPARAM)hBoldFont, 0); SendDlgItemMessage(hwndDlg, IDC_GROUP_OTHERCONTENTS, WM_SETFONT, (WPARAM)hBoldFont, 0); SendDlgItemMessage(hwndDlg, IDC_GROUP_SPAMMERS, WM_SETFONT, (WPARAM)hBoldFont, 0); SendDlgItemMessage(hwndDlg, IDC_GROUP_GOODWORDS, WM_SETFONT, (WPARAM)hBoldFont, 0); SendDlgItemMessage(hwndDlg, IDC_TEXT_WARNING, WM_SETFONT, (WPARAM)hBoldFont, 0); } // Set icon SendMessage(hwndDlg, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)(HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_DEFAULT), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED)); // Init checkboxes CheckDlgButton(hwndDlg, IDC_CHECKBOX_DEFAULTBADWORDS, DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_DEFAULTBADWORDS, (BYTE)(DEFAULT_SETTING_ADVERTISMENT_DEFAULTBADWORDS ? BST_CHECKED : BST_UNCHECKED)) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_CHECKBOX_FORMATING, DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_FORMATING, (BYTE)(DEFAULT_SETTING_ADVERTISMENT_FORMATING ? BST_CHECKED : BST_UNCHECKED)) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_CHECKBOX_URL, DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_URL, (BYTE)(DEFAULT_SETTING_ADVERTISMENT_URL)) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_CHECKBOX_CAPITALIZED, DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_CAPITALIZED, (BYTE)(DEFAULT_SETTING_ADVERTISMENT_CAPITALIZED ? BST_CHECKED : BST_UNCHECKED)) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_CHECKBOX_DEFAULTSPAMMERS, DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_DEFAULTSPAMMERS, (BYTE)(DEFAULT_SETTING_ADVERTISMENT_DEFAULTSPAMMERS ? BST_CHECKED : BST_UNCHECKED)) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_CHECKBOX_MULTIPLEMESSAGES, DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_MULTIPLEMESSAGES, (BYTE)(DEFAULT_SETTING_ADVERTISMENT_MULTIPLEMESSAGES ? BST_CHECKED : BST_UNCHECKED)) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_CHECKBOX_TEASERMESSAGES, DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_TEASERMESSAGES, (BYTE)(DEFAULT_SETTING_ADVERTISMENT_TEASERMESSAGES ? BST_CHECKED : BST_UNCHECKED)) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_CHECKBOX_EMPTY, DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_EMPTY, (BYTE)(DEFAULT_SETTING_ADVERTISMENT_EMPTY ? BST_CHECKED : BST_UNCHECKED)) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_CHECKBOX_PHONENUMBERS, DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_PHONENUMBERS, (BYTE)(DEFAULT_SETTING_ADVERTISMENT_PHONENUMBERS ? BST_CHECKED : BST_UNCHECKED)) ? BST_CHECKED : BST_UNCHECKED); // Load default bad words count (for spins) SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)SLNewList()); SendMessage(hwndDlg, SFM_RELOAD_DEFAULTBADWORDS, 0, 0); // Init listboxes { STRINGLIST* pslWords = SLNewList(); // Bad words GetSpamDefinitionData(pslWords, SDID_CUSTOM_BADWORDS); WordsListBoxInit(hwndDlg, IDC_LISTBOX_CUSTOMIZEDBADWORDS, IDC_BUTTON_ADDBADWORD, IDC_BUTTON_DELETEBADWORD, pslWords, Translate("Add bad phrase/pattern"), Translate("Remove bad phrase/pattern")); CheckDlgButton(hwndDlg, IDC_CHECKBOX_CUSTOMIZEDBADWORDS, (SLGetItemCount(pslWords) > 0) ? (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_CUSTOMIZEDBADWORDS, (BYTE)TRUE)?BST_CHECKED:BST_UNCHECKED) : BST_UNCHECKED); SLClearList(pslWords); // Good words GetSpamDefinitionData(pslWords, SDID_CUSTOM_GOODWORDS); WordsListBoxInit(hwndDlg, IDC_LISTBOX_CUSTOMIZEDGOODWORDS, IDC_BUTTON_ADDGOODWORD, IDC_BUTTON_DELETEGOODWORD, pslWords, Translate("Add good phrase/pattern"), Translate("Remove good phrase/pattern")); CheckDlgButton(hwndDlg, IDC_CHECKBOX_CUSTOMIZEDGOODWORDS, (SLGetItemCount(pslWords) > 0) ? (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_CUSTOMIZEDGOODWORDS, (BYTE)TRUE)?BST_CHECKED:BST_UNCHECKED) : BST_UNCHECKED); SLFreeList(pslWords); } // Init editboxes and spins { BOOL bStatus = TRUE; int iBadWordsCount = ( (IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_CUSTOMIZEDBADWORDS) == BST_CHECKED) ? SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CUSTOMIZEDBADWORDS, LB_GETCOUNT, 0, 0) : 0) + ( (IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_DEFAULTBADWORDS) == BST_CHECKED) ? SLGetItemCount((STRINGLIST*)GetWindowLongPtr(hwndDlg, DWLP_USER)) : 0) - 1; // Allowed bad words edit/spin bStatus = SetSpinCtrlRange(GetDlgItem(hwndDlg, IDC_SPIN_ALLOWEDBADWORDS), 0, iBadWordsCount, DBGetContactSettingWord(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_ALLOWEDBADWORDS, (DWORD)DEFAULT_SETTING_ADVERTISMENT_ALLOWEDBADWORDS), TRUE); EnableDlgItem(hwndDlg, IDC_TEXT_ALLOWEDBADWORDS, bStatus); // Allowed formated words edit/spin bStatus = SetSpinCtrlRange(GetDlgItem(hwndDlg, IDC_SPIN_ALLOWEDFORMATEDWORDS), 0, iBadWordsCount, DBGetContactSettingWord(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_ALLOWEDFORMATEDWORDS, (DWORD)DEFAULT_SETTING_ADVERTISMENT_ALLOWEDFORMATEDWORDS), TRUE); EnableDlgItem(hwndDlg, IDC_TEXT_ALLOWEDFORMATEDWORDS, bStatus); // Allowed good words edit/spin SetSpinCtrlRange(GetDlgItem(hwndDlg, IDC_SPIN_ALLOWEDGOODWORDS), 0, (SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CUSTOMIZEDGOODWORDS, LB_GETCOUNT, 0, 0) - 1), DBGetContactSettingWord(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_ALLOWEDGOODWORDS, (DWORD)DEFAULT_SETTING_ADVERTISMENT_ALLOWEDGOODWORDS), TRUE); } // Check if all definition files do exist if (SLGetItemCount((STRINGLIST*)GetWindowLongPtr(hwndDlg, DWLP_USER)) <= 0) { EnableDlgItem(hwndDlg, IDC_CHECKBOX_DEFAULTBADWORDS, FALSE); ShowDlgItem(hwndDlg, IDC_TEXT_WARNING, TRUE); } if (!IsSpamDefinitionDataPresent(SDID_URLTLDS)) { EnableDlgItem(hwndDlg, IDC_CHECKBOX_URL, FALSE); ShowDlgItem(hwndDlg, IDC_TEXT_WARNING, TRUE); } if (!IsSpamDefinitionDataPresent(SDID_SPAMMERS)) { EnableDlgItem(hwndDlg, IDC_CHECKBOX_DEFAULTSPAMMERS, FALSE); ShowDlgItem(hwndDlg, IDC_TEXT_WARNING, TRUE); } if (!IsSpamDefinitionDataPresent(SDID_PHONENUMBERS)) { EnableDlgItem(hwndDlg, IDC_CHECKBOX_PHONENUMBERS, FALSE); ShowDlgItem(hwndDlg, IDC_TEXT_WARNING, TRUE); } if (!IsSpamDefinitionDataPresent(SDID_TEASERTEXTS)) { EnableDlgItem(hwndDlg, IDC_CHECKBOX_TEASERMESSAGES, FALSE); ShowDlgItem(hwndDlg, IDC_TEXT_WARNING, TRUE); } // Simulate messages SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_CHECKBOX_CUSTOMIZEDBADWORDS, BN_CLICKED), (LPARAM)NULL); SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_CHECKBOX_CUSTOMIZEDGOODWORDS, BN_CLICKED), (LPARAM)NULL); SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_CHECKBOX_FORMATING, BN_CLICKED), (LPARAM)NULL); // Restore dlg position (at the end, so the dialog does not get shown early) Utils_RestoreWindowPositionNoSize(hwndDlg, NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_DIALOGPOSITION); // Make sure the dialog is not moved out of sight SendMessage(hwndDlg, DM_REPOSITION, 0, 0); // SetFocus (SetFocus() is not allowed in Dialogs) SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDOK), (LPARAM)TRUE); return FALSE; } case SFM_RELOAD_DEFAULTBADWORDS: { if (InSendMessage()) ReplyMessage(TRUE); SLClearList((STRINGLIST*)GetWindowLongPtr(hwndDlg, DWLP_USER)); GetSpamDefinitionData((STRINGLIST*)GetWindowLongPtr(hwndDlg, DWLP_USER), SDID_BADWORDS); return TRUE; } case WM_DESTROY: { // Save dlg position Utils_SaveWindowPosition(hwndDlg, NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_DIALOGPOSITION); // Free default bad words SLFreeList((STRINGLIST*)GetWindowLongPtr(hwndDlg, DWLP_USER)); // Free font DeleteObject((HFONT)SendDlgItemMessage(hwndDlg, IDC_GROUP_BADWORDS, WM_GETFONT, 0, 0)); hwndAdvertismentFilter = NULL; return TRUE; } case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_CHECKBOX_DEFAULTBADWORDS: case IDC_CHECKBOX_CUSTOMIZEDBADWORDS: { int iListCount = SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CUSTOMIZEDBADWORDS, LB_GETCOUNT, 0, 0); BOOL bStatus = ((IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_CUSTOMIZEDBADWORDS) == BST_CHECKED) || (IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_DEFAULTBADWORDS) == BST_CHECKED)); EnableDlgItem(hwndDlg, IDC_TEXT_ALLOWEDBADWORDS, bStatus); EnableDlgItem(hwndDlg, IDC_TEXT_ALLOWEDFORMATEDWORDS, bStatus); EnableDlgItem(hwndDlg, IDC_CHECKBOX_FORMATING, bStatus); bStatus = (bStatus && ((iListCount+SLGetItemCount((STRINGLIST*)GetWindowLongPtr(hwndDlg, DWLP_USER))) > 1)); EnableDlgItem(hwndDlg, IDC_TEXT_ALLOWEDBADWORDS, bStatus); EnableDlgItem(hwndDlg, IDC_EDITBOX_ALLOWEDBADWORDS, bStatus); EnableDlgItem(hwndDlg, IDC_SPIN_ALLOWEDBADWORDS, bStatus); EnableDlgItem(hwndDlg, IDC_TEXT_ALLOWEDFORMATEDWORDS, bStatus); EnableDlgItem(hwndDlg, IDC_EDITBOX_ALLOWEDFORMATEDWORDS, bStatus); EnableDlgItem(hwndDlg, IDC_SPIN_ALLOWEDFORMATEDWORDS, bStatus); // Customized bad words box checked -> Deactivate all customized bad words options bStatus = (IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_CUSTOMIZEDBADWORDS) == BST_CHECKED); EnableDlgItem(hwndDlg, IDC_LISTBOX_CUSTOMIZEDBADWORDS, bStatus); EnableDlgItem(hwndDlg, IDC_BUTTON_ADDBADWORD, bStatus); EnableDlgItem(hwndDlg, IDC_BUTTON_DELETEBADWORD, (iListCount > 0) ? bStatus : FALSE); // Set/Check allowed bad words value (Simulate changed edit box) SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_EDITBOX_ALLOWEDBADWORDS, EN_KILLFOCUS), 0); return TRUE; } case IDC_CHECKBOX_CUSTOMIZEDGOODWORDS: { BOOL bStatus; int iListCount = SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CUSTOMIZEDGOODWORDS, LB_GETCOUNT, 0, 0); // Customized good words box checked -> Deactivate all good words options bStatus = (IsDlgButtonChecked(hwndDlg,IDC_CHECKBOX_CUSTOMIZEDGOODWORDS) == BST_CHECKED); EnableDlgItem(hwndDlg, IDC_LISTBOX_CUSTOMIZEDGOODWORDS, bStatus); EnableDlgItem(hwndDlg, IDC_TEXT_ALLOWEDGOODWORDS, bStatus); EnableDlgItem(hwndDlg, IDC_EDITBOX_ALLOWEDGOODWORDS, bStatus); EnableDlgItem(hwndDlg, IDC_SPIN_ALLOWEDGOODWORDS, bStatus); // Activate Add/Delete buttons? EnableDlgItem(hwndDlg, IDC_BUTTON_ADDGOODWORD, bStatus); EnableDlgItem(hwndDlg, IDC_BUTTON_DELETEGOODWORD, (iListCount > 0) ? bStatus : FALSE); EnableDlgItem(hwndDlg, IDC_TEXT_ALLOWEDGOODWORDS, bStatus); bStatus = (bStatus && (iListCount > 1)); EnableDlgItem(hwndDlg, IDC_SPIN_ALLOWEDGOODWORDS, bStatus); EnableDlgItem(hwndDlg, IDC_EDITBOX_ALLOWEDGOODWORDS, bStatus); return TRUE; } case IDC_CHECKBOX_FORMATING: { BOOL bStatus = (IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_FORMATING) == BST_CHECKED); EnableDlgItem(hwndDlg, IDC_TEXT_ALLOWEDFORMATEDWORDS, bStatus); EnableDlgItem(hwndDlg, IDC_EDITBOX_ALLOWEDFORMATEDWORDS, bStatus); EnableDlgItem(hwndDlg, IDC_SPIN_ALLOWEDFORMATEDWORDS, bStatus); return TRUE; } case IDC_EDITBOX_ALLOWEDBADWORDS: case IDC_EDITBOX_ALLOWEDFORMATEDWORDS: { switch(HIWORD(wParam)) { case EN_KILLFOCUS: { int iRangeMax = ((IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_CUSTOMIZEDBADWORDS) == BST_CHECKED) ? SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CUSTOMIZEDBADWORDS, LB_GETCOUNT, 0, 0) : 0) + ((IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_DEFAULTBADWORDS) == BST_CHECKED) ? SLGetItemCount((STRINGLIST*)GetWindowLongPtr(hwndDlg, DWLP_USER)) : 0) - 1; // Check allowed bad words value SetSpinCtrlRange(GetDlgItem(hwndDlg, IDC_SPIN_ALLOWEDBADWORDS), 0, iRangeMax, DEFAULT_SETTING_ADVERTISMENT_ALLOWEDBADWORDS, FALSE); // Check allowed formated words value SetSpinCtrlRange(GetDlgItem(hwndDlg, IDC_SPIN_ALLOWEDFORMATEDWORDS), 0, iRangeMax, DEFAULT_SETTING_ADVERTISMENT_ALLOWEDFORMATEDWORDS, FALSE); return TRUE; } } break; } case IDC_EDITBOX_ALLOWEDGOODWORDS: { switch (HIWORD(wParam)) { case EN_KILLFOCUS: { int iRangeMax = SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CUSTOMIZEDGOODWORDS, LB_GETCOUNT, 0, 0) - 1; if (iRangeMax < 0) iRangeMax = 0; // Check allowed good words value SetSpinCtrlRange(GetDlgItem(hwndDlg, IDC_SPIN_ALLOWEDGOODWORDS), 0, iRangeMax, DEFAULT_SETTING_ADVERTISMENT_ALLOWEDGOODWORDS, FALSE); return TRUE; } } break; } case IDC_BUTTON_ADDBADWORD: { WCHAR* pszMsgTitle = TranslateT("Add bad phrase/pattern"); WCHAR* pszMsgTextInList = TranslateT("The entered bad phrase \"%s\" already exists in the list.\r\n\r\nThe filter doesn't differentiate between lower and upper case.\r\nTwo entries with the same phrase are not neccessary\nand will decrease the filter quality.\r\n\r\nShall the bad phrase be added anyway?"); WCHAR* pszMsgTextInOther = TranslateT("The entered bad phrase \"%s\" already exists in the default bad phrases lists.\r\n\r\nAllowing the same bad phrase in the customized bad phrases lists will\npull down the filter quality.\r\n\r\nShall the bad phrase be added anyway?"); WordsListBoxAddItem(hwndDlg, IDC_LISTBOX_CUSTOMIZEDBADWORDS, (STRINGLIST*)GetWindowLongPtr(hwndDlg, DWLP_USER), pszMsgTitle, pszMsgTextInList, pszMsgTextInOther, IDC_BUTTON_DELETEBADWORD); // Set/Check allowed bad words value (Simulate changed edit box) SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_EDITBOX_ALLOWEDBADWORDS, EN_KILLFOCUS), 0); // Simulate messages SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_CHECKBOX_CUSTOMIZEDBADWORDS, BN_CLICKED), 0); return TRUE; } case IDC_BUTTON_DELETEBADWORD: { int iItemCount = WordsListBoxDeleteItem(hwndDlg, IDC_LISTBOX_CUSTOMIZEDBADWORDS, IDC_BUTTON_DELETEBADWORD); // Deactivate list on zero entries if (iItemCount == 0) { CheckDlgButton(hwndDlg, IDC_CHECKBOX_CUSTOMIZEDBADWORDS, BST_UNCHECKED); SendMessage(hwndDlg, WM_COMMAND, IDC_CHECKBOX_CUSTOMIZEDBADWORDS, 0); } // Set/Check allowed bad words value (Simulate changed edit box) SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_EDITBOX_ALLOWEDBADWORDS, EN_KILLFOCUS), 0); // Simulate messages SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_CHECKBOX_CUSTOMIZEDBADWORDS, BN_CLICKED), 0); return TRUE; } case IDC_BUTTON_ADDGOODWORD: { WCHAR* pszMsgTitle = TranslateT("Add good phrase/pattern"); WCHAR* pszMsgTextInList = TranslateT("The entered good phrase \"%s\" already exists\r\nin the list.\r\n\r\nThe filter doesn't differentiate between lower and upper case.\r\nTwo entries with the same phrase are not neccessary\nand will decrease the filter quality.\r\n\r\nShall the good phrase be added anyway?"); WordsListBoxAddItem(hwndDlg, IDC_LISTBOX_CUSTOMIZEDGOODWORDS, NULL, pszMsgTitle, pszMsgTextInList, NULL, IDC_BUTTON_DELETEGOODWORD); // Set/Check allowed bad words value (Simulate changed edit box) SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_EDITBOX_ALLOWEDGOODWORDS, EN_KILLFOCUS), 0); // Simulate messages SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_CHECKBOX_CUSTOMIZEDGOODWORDS, BN_CLICKED), 0); return TRUE; } case IDC_BUTTON_DELETEGOODWORD: { int iItemCount = WordsListBoxDeleteItem(hwndDlg, IDC_LISTBOX_CUSTOMIZEDGOODWORDS, IDC_BUTTON_DELETEGOODWORD); int iRangeMax = iItemCount - 1; // Deactivate list on zero entries if (iItemCount == 0) { CheckDlgButton(hwndDlg, IDC_CHECKBOX_CUSTOMIZEDGOODWORDS, BST_UNCHECKED); SendMessage(hwndDlg, WM_COMMAND, IDC_CHECKBOX_CUSTOMIZEDGOODWORDS, 0); } // Update allowed good words spin SetSpinCtrlRange(GetDlgItem(hwndDlg, IDC_SPIN_ALLOWEDGOODWORDS), 0, iRangeMax, DEFAULT_SETTING_ADVERTISMENT_ALLOWEDGOODWORDS, FALSE); // Set/Check allowed bad words value (Simulate changed edit box) SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_EDITBOX_ALLOWEDGOODWORDS, EN_KILLFOCUS), 0); // Simulate messages SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_CHECKBOX_CUSTOMIZEDGOODWORDS, BN_CLICKED), 0); // Set focus on list box again (might have gotten lost on IDC_CHECKBOX_CUSTOMIZEDGOODWORDS) PostMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDC_LISTBOX_CUSTOMIZEDGOODWORDS), (LPARAM)TRUE); return TRUE; } case IDC_BUTTON_SPAMDEFINITIONS: { CallService(MS_SPAMFILTER_SHOWFILTERDIALOG, (WPARAM)NULL, (LPARAM)SFT_ADVERTISMENT_FILTER|SFTEXF_SPAMDEFINITIONS_INFO); return TRUE; } case IDOK: { EnableDlgItem(hwndDlg, IDOK, FALSE); // Save changes DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_DEFAULTBADWORDS, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_DEFAULTBADWORDS) == BST_CHECKED)); DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_FORMATING, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_FORMATING) == BST_CHECKED)); DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_URL, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_URL) == BST_CHECKED)); DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_CAPITALIZED, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_CAPITALIZED) == BST_CHECKED)); DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_DEFAULTSPAMMERS, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_DEFAULTSPAMMERS) == BST_CHECKED)); DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_MULTIPLEMESSAGES, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_MULTIPLEMESSAGES) == BST_CHECKED)); DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_TEASERMESSAGES, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_TEASERMESSAGES) == BST_CHECKED)); DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_EMPTY, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_EMPTY) == BST_CHECKED)); DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_PHONENUMBERS, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_PHONENUMBERS) == BST_CHECKED)); DBWriteContactSettingWord(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_ALLOWEDBADWORDS, (WORD)GetDlgItemInt(hwndDlg, IDC_EDITBOX_ALLOWEDBADWORDS, NULL, FALSE)); DBWriteContactSettingWord(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_ALLOWEDFORMATEDWORDS, (WORD)GetDlgItemInt(hwndDlg, IDC_EDITBOX_ALLOWEDFORMATEDWORDS, NULL, FALSE)); DBWriteContactSettingWord(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_ALLOWEDGOODWORDS, (WORD)GetDlgItemInt(hwndDlg, IDC_EDITBOX_ALLOWEDGOODWORDS, NULL, FALSE)); // Save listbox contents { STRINGLIST* pslWords = SLNewList(); // Bad words SLRetrieveFromListBoxCtrl(pslWords, GetDlgItem(hwndDlg, IDC_LISTBOX_CUSTOMIZEDBADWORDS)); SetSpamDefinitionData(pslWords, SDID_CUSTOM_BADWORDS, hwndDlg); DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_CUSTOMIZEDBADWORDS, (BYTE)((SLGetItemCount(pslWords) > 0) ? (IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_CUSTOMIZEDBADWORDS) == BST_CHECKED) : FALSE)); SLClearList(pslWords); // Good words SLRetrieveFromListBoxCtrl(pslWords, GetDlgItem(hwndDlg, IDC_LISTBOX_CUSTOMIZEDGOODWORDS)); SetSpamDefinitionData(pslWords, SDID_CUSTOM_GOODWORDS, hwndDlg); DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENT_CUSTOMIZEDGOODWORDS, (BYTE)((SLGetItemCount(pslWords) > 0) ? (IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_CUSTOMIZEDGOODWORDS) == BST_CHECKED) : FALSE)); SLFreeList(pslWords); } // fall through } case IDCANCEL: // WM_CLOSE is transformed into an IDCANCEL by dialog manager { // Different method of closing the window depending on if the window // was created modal or not if (!GetParent(hwndDlg)) DestroyWindow(hwndDlg); else EndDialog(hwndDlg, LOWORD(wParam)); return TRUE; } } // switch wParam break; } default: { if (WordsListBoxDragDrop(hwndDlg, IDC_LISTBOX_CUSTOMIZEDBADWORDS, uMsg, lParam, FALSE) || WordsListBoxDragDrop(hwndDlg, IDC_LISTBOX_CUSTOMIZEDGOODWORDS, uMsg, lParam, FALSE) ) return TRUE; } } // switch uMsg return FALSE; } BOOL CALLBACK DlgProcConfigureDislikedMessagesFilter(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: { hwndDislikedMessagesFilter = hwndDlg; // Translate dialog TranslateDialogDefault(hwndDlg); // Make group headings bold { HFONT hBoldFont; LOGFONT lf; GetObject((HFONT)SendDlgItemMessage(hwndDlg, IDC_GROUP_OTHERCONTENTS, WM_GETFONT, 0, 0), sizeof(lf), &lf); lf.lfWeight = FW_BOLD; hBoldFont = CreateFontIndirect(&lf); SendDlgItemMessage(hwndDlg, IDC_GROUP_OTHERCONTENTS, WM_SETFONT, (WPARAM)hBoldFont, 0); SendDlgItemMessage(hwndDlg, IDC_GROUP_WORDS, WM_SETFONT, (WPARAM)hBoldFont, 0); SendDlgItemMessage(hwndDlg, IDC_GROUP_NOTIFYSENDER, WM_SETFONT, (WPARAM)hBoldFont, 0); SendDlgItemMessage(hwndDlg, IDC_TEXT_WARNING, WM_SETFONT, (WPARAM)hBoldFont, 0); } // Load icons SendMessage(hwndDlg, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)(HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_DEFAULT), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED)); // Set Data CheckDlgButton(hwndDlg, IDC_CHECKBOX_HOAXTEXTS, (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_HOAXTEXTS, (BYTE)(DEFAULT_SETTING_DISLIKEDMESSAGE_HOAXTEXTS ? BST_CHECKED : BST_UNCHECKED)) ? BST_CHECKED : BST_UNCHECKED)); CheckDlgButton(hwndDlg, IDC_CHECKBOX_MULTIPLEMESSAGES, (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_MULTIPLEMESSAGES, (BYTE)(DEFAULT_SETTING_DISLIKEDMESSAGE_MULTIPLEMESSAGES ? BST_CHECKED : BST_UNCHECKED)) ? BST_CHECKED : BST_UNCHECKED)); CheckDlgButton(hwndDlg, IDC_CHECKBOX_NOTIFYSENDER, (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_NOTIFYSENDER, (BYTE)(DEFAULT_SETTING_DISLIKEDMESSAGE_NOTIFYSENDER ? BST_CHECKED : BST_UNCHECKED)) ? BST_CHECKED : BST_UNCHECKED)); CheckDlgButton(hwndDlg, IDC_CHECKBOX_ADDTOHISTORY, (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_ADDTOHISTORY, (BYTE)(DEFAULT_SETTING_DISLIKEDMESSAGE_ADDTOHISTORY ? BST_CHECKED : BST_UNCHECKED)) ? BST_CHECKED : BST_UNCHECKED)); // Init listboxes { STRINGLIST* pslWords = SLNewList(); // Disliked words GetSpamDefinitionData(pslWords, SDID_CUSTOM_DISLIKEDWORDS); WordsListBoxInit(hwndDlg, IDC_LISTBOX_CUSTOMIZEDWORDS, IDC_BUTTON_ADDWORD, IDC_BUTTON_DELETEWORD, pslWords, Translate("Add indicating phrase/pattern"), Translate("Remove indicating phrase")); CheckDlgButton(hwndDlg, IDC_CHECKBOX_CUSTOMIZEDWORDS, (SLGetItemCount(pslWords) > 0) ? (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_CUSTOMIZEDWORDS, (BYTE)TRUE)?BST_CHECKED:BST_UNCHECKED) : BST_UNCHECKED); SLFreeList(pslWords); } // Init editbox { DBVARIANT dbv; // Notify text if (DBGetContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_RETURNMESSAGE, &dbv) == 0) { SetDlgItemText(hwndDlg, IDC_EDITBOX_NOTIFYSENDER, dbv.ptszVal); DBFreeVariant(&dbv); } else { SetDlgItemText(hwndDlg, IDC_EDITBOX_NOTIFYSENDER, DEFAULT_SETTING_DISLIKEDMESSAGE_RETURNMESSAGE); } } if (!IsSpamDefinitionDataPresent(SDID_HOAXTEXTS)) { EnableDlgItem(hwndDlg, IDC_CHECKBOX_HOAXTEXTS, FALSE); ShowDlgItem(hwndDlg, IDC_TEXT_WARNING, TRUE); } // Show/Hide Variables Plugin help button if (!MakeVariablesHelpButton(hwndDlg, IDC_BUTTON_NOTIFYSENDER_VARIABLES)) { RECT rc; if (GetWindowRect(GetDlgItem(hwndDlg, IDC_TEXT_NOTIFYSENDER), &rc)) SetWindowPos(GetDlgItem(hwndDlg, IDC_TEXT_NOTIFYSENDER), NULL, 0, 0, (rc.right-rc.left)+25, (rc.bottom-rc.top), SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW); } // Simulate messages SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_CHECKBOX_CUSTOMIZEDWORDS, BN_CLICKED), 0); SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_CHECKBOX_NOTIFYSENDER, BN_CLICKED), 0); // Restore dlg position (at the end, so the dialog does not get shown early) Utils_RestoreWindowPositionNoSize(hwndDlg, NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_DIALOGPOSITION); // Make sure the dialog is not moved out of sight SendMessage(hwndDlg, DM_REPOSITION, 0, 0); // SetFocus (SetFocus() is not allowed in Dialogs) SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDOK), (LPARAM)TRUE); return FALSE; } case WM_DESTROY: { // Save dlg position Utils_SaveWindowPosition(hwndDlg, NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_DIALOGPOSITION); // Free font DeleteObject((HFONT)SendDlgItemMessage(hwndDlg, IDC_GROUP_OTHERCONTENTS, WM_GETFONT, 0, 0)); // Destroy help icon DestroyIcon((HICON)SendDlgItemMessage(hwndDlg, IDC_BUTTON_NOTIFYSENDER_VARIABLES, BM_GETIMAGE, (WPARAM)IMAGE_ICON, 0)); hwndDislikedMessagesFilter = NULL; return TRUE; } case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_CHECKBOX_NOTIFYSENDER: { BOOL bStatus = (IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_NOTIFYSENDER) == BST_CHECKED); EnableDlgItem(hwndDlg, IDC_EDITBOX_NOTIFYSENDER, bStatus); EnableDlgItem(hwndDlg, IDC_TEXT_NOTIFYSENDER, bStatus); EnableDlgItem(hwndDlg, IDC_CHECKBOX_ADDTOHISTORY, bStatus); if (ServiceExists(MS_VARS_SHOWHELP) && ServiceExists(MS_VARS_FORMATSTRING)) EnableDlgItem(hwndDlg, IDC_BUTTON_NOTIFYSENDER_VARIABLES, bStatus); // Avoid passing simulated messages to the system if (!lParam) return TRUE; break; } case IDC_CHECKBOX_CUSTOMIZEDWORDS: { BOOL bStatus = (IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_CUSTOMIZEDWORDS) == BST_CHECKED); int iListCount = SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CUSTOMIZEDWORDS, LB_GETCOUNT, 0, 0); // Customized bad words box checked -> Deactivate all customized bad words options EnableDlgItem(hwndDlg, IDC_LISTBOX_CUSTOMIZEDWORDS, bStatus); // Deactivate Add/Delete buttons? EnableDlgItem(hwndDlg, IDC_BUTTON_ADDWORD, bStatus); EnableDlgItem(hwndDlg, IDC_BUTTON_DELETEWORD, (iListCount > 0) ? bStatus : FALSE); // Avoid passing simulated messages to the system if (!lParam) return TRUE; break; } case IDC_BUTTON_NOTIFYSENDER_VARIABLES: { // SetFocus (SetFocus() is not allowed in Dialogs) SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDC_EDITBOX_NOTIFYSENDER), (LPARAM)TRUE); CallService(MS_VARS_SHOWHELP, (WPARAM)GetDlgItem(hwndDlg, IDC_EDITBOX_NOTIFYSENDER), (LPARAM)NULL); break; } case IDC_BUTTON_ADDWORD: { WCHAR* pszMsgTitle = TranslateT("Add indicating phrase/pattern"); WCHAR* pszMsgTextInList = TranslateT("The entered indicating phrase \"%s\" already exists in the list.\r\n\r\nThe filter doesn't differentiate between lower and upper case.\r\nTwo entries with the same phrase are not neccessary\nand will decrease the filter quality.\r\n\r\nShall the indicating phrase be added anyway?"); WordsListBoxAddItem(hwndDlg, IDC_LISTBOX_CUSTOMIZEDWORDS, NULL, pszMsgTitle, pszMsgTextInList, NULL, IDC_BUTTON_DELETEWORD); break; } case IDC_BUTTON_DELETEWORD: { int iItemCount = WordsListBoxDeleteItem(hwndDlg, IDC_LISTBOX_CUSTOMIZEDWORDS, IDC_BUTTON_DELETEWORD); // Deactivate list on zero entries if (iItemCount == 0) { CheckDlgButton(hwndDlg, IDC_CHECKBOX_CUSTOMIZEDWORDS, BST_UNCHECKED); SendMessage(hwndDlg, WM_COMMAND, IDC_CHECKBOX_CUSTOMIZEDWORDS, 0); } break; } case IDC_BUTTON_SPAMDEFINITIONS: { CallService(MS_SPAMFILTER_SHOWFILTERDIALOG, (WPARAM)NULL, (LPARAM)SFT_DISLIKEDMESSAGES_FILTER|SFTEXF_SPAMDEFINITIONS_INFO); break; } case IDOK: { EnableDlgItem(hwndDlg, IDOK, FALSE); // Save changes DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_MULTIPLEMESSAGES, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_MULTIPLEMESSAGES) == BST_CHECKED)); DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_HOAXTEXTS, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_HOAXTEXTS) == BST_CHECKED)); DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_ADDTOHISTORY, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_ADDTOHISTORY) == BST_CHECKED)); // Save texts { HWND hwndEdit = GetDlgItem(hwndDlg, IDC_EDITBOX_NOTIFYSENDER); int iTextLen = GetWindowTextLength(hwndEdit); WCHAR* pszText = (WCHAR*)mir_alloc((iTextLen+1)*sizeof(WCHAR)); // Get entered text if (pszText) { if (GetWindowText(hwndEdit, pszText, iTextLen+1) == 0) pszText[0] = _T('\0'); // Save text if (lstrlen(pszText) > 0) { DBWriteContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_RETURNMESSAGE, pszText); DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_NOTIFYSENDER, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_NOTIFYSENDER) == BST_CHECKED)); } else{ DBWriteContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_RETURNMESSAGE, DEFAULT_SETTING_DISLIKEDMESSAGE_RETURNMESSAGE); DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_NOTIFYSENDER, (BYTE)FALSE); } mir_free(pszText); } } // Save listbox contents { STRINGLIST* pslWords = SLNewList(); // Chain words SLRetrieveFromListBoxCtrl(pslWords, GetDlgItem(hwndDlg, IDC_LISTBOX_CUSTOMIZEDWORDS)); SetSpamDefinitionData(pslWords, SDID_CUSTOM_DISLIKEDWORDS, hwndDlg); DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGE_CUSTOMIZEDWORDS, (BYTE)((SLGetItemCount(pslWords) > 0) ? (IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_CUSTOMIZEDWORDS) == BST_CHECKED) : FALSE)); SLFreeList(pslWords); } // fall through } case IDCANCEL: // WM_CLOSE is transformed into an IDCANCEL by dialog manager { // Different method of closing the window depending on if the window // was created modal or not if (!GetParent(hwndDlg)) DestroyWindow(hwndDlg); else EndDialog(hwndDlg, LOWORD(wParam)); return TRUE; } } // switch wParam break; } default: { if (WordsListBoxDragDrop(hwndDlg, IDC_LISTBOX_CUSTOMIZEDWORDS, uMsg, lParam, FALSE)) return TRUE; } } return FALSE; } BOOL CALLBACK DlgProcConfigureRobotFilter(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: { hwndRobotFilter = hwndDlg; // Translate dialog TranslateDialogDefault(hwndDlg); // Make group headings bold { HFONT hBoldFont; LOGFONT lf; GetObject((HFONT)SendDlgItemMessage(hwndDlg, IDC_GROUP_MESSAGETEXTS, WM_GETFONT, 0, 0), sizeof(lf), &lf); lf.lfWeight = FW_BOLD; hBoldFont = CreateFontIndirect(&lf); SendDlgItemMessage(hwndDlg, IDC_GROUP_MESSAGETEXTS, WM_SETFONT, (WPARAM)hBoldFont, 0); SendDlgItemMessage(hwndDlg, IDC_GROUP_ANSWER, WM_SETFONT, (WPARAM)hBoldFont, 0); } // Load icons SendMessage(hwndDlg, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)(HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_DEFAULT), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED)); // Set Data CheckDlgButton(hwndDlg, IDC_CHECKBOX_ADDTOHISTORY, (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ROBOT_ADDTOHISTORY, (BYTE)DEFAULT_SETTING_ROBOT_ADDTOHISTORY) ? BST_CHECKED : BST_UNCHECKED)); CheckDlgButton(hwndDlg, IDC_CHECKBOX_HIDE, (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ROBOT_HIDEUSERS, (BYTE)DEFAULT_SETTING_ROBOT_HIDEUSERS) ? BST_CHECKED : BST_UNCHECKED)); // Init editboxes { DBVARIANT dbv; // Question if (DBGetContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_ROBOT_INSTRUCTION, &dbv) == 0) { SetDlgItemText(hwndDlg, IDC_EDITBOX_INSTRUCTION, dbv.ptszVal); DBFreeVariant(&dbv); } else { SetDlgItemText(hwndDlg, IDC_EDITBOX_INSTRUCTION, DEFAULT_SETTING_ROBOT_INSTRUCTION); } // Congratulation if (DBGetContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_ROBOT_CONFIRMATION, &dbv) == 0) { SetDlgItemText(hwndDlg, IDC_EDITBOX_CONFIRMATION, dbv.ptszVal); DBFreeVariant(&dbv); } else { SetDlgItemText(hwndDlg, IDC_EDITBOX_CONFIRMATION, DEFAULT_SETTING_ROBOT_CONFIRMATION); } // Answer if (DBGetContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_ROBOT_ANSWER, &dbv) == 0) { SetDlgItemText(hwndDlg, IDC_EDITBOX_ANSWER, dbv.ptszVal); DBFreeVariant(&dbv); } else { WCHAR szRnd[RANDOM_ANSWER_LENGTH+1]; GetRandomString(szRnd, ARRAYSIZE(szRnd)); DBWriteContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_ROBOT_ANSWER, szRnd); SetDlgItemText(hwndDlg, IDC_EDITBOX_ANSWER, szRnd); } } // Show/Hide Variables Plugin help button (Question) MakeVariablesHelpButton(hwndDlg, IDC_BUTTON_INSTRUCTION_VARIABLES); // Show/Hide Variables Plugin help button (Confirmation) if (!MakeVariablesHelpButton(hwndDlg, IDC_BUTTON_CONFIRMATION_VARIABLES)) { RECT rc; if (GetWindowRect(GetDlgItem(hwndDlg, IDC_TEXT_VARS), &rc)) SetWindowPos(GetDlgItem(hwndDlg, IDC_TEXT_VARS), NULL, 0, 0, (rc.right-rc.left)+25, (rc.bottom-rc.top), SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW); } // Restore dlg position (at the end, so the dialog does not get shown early) Utils_RestoreWindowPositionNoSize(hwndDlg, NULL, DB_MODULE_NAME, DB_SETTING_ROBOT_DIALOGPOSITION); // Make sure the dialog is not moved out of sight SendMessage(hwndDlg, DM_REPOSITION, 0, 0); // SetFocus (SetFocus() is not allowed in Dialogs) SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDOK), (LPARAM)TRUE); return FALSE; } case WM_DESTROY: { // Save dlg position Utils_SaveWindowPosition(hwndDlg, NULL, DB_MODULE_NAME, DB_SETTING_ROBOT_DIALOGPOSITION); // Free font DeleteObject((HFONT)SendDlgItemMessage(hwndDlg, IDC_GROUP_MESSAGETEXTS, WM_GETFONT, 0, 0)); // Destroy help icons DestroyIcon((HICON)SendDlgItemMessage(hwndDlg, IDC_BUTTON_INSTRUCTION_VARIABLES, BM_GETIMAGE, (WPARAM)IMAGE_ICON, 0)); DestroyIcon((HICON)SendDlgItemMessage(hwndDlg, IDC_BUTTON_CONFIRMATION_VARIABLES, BM_GETIMAGE, (WPARAM)IMAGE_ICON, 0)); hwndRobotFilter = NULL; return TRUE; } case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_BUTTON_INSTRUCTION_VARIABLES: { // SetFocus (SetFocus() is not allowed in Dialogs) SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDC_EDITBOX_INSTRUCTION), (LPARAM)TRUE); CallService(MS_VARS_SHOWHELP, (WPARAM)GetDlgItem(hwndDlg, IDC_EDITBOX_INSTRUCTION), (LPARAM)NULL); break; } case IDC_BUTTON_CONFIRMATION_VARIABLES: { // SetFocus (SetFocus() is not allowed in Dialogs) SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDC_EDITBOX_CONFIRMATION), (LPARAM)TRUE); CallService(MS_VARS_SHOWHELP, (WPARAM)GetDlgItem(hwndDlg, IDC_EDITBOX_CONFIRMATION), (LPARAM)NULL); break; } case IDC_BUTTON_ANSWER: { WCHAR szRnd[RANDOM_ANSWER_LENGTH+1]; GetRandomString(szRnd, ARRAYSIZE(szRnd)); SetDlgItemText(hwndDlg, IDC_EDITBOX_ANSWER, szRnd); break; } case IDOK: { EnableDlgItem(hwndDlg, IDOK, FALSE); // Save changes DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ROBOT_ADDTOHISTORY, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_ADDTOHISTORY) == BST_CHECKED)); DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ROBOT_HIDEUSERS, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_HIDE) == BST_CHECKED)); // Save texts { int iTextLen; WCHAR* pszText; // Instruction iTextLen = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_EDITBOX_INSTRUCTION)); pszText = (WCHAR*)mir_alloc((iTextLen+1)*sizeof(WCHAR)); if (pszText) { if (GetWindowText(GetDlgItem(hwndDlg, IDC_EDITBOX_INSTRUCTION), pszText, iTextLen+1) == 0) pszText[0] = _T('\0'); DBWriteContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_ROBOT_INSTRUCTION, (lstrlen(pszText)>0) ? pszText : DEFAULT_SETTING_ROBOT_INSTRUCTION); mir_free(pszText); } // Confirmation iTextLen = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_EDITBOX_CONFIRMATION)); pszText = (WCHAR*)mir_alloc((iTextLen+1)*sizeof(WCHAR)); if (pszText) { if (GetWindowText(GetDlgItem(hwndDlg, IDC_EDITBOX_CONFIRMATION), pszText, iTextLen+1) == 0) pszText[0] = _T('\0'); DBWriteContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_ROBOT_CONFIRMATION, (lstrlen(pszText)>0) ? pszText : DEFAULT_SETTING_ROBOT_CONFIRMATION); mir_free(pszText); } // Correct Answer iTextLen = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_EDITBOX_ANSWER)); pszText = (WCHAR*)mir_alloc((iTextLen+1)*sizeof(WCHAR)); if (pszText) { if (GetWindowText(GetDlgItem(hwndDlg, IDC_EDITBOX_ANSWER), pszText, iTextLen+1) == 0) pszText[0] = _T('\0'); if (lstrlen(pszText) > 0) { DBWriteContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_ROBOT_ANSWER, pszText); } else { WCHAR szRnd[RANDOM_ANSWER_LENGTH+1]; GetRandomString(szRnd, ARRAYSIZE(szRnd)); DBWriteContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_ROBOT_ANSWER, szRnd); } mir_free(pszText); } } // fall through } case IDCANCEL: // WM_CLOSE is transformed into an IDCANCEL by dialog manager { // Different method of closing the window depending on if the window // was created modal or not if (!GetParent(hwndDlg)) DestroyWindow(hwndDlg); else EndDialog(hwndDlg, LOWORD(wParam)); return TRUE; } } // switch wParam break; } } return FALSE; } // -- Spam Definitions Info static BOOL CALLBACK EnumSpamDefinitions_InsertItem(UINT uSpamDefID, WCHAR* pszFilePath, WCHAR* pszName, SYSTEMTIME* pstDate, WPARAM wParam, LPARAM lParam) { LVITEM lvi; if (!lParam) return FALSE; ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_TEXT|LVIF_PARAM; lvi.pszText = pszName?TranslateTS(pszName):TranslateT("Not Available"); lvi.lParam = (LPARAM)mir_wstrdup(pszFilePath); lvi.iItem = ListView_InsertItem((HWND)wParam, &lvi); if (lvi.iItem >= 0) { // Version if (pstDate) { WCHAR szDate[9]; if (GetDateFormat(GetThreadLocale(), 0, pstDate, _T("yy'.'MM'.'dd"), szDate, ARRAYSIZE(szDate)) != 0) ListView_SetItemText((HWND)wParam, lvi.iItem, 1, szDate); } if (!IsWinVerXPPlus() || !ListView_IsGroupViewEnabled((HWND)wParam)) { ListView_SetItemText((HWND)wParam, lvi.iItem, 2, (WCHAR*)lParam); // Type } else { if (ListView_HasGroup((HWND)wParam, uSpamDefID)) { lvi.mask = LVIF_GROUPID; lvi.iGroupId = uSpamDefID; ListView_SetItem((HWND)wParam, &lvi); // ListView_MoveItemToGroup not implemented in WinSDK } else { LVGROUP lvg; ZeroMemory(&lvg, sizeof(lvg)); lvg.cbSize = sizeof(lvg); lvg.mask = LVGF_HEADER|LVGF_GROUPID; lvg.iGroupId = uSpamDefID; #if defined(UNICODE) lvg.pszHeader = (WCHAR*)lParam; ListView_InsertGroup((HWND)wParam, lvi.iItem, &lvg); #else lvg.pszHeader = mir_utf8encodeW((WCHAR*)lParam); ListView_InsertGroup((HWND)wParam, lvi.iItem, &lvg); if (lvg.pszHeader) mir_free(lvg.pszHeader); #endif } } } return TRUE; } static int ResizeProcSpamDefinitionsInfo(HWND hwndDlg, LPARAM lParam, UTILRESIZECONTROL *urc) { switch(urc->wId) { case IDC_TEXT_DESCRIPTION: return RD_ANCHORY_TOP|RD_ANCHORX_WIDTH; case IDC_TAB_SPAMDEFINITIONS: return RD_ANCHORY_HEIGHT|RD_ANCHORX_WIDTH; case IDC_LISTVIEW_SPAMDEFINITIONS: { POINT pt = {0, 0}; // Keep exactly same position (resized later) GetWindowRect(GetDlgItem(hwndDlg, urc->wId), &urc->rcItem); if (ClientToScreen(hwndDlg, &pt)) OffsetRect(&urc->rcItem, -pt.x, -pt.y); return RD_ANCHORY_CUSTOM|RD_ANCHORX_CUSTOM; } case IDC_URL_GETMORE: return RD_ANCHORY_BOTTOM|RD_ANCHORX_WIDTH; //case IDCANCEL: //case IDC_SCROLLBAR_SIZEGRIP: default: return RD_ANCHORY_BOTTOM|RD_ANCHORX_RIGHT; } } void FixListHeader(HWND hwndListView) { // Resize header (does not fit fully using small border) // at least on WinME RECT rcList, rcHeader; HWND hwndHeader = ListView_GetHeader(hwndListView); if (GetClientRect(hwndListView, &rcList) && GetClientRect(hwndHeader, &rcHeader)) if ((rcHeader.right-rcHeader.left) != (rcList.right-rcList.left)) SetWindowPos(hwndHeader, NULL, 0, 0, rcList.right-rcList.left, rcHeader.bottom-rcHeader.top, SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE); } BOOL CALLBACK DlgProcSpamDefinitionsInfo(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: { hwndSpamDefinitionsInfo = hwndDlg; /* #if defined(UNICODE) // Convert DlgProc to Unicode (IsWindowUnicode returns true after this call -> see docs) SetWindowLongPtrW(hwndDlg, DWLP_DLGPROC, (LONG_PTR)DlgProcSpamDefinitionsInfo); #endif */ // Translate dialog first TranslateDialogDefault(hwndDlg); // Set icon SendMessage(hwndDlg, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)(HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_SPAM_DEFINITIONS), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED)); // Make heading { HFONT hBoldFont; LOGFONT lf; GetObject((HFONT)SendDlgItemMessage(hwndDlg, IDC_TEXT_DESCRIPTION, WM_GETFONT, 0, 0), sizeof(lf), &lf); lf.lfWeight = FW_BOLD; hBoldFont = CreateFontIndirect(&lf); SendDlgItemMessage(hwndDlg, IDC_TEXT_DESCRIPTION, WM_SETFONT, (WPARAM)hBoldFont, 0); } // Init tabs { HWND hwndTab = GetDlgItem(hwndDlg, IDC_TAB_SPAMDEFINITIONS); TCITEM tci; tci.mask = TCIF_TEXT|TCIF_PARAM; tci.pszText = TranslateT("Advertisment Filter"); tci.lParam = SFT_ADVERTISMENT_FILTER; TabCtrl_InsertItem(hwndTab, 0, &tci); tci.pszText = TranslateT("Disliked Messages Filter"); tci.lParam = SFT_DISLIKEDMESSAGES_FILTER; TabCtrl_InsertItem(hwndTab, 1, &tci); } // Init ListView { HWND hwndList = GetDlgItem(hwndDlg, IDC_LISTVIEW_SPAMDEFINITIONS); LVCOLUMN lvc; int iMinSizePacketCol; ListView_SetExtendedListViewStyle(hwndList, LVS_EX_LABELTIP|LVS_EX_FULLROWSELECT); if (IsWinVerXPPlus()) ListView_EnableGroupView(hwndList, TRUE); lvc.mask = LVCF_TEXT; if (IsWinVerXPPlus() && ListView_IsGroupViewEnabled(hwndList)) { // Name lvc.pszText = TranslateT("Packet"); ListView_InsertColumn(hwndList, 0, &lvc); iMinSizePacketCol = 200; // Date lvc.mask |= LVCF_FMT; lvc.pszText = TranslateT("Version"); lvc.fmt = LVCFMT_RIGHT; ListView_InsertColumn(hwndList, 1, &lvc); } else { // Name lvc.pszText = TranslateT("Packet"); ListView_InsertColumn(hwndList, 0, &lvc); iMinSizePacketCol = 120; // Date lvc.mask |= LVCF_FMT; lvc.pszText = TranslateT("Version"); lvc.fmt = LVCFMT_RIGHT; ListView_InsertColumn(hwndList, 1, &lvc); // Type lvc.mask ^= LVCF_FMT; lvc.pszText = TranslateT("Type"); ListView_InsertColumn(hwndList, 2, &lvc); } // Insert info items SendMessage(hwndDlg, SFM_REFRESH_SPAMDEFINITIONS, (WPARAM)TRUE, (LPARAM)lParam); ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE_USEHEADER); if (ListView_GetColumnWidth(hwndList, 0) < iMinSizePacketCol) ListView_SetColumnWidth(hwndList, 0, iMinSizePacketCol); ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE_USEHEADER); if (ListView_GetColumnWidth(hwndList, 1) < 60) ListView_SetColumnWidth(hwndList, 1, 60); // Restore dlg position (at the end, so the dialog does not get shown early) Utils_RestoreWindowPosition(hwndDlg, NULL, DB_MODULE_NAME, DB_SETTING_SPAMDEF_DIALOGPOSITION); // Make sure the dialog is not moved out of sight SendMessage(hwndDlg, DM_REPOSITION, 0, 0); SendMessage(hwndDlg, WM_SIZE, 0, 0); //simulate message // Stretch last column to fit remaining space if (!IsWinVerXPPlus() || !ListView_IsGroupViewEnabled(hwndList)) ListView_SetColumnWidth(hwndList, 2, LVSCW_AUTOSIZE_USEHEADER); else ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE_USEHEADER); FixListHeader(hwndList); } // SetFocus (SetFocus() is not allowed in Dialogs) SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDCANCEL), (LPARAM)TRUE); return FALSE; } case SFM_REFRESH_SPAMDEFINITIONS: { HWND hwndList = GetDlgItem(hwndDlg, IDC_LISTVIEW_SPAMDEFINITIONS); DWORD dwFilterType; int iSelectedIndex = ListView_GetSelectionMark(hwndList); if ((DWORD)lParam == 0) { dwFilterType = (DWORD)GetWindowLongPtr(hwndDlg, DWLP_USER); } else { dwFilterType = (DWORD)lParam; if ((DWORD)SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)dwFilterType) == dwFilterType) if (!(BOOL)wParam) // if not forced refresh return TRUE; } ListView_DeleteAllItems(hwndList); //ListView_RemoveAllGroups(); // not really needed, always the same groups FixListHeader(hwndList); if (InSendMessage()) ReplyMessage(TRUE); // Change tab { HWND hwndTab = GetDlgItem(hwndDlg, IDC_TAB_SPAMDEFINITIONS); int i; TCITEM tci; tci.mask = TCIF_PARAM; for (i=TabCtrl_GetItemCount(hwndTab)-1; i>=0; i--) { if (TabCtrl_GetItem(hwndTab, i, &tci)) if ((DWORD)tci.lParam == dwFilterType) { if (TabCtrl_GetCurSel(hwndTab) != i) TabCtrl_SetCurSel(hwndTab, i); break; } if (i==0) TabCtrl_SetCurSel(hwndTab, -1); } FixListHeader(hwndList); } // Insert info items switch (dwFilterType) { case SFT_ADVERTISMENT_FILTER: { SetWindowText(hwndDlg, TranslateT("Spam Definitions: Advertisment Filter")); EnumSpamDefinitions(SDID_BADWORDS, TRUE, EnumSpamDefinitions_InsertItem, (WPARAM)hwndList, (LPARAM)TranslateT("Default Bad Words")); EnumSpamDefinitions(SDID_SPAMMERS, TRUE, EnumSpamDefinitions_InsertItem, (WPARAM)hwndList, (LPARAM)TranslateT("Known Spammers")); EnumSpamDefinitions(SDID_TEASERTEXTS, TRUE, EnumSpamDefinitions_InsertItem, (WPARAM)hwndList, (LPARAM)TranslateT("Known Teaser Texts")); EnumSpamDefinitions(SDID_URLTLDS, TRUE, EnumSpamDefinitions_InsertItem, (WPARAM)hwndList, (LPARAM)TranslateT("URL Recognition")); EnumSpamDefinitions(SDID_PHONENUMBERS, TRUE, EnumSpamDefinitions_InsertItem, (WPARAM)hwndList, (LPARAM)TranslateT("Phone Number Recognition")); EnumSpamDefinitions(SDID_SPECIALCHARS_REPLACE_TEXT, TRUE, EnumSpamDefinitions_InsertItem, (WPARAM)hwndList, (LPARAM)TranslateT("Different Format Recognition: Text")); EnumSpamDefinitions(SDID_SPECIALCHARS_REPLACE_NUMBERS, TRUE, EnumSpamDefinitions_InsertItem, (WPARAM)hwndList, (LPARAM)TranslateT("Different Format Recognition: Numbers")); EnumSpamDefinitions(SDID_SPECIALCHARS_SEPARATORS, TRUE, EnumSpamDefinitions_InsertItem, (WPARAM)hwndList, (LPARAM)TranslateT("Different Format Recognition: Separators")); break; } case SFT_DISLIKEDMESSAGES_FILTER: { SetWindowText(hwndDlg, TranslateT("Spam Definitions: Disliked Messages Filter")); EnumSpamDefinitions(SDID_HOAXTEXTS, TRUE, EnumSpamDefinitions_InsertItem, (WPARAM)hwndList, (LPARAM)TranslateT("Known Hoax Texts")); break; } } if (iSelectedIndex >= 0) { if (iSelectedIndex >= ListView_GetItemCount(hwndList)) iSelectedIndex = ListView_GetItemCount(hwndList)-1; ListView_SetSelectionMark(hwndList, iSelectedIndex); ListView_EnsureVisible(hwndList, iSelectedIndex, FALSE); } FixListHeader(hwndList); return TRUE; } case SFM_REMOVE_SPAMDEFINITIONFILE: { int iItem = (int)wParam; HWND hwndList = GetDlgItem(hwndDlg, IDC_LISTVIEW_SPAMDEFINITIONS); LVITEM lvi; ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_PARAM; lvi.iItem = iItem; // Get item if (ListView_GetItem(hwndList, &lvi)) { if (lvi.lParam) { SHFILEOPSTRUCT sfo; // Doubly-null terminated pFrom (as required) WCHAR szFrom[MAX_PATH+1]; mir_sntprintf(szFrom, ARRAYSIZE(szFrom)-1, _T("%s"), lvi.lParam); szFrom[lstrlen(szFrom)+1] = _T('\0'); ZeroMemory(&sfo, sizeof(sfo)); sfo.hwnd = hwndDlg; sfo.wFunc = FO_DELETE; sfo.pFrom = szFrom; sfo.fFlags = FOF_SIMPLEPROGRESS|FOF_NO_CONNECTED_ELEMENTS; sfo.lpszProgressTitle = lvi.pszText; // Ask to delete file if (SHFileOperation(&sfo) == 0) if (!sfo.fAnyOperationsAborted) if (ListView_DeleteItem(hwndList, iItem)) { // Select next item if (iItem >= ListView_GetItemCount(hwndList)) iItem--; ListView_SetSelectionMark(hwndList, iItem); } } } return TRUE; } case WM_NOTIFY: { LPNMHDR pnmhdr = (LPNMHDR)lParam; switch (pnmhdr->idFrom) { case IDC_TAB_SPAMDEFINITIONS: { switch (pnmhdr->code) { case TCN_SELCHANGE: { TCITEM tci; tci.mask = TCIF_PARAM; if (TabCtrl_GetItem(pnmhdr->hwndFrom, TabCtrl_GetCurSel(pnmhdr->hwndFrom), &tci)) SendMessage(hwndDlg, SFM_REFRESH_SPAMDEFINITIONS, (WPARAM)FALSE, (LPARAM)tci.lParam); return TRUE; } } break; } case IDC_LISTVIEW_SPAMDEFINITIONS: { switch (pnmhdr->code) { case LVN_DELETEITEM: { LVITEM lvi; lvi.mask = LVIF_PARAM; lvi.iItem = ((LPNMLISTVIEW)lParam)->iItem; // Release lParam memory of removed item if (ListView_GetItem(pnmhdr->hwndFrom, &lvi)) if (lvi.lParam) mir_free((WCHAR*)lvi.lParam); return FALSE; } case LVN_KEYDOWN: { switch (((NMLVKEYDOWN*)lParam)->wVKey) { case VK_DELETE: { PostMessage(hwndDlg, SFM_REMOVE_SPAMDEFINITIONFILE, (WPARAM)ListView_GetSelectionMark(pnmhdr->hwndFrom), 0); // Prevent default processing SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)FALSE); return TRUE; } } break; } case NM_RCLICK: { LPNMLISTVIEW pnmlw = (LPNMLISTVIEW)lParam; HMENU hMenu, hContextMenu; LVITEM lvi; // Click was not on an item if (pnmlw->iItem < 0) break; ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_PARAM; lvi.iItem = pnmlw->iItem; // Get item if (!ListView_GetItem(pnmhdr->hwndFrom, &lvi)) break; if (!lvi.lParam) break; if (!ClientToScreen(pnmhdr->hwndFrom, &(pnmlw->ptAction))) break; // Context menu hMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_CONTEXT)); hContextMenu = GetSubMenu(hMenu, 1); CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM)hContextMenu, 0); switch (TrackPopupMenuEx(hContextMenu, TPM_RETURNCMD|TPM_TOPALIGN|TPM_LEFTALIGN|TPM_RIGHTBUTTON, pnmlw->ptAction.x, pnmlw->ptAction.y, pnmhdr->hwndFrom, NULL)) { case ID_MENU_DELETE: { PostMessage(hwndDlg, SFM_REMOVE_SPAMDEFINITIONFILE, (WPARAM)pnmlw->iItem, 0); break; } } // Destroy context menu if (hMenu) DestroyMenu(hMenu); // Prevent default processing SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)FALSE); return TRUE; } } // switch break; } } // switch break; } case WM_DESTROY: { hwndSpamDefinitionsInfo = NULL; // Free font DeleteObject((HFONT)SendDlgItemMessage(hwndDlg, IDC_TEXT_DESCRIPTION, WM_GETFONT, 0, 0)); // Save dlg position Utils_SaveWindowPosition(hwndDlg, NULL, DB_MODULE_NAME, DB_SETTING_SPAMDEF_DIALOGPOSITION); return TRUE; } case WM_CLOSE: { // Different method of closing the window depending on if the window // was created modal or not if (!GetParent(hwndDlg)) DestroyWindow(hwndDlg); else EndDialog(hwndDlg, IDCANCEL); return TRUE; } case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_URL_GETMORE: { CallService(MS_UTILS_OPENURL, (WPARAM)TRUE, (LPARAM)Translate("http://addons.miranda-im.org/index.php?action=display&id=92")); return TRUE; } case IDOK: case IDCANCEL: // WM_CLOSE is transformed into an IDCANCEL by dialog manager { // Different method of closing the window depending on if the window // was created modal or not if (!GetParent(hwndDlg)) DestroyWindow(hwndDlg); else EndDialog(hwndDlg, LOWORD(wParam)); return TRUE; } } // switch wParam break; } case WM_SIZE: { UTILRESIZEDIALOG urd; ZeroMemory(&urd, sizeof(urd)); urd.cbSize = sizeof(urd); urd.hInstance = hInstance; urd.hwndDlg = hwndDlg; urd.lpTemplate = MAKEINTRESOURCEA(IDD_INFO_SPAMDEFINITIONS); urd.pfnResizer = ResizeProcSpamDefinitionsInfo; CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd); // Resize listview to exactly fit tab control { RECT rcDisplay; POINT pt = {0, 0}; if (GetWindowRect(GetDlgItem(hwndDlg, IDC_TAB_SPAMDEFINITIONS), &rcDisplay)) { TabCtrl_AdjustRect(GetDlgItem(hwndDlg, IDC_TAB_SPAMDEFINITIONS), FALSE, &rcDisplay); if (ClientToScreen(hwndDlg, &pt)) OffsetRect(&rcDisplay, -pt.x, -pt.y); SetWindowPos(GetDlgItem(hwndDlg, IDC_LISTVIEW_SPAMDEFINITIONS), HWND_TOP, rcDisplay.left, rcDisplay.top, rcDisplay.right-rcDisplay.left, rcDisplay.bottom-rcDisplay.top, SWP_NOACTIVATE); } } FixListHeader(GetDlgItem(hwndDlg, IDC_LISTVIEW_SPAMDEFINITIONS)); return TRUE; } case WM_GETMINMAXINFO: { ((LPMINMAXINFO)lParam)->ptMinTrackSize.x = 340; ((LPMINMAXINFO)lParam)->ptMinTrackSize.y = 150; return TRUE; } } return FALSE; } void Spammers_ResetListOptions(HWND hwndList) { int i; // Same layout as Ignore options SendMessage(hwndList, CLM_SETBKBITMAP, 0, (LPARAM)(HBITMAP)NULL); SendMessage(hwndList, CLM_SETBKCOLOR, GetSysColor(COLOR_WINDOW),0); SendMessage(hwndList, CLM_SETGREYOUTFLAGS, 0, 0); SendMessage(hwndList, CLM_SETLEFTMARGIN, 4, 0); SendMessage(hwndList, CLM_SETINDENT, 10, 0); SendMessage(hwndList, CLM_SETHIDEEMPTYGROUPS, TRUE, 0); SendMessage(hwndList, CLM_SETUSEGROUPS, FALSE, 0); for(i=0;i<=FONTID_MAX;i++) SendMessage(hwndList, CLM_SETTEXTCOLOR, i, GetSysColor(COLOR_WINDOWTEXT)); } int Spammers_GetListIcon(HWND hwndList, HANDLE hItem) { int i; for (i=0; iwId) { case IDC_TEXT_DESCRIPTION: return RD_ANCHORY_TOP|RD_ANCHORX_WIDTH; case IDC_CLIST: return RD_ANCHORY_HEIGHT|RD_ANCHORX_WIDTH; case IDC_GROUP: case IDC_CHECKBOX_GROUP: case IDC_CHECKBOX_HIDE: case IDC_EDITBOX_GROUP: return RD_ANCHORY_BOTTOM|RD_ANCHORX_WIDTH; case IDC_ICON_SPAM: case IDC_TEXT_SPAM: case IDC_ICON_NORMAL: case IDC_TEXT_NORMAL: case IDC_ICON_DELETE: case IDC_TEXT_DELETE: return RD_ANCHORY_TOP|RD_ANCHORX_RIGHT; //case IDOK: //case IDC_BUTTON_RESET: //case IDC_SCROLLBAR_SIZEGRIP: default: return RD_ANCHORY_BOTTOM|RD_ANCHORX_RIGHT; } } BOOL CALLBACK DlgProcSpammersInfo(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: { HIMAGELIST hIml; HICON hSpam, hNormal, hDelete, hDots; hwndSpammersInfo = hwndDlg; // Translate dialog first TranslateDialogDefault(hwndDlg); // Init set/unset icons (Loading icons out of miranda32.exe) hIml = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), (IsWinVerXPPlus()?ILC_COLOR32:ILC_COLOR16)|ILC_MASK, 4, 0); hSpam = LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(212), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED); ImageList_AddIcon(hIml, hSpam); hDelete = LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(175), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED); ImageList_AddIcon(hIml, hDelete); hNormal = LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(213), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED); ImageList_AddIcon(hIml, hNormal); SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETEXTRAIMAGELIST, 0, (LPARAM)hIml); hDots = LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(211), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED); ImageList_AddIcon(hIml, hDots); Spammers_ResetListOptions(GetDlgItem(hwndDlg, IDC_CLIST)); SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_SETEXTRACOLUMNS, (WPARAM)3, 0); Spammers_SetAllListIcons(GetDlgItem(hwndDlg, IDC_CLIST), 0, TRUE, TRUE); SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_ICON_SPAM), GWLP_USERDATA, (LONG_PTR)0); SendDlgItemMessage(hwndDlg, IDC_ICON_SPAM, STM_SETICON, (WPARAM)hSpam, 0); SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_ICON_DELETE), GWLP_USERDATA, (LONG_PTR)1); SendDlgItemMessage(hwndDlg, IDC_ICON_DELETE, STM_SETICON, (WPARAM)hDelete, 0); SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_ICON_NORMAL), GWLP_USERDATA, (LONG_PTR)2); SendDlgItemMessage(hwndDlg, IDC_ICON_NORMAL, STM_SETICON, (WPARAM)hNormal, 0); // New window icon SendMessage(hwndDlg, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)hSpam); // Make top text { HFONT hBoldFont; LOGFONT lf; GetObject((HFONT)SendDlgItemMessage(hwndDlg, IDC_TEXT_DESCRIPTION, WM_GETFONT, 0, 0), sizeof(lf), &lf); lf.lfWeight = FW_BOLD; hBoldFont = CreateFontIndirect(&lf); SendDlgItemMessage(hwndDlg, IDC_TEXT_DESCRIPTION, WM_SETFONT, (WPARAM)hBoldFont, 0); } // Spammers group { DBVARIANT dbv; if (DBGetContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_MOVETOGROUPNAME, &dbv) == 0) { SetDlgItemText(hwndDlg, IDC_EDITBOX_GROUP, dbv.ptszVal); DBFreeVariant(&dbv); } else { SetDlgItemText(hwndDlg, IDC_EDITBOX_GROUP, DEFAULT_SETTING_MOVETOGROUPNAME); } CheckDlgButton(hwndDlg, IDC_CHECKBOX_GROUP, (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_MOVETOGROUP, (BYTE)DEFAULT_SETTING_MOVETOGROUP) ? BST_CHECKED : BST_UNCHECKED)); CheckDlgButton(hwndDlg, IDC_CHECKBOX_HIDE, (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_HIDEFROMCLIST, (BYTE)DEFAULT_SETTING_HIDEFROMCLIST) ? BST_CHECKED : BST_UNCHECKED)); } SendMessage(hwndDlg, SFM_ENABLE_SUBCTRLS, 0, 0); // Restore dlg position (at the end, so the dialog does not get shown early) Utils_RestoreWindowPosition(hwndDlg, NULL, DB_MODULE_NAME, DB_SETTING_SPAMMERS_DIALOGPOSITION); // Make sure the dialog is not moved out of sight SendMessage(hwndDlg, DM_REPOSITION, 0, 0); SendMessage(hwndDlg, WM_SIZE, 0, 0); //simulate message // SetFocus (SetFocus() is not allowed in Dialogs) SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDOK), (LPARAM)TRUE); return FALSE; } case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR)lParam; switch (pnmh->idFrom) { case IDC_CLIST: { switch (pnmh->code) { case CLN_NEWCONTACT: case CLN_CONTACTMOVED: case CLN_LISTREBUILT: Spammers_SetAllListIcons(pnmh->hwndFrom, 0, FALSE, TRUE); return TRUE; case CLN_OPTIONSCHANGED: Spammers_ResetListOptions(pnmh->hwndFrom); return TRUE; case NM_CLICK: { HANDLE hItem; NMCLISTCONTROL* nm = (NMCLISTCONTROL*)lParam; DWORD hitFlags; if (nm->iColumn < 0) break; hItem = (HANDLE)SendMessage(pnmh->hwndFrom, CLM_HITTEST, (WPARAM)&hitFlags, MAKELPARAM(nm->pt.x, nm->pt.y)); if (hItem == NULL) break; if (!(hitFlags&CLCHT_ONITEMEXTRA)) break; Spammers_SetListIcon(pnmh->hwndFrom, hItem, nm->iColumn); return TRUE; } } break; } } break; } case SFM_REFRESH_SPAMMERS: { SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_AUTOREBUILD, 0, 0); return TRUE; } case SFM_ENABLE_SUBCTRLS: { BOOL bStatus = (IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_GROUP) == BST_CHECKED); EnableDlgItem(hwndDlg, IDC_EDITBOX_GROUP, bStatus); return TRUE; } case WM_CLOSE: { // Different method of closing the window depending on if the window // was created modal or not if (!GetParent(hwndDlg)) DestroyWindow(hwndDlg); else EndDialog(hwndDlg, IDCANCEL); return TRUE; } case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_ICON_SPAM: case IDC_ICON_NORMAL: case IDC_ICON_DELETE: { if (HIWORD(wParam) == STN_CLICKED) { Spammers_SetAllListIcons(GetDlgItem(hwndDlg, IDC_CLIST), (int)GetWindowLongPtr(GetDlgItem(hwndDlg, LOWORD(wParam)), GWLP_USERDATA), TRUE, FALSE); return TRUE; } break; } case IDC_CHECKBOX_GROUP: { SendMessage(hwndDlg, SFM_ENABLE_SUBCTRLS, 0, 0); return TRUE; } case IDOK: { HANDLE hContact, hItem; HWND hwndList = GetDlgItem(hwndDlg, IDC_CLIST); EnableDlgItem(hwndDlg, IDOK, FALSE); // Spammers group { HWND hwndEdit = GetDlgItem(hwndDlg, IDC_EDITBOX_GROUP); int iTextLen = GetWindowTextLength(hwndEdit); WCHAR* pszText = (WCHAR*)mir_alloc((iTextLen+1)*sizeof(WCHAR)); BOOL bUseGroup, bGroupCreated; DBVARIANT dbv; // Get entered text if (pszText) { if (GetWindowText(hwndEdit, pszText, iTextLen+1) == 0) pszText[0] = _T('\0'); // Save text if (lstrlen(pszText) > 0) { DBWriteContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_MOVETOGROUPNAME, pszText); bUseGroup = (IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_GROUP) == BST_CHECKED); } else { DBWriteContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_MOVETOGROUPNAME, DEFAULT_SETTING_MOVETOGROUPNAME); bUseGroup = FALSE; } DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_MOVETOGROUP, (BYTE)bUseGroup); } else { bUseGroup = FALSE; } DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_HIDEFROMCLIST, (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CHECKBOX_HIDE) == BST_CHECKED)); // Remove previous group (if changed) if (DBGetContactSettingTString(NULL, DB_MODULE_NAME, DB_SETTING_MOVETOGROUPNAME, &dbv) == 0) { // Show remove group UI if (StrCmp(dbv.ptszVal, pszText) != 0) RemoveContactListGroup(dbv.ptszVal); DBFreeVariant(&dbv); } // Move all spammers to this group bGroupCreated = FALSE; for (hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); hContact; hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0)) { hItem = (HANDLE)SendMessage(hwndList, CLM_FINDCONTACT, (WPARAM)hContact, 0); if (!hItem) continue; switch (Spammers_GetListIcon(hwndList, hItem)) { case 1: // delete { int status; char* pszProto; // Check if protocol uses server side lists pszProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); if (pszProto) if ((DWORD)CallProtoService(pszProto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_SERVERCLIST) { status = CallProtoService(pszProto, PS_GETSTATUS, 0, 0); if (status == ID_STATUS_OFFLINE || (status >= ID_STATUS_CONNECTING && status < ID_STATUS_CONNECTING + MAX_CONNECT_RETRIES)) { DBWriteContactSettingByte(hContact, "CList", "Delete", 1); break; } } CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0); break; } case 2: // normal DBDeleteContactSetting(hContact, "CList", "Delete"); CallService(MS_SPAMFILTER_CONTACT_UNSETSPAMMER, (WPARAM)hContact, 0); break; case 0: // spammer if (bUseGroup && !bGroupCreated) { CreateContactListGroup(pszText); bGroupCreated = TRUE; } if (bUseGroup) { if (DBGetContactSettingTString(hContact, "CList", "Group", &dbv) == 0) { if (StrCmp(dbv.ptszVal, pszText) != 0) DBWriteContactSettingTString(hContact, "CList", "Group", pszText); DBFreeVariant(&dbv); } } else { DBDeleteContactSetting(hContact, "CList", "Group"); } DBDeleteContactSetting(hContact, "CList", "Delete"); break; } } // Display remove group window //if (!bUseGroup || !bGroupCreated) // RemoveContactListGroup(pszText); if (pszText) mir_free(pszText); } // fall through } case IDCANCEL: // WM_CLOSE is transformed into an IDCANCEL by dialog manager { // Different method of closing the window depending on if the window // was created modal or not if (!GetParent(hwndDlg)) DestroyWindow(hwndDlg); else EndDialog(hwndDlg, LOWORD(wParam)); return TRUE; } } break; } case WM_DESTROY: { hwndSpammersInfo = NULL; ImageList_Destroy((HIMAGELIST)SendDlgItemMessage(hwndDlg, IDC_CLIST, CLM_GETEXTRAIMAGELIST, 0, 0)); // Free font DeleteObject((HFONT)SendDlgItemMessage(hwndDlg, IDC_TEXT_DESCRIPTION, WM_GETFONT, 0, 0)); // Save dlg position Utils_SaveWindowPosition(hwndDlg, NULL, DB_MODULE_NAME, DB_SETTING_SPAMMERS_DIALOGPOSITION); return TRUE; } case WM_SIZE: { UTILRESIZEDIALOG urd; ZeroMemory(&urd, sizeof(urd)); urd.cbSize = sizeof(urd); urd.hInstance = hInstance; urd.hwndDlg = hwndDlg; urd.lpTemplate = MAKEINTRESOURCEA(IDD_INFO_SPAMMERS); urd.pfnResizer = ResizeProcSpammersInfo; CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd); return TRUE; } case WM_GETMINMAXINFO: { ((LPMINMAXINFO)lParam)->ptMinTrackSize.x = 370; ((LPMINMAXINFO)lParam)->ptMinTrackSize.y = 220; return TRUE; } } return FALSE; } // -- ListBox helper functions LRESULT CALLBACK WordsListBoxSubclassProc(HWND hwndListBox, UINT uMsg, WPARAM wParam, LPARAM lParam) { int iButtonAdd; int iButtonDelete; // Get associated list box control id switch (GetDlgCtrlID(hwndListBox)) { case IDC_LISTBOX_CUSTOMIZEDBADWORDS: { iButtonAdd = IDC_BUTTON_ADDBADWORD; iButtonDelete = IDC_BUTTON_DELETEBADWORD; break; } case IDC_LISTBOX_CUSTOMIZEDGOODWORDS: { iButtonAdd = IDC_BUTTON_ADDGOODWORD; iButtonDelete = IDC_BUTTON_DELETEGOODWORD; break; } case IDC_LISTBOX_CUSTOMIZEDWORDS: { iButtonAdd = IDC_BUTTON_ADDWORD; iButtonDelete = IDC_BUTTON_DELETEWORD; break; } default: { iButtonAdd = -1; iButtonDelete = -1; break; } } switch (uMsg) { case LB_INSERTSTRING: case LB_ADDSTRING: { // Set horizontal extent int iHorExt; if (!lParam) break; iHorExt = GetCtrlTextExtent(hwndListBox, (WCHAR*)lParam, TRUE); if (iHorExt > SendMessage(hwndListBox, LB_GETHORIZONTALEXTENT, 0, 0)) PostMessage(hwndListBox, LB_SETHORIZONTALEXTENT, (LPARAM)iHorExt, 0); break; } case LB_DELETESTRING: { // Set horizontal extent int i; int iLen, iHorExt = 0; int iItemCount = (int)SendMessage(hwndListBox, LB_GETCOUNT, 0, 0); WCHAR* pszItemText; for (i=0; i (rc.right-rc.left)); else bShowHScroll = TRUE; // Show/Hide horizontal scrollbars; DISABLENOSCROLL does not work correctly ShowScrollBar(hwndListBox, SB_HORZ, bShowHScroll); // Scroll to left if scrollbar hidden if (!bShowHScroll) PostMessage(hwndListBox, WM_HSCROLL, SB_LEFT, 0); break; } case WM_CONTEXTMENU: { HMENU hMenu, hContextMenu; int iHoveredItem; POINT pt; POINTSTOPOINT(pt, MAKEPOINTS(lParam)); // Menu started by keyboard shortcut if ((pt.x == -1) && (pt.y == -1)) { RECT rc; iHoveredItem = SendMessage(hwndListBox, LB_GETCURSEL, 0, 0); // Get item pos if (SendMessage(hwndListBox, LB_GETITEMRECT, (WPARAM)iHoveredItem, (LPARAM)&rc) != LB_ERR) if (!GetWindowRect(hwndListBox, &rc)) rc.left = rc.top = rc.right = rc.bottom = 0; // Position it in the middle of the rect pt.x = rc.left + (int)((rc.right-rc.left)/2); pt.y = rc.top + (int)((rc.bottom-rc.top)/2); } else { // LBItemFromPt returns an item if no item is in list if (SendMessage(hwndListBox, LB_GETCOUNT, 0, 0) == 0) iHoveredItem = LB_ERR; else iHoveredItem = LBItemFromPt(hwndListBox, pt, FALSE); // Select list box item if (iHoveredItem >= 0) SendMessage(hwndListBox, LB_SETCURSEL, iHoveredItem, 0); } // Context menu hMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_CONTEXT)); hContextMenu = GetSubMenu(hMenu, 0); CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM)hContextMenu, 0); // If user did not click on a list item if (iHoveredItem < 0) RemoveMenu(hContextMenu, ID_MENU_DELETE, MF_BYCOMMAND); switch (TrackPopupMenuEx(hContextMenu, TPM_RETURNCMD|TPM_TOPALIGN|TPM_LEFTALIGN|TPM_RIGHTBUTTON, pt.x, pt.y, hwndListBox, NULL)) { case ID_MENU_DELETE: { // Simulate 'Delete' button if (iButtonDelete >= 0) SendMessage(GetParent(hwndListBox), WM_COMMAND, MAKEWPARAM(iButtonDelete, BN_CLICKED), (LPARAM)GetDlgItem(GetParent(hwndListBox), iButtonDelete)); break; } case ID_MENU_ADD: { // Simulate 'Add' button if (iButtonAdd >= 0) SendMessage(GetParent(hwndListBox), WM_COMMAND, MAKEWPARAM(iButtonAdd, BN_CLICKED), (LPARAM)GetDlgItem(GetParent(hwndListBox), iButtonAdd)); break; } } // Destroy context menu if (hMenu) DestroyMenu(hMenu); return 0; } case WM_KEYDOWN: { int iSelectedItem = SendMessage(hwndListBox, LB_GETCURSEL, 0, 0); if (iSelectedItem >= 0) { switch (wParam) { case VK_BACK: case VK_SUBTRACT: case VK_DELETE: { // Simulate 'Delete' button if (iButtonDelete >= 0) SendMessage(GetParent(hwndListBox), WM_COMMAND, MAKEWPARAM(iButtonDelete, BN_CLICKED), (LPARAM)GetDlgItem(GetParent(hwndListBox), iButtonDelete)); return TRUE; } case VK_SPACE: case VK_ADD: case VK_INSERT: { // Simulate 'Add' button if (iButtonAdd >= 0) SendMessage(GetParent(hwndListBox), WM_COMMAND, MAKEWPARAM(iButtonAdd, BN_CLICKED), (LPARAM)GetDlgItem(GetParent(hwndListBox), iButtonAdd)); return TRUE; } //case VK_PRIOR: case VK_UP: { // Select one entry up if not first entry if (iSelectedItem > 0) SendMessage(hwndListBox, LB_SETCURSEL, (WPARAM)iSelectedItem-1, 0); return TRUE; } //case VK_NEXT: case VK_DOWN: { // Select one entry down SendMessage(hwndListBox, LB_SETCURSEL, (WPARAM)iSelectedItem+1, 0); return TRUE; } } // switch wParam } return FALSE; } case WM_GETDLGCODE: { return DLGC_WANTALLKEYS; } } //switch uMsg return CallWindowProc((WNDPROC)GetWindowLongPtr(hwndListBox, GWLP_USERDATA), hwndListBox, uMsg, wParam, lParam); } BOOL CALLBACK DlgProcWordsListBoxAddItem(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: { // Get passed data struct WORDSLISTBOXADDITEMPARAMS* pwlbaip = (struct WORDSLISTBOXADDITEMPARAMS*)lParam; SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pwlbaip); // Translate dialog TranslateDialogDefault(hwndDlg); // Set text SetWindowText(hwndDlg, pwlbaip->pszTitle); // Make button and caption use message box font { NONCLIENTMETRICS ncm; HFONT hBoldFont; ZeroMemory(&ncm, sizeof(ncm)); ncm.cbSize = sizeof(ncm); if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0)) { hBoldFont = CreateFontIndirect(&ncm.lfMessageFont); SendDlgItemMessage(hwndDlg, IDC_TEXT_DESCRIPTION, WM_SETFONT, (WPARAM)hBoldFont, 0); //SendDlgItemMessage(hwndDlg, IDOK, WM_SETFONT, (WPARAM)hBoldFont, 0); //SendDlgItemMessage(hwndDlg, IDCANCEL, WM_SETFONT, (WPARAM)hBoldFont, 0); SendDlgItemMessage(hwndDlg, IDC_TEXT_QUICKHELP, WM_SETFONT, (WPARAM)hBoldFont, 0); SendDlgItemMessage(hwndDlg, IDC_TEXT_HELPNESTED, WM_SETFONT, (WPARAM)hBoldFont, 0); } } // Show/Hide RegExp hint and help // More info about Regular Expressions: http://perldoc.perl.org/perlrequick.html { // Set icon and resize button SetWindowPos(GetDlgItem(hwndDlg, IDC_BUTTON_REGEXP), NULL, 0, 0, 20, 20, SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW); SendDlgItemMessage(hwndDlg, IDC_BUTTON_REGEXP, BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)LoadSystemIcon(IDB_STD_SMALL_COLOR, STD_HELP)); PostMessage(GetDlgItem(hwndDlg, IDC_BUTTON_REGEXP), BUTTONADDTOOLTIP, (WPARAM)Translate("&How to use Regular Expressions"), 0); SendMessage(GetDlgItem(hwndDlg, IDC_BUTTON_REGEXP), BUTTONSETASFLATBTN, 0, 0); SendMessage(GetDlgItem(hwndDlg, IDC_BUTTON_REGEXP), BUTTONSETASPUSHBTN, 0, 0); // Do not show hint/help if RegExp DLL not available if (!RegExpEnabled()) { RECT rcEdit, rcBtn; SetDlgItemText(hwndDlg, IDC_TEXT_REGEXP, TranslateT("(Regular Expressions disabled)")); ShowDlgItem(hwndDlg, IDC_BUTTON_REGEXP, FALSE); if (GetWindowRect(GetDlgItem(hwndDlg, IDC_EDITBOX_NEWITEM), &rcEdit)) if (GetWindowRect(GetDlgItem(hwndDlg, IDC_BUTTON_REGEXP), &rcBtn)) SetWindowPos(GetDlgItem(hwndDlg, IDC_EDITBOX_NEWITEM), NULL, 0, 0, (rcBtn.right-rcEdit.left), (rcEdit.bottom-rcEdit.top), SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW); } } // Position/Resize window { RECT rcWin, rcSep; int iHeight, iWidth; // Get sizes if ( GetWindowRect(hwndDlg, &rcWin) && GetWindowRect(GetDlgItem(hwndDlg, IDC_RECT_SEPARATOR), &rcSep) ) { iHeight = rcSep.top-rcWin.top + (int)((rcSep.bottom-rcSep.top)/2); iWidth = rcWin.right-rcWin.left; // Remember normal height SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_RECT_SEPARATOR), GWLP_USERDATA, (LONG_PTR)(rcWin.bottom-rcWin.top)); // Hide separator ShowDlgItem(hwndDlg, IDC_RECT_SEPARATOR, FALSE); } else { iHeight = 0; iWidth = 0; } // Position the window (and hide RegExp help initially) SetWindowPos(hwndDlg, NULL, pwlbaip->ptPos.x, pwlbaip->ptPos.y, iWidth, iHeight, (((iHeight==0)||(iWidth==0))?SWP_NOSIZE:0)|SWP_NOZORDER|SWP_NOOWNERZORDER|SWP_NOACTIVATE|SWP_NOREDRAW); // Make sure the dialog is not moved out of sight SendMessage(hwndDlg, DM_REPOSITION, 0, 0); } // SetFocus (SetFocus() is not allowed in Dialogs) SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDC_EDITBOX_NEWITEM), (LPARAM)TRUE); return FALSE; } case WM_SETTINGCHANGE: { NONCLIENTMETRICS ncm; HFONT hBoldFont; // Free old message box font DeleteObject((HFONT)SendDlgItemMessage(hwndDlg, IDC_TEXT_DESCRIPTION, WM_GETFONT, 0, 0)); // Update message box font ZeroMemory(&ncm, sizeof(ncm)); ncm.cbSize = sizeof(ncm); if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0)) { hBoldFont = CreateFontIndirect(&ncm.lfMessageFont); SendDlgItemMessage(hwndDlg, IDC_TEXT_DESCRIPTION, WM_SETFONT, (WPARAM)hBoldFont, 0); //SendDlgItemMessage(hwndDlg, IDOK, WM_SETFONT, (WPARAM)hBoldFont, 0); //SendDlgItemMessage(hwndDlg, IDCANCEL, WM_SETFONT, (WPARAM)hBoldFont, 0); } return TRUE; } case WM_DESTROY: { // Destroy help icon DestroyIcon((HICON)SendDlgItemMessage(hwndDlg, IDC_BUTTON_REGEXP, BM_GETIMAGE, (WPARAM)IMAGE_ICON, 0)); // Free message box font DeleteObject((HFONT)SendDlgItemMessage(hwndDlg, IDC_TEXT_DESCRIPTION, WM_GETFONT, 0, 0)); return TRUE; } case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_BUTTON_REGEXP: { // Show/Hide RegExp help part RECT rcWin, rcSep; int iHeight, iWidth; if (GetWindowRect(hwndDlg, &rcWin)) { iWidth = rcWin.right-rcWin.left; // Hide/Show help if (!IsDlgButtonChecked(hwndDlg, IDC_BUTTON_REGEXP)) { if (GetWindowRect(GetDlgItem(hwndDlg, IDC_RECT_SEPARATOR), &rcSep)) { iHeight = rcSep.top-rcWin.top + (int)((rcSep.bottom-rcSep.top)/2); // Position the window ShowDlgItem(hwndDlg, IDC_RECT_SEPARATOR, FALSE); SetWindowPos(hwndDlg, NULL, 0, 0, iWidth, iHeight, SWP_NOMOVE|SWP_NOZORDER|SWP_NOOWNERZORDER|SWP_NOACTIVATE); } } else { iHeight = (int)GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_RECT_SEPARATOR), GWLP_USERDATA); // Position the window SetWindowPos(hwndDlg, NULL, 0, 0, iWidth, iHeight, SWP_NOMOVE|SWP_NOZORDER|SWP_NOOWNERZORDER|SWP_NOACTIVATE); ShowDlgItem(hwndDlg, IDC_RECT_SEPARATOR, TRUE); } } // Make sure the dialog is not enlarged out of sight SendMessage(hwndDlg, DM_REPOSITION, 0, 0); return TRUE; } case IDOK: { struct WORDSLISTBOXADDITEMPARAMS* pwlbaip; HWND hwndEdit; int iNewItemSize; pwlbaip = (struct WORDSLISTBOXADDITEMPARAMS*)GetWindowLongPtr(hwndDlg, DWLP_USER); // Get entered text if (pwlbaip) { hwndEdit = GetDlgItem(hwndDlg, IDC_EDITBOX_NEWITEM); iNewItemSize = GetWindowTextLength(hwndEdit)+1; pwlbaip->pszNewItem = (WCHAR*)mir_alloc((iNewItemSize)*sizeof(WCHAR)); if (pwlbaip->pszNewItem) if (GetWindowText(hwndEdit, pwlbaip->pszNewItem, iNewItemSize) == 0) // GetWindowText takes the size not the len of the string *pwlbaip->pszNewItem = _T('\0'); } // fall through } case IDCANCEL: // WM_CLOSE is transformed into an IDCANCEL by dialog manager { EndDialog(hwndDlg, LOWORD(wParam)); return TRUE; } case IDC_EDITBOX_NEWITEM: { switch (HIWORD(wParam)) { case EN_CHANGE: { HWND hwndEdit = GetDlgItem(hwndDlg, IDC_EDITBOX_NEWITEM); int iNewItemLen = GetWindowTextLength(hwndEdit); WCHAR* pszNewItem = (WCHAR*)mir_alloc((iNewItemLen+1)*sizeof(WCHAR)); if (pszNewItem) { // Get entered text if (GetWindowText(hwndEdit, pszNewItem, iNewItemLen+1) == 0) pszNewItem[0] = _T('\0'); // Check if OK button can be released EnableDlgItem(hwndDlg, IDOK, (lstrlen(pszNewItem) > 0)); mir_free(pszNewItem); } return TRUE; } } // switch HIWORD(wParam) break; } } // switch wParam break; } } return FALSE; } void WordsListBoxInit(HWND hwndDlg, int iIDListBox, int iIDAddButton, int iIDDeleteButton, STRINGLIST* pslContents, const char* pszAddTooltip, const char* pszDeleteTooltip) { HWND hwndListBox = GetDlgItem(hwndDlg, iIDListBox); HWND hwndAddButton = GetDlgItem(hwndDlg, iIDAddButton); HWND hwndDeleteButton = GetDlgItem(hwndDlg, iIDDeleteButton); HICON hAddIcon = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_ADD_BUTTON), IMAGE_ICON, 0, 0, LR_SHARED); HICON hDeleteIcon = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_DELETE_BUTTON), IMAGE_ICON, 0, 0, LR_SHARED); // Subclass to get key strokes/contextmenu/horizontal extent SetWindowLongPtr(hwndListBox, GWLP_USERDATA, SetWindowLongPtr(hwndListBox, GWLP_WNDPROC, (LONG_PTR)WordsListBoxSubclassProc)); // Init drag-drop support MakeDragList(hwndListBox); // Insert contents SLAssignToListBoxCtrl(pslContents, hwndListBox); // Select first item SendMessage(hwndListBox, LB_SETCURSEL, (WPARAM)0, 0); // Init add button SetWindowPos(hwndAddButton, NULL, 0, 0, 20, 20, SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW); SendMessage(hwndAddButton, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hAddIcon); PostMessage(hwndAddButton, BUTTONADDTOOLTIP, (WPARAM)pszAddTooltip, 0); SendMessage(hwndAddButton, BUTTONSETASFLATBTN, 0, 0); // Init delete button SetWindowPos(hwndDeleteButton, NULL, 0, 0, 20, 20, SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW); SendMessage(hwndDeleteButton, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hDeleteIcon); PostMessage(hwndDeleteButton, BUTTONADDTOOLTIP, (WPARAM)pszDeleteTooltip, 0); SendMessage(hwndDeleteButton, BUTTONSETASFLATBTN, 0, 0); } BOOL WordsListBoxDragDrop(HWND hwndDlg, int iIDListBox, UINT uMsg, LPARAM lParam, BOOL bAllowCopy) { // This function needs to be called in the default handler of the dialog if (uMsg == RegisterWindowMessage(DRAGLISTMSGSTRING)) { DRAGLISTINFO* pdli = (DRAGLISTINFO*)lParam; if (GetDlgItem(hwndDlg, iIDListBox) == pdli->hWnd) { int iHoveredItem = LBItemFromPt(pdli->hWnd, pdli->ptCursor, (pdli->uNotification==DL_DRAGGING)); switch (pdli->uNotification) { case DL_BEGINDRAG: { // Remember start position SetProp(pdli->hWnd, DRAGLISTMSGSTRING, (HANDLE)iHoveredItem); // Allow/Disallow drag SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)(BOOL)(iHoveredItem >= 0)); return TRUE; } case DL_DRAGGING: { // LBItemFromPt returns an item if no item is in list if (SendMessage(pdli->hWnd, LB_GETCOUNT, 0, 0) <= 1) iHoveredItem = LB_ERR; if (iHoveredItem >= 0) { BOOL bMakeCopy = ((bAllowCopy) && (GetAsyncKeyState(VK_CONTROL) < 0)); // Show insertion mark DrawInsert(hwndDlg, pdli->hWnd, iHoveredItem); SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)(bMakeCopy?DL_COPYCURSOR:DL_MOVECURSOR)); } else { // Cursor moved to impossible position DrawInsert(hwndDlg, pdli->hWnd, LB_ERR); SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)DL_STOPCURSOR); } return TRUE; } case DL_DROPPED: { int iDragItem = (int)GetProp(pdli->hWnd, DRAGLISTMSGSTRING); if ((iHoveredItem >= 0 ) && (iHoveredItem != iDragItem) && (iHoveredItem != iDragItem+1)) { LPARAM lParamItemData; int iLenItem; WCHAR* pszItemText; iLenItem = (int)SendMessage(pdli->hWnd, LB_GETTEXTLEN, (WPARAM)iDragItem, 0); if (iLenItem == LB_ERR) iLenItem = 0; pszItemText = (WCHAR*)mir_alloc((iLenItem+1)*sizeof(WCHAR)); if (pszItemText) { if (SendMessage(pdli->hWnd, LB_GETTEXT, (WPARAM)iDragItem, (LPARAM)pszItemText) != LB_ERR) { lParamItemData = (LPARAM)SendMessage(pdli->hWnd, LB_GETITEMDATA, (WPARAM)iDragItem, 0); // Make copy of item iHoveredItem = (int)SendMessage(pdli->hWnd, LB_INSERTSTRING, (WPARAM)iHoveredItem, (LPARAM)pszItemText); if (iHoveredItem >= 0) { BOOL bMakeCopy = ((bAllowCopy) && (GetAsyncKeyState(VK_CONTROL) < 0)); SendMessage(pdli->hWnd, LB_SETITEMDATA, (WPARAM)iHoveredItem, (LPARAM)lParamItemData); // Delete old item if moving if (!bMakeCopy) { if (iHoveredItem < iDragItem) iDragItem++; SendMessage(pdli->hWnd, LB_DELETESTRING, (WPARAM)iDragItem, 0); } // Set current selection SendMessage(pdli->hWnd, LB_SETCURSEL, (WPARAM)iHoveredItem, 0); } } mir_free(pszItemText); } } // fall trough } case DL_CANCELDRAG: { // Remove insertion mark DrawInsert(hwndDlg, pdli->hWnd, LB_ERR); // Remove buffer data RemoveProp(pdli->hWnd, DRAGLISTMSGSTRING); return TRUE; } } // switch } } return FALSE; } BOOL WordsListBoxAddItem(HWND hwndDlg, int iIDListBox, STRINGLIST* pslOtherContents, const WCHAR* pszMsgTitle, const WCHAR* pszMsgTextInList, const WCHAR* pszMsgTextInOther, int iIDButtonDelete) { HWND hwndListBox = GetDlgItem(hwndDlg, iIDListBox); BOOL bDoAdd; struct WORDSLISTBOXADDITEMPARAMS wlbaip; RECT rc; if (!hwndListBox) return FALSE; if (GetWindowRect(hwndListBox, &rc)) { wlbaip.ptPos.x = rc.left-30; wlbaip.ptPos.y = rc.top-5; } else { wlbaip.ptPos.x = 0; wlbaip.ptPos.y = 0; } wlbaip.pszTitle = (WCHAR*)pszMsgTitle; // Show dialog bDoAdd = (DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_LISTBOX_ADD_ITEM), hwndDlg, DlgProcWordsListBoxAddItem, (LPARAM)&wlbaip) == IDOK); if (bDoAdd) { // Check if regular expression is valid (if any) if (!wlbaip.pszNewItem || !ValidateRegExp(wlbaip.pszNewItem)) { WCHAR* pszBoxTextFmt = TranslateT("The entered phrase \"%s\" consists of a Regular Expression containing a syntax error!\r\n\r\nAdding an malformed Regular Expression will cause the filter\r\nto treat the expression as a normal phrase.\r\n\r\nShall the malformed Regular Expression be added anyway?"); WCHAR* pszBoxText = (WCHAR*)mir_alloc((lstrlen(pszBoxTextFmt)+lstrlen(wlbaip.pszNewItem)+1)*sizeof(WCHAR)); bDoAdd = FALSE; if (pszBoxTextFmt && pszBoxText) { mir_sntprintf(pszBoxText, (lstrlen(pszBoxTextFmt)+lstrlen(wlbaip.pszNewItem)+1), pszBoxTextFmt, wlbaip.pszNewItem); // Show message box that the item is malformed if (!Miranda_Terminated()) bDoAdd = (MessageBoxEx(hwndDlg, pszBoxText, TranslateT("Syntax Error in Regular Expression"), MB_YESNO|MB_ICONEXCLAMATION|MB_DEFBUTTON2, LANGIDFROMLCID(GetThreadLocale())) == IDYES); } if (pszBoxTextFmt) mir_free(pszBoxTextFmt); if (pszBoxText) mir_free(pszBoxText); } else { bDoAdd = TRUE; } if (bDoAdd) { int iIndexIfFound; // Look for same item in list (not case sensitive) iIndexIfFound = SendMessage(hwndListBox, LB_FINDSTRINGEXACT, 0, (LPARAM)wlbaip.pszNewItem); if (iIndexIfFound >= 0) { WCHAR* pszBoxText = (WCHAR*)mir_alloc((lstrlen(pszMsgTextInList)+lstrlen(wlbaip.pszNewItem)+1)*sizeof(WCHAR)); bDoAdd = FALSE; if (pszBoxText) { mir_sntprintf(pszBoxText, (lstrlen(pszMsgTextInList) + lstrlen(wlbaip.pszNewItem) + 1), pszMsgTextInList, wlbaip.pszNewItem); SendMessage(hwndListBox, LB_SETCURSEL, (WPARAM)iIndexIfFound, 0); // Show message box that the item can not be added if (!Miranda_Terminated()) bDoAdd = (MessageBoxEx(hwndDlg, pszBoxText, pszMsgTitle, MB_YESNO|MB_ICONEXCLAMATION|MB_DEFBUTTON2, LANGIDFROMLCID(GetThreadLocale())) == IDYES); mir_free(pszBoxText); } } else if (pslOtherContents && SLIsItem(pslOtherContents, wlbaip.pszNewItem, FALSE) ) { WCHAR* pszBoxText = (WCHAR*)mir_alloc((lstrlen(pszMsgTextInOther)+lstrlen(wlbaip.pszNewItem)+1)*sizeof(WCHAR)); bDoAdd = FALSE; if (pszBoxText) { // Show message box that it is not good to add the item mir_sntprintf(pszBoxText, (lstrlen(pszMsgTextInOther) + lstrlen(wlbaip.pszNewItem) + 1), pszMsgTextInOther, wlbaip.pszNewItem); if (!Miranda_Terminated()) bDoAdd = (MessageBoxEx(hwndDlg, pszBoxText, pszMsgTitle, MB_YESNO|MB_ICONEXCLAMATION|MB_DEFBUTTON2, LANGIDFROMLCID(GetThreadLocale())) == IDYES); mir_free(pszBoxText); } } else { bDoAdd = TRUE; } } // Add the item if everything is OK if (bDoAdd) { int iPos; // Add new item to list iPos = SendMessage(hwndListBox, LB_ADDSTRING, 0, (LPARAM)wlbaip.pszNewItem); if (iPos >= 0) { // Select new entry SendMessage(hwndListBox, LB_SETCURSEL, iPos, 0); // Activate delete button EnableDlgItem(hwndDlg, iIDButtonDelete, TRUE); } else { bDoAdd = FALSE; } } // Free allocated memory mir_free(wlbaip.pszNewItem); } // Set focus on list box SetFocus(hwndListBox); return bDoAdd; } int WordsListBoxDeleteItem(HWND hwndDlg, int iIDListBox, int iIDButtonDelete) { HWND hwndListBox = GetDlgItem(hwndDlg, iIDListBox); int iSelectedItem; int iItemCount; if (!hwndListBox) return LB_ERR; iSelectedItem = SendMessage(hwndListBox, LB_GETCURSEL, 0, 0); if (iSelectedItem >= 0) { // Delete entry and get new list item count iItemCount = SendMessage(hwndListBox, LB_DELETESTRING, (WPARAM)iSelectedItem, 0); // Deactivate delete button? if (iItemCount == 0) EnableDlgItem(hwndDlg, iIDButtonDelete, FALSE); // Select next item for 'fast delete' if (SendMessage(hwndListBox, LB_SETCURSEL, (WPARAM)iSelectedItem, 0) < 0) SendMessage(hwndListBox, LB_SETCURSEL, (WPARAM)((iSelectedItem>0)?(iSelectedItem-1):0), 0); } else { iItemCount = LB_ERR; } // Set focus on list box SetFocus(hwndListBox); return iItemCount; } BOOL ToggleTreeViewItemState(HWND hwndTreeView, HTREEITEM hTreeItem) { UINT uCurrentState; BOOL bChangeAllowed; uCurrentState = TreeView_GetItemState(hwndTreeView, hTreeItem, TVIS_STATEIMAGEMASK); // No toggle if item is section item if (uCurrentState&INDEXTOSTATEIMAGEMASK(0)) // no checkbox { bChangeAllowed = FALSE; // Check if another checkbox is still checked before unchecking this one } else if (uCurrentState&INDEXTOSTATEIMAGEMASK(2)) // checkbox checked { HTREEITEM hItem; HTREEITEM hSectionItem; bChangeAllowed = FALSE; for (hSectionItem=TreeView_GetRoot(hwndTreeView); hSectionItem; hSectionItem=TreeView_GetNextSibling(hwndTreeView, hSectionItem)) { for (hItem=TreeView_GetChild(hwndTreeView, hSectionItem); hItem; hItem=TreeView_GetNextSibling(hwndTreeView, hItem)) { if (hItem == hTreeItem) continue; // Check setting (checkbox checked?) if (TreeView_GetItemState(hwndTreeView, hItem, TVIS_STATEIMAGEMASK)&INDEXTOSTATEIMAGEMASK(2)) { bChangeAllowed = TRUE; break; } } } // System default sound (mistake notify) if (!bChangeAllowed) MessageBeep(MB_OK); } else { bChangeAllowed = TRUE; } if (bChangeAllowed) TreeView_SetItemState(hwndTreeView, hTreeItem, INDEXTOSTATEIMAGEMASK((uCurrentState&INDEXTOSTATEIMAGEMASK(2))?1:2), TVIS_STATEIMAGEMASK); return bChangeAllowed; } MESSAGETYPEDESC* GetDataFromTreeViewItem(HWND hwndTreeView, HTREEITEM hTreeItem) { TVITEM tvi; tvi.hItem = hTreeItem; tvi.mask = TVIF_HANDLE|TVIF_PARAM; if (TreeView_GetItem(hwndTreeView, &tvi)) if (((unsigned int)tvi.lParam >= 0) && ((unsigned int)tvi.lParam < uMsgTypesCount)) return &pamtdMsgTypes[(unsigned int)tvi.lParam]; return NULL; } BOOL MakeVariablesHelpButton(HWND hwndDlg, int iIDButton) { BOOL bReturn; // Set icon and resize button SetWindowPos(GetDlgItem(hwndDlg, iIDButton), NULL, 0, 0, 20, 20, SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW); SendDlgItemMessage(hwndDlg, iIDButton, BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)LoadSystemIcon(IDB_STD_SMALL_COLOR, STD_HELP)); PostMessage(GetDlgItem(hwndDlg, iIDButton), BUTTONADDTOOLTIP, (WPARAM)Translate("Use variables in the message text"), 0); SendMessage(GetDlgItem(hwndDlg, iIDButton), BUTTONSETASFLATBTN, 0, 0); // Do not show help button if variables are not available bReturn = (ServiceExists(MS_VARS_SHOWHELP) && ServiceExists(MS_VARS_FORMATSTRING)); ShowDlgItem(hwndDlg, iIDButton, bReturn); return bReturn; } // ------------------------------ static int OptionsInitialise(WPARAM wParam, LPARAM lParam) { // (Options page max. size: 314, 240) // These controls will be hidden in simple (non-expert) options mode static UINT SpamFilterExpertOnlyControls[] = {IDC_BUTTON_ADVERTISMENTFILTER, IDC_BUTTON_DISLIKEDMESSAGEFILTER, IDC_BUTTON_ROBOTFILTER, IDC_BUTTON_RESETAUTOIGNORE, IDC_GROUP_MESSAGETYPES, IDC_TEXT_MESSAGETYPES, IDC_TREEVIEW_MESSAGETYPES}; OPTIONSDIALOGPAGE odp; INITCOMMONCONTROLSEX icc; // Add Spam Filter option page ZeroMemory(&odp, sizeof(odp)); odp.cbSize = sizeof(odp); odp.hInstance = hInstance; odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS_MAIN); odp.position = 900000001; // 900000000 = Ignore options odp.ptszTitle = TranslateT("Spam Filter"); odp.ptszGroup = TranslateT("Events"); odp.flags = ODPF_BOLDGROUPS|ODPF_UNICODE; odp.pfnDlgProc = DlgProcSpamFilterOpt; //odp.nIDBottomSimpleControl = IDC_GROUP_POPUP; // In simple mode the dlg will be cut off after this control odp.expertOnlyControls = SpamFilterExpertOnlyControls; odp.nExpertOnlyControls = ARRAYSIZE(SpamFilterExpertOnlyControls); // Ensure the needed common controls are loaded ZeroMemory(&icc, sizeof(icc)); icc.dwSize = sizeof(icc); icc.dwICC = ICC_TREEVIEW_CLASSES|ICC_UPDOWN_CLASS; InitCommonControlsEx(&icc); CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&odp); return 0; } static int DbSettingChanged(WPARAM wParam, LPARAM lParam) { DBCONTACTWRITESETTING* pdcws = (DBCONTACTWRITESETTING*)lParam; HANDLE hContact = (HANDLE)wParam; // Ignore Options Extension if ( (hContact == NULL) && (StrCmpA(pdcws->szModule, "Ignore") == 0)) { if ( (( (IsWindow(hwndSpamFilterOpt) ? IsDlgButtonChecked(hwndSpamFilterOpt, IDC_CHECKBOX_ADVERTISMENTFILTER) : FALSE) || DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENTFILTER, (BYTE)DEFAULT_SETTING_ADVERTISMENTFILTER) ) || ( (IsWindow(hwndSpamFilterOpt) ? IsDlgButtonChecked(hwndSpamFilterOpt, IDC_CHECKBOX_ROBOTFILTER) : FALSE) || DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ROBOTFILTER, (BYTE)DEFAULT_SETTING_ROBOTFILTER) )) && (BOOL)CallService(MS_IGNORE_ISIGNORED, (WPARAM)NULL, (LPARAM)IGNOREEVENT_MESSAGE) && (BOOL)CallService(MS_IGNORE_ISIGNORED, (WPARAM)NULL, (LPARAM)IGNOREEVENT_URL) && (BOOL)CallService(MS_IGNORE_ISIGNORED, (WPARAM)NULL, (LPARAM)IGNOREEVENT_FILE) && (BOOL)CallService(MS_IGNORE_ISIGNORED, (WPARAM)NULL, (LPARAM)IGNOREEVENT_AUTHORIZATION) ) { if (!Miranda_Terminated()) { HWND hwndParent = IsWindow(hwndSpamFilterOpt) ? GetParent(hwndSpamFilterOpt) : NULL; if (MessageBoxEx(hwndParent, TranslateT("You chose to ignore all kind of messages from contacts that are not on your contact list although the spam filter is activated.\r\n\r\nShall the spam filter be deactivated?"), TranslateT("Spam Filter"), MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON1|(!hwndParent?(MB_SETFOREGROUND|MB_TASKMODAL):0), LANGIDFROMLCID(GetThreadLocale())) == IDYES) { DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENTFILTER, (BYTE)FALSE); DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ROBOTFILTER, (BYTE)FALSE); if (IsWindow(hwndSpamFilterOpt)) { CheckDlgButton(hwndSpamFilterOpt, IDC_CHECKBOX_ADVERTISMENTFILTER, BST_UNCHECKED); CheckDlgButton(hwndSpamFilterOpt, IDC_CHECKBOX_ROBOTFILTER, BST_UNCHECKED); } } } } } // Watch "Hidden" setting to sync with IsSammer-state (Ignore opts change) /* if (StrCmpA(pdcws->szModule, "CList") == 0) if (StrCmpA(pdcws->szSetting, "Hidden") == 0) if ((pdcws->value.type==DBVT_DELETED) || !pdcws->value.bVal) if ((BOOL)CallService(MS_SPAMFILTER_CONTACT_ISSPAMMER, (WPARAM)hContact, 0)) DBWriteContactSettingByte((HANDLE)wParam, DB_MODULE_NAME, DB_SETTING_ISSPAMMER, (BYTE)FALSE); // no service call here! */ // Cache starting/stopping according to Filter settings (to save a little memory) if ( (hContact == NULL) && (StrCmpA(pdcws->szModule, DB_MODULE_NAME) == 0) && (StrCmpA(pdcws->szSetting, DB_SETTING_ADVERTISMENTFILTER) == 0) ) { BOOL bAdvertismentFilter = (pdcws->value.type==DBVT_BYTE) ? pdcws->value.bVal : DEFAULT_SETTING_ADVERTISMENTFILTER; BOOL bDislikedMessagesFilter = DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGEFILTER, (BYTE)DEFAULT_SETTING_DISLIKEDMESSAGEFILTER); ToggleSpamDefinitionsCache(bAdvertismentFilter || bDislikedMessagesFilter); } if ( (hContact == NULL) && (StrCmpA(pdcws->szModule, DB_MODULE_NAME) == 0) && (StrCmpA(pdcws->szSetting, DB_SETTING_DISLIKEDMESSAGEFILTER) == 0) ) { BOOL bDislikedMessagesFilter = (pdcws->value.type==DBVT_BYTE) ? pdcws->value.bVal : DEFAULT_SETTING_DISLIKEDMESSAGEFILTER; BOOL bAdvertismentFilter = DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENTFILTER, (BYTE)DEFAULT_SETTING_ADVERTISMENTFILTER); ToggleSpamDefinitionsCache(bAdvertismentFilter || bDislikedMessagesFilter); } return 0; } // ------------------------------------ void InitOptions(void) { hHookOptInit = HookEvent(ME_OPT_INITIALISE, OptionsInitialise); hHookDbSettingChangedOpt = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, DbSettingChanged); } void UninitOptions(void) { if (hHookOptInit) UnhookEvent(hHookOptInit); if (hHookDbSettingChangedOpt) UnhookEvent(hHookDbSettingChangedOpt); // Dialogs that are created without parent (non-modal) need to be destroyed if (IsWindow(hwndAdvertismentFilter)) SendMessage(hwndAdvertismentFilter, WM_CLOSE, 0, 0); if (IsWindow(hwndRobotFilter)) SendMessage(hwndRobotFilter, WM_CLOSE, 0, 0); if (IsWindow(hwndDislikedMessagesFilter)) SendMessage(hwndDislikedMessagesFilter, WM_CLOSE, 0, 0); if (IsWindow(hwndSpamDefinitionsInfo)) SendMessage(hwndSpamDefinitionsInfo, WM_CLOSE, 0, 0); if (IsWindow(hwndSpammersInfo)) SendMessage(hwndSpammersInfo, WM_CLOSE, 0, 0); }