From b01805cbb22c14e9a3cd83f5c49c97e6ecb80074 Mon Sep 17 00:00:00 2001 From: sje Date: Mon, 13 Nov 2006 14:48:02 +0000 Subject: git-svn-id: https://server.scottellis.com.au/svn/mim_plugs@45 4f64403b-2f21-0410-a795-97e2b3489a10 --- last_contact/LastContact.cpp | 195 ++++++++++++++++++++ last_contact/LastContact.mdsp | 94 ++++++++++ last_contact/LastContact_8.sln | 20 ++ last_contact/LastContact_8.vcproj | 295 ++++++++++++++++++++++++++++++ last_contact/common.h | 34 ++++ last_contact/docs/licence_LastContact.txt | 6 + last_contact/options.cpp | 82 +++++++++ last_contact/options.h | 16 ++ last_contact/resource.h | 20 ++ last_contact/resource.rc | 110 +++++++++++ 10 files changed, 872 insertions(+) create mode 100644 last_contact/LastContact.cpp create mode 100644 last_contact/LastContact.mdsp create mode 100644 last_contact/LastContact_8.sln create mode 100644 last_contact/LastContact_8.vcproj create mode 100644 last_contact/common.h create mode 100644 last_contact/docs/licence_LastContact.txt create mode 100644 last_contact/options.cpp create mode 100644 last_contact/options.h create mode 100644 last_contact/resource.h create mode 100644 last_contact/resource.rc diff --git a/last_contact/LastContact.cpp b/last_contact/LastContact.cpp new file mode 100644 index 0000000..3cce9bd --- /dev/null +++ b/last_contact/LastContact.cpp @@ -0,0 +1,195 @@ +/* +Miranda plugin template, originally by Richard Hughes +http://miranda-icq.sourceforge.net/ + +This file is placed in the public domain. Anybody is free to use or +modify it as they wish with no restriction. +There is no warranty. +*/ + +#include "common.h" +#include "options.h" + +HINSTANCE hInst; +PLUGINLINK *pluginLink; +MM_INTERFACE mmi; + +HANDLE hEventWindow; + +//typedef LRESULT (CALLBACK *WNDPROC)(HWND, UINT, WPARAM, LPARAM); + +HANDLE hLastContact = 0; +HWND hWndLastContact = 0; + +int vk = 'M', mod = VK_MENU; + +PLUGININFO pluginInfo={ + sizeof(PLUGININFO), + MODULE, + PLUGIN_MAKE_VERSION(0,0,0,1), + "Re-open the last open message window using a configurable hot key.", + "Scott Ellis", + "mail@scottellis.com.au", + "© 2006 Scott Ellis", + "http://scottellis.com.au", + 0, //not transient + 0 //doesn't replace anything built-in +}; + +extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) +{ + hInst=hinstDLL; + return TRUE; +} + +extern "C" __declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion) +{ + return &pluginInfo; +} + +void PlaceOnTop(HWND hwnd) { + // set window style + LONG ex_style = GetWindowLong(hwnd, GWL_EXSTYLE); + ex_style |= WS_EX_TOPMOST; + SetWindowLong(hwnd, GWL_EXSTYLE, ex_style); + + if(DBGetContactSettingByte(0, MODULE, "MakeChildFullScreen", 0)) { + // make window child of any full-screen topmost windows + int w = GetSystemMetrics(SM_CXSCREEN); + int h = GetSystemMetrics(SM_CYSCREEN); + + HWND hWnd = 0; + while (hWnd = FindWindowEx(NULL, hWnd, NULL, NULL)) { + if(!IsWindowVisible(hWnd) || IsIconic(hWnd)) + continue; + + if (!(GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_TOPMOST)) + continue; + + // not sure if this could be done more simply using 'IsZoomed'? + RECT WindowRect; + GetWindowRect(hWnd, &WindowRect); + if ((w != (WindowRect.right - WindowRect.left)) || (h != (WindowRect.bottom - WindowRect.top))) + continue; + + SetParent(hwnd, hWnd); + break; + } + } +} + +int WindowEvent(WPARAM wParam, LPARAM lParam) { + MessageWindowEventData *ed = (MessageWindowEventData *)lParam; + + /* + // ignore chat room contacts? + char *proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)ed->hContact, 0); + if(proto && DBGetContactSettingByte(ed->hContact, proto, "ChatRoom", 0)) return 0; + */ + + switch(ed->uType) { + case MSG_WINDOW_EVT_OPENING: + hLastContact = ed->hContact; + break; + case MSG_WINDOW_EVT_OPEN: + // if there's a full-screen app running, make the window its child + hWndLastContact = ed->hwndWindow; + if(options.make_topmost) { + HWND hwnd = hWndLastContact, parent = 0; + while((parent = GetParent(hwnd)) != 0) hwnd = parent; + PlaceOnTop(hwnd); + } + break; + case MSG_WINDOW_EVT_CLOSING: + case MSG_WINDOW_EVT_CLOSE: + // care factor? + break; + } + + return 0; +} + +int ModulesLoaded(WPARAM wParam,LPARAM lParam) { + if(ServiceExists(MS_UPDATE_REGISTER)) { + // register with updater + Update update = {0}; + char szVersion[16]; + + update.cbSize = sizeof(Update); + + update.szComponentName = pluginInfo.shortName; + update.pbVersion = (BYTE *)CreateVersionString(pluginInfo.version, szVersion); + update.cpbVersion = strlen((char *)update.pbVersion); + + update.szUpdateURL = UPDATER_AUTOREGISTER; + + // these are the three lines that matter - the archive, the page containing the version string, and the text (or data) + // before the version that we use to locate it on the page + // (note that if the update URL and the version URL point to standard file listing entries, the backend xml + // data will be used to check for updates rather than the actual web page - this is not true for beta urls) + update.szBetaUpdateURL = "http://www.scottellis.com.au/miranda_plugins/last_contact.zip"; + update.szBetaVersionURL = "http://www.scottellis.com.au/miranda_plugins/ver_last_contact.html"; + update.pbBetaVersionPrefix = (BYTE *)MODULE " version "; + + update.cpbBetaVersionPrefix = strlen((char *)update.pbBetaVersionPrefix); + + CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update); + } + + hEventWindow = HookEvent(ME_MSG_WINDOWEVENT, WindowEvent); + + return 0; +} + +int Shutdown(WPARAM wParam, LPARAM lParam) { + if(hEventWindow) UnhookEvent(hEventWindow); + return 0; +} + +void CALLBACK TimerProc(HWND, UINT, UINT_PTR, DWORD) { + if(GetAsyncKeyState(vk) + && (options.mod_alt == false || GetAsyncKeyState(VK_MENU)) + && (options.mod_shift == false || GetAsyncKeyState(VK_SHIFT)) + && (options.mod_ctrl == false || GetAsyncKeyState(VK_CONTROL)) + && hLastContact) + { + if(options.hide_if_visible && IsWindow(hWndLastContact) && IsWindowVisible(hWndLastContact)) { + PostMessage(hWndLastContact, WM_COMMAND, 1023, 0); // chat close tab + PostMessage(hWndLastContact, WM_COMMAND, IDCANCEL, 0); // srmm/scriver close session button + PostMessage(hWndLastContact, WM_COMMAND, 1025, 0); // tabsrmm close session button + } else { + CallService(MS_MSG_SENDMESSAGE, (WPARAM)hLastContact, 0); + } + } +} + +UINT_PTR timer_id; + +extern "C" int __declspec(dllexport) Load(PLUGINLINK *link) +{ + pluginLink = link; + + mir_getMMI(&mmi); + + HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded); + HookEvent(ME_SYSTEM_PRESHUTDOWN, Shutdown); + + InitOptions(); + + // clear the key pressed flags + GetAsyncKeyState(vk); + if(options.mod_alt) GetAsyncKeyState(VK_MENU); + if(options.mod_shift) GetAsyncKeyState(VK_SHIFT); + if(options.mod_ctrl) GetAsyncKeyState(VK_CONTROL); + + timer_id = SetTimer(0, 0, 500, TimerProc); + + return 0; +} + +extern "C" int __declspec(dllexport) Unload(void) +{ + KillTimer(0, timer_id); + return 0; +} + diff --git a/last_contact/LastContact.mdsp b/last_contact/LastContact.mdsp new file mode 100644 index 0000000..fc950a0 --- /dev/null +++ b/last_contact/LastContact.mdsp @@ -0,0 +1,94 @@ +[Project] +name=LastContact +type=2 +defaultConfig=0 + + +[Debug] +// compiler +workingDirectory= +arguments= +intermediateFilesDirectory=Debug +outputFilesDirectory=Debug +compilerPreprocessor= +extraCompilerOptions= +compilerIncludeDirectory=..\..\include +noWarning=0 +defaultWarning=0 +allWarning=1 +extraWarning=0 +isoWarning=0 +warningsAsErrors=0 +debugType=1 +debugLevel=2 +exceptionEnabled=1 +runtimeTypeEnabled=1 +optimizeLevel=0 + +// linker +libraryPath= +outputFilename=Debug\LastContact.dll +libraries=gdi32, comctl32 +extraLinkerOptions= +ignoreStartupFile=0 +ignoreDefaultLibs=0 +stripExecutableFile=0 + +// archive +extraArchiveOptions= + +//resource +resourcePreprocessor= +resourceIncludeDirectory= +extraResourceOptions= + +[Release] +// compiler +workingDirectory= +arguments= +intermediateFilesDirectory=Release +outputFilesDirectory=Release +compilerPreprocessor= +extraCompilerOptions= +compilerIncludeDirectory=..\..\include +noWarning=0 +defaultWarning=0 +allWarning=1 +extraWarning=0 +isoWarning=0 +warningAsErrors=0 +debugType=0 +debugLevel=1 +exceptionEnabled=0 +runtimeTypeEnabled=0 +optimizeLevel=4 + +// linker +libraryPath= +outputFilename=Release\LastContact.dll +libraries=gdi32, comctl32 +extraLinkerOptions= +ignoreStartupFile=0 +ignoreDefaultLibs=0 +stripExecutableFile=1 + +// archive +extraArchiveOptions= + +//resource +resourcePreprocessor= +resourceIncludeDirectory= +extraResourceOptions= + +[Source] +1=LastContact.cpp +3=options.cpp +[Header] +1=resource.h +2=common.h +3=options.h +[Resource] +1=resource.rc +[Other] +[History] +LastContact.cpp,555 diff --git a/last_contact/LastContact_8.sln b/last_contact/LastContact_8.sln new file mode 100644 index 0000000..1cb8884 --- /dev/null +++ b/last_contact/LastContact_8.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LastContact", "LastContact_8.vcproj", "{3B858A66-7A23-4EB1-9440-605B96717F06}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3B858A66-7A23-4EB1-9440-605B96717F06}.Debug|Win32.ActiveCfg = Debug|Win32 + {3B858A66-7A23-4EB1-9440-605B96717F06}.Debug|Win32.Build.0 = Debug|Win32 + {3B858A66-7A23-4EB1-9440-605B96717F06}.Release|Win32.ActiveCfg = Release|Win32 + {3B858A66-7A23-4EB1-9440-605B96717F06}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/last_contact/LastContact_8.vcproj b/last_contact/LastContact_8.vcproj new file mode 100644 index 0000000..7063ed4 --- /dev/null +++ b/last_contact/LastContact_8.vcproj @@ -0,0 +1,295 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/last_contact/common.h b/last_contact/common.h new file mode 100644 index 0000000..7201202 --- /dev/null +++ b/last_contact/common.h @@ -0,0 +1,34 @@ +#ifndef _COMMON_H +#define _COMMON_H + +#define _WIN32_IE 0x400 + +#include +#include + +#include "resource.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define MODULE "LastContact" + +extern HWND pluginwind; +extern HINSTANCE hInst; + +#endif diff --git a/last_contact/docs/licence_LastContact.txt b/last_contact/docs/licence_LastContact.txt new file mode 100644 index 0000000..c23c973 --- /dev/null +++ b/last_contact/docs/licence_LastContact.txt @@ -0,0 +1,6 @@ +The LastContact plugin for Miranda-IM is Copyright (c) 2006 Scott Ellis (mail@scottellis.com.au) + +http://www.scottellis.com.au + +It is released under the General Public Licence, available here: +http://www.gnu.org/copyleft/gpl.html \ No newline at end of file diff --git a/last_contact/options.cpp b/last_contact/options.cpp new file mode 100644 index 0000000..940019b --- /dev/null +++ b/last_contact/options.cpp @@ -0,0 +1,82 @@ +#include "common.h" +#include "options.h" + +Options options; + +static BOOL CALLBACK DlgProcOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { + + switch ( msg ) { + case WM_INITDIALOG: { + TranslateDialogDefault( hwndDlg ); + WORD mod = 0; + if(options.mod_alt) mod |= HOTKEYF_ALT; + if(options.mod_shift) mod |= HOTKEYF_SHIFT; + if(options.mod_ctrl) mod |= HOTKEYF_CONTROL; + + SendDlgItemMessage(hwndDlg, IDC_HOTKEY, HKM_SETHOTKEY, (mod << 8) + options.vk, 0); + + CheckDlgButton(hwndDlg, IDC_CHK_HIDE, options.hide_if_visible ? TRUE : FALSE); + CheckDlgButton(hwndDlg, IDC_CHK_ONTOP, options.make_topmost ? TRUE : FALSE); + + return TRUE; + } + case WM_COMMAND: + if(HIWORD(wParam) == BN_CLICKED) { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + if ( HIWORD( wParam ) == EN_CHANGE && ( HWND )lParam == GetFocus()) { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + return TRUE; + case WM_NOTIFY: + if (((LPNMHDR)lParam)->code == (unsigned)PSN_APPLY ) { + WORD hkcode = (WORD)SendDlgItemMessage(hwndDlg, IDC_HOTKEY, HKM_GETHOTKEY, 0, 0); + options.vk = LOBYTE(hkcode); + options.mod_alt = (HIBYTE(hkcode) & HOTKEYF_ALT) != 0; + options.mod_shift = (HIBYTE(hkcode) & HOTKEYF_SHIFT) != 0; + options.mod_ctrl = (HIBYTE(hkcode) & HOTKEYF_CONTROL) != 0; + + DBWriteContactSettingByte(0, MODULE, "VK", (BYTE)options.vk); + DBWriteContactSettingByte(0, MODULE, "MOD_ALT", options.mod_alt ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "MOD_SHIFT", options.mod_shift ? 1 : 0); + DBWriteContactSettingByte(0, MODULE, "MOD_CTRL", options.mod_ctrl ? 1 : 0); + + options.hide_if_visible = IsDlgButtonChecked(hwndDlg, IDC_CHK_HIDE) ? true : false; + DBWriteContactSettingByte(0, MODULE, "HideIfVisible", options.hide_if_visible ? 1 : 0); + options.make_topmost = IsDlgButtonChecked(hwndDlg, IDC_CHK_ONTOP) ? true : false; + DBWriteContactSettingByte(0, MODULE, "MakeTopmost", options.make_topmost ? 1 : 0); + } + return TRUE; + } + + return FALSE; +} + + +int OptInit(WPARAM wParam,LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp = { 0 }; + odp.cbSize = sizeof(odp); + odp.position = -790000000; + odp.hInstance = hInst; + odp.pszTemplate = MAKEINTRESOURCE(IDD_OPT1); + odp.pszTitle = Translate("Last Contact"); + odp.pszGroup = Translate("Events"); + odp.flags = ODPF_BOLDGROUPS; + odp.nIDBottomSimpleControl = 0; + odp.pfnDlgProc = DlgProcOpts; + CallService( MS_OPT_ADDPAGE, wParam,( LPARAM )&odp ); + + return 0; +} + +void InitOptions() { + options.vk = DBGetContactSettingByte(0, MODULE, "VK", (BYTE)'M'); + options.mod_alt = (DBGetContactSettingByte(0, MODULE, "MOD_ALT", 1) == 1); + options.mod_shift = (DBGetContactSettingByte(0, MODULE, "MOD_SHIFT", 0) == 1); + options.mod_ctrl = (DBGetContactSettingByte(0, MODULE, "MOD_CTRL", 0) == 1); + + options.hide_if_visible = (DBGetContactSettingByte(0, MODULE, "HideIfVisible", 1) == 1); + options.make_topmost = (DBGetContactSettingByte(0, MODULE, "MakeTopmost", 0) == 1); + HookEvent(ME_OPT_INITIALISE, OptInit); +} diff --git a/last_contact/options.h b/last_contact/options.h new file mode 100644 index 0000000..8e428c6 --- /dev/null +++ b/last_contact/options.h @@ -0,0 +1,16 @@ +#ifndef _OPTIONS_INC +#define _OPTIONS_INC + +typedef struct { + int vk; + bool mod_shift, mod_alt, mod_ctrl; + + bool hide_if_visible; + bool make_topmost; +} Options; + +extern Options options; + +void InitOptions(); + +#endif diff --git a/last_contact/resource.h b/last_contact/resource.h new file mode 100644 index 0000000..aad97c5 --- /dev/null +++ b/last_contact/resource.h @@ -0,0 +1,20 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by resource.rc +// +#define IDD_OPT1 101 +#define IDC_HOTKEY 1009 +#define IDC_CHK_HIDE 1010 +#define IDC_CHK_HIDE2 1011 +#define IDC_CHK_ONTOP 1011 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1011 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/last_contact/resource.rc b/last_contact/resource.rc new file mode 100644 index 0000000..cd79237 --- /dev/null +++ b/last_contact/resource.rc @@ -0,0 +1,110 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_OPT1 DIALOGEX 0, 0, 246, 179 +STYLE DS_SETFONT | WS_POPUP +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + CONTROL "",IDC_HOTKEY,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,110,59,80,14 + RTEXT "Hot key:",IDC_STATIC,48,63,55,8 + CONTROL "Hide window if already visible",IDC_CHK_HIDE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,77,91,108,10 + CONTROL "Make window topmost",IDC_CHK_ONTOP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,77,108,87,10 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_OPT1, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 239 + TOPMARGIN, 7 + BOTTOMMARGIN, 172 + END +END +#endif // APSTUDIO_INVOKED + +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (Australia) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (Australia) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + -- cgit v1.2.3