// History Linklist Plus // Copyright (C) 2010 Thomas Wendel, gureedo // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include "resource.h" #ifdef _DEBUG #include #endif // Miranda SDK Includes #pragma warning(disable:4996) #pragma warning(disable:4100) #include #include #include #include #include #include #pragma warning(default:4100) #pragma warning(default:4996) #include "linklist_dlg.h" #include "linklist_fct.h" #include "linklist.h" #include "language.h" #define MIID_LINKLIST { 0xc9c94733, 0xa054, 0x42b9, { 0x89, 0xcb, 0xb9, 0x71, 0x27, 0xa7, 0xa3, 0x43 } } // Global variables HINSTANCE hInst; HINSTANCE hRichEdit; PLUGINLINK *pluginLink; HANDLE hWindowList; HCURSOR splitCursor; int hLangpack; PLUGININFOEX pluginInfo = { sizeof(PLUGININFOEX), #ifdef _WIN64 "History Linklist Plus (x64, Unicode)", #else #ifdef _UNICODE "History Linklist Plus (Unicode)", #else "History Linklist Plus", #endif #endif PLUGIN_MAKE_VERSION(0,0,0,2), "Generates a list of extracted URIs from the history", "Thomas Wendel, gureedo", "gureedo@gmail.com", "© 2010-2011 gureedo", "http://www.miranda-im.org", UNICODE_AWARE, //not transient 0, //doesn't replace anything built-in #ifdef _UNICODE { 0xDA0B09F5, 0x9C66, 0x488C, { 0xAE, 0x37, 0x8A, 0x5F, 0x19, 0x1C, 0x90, 0x79 } } // {DA0B09F5-9C66-488C-AE37-8A5F191C9079} #else { 0x06F23FA4, 0xABD4, 0x41CA, { 0xAD, 0xFA, 0x7B, 0xE8, 0x69, 0xC0, 0x63, 0x5A } } // {06F23FA4-ABD4-41CA-ADFA-7BE869C0635A} #endif }; static const MUUID interfaces[] = {MIID_LINKLIST, MIID_LAST}; struct MM_INTERFACE mmi; // Functions __declspec(dllexport) const MUUID * MirandaPluginInterfaces(void) { return interfaces; } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { UNREFERENCED_PARAMETER(lpvReserved); hInst = hinstDLL; // Load Rich Edit control if ( fdwReason == DLL_PROCESS_ATTACH || fdwReason == DLL_THREAD_ATTACH ) { hRichEdit = LoadLibrary(_T("RICHED32.DLL")); if ( !hRichEdit ) { // If Rich Edit DLL load fails, exit MessageBox(NULL, _T("Unable to load the Rich Edit control!"), _T("Error"), MB_OK | MB_ICONEXCLAMATION); return FALSE; } #ifdef DEBUG { int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); flag |= _CRTDBG_LEAK_CHECK_DF|_CRTDBG_CHECK_ALWAYS_DF; _CrtSetDbgFlag(flag); } #endif DisableThreadLibraryCalls(hinstDLL); } if ( fdwReason == DLL_PROCESS_DETACH || fdwReason == DLL_THREAD_DETACH ) { FreeLibrary(hRichEdit); } return TRUE; } int __declspec(dllexport) Load(PLUGINLINK *link) { CLISTMENUITEM linklistmenuitem; WNDCLASS wndclass; pluginLink = link; mir_getLP(&pluginInfo); CreateServiceFunction("Linklist/MenuCommand", LinkList_Main); ZeroMemory(&linklistmenuitem, sizeof(linklistmenuitem)); linklistmenuitem.cbSize = sizeof(linklistmenuitem); linklistmenuitem.position = 0x00; linklistmenuitem.flags = CMIF_TCHAR; linklistmenuitem.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_LINKLISTICON)); linklistmenuitem.ptszName = LPGENT("&Create Linklist"); linklistmenuitem.pszService = "Linklist/MenuCommand"; CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&linklistmenuitem); hWindowList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = ProgressBarDlg; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInst; wndclass.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_LINKLISTICON)); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); wndclass.lpszClassName = _T("Progressbar"); wndclass.lpszMenuName = NULL; RegisterClass(&wndclass); splitCursor = LoadCursor(NULL, IDC_SIZENS); mir_getMMI(&mmi); HookEvent(ME_OPT_INITIALISE, InitOptionsDlg); HookEvent(ME_DB_EVENT_ADDED, DBUpdate); return 0; } __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) { UNREFERENCED_PARAMETER(mirandaVersion); return &pluginInfo; } int __declspec(dllexport) Unload(void) { UnhookEvent(ME_DB_EVENT_ADDED); DestroyCursor(splitCursor); return 0; } int InitOptionsDlg(WPARAM wParam, LPARAM lParam) { OPTIONSDIALOGPAGE optionsDialog; UNREFERENCED_PARAMETER(lParam); ZeroMemory(&optionsDialog, sizeof(OPTIONSDIALOGPAGE)); optionsDialog.cbSize = sizeof(optionsDialog); optionsDialog.hInstance = hInst; optionsDialog.ptszGroup = LPGENT("History"); optionsDialog.ptszTitle = LPGENT("History Linklist"); optionsDialog.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS_DLG); optionsDialog.pfnDlgProc = OptionsDlgProc; optionsDialog.expertOnlyControls = NULL; optionsDialog.nExpertOnlyControls = 0; optionsDialog.flags = ODPF_BOLDGROUPS|ODPF_TCHAR; CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&optionsDialog); return 0; } static INT_PTR LinkList_Main(WPARAM wParam,LPARAM lParam) { HANDLE hEvent; HANDLE hContact = (HANDLE)wParam; DBEVENTINFO dbe; HWND hWnd; HWND hWndProgress; HWND hWndMain; int histCount = 0; int actCount = 0; RECT DesktopRect; DIALOGPARAM *DlgParam; LISTELEMENT *listStart; UNREFERENCED_PARAMETER(lParam); listStart = (LISTELEMENT*)malloc(sizeof(LISTELEMENT)); ZeroMemory(listStart, sizeof(LISTELEMENT)); hWnd = WindowList_Find(hWindowList,hContact); if ( hWnd != NULL ) { int len; SetForegroundWindow(hWnd); SetFocus(hWnd); len = GetWindowTextLength(GetDlgItem(hWnd, IDC_MAIN)); PostMessage(GetDlgItem(hWnd, IDC_MAIN), EM_SETSEL, (WPARAM)len, (LPARAM)len); return 0; } hEvent = (HANDLE)CallService(MS_DB_EVENT_FINDFIRST, (WPARAM)hContact, 0); if ( hEvent == NULL ) { MessageBox(NULL, TranslateT(TXT_EMPTYHISTORY), TranslateT(TXT_PLUGINNAME), MB_OK | MB_ICONINFORMATION ); return 0; } histCount = CallService(MS_DB_EVENT_GETCOUNT, (WPARAM)hContact, 0); ZeroMemory(&dbe, sizeof(dbe)); dbe.cbSize = sizeof(dbe); dbe.cbBlob = (int)CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hEvent, 0); dbe.pBlob = (PBYTE)malloc(dbe.cbBlob+1); CallService(MS_DB_EVENT_GET, (WPARAM)hEvent, (LPARAM)&dbe); dbe.pBlob[dbe.cbBlob] = 0; GetWindowRect(GetDesktopWindow(), &DesktopRect); hWndProgress = CreateWindow(_T("Progressbar"), TranslateT("Processing history..."), WS_OVERLAPPED, CW_USEDEFAULT, CW_USEDEFAULT, 350, 45, NULL, NULL, hInst, NULL); if ( hWndProgress == 0 ) { free(dbe.pBlob); MessageBox(NULL, TranslateT("Could not create window!"), TranslateT("Error"), MB_OK | MB_ICONEXCLAMATION ); return -1; } SetWindowPos(hWndProgress, HWND_TOP, (int)(DesktopRect.right*0.5)-175, (int)(DesktopRect.bottom*0.5)-22, 0, 0, SWP_NOSIZE); ShowWindow(hWndProgress, SW_SHOW); SetForegroundWindow(hWndProgress); while( 1 ) { if ( dbe.eventType == EVENTTYPE_URL || dbe.eventType == EVENTTYPE_MESSAGE ) { // Call function to find URIs if ( ExtractURI(&dbe, hEvent, listStart) < 0 ) { free(dbe.pBlob); RemoveList(listStart); MessageBox(NULL, TranslateTS("Could not allocate memory!"), TranslateT("Error"), MB_OK | MB_ICONEXCLAMATION); return -1; } } actCount++; if ( ((int)(((float)actCount/histCount)*100.00)) % 10 == 0 ) SendMessage(hWndProgress, WM_COMMAND, 100, ((int)(((float)actCount/histCount)*100.00))); hEvent = (HANDLE)CallService(MS_DB_EVENT_FINDNEXT, (WPARAM)hEvent, 0); if ( hEvent == NULL ) break; free(dbe.pBlob); dbe.cbBlob = (int)CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hEvent, 0); dbe.pBlob = (PBYTE)malloc(dbe.cbBlob+1); CallService(MS_DB_EVENT_GET, (WPARAM)hEvent, (LPARAM)&dbe); dbe.pBlob[dbe.cbBlob] = 0; } free(dbe.pBlob); SendMessage(hWndProgress, WM_CLOSE, 0, 0); if ( ListCount(listStart) <= 0 ) { RemoveList(listStart); MessageBox(NULL, TranslateT("There are no links in history!"), TranslateT(TXT_PLUGINNAME), MB_OK | MB_ICONINFORMATION); return 0; } DlgParam = (DIALOGPARAM*)malloc(sizeof(DIALOGPARAM)); DlgParam->hContact = hContact; DlgParam->listStart = listStart; DlgParam->findMessage = 0; DlgParam->chrg.cpMax = -1; DlgParam->chrg.cpMin = -1; hWndMain = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_MAIN_DLG), NULL, MainDlgProc, (LPARAM)DlgParam); if ( hWndMain == 0 ) { RemoveList(listStart); MessageBox(NULL, TranslateT("Could not create window!"), TranslateT("Error"), MB_OK | MB_ICONEXCLAMATION ); return -1; } ShowWindow(hWndMain, SW_SHOW); return 0; }