-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// function.cpp
-
-
-#include "engine.h"
-#include "hook.h"
-#include "mayu.h"
-#include "mayurc.h"
-#include "misc.h"
-#include "registry.h"
-#include "vkeytable.h"
-#include "windowstool.h"
-#include <algorithm>
-#include <process.h>
-
-#define FUNCTION_DATA
-#include "functions.h"
-#undef FUNCTION_DATA
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// TypeTable
-
-
-template <class T> class TypeTable
-{
-public:
- T m_type;
- const _TCHAR *m_name;
-};
-
-
-template <class T> static inline
-bool getTypeName(tstring *o_name, T i_type,
- const TypeTable<T> *i_table, size_t i_n)
-{
- for (size_t i = 0; i < i_n; ++ i)
- if (i_table[i].m_type == i_type)
- {
- *o_name = i_table[i].m_name;
- return true;
- }
- return false;
-}
-
-template <class T> static inline
-bool getTypeValue(T *o_type, const tstringi &i_name,
- const TypeTable<T> *i_table, size_t i_n)
-{
- for (size_t i = 0; i < i_n; ++ i)
- if (i_table[i].m_name == i_name)
- {
- *o_type = i_table[i].m_type;
- return true;
- }
- return false;
-}
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// VKey
-
-
-// stream output
-tostream &operator<<(tostream &i_ost, VKey i_data)
-{
- if (i_data & VKey_extended)
- i_ost << _T("E-");
- if (i_data & VKey_released)
- i_ost << _T("U-");
- if (i_data & VKey_pressed)
- i_ost << _T("D-");
-
- u_int8 code = i_data & ~(VKey_extended | VKey_released | VKey_pressed);
- const VKeyTable *vkt;
- for (vkt = g_vkeyTable; vkt->m_name; ++ vkt)
- if (vkt->m_code == code)
- break;
- if (vkt->m_name)
- i_ost << vkt->m_name;
- else
- i_ost << _T("0x") << std::hex << code << std::dec;
- return i_ost;
-}
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// ToWindowType
-
-
-// ToWindowType table
-typedef TypeTable<ToWindowType> TypeTable_ToWindowType;
-static const TypeTable_ToWindowType g_toWindowTypeTable[] =
-{
- { ToWindowType_toOverlappedWindow, _T("toOverlappedWindow") },
- { ToWindowType_toMainWindow, _T("toMainWindow") },
- { ToWindowType_toItself, _T("toItself") },
- { ToWindowType_toParentWindow, _T("toParentWindow") },
-};
-
-
-// stream output
-tostream &operator<<(tostream &i_ost, ToWindowType i_data)
-{
- tstring name;
- if (getTypeName(&name, i_data,
- g_toWindowTypeTable, NUMBER_OF(g_toWindowTypeTable)))
- i_ost << name;
- else
- i_ost << static_cast<int>(i_data);
- return i_ost;
-}
-
-
-// get value of ToWindowType
-bool getTypeValue(ToWindowType *o_type, const tstring &i_name)
-{
- return getTypeValue(o_type, i_name,
- g_toWindowTypeTable, NUMBER_OF(g_toWindowTypeTable));
-}
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// GravityType
-
-
-// GravityType table
-typedef TypeTable<GravityType> TypeTable_GravityType;
-static const TypeTable_GravityType g_gravityTypeTable[] =
-{
- { GravityType_C, _T("C") },
- { GravityType_N, _T("N") },
- { GravityType_E, _T("E") },
- { GravityType_W, _T("W") },
- { GravityType_S, _T("S") },
- { GravityType_NW, _T("NW") },
- { GravityType_NW, _T("WN") },
- { GravityType_NE, _T("NE") },
- { GravityType_NE, _T("EN") },
- { GravityType_SW, _T("SW") },
- { GravityType_SW, _T("WS") },
- { GravityType_SE, _T("SE") },
- { GravityType_SE, _T("ES") },
-};
-
-
-// stream output
-tostream &operator<<(tostream &i_ost, GravityType i_data)
-{
- tstring name;
- if (getTypeName(&name, i_data,
- g_gravityTypeTable, NUMBER_OF(g_gravityTypeTable)))
- i_ost << name;
- else
- i_ost << _T("(GravityType internal error)");
- return i_ost;
-}
-
-
-// get value of GravityType
-bool getTypeValue(GravityType *o_type, const tstring &i_name)
-{
- return getTypeValue(o_type, i_name,
- g_gravityTypeTable, NUMBER_OF(g_gravityTypeTable));
-}
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// MouseHookType
-
-
-// MouseHookType table
-typedef TypeTable<MouseHookType> TypeTable_MouseHookType;
-static const TypeTable_MouseHookType g_mouseHookTypeTable[] =
-{
- { MouseHookType_None, _T("None") },
- { MouseHookType_Wheel, _T("Wheel") },
- { MouseHookType_WindowMove, _T("WindowMove") },
-};
-
-
-// stream output
-tostream &operator<<(tostream &i_ost, MouseHookType i_data)
-{
- tstring name;
- if (getTypeName(&name, i_data,
- g_mouseHookTypeTable, NUMBER_OF(g_mouseHookTypeTable)))
- i_ost << name;
- else
- i_ost << _T("(MouseHookType internal error)");
- return i_ost;
-}
-
-
-// get value of MouseHookType
-bool getTypeValue(MouseHookType *o_type, const tstring &i_name)
-{
- return getTypeValue(o_type, i_name, g_mouseHookTypeTable,
- NUMBER_OF(g_mouseHookTypeTable));
-}
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// MayuDialogType
-
-
-// ModifierLockType table
-typedef TypeTable<MayuDialogType> TypeTable_MayuDialogType;
-static const TypeTable_MayuDialogType g_mayuDialogTypeTable[] =
-{
- { MayuDialogType_investigate, _T("investigate") },
- { MayuDialogType_log, _T("log") },
-};
-
-
-// stream output
-tostream &operator<<(tostream &i_ost, MayuDialogType i_data)
-{
- tstring name;
- if (getTypeName(&name, i_data,
- g_mayuDialogTypeTable, NUMBER_OF(g_mayuDialogTypeTable)))
- i_ost << name;
- else
- i_ost << _T("(MayuDialogType internal error)");
- return i_ost;
-}
-
-
-// get value of MayuDialogType
-bool getTypeValue(MayuDialogType *o_type, const tstring &i_name)
-{
- return getTypeValue(o_type, i_name, g_mayuDialogTypeTable,
- NUMBER_OF(g_mayuDialogTypeTable));
-}
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// ToggleType
-
-
-// ToggleType table
-typedef TypeTable<ToggleType> TypeTable_ToggleType;
-static const TypeTable_ToggleType g_toggleType[] =
-{
- { ToggleType_toggle, _T("toggle") },
- { ToggleType_off, _T("off") },
- { ToggleType_off, _T("false") },
- { ToggleType_off, _T("released") },
- { ToggleType_on, _T("on") },
- { ToggleType_on, _T("true") },
- { ToggleType_on, _T("pressed") },
-};
-
-
-// stream output
-tostream &operator<<(tostream &i_ost, ToggleType i_data)
-{
- tstring name;
- if (getTypeName(&name, i_data, g_toggleType, NUMBER_OF(g_toggleType)))
- i_ost << name;
- else
- i_ost << _T("(ToggleType internal error)");
- return i_ost;
-}
-
-
-// get value of ToggleType
-bool getTypeValue(ToggleType *o_type, const tstring &i_name)
-{
- return getTypeValue(o_type, i_name, g_toggleType,
- NUMBER_OF(g_toggleType));
-}
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// ModifierLockType
-
-
-// ModifierLockType table
-typedef TypeTable<ModifierLockType> TypeTable_ModifierLockType;
-static const TypeTable_ModifierLockType g_modifierLockTypeTable[] =
-{
- { ModifierLockType_Lock0, _T("lock0") },
- { ModifierLockType_Lock1, _T("lock1") },
- { ModifierLockType_Lock2, _T("lock2") },
- { ModifierLockType_Lock3, _T("lock3") },
- { ModifierLockType_Lock4, _T("lock4") },
- { ModifierLockType_Lock5, _T("lock5") },
- { ModifierLockType_Lock6, _T("lock6") },
- { ModifierLockType_Lock7, _T("lock7") },
- { ModifierLockType_Lock8, _T("lock8") },
- { ModifierLockType_Lock9, _T("lock9") },
-};
-
-
-// stream output
-tostream &operator<<(tostream &i_ost, ModifierLockType i_data)
-{
- tstring name;
- if (getTypeName(&name, i_data,
- g_modifierLockTypeTable, NUMBER_OF(g_modifierLockTypeTable)))
- i_ost << name;
- else
- i_ost << _T("(ModifierLockType internal error)");
- return i_ost;
-}
-
-
-// get value of ModifierLockType
-bool getTypeValue(ModifierLockType *o_type, const tstring &i_name)
-{
- return getTypeValue(o_type, i_name, g_modifierLockTypeTable,
- NUMBER_OF(g_modifierLockTypeTable));
-}
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// ShowCommandType
-
-
-// ShowCommandType table
-typedef TypeTable<ShowCommandType> TypeTable_ShowCommandType;
-static const TypeTable_ShowCommandType g_showCommandTypeTable[] =
-{
- { ShowCommandType_hide, _T("hide") },
- { ShowCommandType_maximize, _T("maximize") },
- { ShowCommandType_minimize, _T("minimize") },
- { ShowCommandType_restore, _T("restore") },
- { ShowCommandType_show, _T("show") },
- { ShowCommandType_showDefault, _T("showDefault") },
- { ShowCommandType_showMaximized, _T("showMaximized") },
- { ShowCommandType_showMinimized, _T("showMinimized") },
- { ShowCommandType_showMinNoActive, _T("showMinNoActive") },
- { ShowCommandType_showNA, _T("showNA") },
- { ShowCommandType_showNoActivate, _T("showNoActivate") },
- { ShowCommandType_showNormal, _T("showNormal") },
-};
-
-
-// stream output
-tostream &operator<<(tostream &i_ost, ShowCommandType i_data)
-{
- tstring name;
- if (getTypeName(&name, i_data,
- g_showCommandTypeTable, NUMBER_OF(g_showCommandTypeTable)))
- i_ost << name;
- else
- i_ost << _T("(ShowCommandType internal error)");
- return i_ost;
-}
-
-
-// get value of ShowCommandType
-bool getTypeValue(ShowCommandType *o_type, const tstring &i_name)
-{
- return getTypeValue(o_type, i_name, g_showCommandTypeTable,
- NUMBER_OF(g_showCommandTypeTable));
-}
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// TargetWindowType
-
-
-// ModifierLockType table
-typedef TypeTable<TargetWindowType> TypeTable_TargetWindowType;
-static const TypeTable_TargetWindowType g_targetWindowType[] =
-{
- { TargetWindowType_overlapped, _T("overlapped") },
- { TargetWindowType_mdi, _T("mdi") },
-};
-
-
-// stream output
-tostream &operator<<(tostream &i_ost, TargetWindowType i_data)
-{
- tstring name;
- if (getTypeName(&name, i_data,
- g_targetWindowType, NUMBER_OF(g_targetWindowType)))
- i_ost << name;
- else
- i_ost << _T("(TargetWindowType internal error)");
- return i_ost;
-}
-
-
-// get value of TargetWindowType
-bool getTypeValue(TargetWindowType *o_type, const tstring &i_name)
-{
- return getTypeValue(o_type, i_name, g_targetWindowType,
- NUMBER_OF(g_targetWindowType));
-}
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// BooleanType
-
-
-// BooleanType table
-typedef TypeTable<BooleanType> TypeTable_BooleanType;
-static const TypeTable_BooleanType g_booleanType[] =
-{
- { BooleanType_false, _T("false") },
- { BooleanType_true, _T("true") },
-};
-
-
-// stream output
-tostream &operator<<(tostream &i_ost, BooleanType i_data)
-{
- tstring name;
- if (getTypeName(&name, i_data, g_booleanType, NUMBER_OF(g_booleanType)))
- i_ost << name;
- else
- i_ost << _T("(BooleanType internal error)");
- return i_ost;
-}
-
-
-// get value of BooleanType
-bool getTypeValue(BooleanType *o_type, const tstring &i_name)
-{
- return getTypeValue(o_type, i_name, g_booleanType,
- NUMBER_OF(g_booleanType));
-}
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// LogicalOperatorType
-
-
-// LogicalOperatorType table
-typedef TypeTable<LogicalOperatorType> TypeTable_LogicalOperatorType;
-static const TypeTable_LogicalOperatorType g_logicalOperatorType[] =
-{
- { LogicalOperatorType_or, _T("||") },
- { LogicalOperatorType_and, _T("&&") },
-};
-
-
-// stream output
-tostream &operator<<(tostream &i_ost, LogicalOperatorType i_data)
-{
- tstring name;
- if (getTypeName(&name, i_data, g_logicalOperatorType,
- NUMBER_OF(g_logicalOperatorType)))
- i_ost << name;
- else
- i_ost << _T("(LogicalOperatorType internal error)");
- return i_ost;
-}
-
-
-// get value of LogicalOperatorType
-bool getTypeValue(LogicalOperatorType *o_type, const tstring &i_name)
-{
- return getTypeValue(o_type, i_name, g_logicalOperatorType,
- NUMBER_OF(g_logicalOperatorType));
-}
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// WindowMonitorFromType
-
-
-// WindowMonitorFromType table
-typedef TypeTable<WindowMonitorFromType> TypeTable_WindowMonitorFromType;
-static const TypeTable_WindowMonitorFromType g_windowMonitorFromType[] =
-{
- { WindowMonitorFromType_primary, _T("primary") },
- { WindowMonitorFromType_current, _T("current") },
-};
-
-
-// stream output
-tostream &operator<<(tostream &i_ost, WindowMonitorFromType i_data)
-{
- tstring name;
- if(getTypeName(&name, i_data, g_windowMonitorFromType,
- NUMBER_OF(g_windowMonitorFromType)))
- i_ost << name;
- else
- i_ost << _T("(WindowMonitorFromType internal error)");
- return i_ost;
-}
-
-
-// get value of WindowMonitorFromType
-bool getTypeValue(WindowMonitorFromType *o_type, const tstring &i_name)
-{
- return getTypeValue(o_type, i_name, g_windowMonitorFromType,
- NUMBER_OF(g_windowMonitorFromType));
-}
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// std::list<tstringq>
-
-
-/// stream output
-tostream &operator<<(tostream &i_ost, const std::list<tstringq> &i_data)
-{
- for (std::list<tstringq>::const_iterator
- i = i_data.begin(); i != i_data.end(); ++ i)
- {
- i_ost << *i << _T(", ");
- }
- return i_ost;
-}
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// FunctionData
-
-
-//
-FunctionData::~FunctionData()
-{
-}
-
-
-// stream output
-tostream &operator<<(tostream &i_ost, const FunctionData *i_data)
-{
- return i_data->output(i_ost);
-}
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// FunctionCreator
-
-
-///
-class FunctionCreator
-{
-public:
- typedef FunctionData *(*Creator)(); ///
-
-public:
- const _TCHAR *m_name; /// function name
- Creator m_creator; /// function data creator
-};
-
-
-// create function
-FunctionData *createFunctionData(const tstring &i_name)
-{
- static
-#define FUNCTION_CREATOR
-#include "functions.h"
-#undef FUNCTION_CREATOR
- ;
-
- for (size_t i = 0; i != NUMBER_OF(functionCreators); ++ i)
- if (i_name == functionCreators[i].m_name)
- return functionCreators[i].m_creator();
- return NULL;
-}
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// misc. functions
-
-
-//
-bool getSuitableWindow(FunctionParam *i_param, HWND *o_hwnd)
-{
- if (!i_param->m_isPressed)
- return false;
- *o_hwnd = getToplevelWindow(i_param->m_hwnd, NULL);
- if (!*o_hwnd)
- return false;
- return true;
-}
-
-//
-bool getSuitableMdiWindow(FunctionParam *i_param, HWND *o_hwnd,
- TargetWindowType *io_twt,
- RECT *o_rcWindow = NULL, RECT *o_rcParent = NULL)
-{
- if (!i_param->m_isPressed)
- return false;
- bool isMdi = *io_twt == TargetWindowType_mdi;
- *o_hwnd = getToplevelWindow(i_param->m_hwnd, &isMdi);
- *io_twt = isMdi ? TargetWindowType_mdi : TargetWindowType_overlapped;
- if (!*o_hwnd)
- return false;
- switch (*io_twt)
- {
- case TargetWindowType_overlapped:
- if (o_rcWindow)
- GetWindowRect(*o_hwnd, o_rcWindow);
- if (o_rcParent) {
- HMONITOR hm = monitorFromWindow(i_param->m_hwnd,
- MONITOR_DEFAULTTONEAREST);
- MONITORINFO mi;
- mi.cbSize = sizeof(mi);
- getMonitorInfo(hm, &mi);
- *o_rcParent = mi.rcWork;
- }
- break;
- case TargetWindowType_mdi:
- if (o_rcWindow)
- getChildWindowRect(*o_hwnd, o_rcWindow);
- if (o_rcParent)
- GetClientRect(GetParent(*o_hwnd), o_rcParent);
- break;
- }
- return true;
-}
-
-// get clipboard text (you must call closeClopboard())
-static const _TCHAR *getTextFromClipboard(HGLOBAL *o_hdata)
-{
- *o_hdata = NULL;
-
- if (!OpenClipboard(NULL))
- return NULL;
-
-#ifdef UNICODE
- *o_hdata = GetClipboardData(CF_UNICODETEXT);
-#else
- *o_hdata = GetClipboardData(CF_TEXT);
-#endif
- if (!*o_hdata)
- return NULL;
-
- _TCHAR *data = reinterpret_cast<_TCHAR *>(GlobalLock(*o_hdata));
- if (!data)
- return NULL;
- return data;
-}
-
-// close clipboard that opend by getTextFromClipboard()
-static void closeClipboard(HGLOBAL i_hdata, HGLOBAL i_hdataNew = NULL)
-{
- if (i_hdata)
- GlobalUnlock(i_hdata);
- if (i_hdataNew)
- {
- EmptyClipboard();
-#ifdef UNICODE
- SetClipboardData(CF_UNICODETEXT, i_hdataNew);
-#else
- SetClipboardData(CF_TEXT, i_hdataNew);
-#endif
- }
- CloseClipboard();
-}
-
-
-// EmacsEditKillLineFunc.
-// clear the contents of the clopboard
-// at that time, confirm if it is the result of the previous kill-line
-void Engine::EmacsEditKillLine::func()
-{
- if (!m_buf.empty())
- {
- HGLOBAL g;
- const _TCHAR *text = getTextFromClipboard(&g);
- if (text == NULL || m_buf != text)
- reset();
- closeClipboard(g);
- }
- if (OpenClipboard(NULL))
- {
- EmptyClipboard();
- CloseClipboard();
- }
-}
-
-
-/** if the text of the clipboard is
-@doc
-<pre>
-1: EDIT Control (at EOL C-K): "" => buf + "\r\n", Delete
-0: EDIT Control (other C-K): "(.+)" => buf + "\1"
-0: IE FORM TEXTAREA (at EOL C-K): "\r\n" => buf + "\r\n"
-2: IE FORM TEXTAREA (other C-K): "(.+)\r\n" => buf + "\1", Return Left
-^retval
-</pre>
-*/
-HGLOBAL Engine::EmacsEditKillLine::makeNewKillLineBuf(
- const _TCHAR *i_data, int *o_retval)
-{
- size_t len = m_buf.size();
- len += _tcslen(i_data) + 3;
-
- HGLOBAL hdata = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
- len * sizeof(_TCHAR));
- if (!hdata)
- return NULL;
- _TCHAR *dataNew = reinterpret_cast<_TCHAR *>(GlobalLock(hdata));
- *dataNew = _T('\0');
- if (!m_buf.empty())
- _tcscpy(dataNew, m_buf.c_str());
-
- len = _tcslen(i_data);
- if (3 <= len &&
- i_data[len - 2] == _T('\r') && i_data[len - 1] == _T('\n'))
- {
- _tcscat(dataNew, i_data);
- len = _tcslen(dataNew);
- dataNew[len - 2] = _T('\0'); // chomp
- *o_retval = 2;
- }
- else if (len == 0)
- {
- _tcscat(dataNew, _T("\r\n"));
- *o_retval = 1;
- }
- else
- {
- _tcscat(dataNew, i_data);
- *o_retval = 0;
- }
-
- m_buf = dataNew;
-
- GlobalUnlock(hdata);
- return hdata;
-}
-
-
-// EmacsEditKillLinePred
-int Engine::EmacsEditKillLine::pred()
-{
- HGLOBAL g;
- const _TCHAR *text = getTextFromClipboard(&g);
- int retval;
- HGLOBAL hdata = makeNewKillLineBuf(text ? text : _T(""), &retval);
- closeClipboard(g, hdata);
- return retval;
-}
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// functions
-
-
-// send a default key to Windows
-void Engine::funcDefault(FunctionParam *i_param)
-{
- {
- Acquire a(&m_log, 1);
- m_log << std::endl;
- i_param->m_doesNeedEndl = false;
- }
- if (i_param->m_isPressed)
- generateModifierEvents(i_param->m_c.m_mkey.m_modifier);
- generateKeyEvent(i_param->m_c.m_mkey.m_key, i_param->m_isPressed, true);
-}
-
-// use a corresponding key of a parent keymap
-void Engine::funcKeymapParent(FunctionParam *i_param)
-{
- Current c(i_param->m_c);
- c.m_keymap = c.m_keymap->getParentKeymap();
- if (!c.m_keymap)
- {
- funcDefault(i_param);
- return;
- }
-
- {
- Acquire a(&m_log, 1);
- m_log << _T("(") << c.m_keymap->getName() << _T(")") << std::endl;
- }
- i_param->m_doesNeedEndl = false;
- generateKeyboardEvents(c);
-}
-
-// use a corresponding key of a current window
-void Engine::funcKeymapWindow(FunctionParam *i_param)
-{
- Current c(i_param->m_c);
- c.m_keymap = m_currentFocusOfThread->m_keymaps.front();
- c.m_i = m_currentFocusOfThread->m_keymaps.begin();
- generateKeyboardEvents(c);
-}
-
-// use a corresponding key of the previous prefixed keymap
-void Engine::funcKeymapPrevPrefix(FunctionParam *i_param, int i_previous)
-{
- Current c(i_param->m_c);
- if (0 < i_previous && 0 <= m_keymapPrefixHistory.size() - i_previous)
- {
- int n = i_previous - 1;
- KeymapPtrList::reverse_iterator i = m_keymapPrefixHistory.rbegin();
- while (0 < n && i != m_keymapPrefixHistory.rend())
- --n, ++i;
- c.m_keymap = *i;
- generateKeyboardEvents(c);
- }
-}
-
-// use a corresponding key of an other window class, or use a default key
-void Engine::funcOtherWindowClass(FunctionParam *i_param)
-{
- Current c(i_param->m_c);
- ++ c.m_i;
- if (c.m_i == m_currentFocusOfThread->m_keymaps.end())
- {
- funcDefault(i_param);
- return;
- }
-
- c.m_keymap = *c.m_i;
- {
- Acquire a(&m_log, 1);
- m_log << _T("(") << c.m_keymap->getName() << _T(")") << std::endl;
- }
- i_param->m_doesNeedEndl = false;
- generateKeyboardEvents(c);
-}
-
-// prefix key
-void Engine::funcPrefix(FunctionParam *i_param, const Keymap *i_keymap,
- BooleanType i_doesIgnoreModifiers)
-{
- if (!i_param->m_isPressed)
- return;
-
- setCurrentKeymap(i_keymap, true);
-
- // generate prefixed event
- generateEvents(i_param->m_c, m_currentKeymap, &Event::prefixed);
-
- m_isPrefix = true;
- m_doesEditNextModifier = false;
- m_doesIgnoreModifierForPrefix = !!i_doesIgnoreModifiers;
-
- {
- Acquire a(&m_log, 1);
- m_log << _T("(") << i_keymap->getName() << _T(", ")
- << (i_doesIgnoreModifiers ? _T("true") : _T("false")) << _T(")");
- }
-}
-
-// other keymap's key
-void Engine::funcKeymap(FunctionParam *i_param, const Keymap *i_keymap)
-{
- Current c(i_param->m_c);
- c.m_keymap = i_keymap;
- {
- Acquire a(&m_log, 1);
- m_log << _T("(") << c.m_keymap->getName() << _T(")") << std::endl;
- i_param->m_doesNeedEndl = false;
- }
- generateKeyboardEvents(c);
-}
-
-// sync
-void Engine::funcSync(FunctionParam *i_param)
-{
- if (i_param->m_isPressed)
- generateModifierEvents(i_param->m_af->m_modifier);
- if (!i_param->m_isPressed || m_currentFocusOfThread->m_isConsole)
- return;
-
- Key *sync = m_setting->m_keyboard.getSyncKey();
- if (sync->getScanCodesSize() == 0)
- return;
- const ScanCode *sc = sync->getScanCodes();
-
- // set variables exported from mayu.dll
- g_hookData->m_syncKey = sc->m_scan;
- g_hookData->m_syncKeyIsExtended = !!(sc->m_flags & ScanCode::E0E1);
- m_isSynchronizing = true;
-#if defined(_WINNT)
- generateKeyEvent(sync, false, false);
-#elif defined(_WIN95)
- generateKeyEvent(sync, true, false);
-#else
-# error
-#endif
-
- m_cs.release();
- DWORD r = WaitForSingleObject(m_eSync, 5000);
- if (r == WAIT_TIMEOUT)
- {
- Acquire a(&m_log, 0);
- m_log << _T(" *FAILED*") << std::endl;
- }
- m_cs.acquire();
- m_isSynchronizing = false;
-}
-
-// toggle lock
-void Engine::funcToggle(FunctionParam *i_param, ModifierLockType i_lock,
- ToggleType i_toggle)
-{
- if (i_param->m_isPressed) // ignore PRESS
- return;
-
- Modifier::Type mt = static_cast<Modifier::Type>(i_lock);
- switch (i_toggle)
- {
- case ToggleType_toggle:
- m_currentLock.press(mt, !m_currentLock.isPressed(mt));
- break;
- case ToggleType_off:
- m_currentLock.press(mt, false);
- break;
- case ToggleType_on:
- m_currentLock.press(mt, true);
- break;
- }
-}
-
-// edit next user input key's modifier
-void Engine::funcEditNextModifier(FunctionParam *i_param,
- const Modifier &i_modifier)
-{
- if (!i_param->m_isPressed)
- return;
-
- m_isPrefix = true;
- m_doesEditNextModifier = true;
- m_doesIgnoreModifierForPrefix = true;
- m_modifierForNextKey = i_modifier;
-}
-
-// variable
-void Engine::funcVariable(FunctionParam *i_param, int i_mag, int i_inc)
-{
- if (!i_param->m_isPressed)
- return;
- m_variable *= i_mag;
- m_variable += i_inc;
-}
-
-// repeat N times
-void Engine::funcRepeat(FunctionParam *i_param, const KeySeq *i_keySeq,
- int i_max)
-{
- if (i_param->m_isPressed)
- {
- int end = MIN(m_variable, i_max);
- for (int i = 0; i < end - 1; ++ i)
- generateKeySeqEvents(i_param->m_c, i_keySeq, Part_all);
- if (0 < end)
- generateKeySeqEvents(i_param->m_c, i_keySeq, Part_down);
- }
- else
- generateKeySeqEvents(i_param->m_c, i_keySeq, Part_up);
-}
-
-// undefined (bell)
-void Engine::funcUndefined(FunctionParam *i_param)
-{
- if (!i_param->m_isPressed)
- return;
- MessageBeep(MB_OK);
-}
-
-// ignore
-void Engine::funcIgnore(FunctionParam *)
-{
- // do nothing
-}
-
-// post message
-void Engine::funcPostMessage(FunctionParam *i_param, ToWindowType i_window,
- UINT i_message, WPARAM i_wParam, LPARAM i_lParam)
-{
- if (!i_param->m_isPressed)
- return;
-
- int window = static_cast<int>(i_window);
-
- HWND hwnd = i_param->m_hwnd;
- if (0 < window)
- {
- for (int i = 0; i < window; ++ i)
- hwnd = GetParent(hwnd);
- }
- else if (window == ToWindowType_toMainWindow)
- {
- while (true)
- {
- HWND p = GetParent(hwnd);
- if (!p)
- break;
- hwnd = p;
- }
- }
- else if (window == ToWindowType_toOverlappedWindow)
- {
- while (hwnd)
- {
- LONG style = GetWindowLong(hwnd, GWL_STYLE);
- if ((style & WS_CHILD) == 0)
- break;
- hwnd = GetParent(hwnd);
- }
- }
-
- if (hwnd)
- PostMessage(hwnd, i_message, i_wParam, i_lParam);
-}
-
-
-// ShellExecute
-void Engine::funcShellExecute(FunctionParam *i_param,
- const StrExprArg &/*i_operation*/,
- const StrExprArg &/*i_file*/,
- const StrExprArg &/*i_parameters*/,
- const StrExprArg &/*i_directory*/,
- ShowCommandType /*i_showCommand*/)
-{
- if (!i_param->m_isPressed)
- return;
- m_afShellExecute = i_param->m_af;
- PostMessage(m_hwndAssocWindow,
- WM_APP_engineNotify, EngineNotify_shellExecute, 0);
-}
-
-
-// shell execute
-void Engine::shellExecute()
-{
- Acquire a(&m_cs);
-
- FunctionData_ShellExecute *fd =
- reinterpret_cast<FunctionData_ShellExecute *>(
- m_afShellExecute->m_functionData);
-
- int r = (int)ShellExecute(
- NULL,
- fd->m_operation.eval().empty() ? _T("open") : fd->m_operation.eval().c_str(),
- fd->m_file.eval().empty() ? NULL : fd->m_file.eval().c_str(),
- fd->m_parameters.eval().empty() ? NULL : fd->m_parameters.eval().c_str(),
- fd->m_directory.eval().empty() ? NULL : fd->m_directory.eval().c_str(),
- fd->m_showCommand);
- if (32 < r)
- return; // success
-
- typedef TypeTable<int> ErrorTable;
- static const ErrorTable errorTable[] =
- {
- { 0, _T("The operating system is out of memory or resources.") },
- { ERROR_FILE_NOT_FOUND, _T("The specified file was not found.") },
- { ERROR_PATH_NOT_FOUND, _T("The specified path was not found.") },
- { ERROR_BAD_FORMAT, _T("The .exe file is invalid ")
- _T("(non-Win32R .exe or error in .exe image).") },
- { SE_ERR_ACCESSDENIED,
- _T("The operating system denied access to the specified file.") },
- { SE_ERR_ASSOCINCOMPLETE,
- _T("The file name association is incomplete or invalid.") },
- { SE_ERR_DDEBUSY,
- _T("The DDE transaction could not be completed ")
- _T("because other DDE transactions were being processed. ") },
- { SE_ERR_DDEFAIL, _T("The DDE transaction failed.") },
- { SE_ERR_DDETIMEOUT, _T("The DDE transaction could not be completed ")
- _T("because the request timed out.") },
- { SE_ERR_DLLNOTFOUND,
- _T("The specified dynamic-link library was not found.") },
- { SE_ERR_FNF, _T("The specified file was not found.") },
- { SE_ERR_NOASSOC, _T("There is no application associated ")
- _T("with the given file name extension.") },
- { SE_ERR_OOM,
- _T("There was not enough memory to complete the operation.") },
- { SE_ERR_PNF, _T("The specified path was not found.") },
- { SE_ERR_SHARE, _T("A sharing violation occurred.") },
- };
-
- tstring errorMessage(_T("Unknown error."));
- getTypeName(&errorMessage, r, errorTable, NUMBER_OF(errorTable));
-
- Acquire b(&m_log, 0);
- m_log << _T("error: ") << fd << _T(": ") << errorMessage << std::endl;
-}
-
-
-struct EnumWindowsForSetForegroundWindowParam
-{
- const FunctionData_SetForegroundWindow *m_fd;
- HWND m_hwnd;
-
-public:
- EnumWindowsForSetForegroundWindowParam(
- const FunctionData_SetForegroundWindow *i_fd)
- : m_fd(i_fd),
- m_hwnd(NULL)
- {
- }
-};
-
-
-/// enum windows for SetForegroundWindow
-static BOOL CALLBACK enumWindowsForSetForegroundWindow(
- HWND i_hwnd, LPARAM i_lParam)
-{
- EnumWindowsForSetForegroundWindowParam &ep =
- *reinterpret_cast<EnumWindowsForSetForegroundWindowParam *>(i_lParam);
-
- _TCHAR name[GANA_MAX_ATOM_LENGTH];
- if (!GetClassName(i_hwnd, name, NUMBER_OF(name)))
- return TRUE;
- tsmatch what;
- if (!boost::regex_search(tstring(name), what, ep.m_fd->m_windowClassName))
- if (ep.m_fd->m_logicalOp == LogicalOperatorType_and)
- return TRUE; // match failed
-
- if (ep.m_fd->m_logicalOp == LogicalOperatorType_and)
- {
- if (GetWindowText(i_hwnd, name, NUMBER_OF(name)) == 0)
- name[0] = _T('\0');
- if (!boost::regex_search(tstring(name), what,
- ep.m_fd->m_windowTitleName))
- return TRUE; // match failed
- }
-
- ep.m_hwnd = i_hwnd;
- return FALSE;
-}
-
-
-/// SetForegroundWindow
-void Engine::funcSetForegroundWindow(FunctionParam *i_param, const tregex &,
- LogicalOperatorType , const tregex &)
-{
- if (!i_param->m_isPressed)
- return;
- EnumWindowsForSetForegroundWindowParam
- ep(static_cast<const FunctionData_SetForegroundWindow *>(
- i_param->m_af->m_functionData));
- EnumWindows(enumWindowsForSetForegroundWindow,
- reinterpret_cast<LPARAM>(&ep));
- if (ep.m_hwnd)
- PostMessage(m_hwndAssocWindow,
- WM_APP_engineNotify, EngineNotify_setForegroundWindow,
- reinterpret_cast<LPARAM>(ep.m_hwnd));
-
-}
-
-
-// load setting
-void Engine::funcLoadSetting(FunctionParam *i_param, const StrExprArg &i_name)
-{
- if (!i_param->m_isPressed)
- return;
- if (!i_name.eval().empty())
- {
- // set MAYU_REGISTRY_ROOT\.mayuIndex which name is same with i_name
- Registry reg(MAYU_REGISTRY_ROOT);
-
- tregex split(_T("^([^;]*);([^;]*);(.*)$"));
- tstringi dot_mayu;
- for (size_t i = 0; i < MAX_MAYU_REGISTRY_ENTRIES; ++ i)
- {
- _TCHAR buf[100];
- _sntprintf(buf, NUMBER_OF(buf), _T(".mayu%d"), i);
- if (!reg.read(buf, &dot_mayu))
- break;
-
- tsmatch what;
- if (boost::regex_match(dot_mayu, what, split) &&
- what.str(1) == i_name.eval())
- {
- reg.write(_T(".mayuIndex"), i);
- goto success;
- }
- }
-
- {
- Acquire a(&m_log, 0);
- m_log << _T("unknown setting name: ") << i_name;
- }
- return;
-
- success: ;
- }
- PostMessage(m_hwndAssocWindow,
- WM_APP_engineNotify, EngineNotify_loadSetting, 0);
-}
-
-// virtual key
-void Engine::funcVK(FunctionParam *i_param, VKey i_vkey)
-{
- long key = static_cast<long>(i_vkey);
- BYTE vkey = static_cast<BYTE>(i_vkey);
- bool isExtended = !!(key & VKey_extended);
- bool isUp = !i_param->m_isPressed && !!(key & VKey_released);
- bool isDown = i_param->m_isPressed && !!(key & VKey_pressed);
-
- if (vkey == VK_LBUTTON && isDown)
- mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
- else if (vkey == VK_LBUTTON && isUp)
- mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
- else if (vkey == VK_MBUTTON && isDown)
- mouse_event(MOUSEEVENTF_MIDDLEDOWN, 0, 0, 0, 0);
- else if (vkey == VK_MBUTTON && isUp)
- mouse_event(MOUSEEVENTF_MIDDLEUP, 0, 0, 0, 0);
- else if (vkey == VK_RBUTTON && isDown)
- mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);
- else if (vkey == VK_RBUTTON && isUp)
- mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
-#if(_WIN32_WINNT >= 0x0500)
- else if (vkey == VK_XBUTTON1 && isDown)
- mouse_event(MOUSEEVENTF_XDOWN, 0, 0, XBUTTON1, 0);
- else if (vkey == VK_XBUTTON1 && isUp)
- mouse_event(MOUSEEVENTF_XUP, 0, 0, XBUTTON1, 0);
- else if (vkey == VK_XBUTTON2 && isDown)
- mouse_event(MOUSEEVENTF_XDOWN, 0, 0, XBUTTON2, 0);
- else if (vkey == VK_XBUTTON2 && isUp)
- mouse_event(MOUSEEVENTF_XUP, 0, 0, XBUTTON2, 0);
-#endif /* _WIN32_WINNT >= 0x0500 */
- else if (isUp || isDown)
- keybd_event(vkey,
- static_cast<BYTE>(MapVirtualKey(vkey, 0)),
- (isExtended ? KEYEVENTF_EXTENDEDKEY : 0) |
- (i_param->m_isPressed ? 0 : KEYEVENTF_KEYUP), 0);
-}
-
-// wait
-void Engine::funcWait(FunctionParam *i_param, int i_milliSecond)
-{
- if (!i_param->m_isPressed)
- return;
- if (i_milliSecond < 0 || 5000 < i_milliSecond) // too long wait
- return;
-
- m_isSynchronizing = true;
- m_cs.release();
- Sleep(i_milliSecond);
- m_cs.acquire();
- m_isSynchronizing = false;
-}
-
-// investigate WM_COMMAND, WM_SYSCOMMAND
-void Engine::funcInvestigateCommand(FunctionParam *i_param)
-{
- if (!i_param->m_isPressed)
- return;
- Acquire a(&m_log, 0);
- g_hookData->m_doesNotifyCommand = !g_hookData->m_doesNotifyCommand;
- if (g_hookData->m_doesNotifyCommand)
- m_log << _T(" begin") << std::endl;
- else
- m_log << _T(" end") << std::endl;
-}
-
-// show mayu dialog box
-void Engine::funcMayuDialog(FunctionParam *i_param, MayuDialogType i_dialog,
- ShowCommandType i_showCommand)
-{
- if (!i_param->m_isPressed)
- return;
- PostMessage(getAssociatedWndow(), WM_APP_engineNotify, EngineNotify_showDlg,
- static_cast<LPARAM>(i_dialog) |
- static_cast<LPARAM>(i_showCommand));
-}
-
-// describe bindings
-void Engine::funcDescribeBindings(FunctionParam *i_param)
-{
- if (!i_param->m_isPressed)
- return;
- {
- Acquire a(&m_log, 1);
- m_log << std::endl;
- }
- describeBindings();
-}
-
-// show help message
-void Engine::funcHelpMessage(FunctionParam *i_param, const StrExprArg &i_title,
- const StrExprArg &i_message)
-{
- if (!i_param->m_isPressed)
- return;
-
- m_helpTitle = i_title.eval();
- m_helpMessage = i_message.eval();
- bool doesShow = !(i_title.eval().size() == 0 && i_message.eval().size() == 0);
- PostMessage(getAssociatedWndow(), WM_APP_engineNotify,
- EngineNotify_helpMessage, doesShow);
-}
-
-// show variable
-void Engine::funcHelpVariable(FunctionParam *i_param, const StrExprArg &i_title)
-{
- if (!i_param->m_isPressed)
- return;
-
- _TCHAR buf[20];
- _sntprintf(buf, NUMBER_OF(buf), _T("%d"), m_variable);
-
- m_helpTitle = i_title.eval();
- m_helpMessage = buf;
- PostMessage(getAssociatedWndow(), WM_APP_engineNotify,
- EngineNotify_helpMessage, true);
-}
-
-// raise window
-void Engine::funcWindowRaise(FunctionParam *i_param,
- TargetWindowType i_twt)
-{
- HWND hwnd;
- if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt))
- return;
- SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,
- SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSIZE);
-}
-
-// lower window
-void Engine::funcWindowLower(FunctionParam *i_param, TargetWindowType i_twt)
-{
- HWND hwnd;
- if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt))
- return;
- SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0,
- SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSIZE);
-}
-
-// minimize window
-void Engine::funcWindowMinimize(FunctionParam *i_param, TargetWindowType i_twt)
-{
- HWND hwnd;
- if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt))
- return;
- PostMessage(hwnd, WM_SYSCOMMAND,
- IsIconic(hwnd) ? SC_RESTORE : SC_MINIMIZE, 0);
-}
-
-// maximize window
-void Engine::funcWindowMaximize(FunctionParam *i_param, TargetWindowType i_twt)
-{
- HWND hwnd;
- if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt))
- return;
- PostMessage(hwnd, WM_SYSCOMMAND,
- IsZoomed(hwnd) ? SC_RESTORE : SC_MAXIMIZE, 0);
-}
-
-// maximize horizontally or virtically
-void Engine::funcWindowHVMaximize(FunctionParam *i_param,
- BooleanType i_isHorizontal,
- TargetWindowType i_twt)
-{
- HWND hwnd;
- RECT rc, rcd;
- if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt, &rc, &rcd))
- return;
-
- // erase non window
- while (true)
- {
- WindowPositions::iterator i = m_windowPositions.begin();
- WindowPositions::iterator end = m_windowPositions.end();
- for (; i != end; ++ i)
- if (!IsWindow((*i).m_hwnd))
- break;
- if (i == end)
- break;
- m_windowPositions.erase(i);
- }
-
- // find target
- WindowPositions::iterator i = m_windowPositions.begin();
- WindowPositions::iterator end = m_windowPositions.end();
- WindowPositions::iterator target = end;
- for (; i != end; ++ i)
- if ((*i).m_hwnd == hwnd)
- {
- target = i;
- break;
- }
-
- if (IsZoomed(hwnd))
- PostMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0);
- else
- {
- WindowPosition::Mode mode = WindowPosition::Mode_normal;
-
- if (target != end)
- {
- WindowPosition &wp = *target;
- rc = wp.m_rc;
- if (wp.m_mode == WindowPosition::Mode_HV)
- mode = wp.m_mode =
- i_isHorizontal ? WindowPosition::Mode_V : WindowPosition::Mode_H;
- else if (( i_isHorizontal && wp.m_mode == WindowPosition::Mode_V) ||
- (!i_isHorizontal && wp.m_mode == WindowPosition::Mode_H))
- mode = wp.m_mode = WindowPosition::Mode_HV;
- else
- m_windowPositions.erase(target);
- }
- else
- {
- mode = i_isHorizontal ? WindowPosition::Mode_H : WindowPosition::Mode_V;
- m_windowPositions.push_front(WindowPosition(hwnd, rc, mode));
- }
-
- if (static_cast<int>(mode) & static_cast<int>(WindowPosition::Mode_H))
- rc.left = rcd.left, rc.right = rcd.right;
- if (static_cast<int>(mode) & static_cast<int>(WindowPosition::Mode_V))
- rc.top = rcd.top, rc.bottom = rcd.bottom;
-
- asyncMoveWindow(hwnd, rc.left, rc.top, rcWidth(&rc), rcHeight(&rc));
- }
-}
-
-// maximize window horizontally
-void Engine::funcWindowHMaximize(FunctionParam *i_param,
- TargetWindowType i_twt)
-{
- funcWindowHVMaximize(i_param, BooleanType_true, i_twt);
-}
-
-// maximize window virtically
-void Engine::funcWindowVMaximize(FunctionParam *i_param,
- TargetWindowType i_twt)
-{
- funcWindowHVMaximize(i_param, BooleanType_false, i_twt);
-}
-
-// move window
-void Engine::funcWindowMove(FunctionParam *i_param, int i_dx, int i_dy,
- TargetWindowType i_twt)
-{
- funcWindowMoveTo(i_param, GravityType_C, i_dx, i_dy, i_twt);
-}
-
-// move window to ...
-void Engine::funcWindowMoveTo(FunctionParam *i_param,
- GravityType i_gravityType,
- int i_dx, int i_dy, TargetWindowType i_twt)
-{
- HWND hwnd;
- RECT rc, rcd;
- if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt, &rc, &rcd))
- return;
-
- int x = rc.left + i_dx;
- int y = rc.top + i_dy;
-
- if (i_gravityType & GravityType_N)
- y = i_dy + rcd.top;
- if (i_gravityType & GravityType_E)
- x = i_dx + rcd.right - rcWidth(&rc);
- if (i_gravityType & GravityType_W)
- x = i_dx + rcd.left;
- if (i_gravityType & GravityType_S)
- y = i_dy + rcd.bottom - rcHeight(&rc);
- asyncMoveWindow(hwnd, x, y);
-}
-
-
-// move window visibly
-void Engine::funcWindowMoveVisibly(FunctionParam *i_param,
- TargetWindowType i_twt)
-{
- HWND hwnd;
- RECT rc, rcd;
- if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt, &rc, &rcd))
- return;
-
- int x = rc.left;
- int y = rc.top;
- if (rc.left < rcd.left)
- x = rcd.left;
- else if (rcd.right < rc.right)
- x = rcd.right - rcWidth(&rc);
- if (rc.top < rcd.top)
- y = rcd.top;
- else if (rcd.bottom < rc.bottom)
- y = rcd.bottom - rcHeight(&rc);
- asyncMoveWindow(hwnd, x, y);
-}
-
-
-struct EnumDisplayMonitorsForWindowMonitorToParam
-{
- std::vector<HMONITOR> m_monitors;
- std::vector<MONITORINFO> m_monitorinfos;
- int m_primaryMonitorIdx;
- int m_currentMonitorIdx;
-
- HMONITOR m_hmon;
-
-public:
- EnumDisplayMonitorsForWindowMonitorToParam(HMONITOR i_hmon)
- : m_hmon(i_hmon),
- m_primaryMonitorIdx(-1), m_currentMonitorIdx(-1)
- {
- }
-};
-
-static BOOL CALLBACK enumDisplayMonitorsForWindowMonitorTo(
- HMONITOR i_hmon, HDC i_hdc, LPRECT i_rcMonitor, LPARAM i_data)
-{
- EnumDisplayMonitorsForWindowMonitorToParam &ep =
- *reinterpret_cast<EnumDisplayMonitorsForWindowMonitorToParam *>(i_data);
-
- ep.m_monitors.push_back(i_hmon);
-
- MONITORINFO mi;
- mi.cbSize = sizeof(mi);
- getMonitorInfo(i_hmon, &mi);
- ep.m_monitorinfos.push_back(mi);
-
- if(mi.dwFlags & MONITORINFOF_PRIMARY)
- ep.m_primaryMonitorIdx = ep.m_monitors.size() - 1;
- if(i_hmon == ep.m_hmon)
- ep.m_currentMonitorIdx = ep.m_monitors.size() - 1;
-
- return TRUE;
-}
-
-/// move window to other monitor
-void Engine::funcWindowMonitorTo(
- FunctionParam *i_param, WindowMonitorFromType i_fromType, int i_monitor,
- BooleanType i_adjustPos, BooleanType i_adjustSize)
-{
- HWND hwnd;
- if(! getSuitableWindow(i_param, &hwnd))
- return;
-
- HMONITOR hmonCur;
- hmonCur = monitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
-
- EnumDisplayMonitorsForWindowMonitorToParam ep(hmonCur);
- enumDisplayMonitors(NULL, NULL, enumDisplayMonitorsForWindowMonitorTo,
- reinterpret_cast<LPARAM>(&ep));
- if(ep.m_monitors.size() < 1 ||
- ep.m_primaryMonitorIdx < 0 || ep.m_currentMonitorIdx < 0)
- return;
-
- int targetIdx;
- switch(i_fromType) {
- case WindowMonitorFromType_primary:
- targetIdx = (ep.m_primaryMonitorIdx + i_monitor) % ep.m_monitors.size();
- break;
-
- case WindowMonitorFromType_current:
- targetIdx = (ep.m_currentMonitorIdx + i_monitor) % ep.m_monitors.size();
- break;
- }
- if(ep.m_currentMonitorIdx == targetIdx)
- return;
-
- RECT rcCur, rcTarget, rcWin;
- rcCur = ep.m_monitorinfos[ep.m_currentMonitorIdx].rcWork;
- rcTarget = ep.m_monitorinfos[targetIdx].rcWork;
- GetWindowRect(hwnd, &rcWin);
-
- int x = rcTarget.left + (rcWin.left - rcCur.left);
- int y = rcTarget.top + (rcWin.top - rcCur.top);
- int w = rcWidth(&rcWin);
- int h = rcHeight(&rcWin);
-
- if(i_adjustPos) {
- if(x + w > rcTarget.right)
- x = rcTarget.right - w;
- if(x < rcTarget.left)
- x = rcTarget.left;
- if(w > rcWidth(&rcTarget)) {
- x = rcTarget.left;
- w = rcWidth(&rcTarget);
- }
-
- if(y + h > rcTarget.bottom)
- y = rcTarget.bottom - h;
- if(y < rcTarget.top)
- y = rcTarget.top;
- if(h > rcHeight(&rcTarget)) {
- y = rcTarget.top;
- h = rcHeight(&rcTarget);
- }
- }
-
- if(i_adjustPos && i_adjustSize) {
- if(IsZoomed(hwnd))
- PostMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0);
- asyncMoveWindow(hwnd, x, y, w, h);
- } else {
- asyncMoveWindow(hwnd, x, y);
- }
-}
-
-/// move window to other monitor
-void Engine::funcWindowMonitor(
- FunctionParam *i_param, int i_monitor,
- BooleanType i_adjustPos, BooleanType i_adjustSize)
-{
- funcWindowMonitorTo(i_param, WindowMonitorFromType_primary, i_monitor,
- i_adjustPos, i_adjustSize);
-}
-
-
-//
-void Engine::funcWindowClingToLeft(FunctionParam *i_param,
- TargetWindowType i_twt)
-{
- funcWindowMoveTo(i_param, GravityType_W, 0, 0, i_twt);
-}
-
-//
-void Engine::funcWindowClingToRight(FunctionParam *i_param,
- TargetWindowType i_twt)
-{
- funcWindowMoveTo(i_param, GravityType_E, 0, 0, i_twt);
-}
-
-//
-void Engine::funcWindowClingToTop(FunctionParam *i_param,
- TargetWindowType i_twt)
-{
- funcWindowMoveTo(i_param, GravityType_N, 0, 0, i_twt);
-}
-
-//
-void Engine::funcWindowClingToBottom(FunctionParam *i_param,
- TargetWindowType i_twt)
-{
- funcWindowMoveTo(i_param, GravityType_S, 0, 0, i_twt);
-}
-
-// close window
-void Engine::funcWindowClose(FunctionParam *i_param, TargetWindowType i_twt)
-{
- HWND hwnd;
- if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt))
- return;
- PostMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0);
-}
-
-// toggle top-most flag of the window
-void Engine::funcWindowToggleTopMost(FunctionParam *i_param)
-{
- HWND hwnd;
- if (!getSuitableWindow(i_param, &hwnd))
- return;
- SetWindowPos(
- hwnd,
- (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) ?
- HWND_NOTOPMOST : HWND_TOPMOST,
- 0, 0, 0, 0,
- SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSIZE);
-}
-
-// identify the window
-void Engine::funcWindowIdentify(FunctionParam *i_param)
-{
- if (!i_param->m_isPressed)
- return;
-
- _TCHAR className[GANA_MAX_ATOM_LENGTH];
- bool ok = false;
- if (GetClassName(i_param->m_hwnd, className, NUMBER_OF(className)))
- {
- if (_tcsicmp(className, _T("ConsoleWindowClass")) == 0)
- {
- _TCHAR titleName[1024];
- if (GetWindowText(i_param->m_hwnd, titleName, NUMBER_OF(titleName)) == 0)
- titleName[0] = _T('\0');
- {
- Acquire a(&m_log, 1);
- m_log << _T("HWND:\t") << std::hex
- << reinterpret_cast<int>(i_param->m_hwnd)
- << std::dec << std::endl;
- }
- Acquire a(&m_log, 0);
- m_log << _T("CLASS:\t") << className << std::endl;
- m_log << _T("TITLE:\t") << titleName << std::endl;
-
- HWND hwnd = getToplevelWindow(i_param->m_hwnd, NULL);
- RECT rc;
- GetWindowRect(hwnd, &rc);
- m_log << _T("Toplevel Window Position/Size: (")
- << rc.left << _T(", ") << rc.top << _T(") / (")
- << rcWidth(&rc) << _T("x") << rcHeight(&rc)
- << _T(")") << std::endl;
-
- SystemParametersInfo(SPI_GETWORKAREA, 0, (void *)&rc, FALSE);
- m_log << _T("Desktop Window Position/Size: (")
- << rc.left << _T(", ") << rc.top << _T(") / (")
- << rcWidth(&rc) << _T("x") << rcHeight(&rc)
- << _T(")") << std::endl;
-
- m_log << std::endl;
- ok = true;
- }
- }
- if (!ok)
- {
- UINT WM_MAYU_MESSAGE = RegisterWindowMessage(
- addSessionId(WM_MAYU_MESSAGE_NAME).c_str());
- CHECK_TRUE( PostMessage(i_param->m_hwnd, WM_MAYU_MESSAGE,
- MayuMessage_notifyName, 0) );
- }
-}
-
-// set alpha blending parameter to the window
-void Engine::funcWindowSetAlpha(FunctionParam *i_param, int i_alpha)
-{
-#if defined(_WINNT)
- HWND hwnd;
- if (!getSuitableWindow(i_param, &hwnd))
- return;
-
- if (i_alpha < 0) // remove all alpha
- {
- for (WindowsWithAlpha::iterator i = m_windowsWithAlpha.begin();
- i != m_windowsWithAlpha.end(); ++ i)
- {
- SetWindowLong(*i, GWL_EXSTYLE,
- GetWindowLong(*i, GWL_EXSTYLE) & ~WS_EX_LAYERED);
- RedrawWindow(*i, NULL, NULL,
- RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
- }
- m_windowsWithAlpha.clear();
- }
- else
- {
- LONG exStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
- if (exStyle & WS_EX_LAYERED) // remove alpha
- {
- WindowsWithAlpha::iterator
- i = std::find(m_windowsWithAlpha.begin(), m_windowsWithAlpha.end(),
- hwnd);
- if (i == m_windowsWithAlpha.end())
- return; // already layered by the application
-
- m_windowsWithAlpha.erase(i);
-
- SetWindowLong(hwnd, GWL_EXSTYLE, exStyle & ~WS_EX_LAYERED);
- }
- else // add alpha
- {
- SetWindowLong(hwnd, GWL_EXSTYLE, exStyle | WS_EX_LAYERED);
- i_alpha %= 101;
- if (!setLayeredWindowAttributes(hwnd, 0,
- (BYTE)(255 * i_alpha / 100), LWA_ALPHA))
- {
- Acquire a(&m_log, 0);
- m_log << _T("error: &WindowSetAlpha(") << i_alpha
- << _T(") failed for HWND: ") << std::hex
- << hwnd << std::dec << std::endl;
- return;
- }
- m_windowsWithAlpha.push_front(hwnd);
- }
- RedrawWindow(hwnd, NULL, NULL,
- RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
- }
-#endif // _WINNT
-}
-
-
-// redraw the window
-void Engine::funcWindowRedraw(FunctionParam *i_param)
-{
- HWND hwnd;
- if (!getSuitableWindow(i_param, &hwnd))
- return;
- RedrawWindow(hwnd, NULL, NULL,
- RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
-}
-
-// resize window to
-void Engine::funcWindowResizeTo(FunctionParam *i_param, int i_width,
- int i_height, TargetWindowType i_twt)
-{
- HWND hwnd;
- RECT rc, rcd;
- if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt, &rc, &rcd))
- return;
-
- if (i_width == 0)
- i_width = rcWidth(&rc);
- else if (i_width < 0)
- i_width += rcWidth(&rcd);
-
- if (i_height == 0)
- i_height = rcHeight(&rc);
- else if (i_height < 0)
- i_height += rcHeight(&rcd);
-
- asyncResize(hwnd, i_width, i_height);
-}
-
-// move the mouse cursor
-void Engine::funcMouseMove(FunctionParam *i_param, int i_dx, int i_dy)
-{
- if (!i_param->m_isPressed)
- return;
- POINT pt;
- GetCursorPos(&pt);
- SetCursorPos(pt.x + i_dx, pt.y + i_dy);
-}
-
-// send a mouse-wheel-message to Windows
-void Engine::funcMouseWheel(FunctionParam *i_param, int i_delta)
-{
- if (!i_param->m_isPressed)
- return;
- mouse_event(MOUSEEVENTF_WHEEL, 0, 0, i_delta, 0);
-}
-
-// convert the contents of the Clipboard to upper case
-void Engine::funcClipboardChangeCase(FunctionParam *i_param,
- BooleanType i_doesConvertToUpperCase)
-{
- if (!i_param->m_isPressed)
- return;
-
- HGLOBAL hdata;
- const _TCHAR *text = getTextFromClipboard(&hdata);
- HGLOBAL hdataNew = NULL;
- if (text)
- {
- int size = static_cast<int>(GlobalSize(hdata));
- hdataNew = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, size);
- if (hdataNew)
- {
- if (_TCHAR *dataNew = reinterpret_cast<_TCHAR *>(GlobalLock(hdataNew)))
- {
- std::memcpy(dataNew, text, size);
- _TCHAR *dataEnd = dataNew + size;
- while (dataNew < dataEnd && *dataNew)
- {
- _TCHAR c = *dataNew;
- if (_istlead(c))
- dataNew += 2;
- else
- *dataNew++ =
- i_doesConvertToUpperCase ? _totupper(c) : _totlower(c);
- }
- GlobalUnlock(hdataNew);
- }
- }
- }
- closeClipboard(hdata, hdataNew);
-}
-
-// convert the contents of the Clipboard to upper case
-void Engine::funcClipboardUpcaseWord(FunctionParam *i_param)
-{
- funcClipboardChangeCase(i_param, BooleanType_true);
-}
-
-// convert the contents of the Clipboard to lower case
-void Engine::funcClipboardDowncaseWord(FunctionParam *i_param)
-{
- funcClipboardChangeCase(i_param, BooleanType_false);
-}
-
-// set the contents of the Clipboard to the string
-void Engine::funcClipboardCopy(FunctionParam *i_param, const StrExprArg &i_text)
-{
- if (!i_param->m_isPressed)
- return;
- if (!OpenClipboard(NULL))
- return;
-
- HGLOBAL hdataNew =
- GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
- (i_text.eval().size() + 1) * sizeof(_TCHAR));
- if (!hdataNew)
- return;
- _TCHAR *dataNew = reinterpret_cast<_TCHAR *>(GlobalLock(hdataNew));
- _tcscpy(dataNew, i_text.eval().c_str());
- GlobalUnlock(hdataNew);
- closeClipboard(NULL, hdataNew);
-}
-
-//
-void Engine::funcEmacsEditKillLinePred(
- FunctionParam *i_param, const KeySeq *i_keySeq1, const KeySeq *i_keySeq2)
-{
- m_emacsEditKillLine.m_doForceReset = false;
- if (!i_param->m_isPressed)
- return;
-
- int r = m_emacsEditKillLine.pred();
- const KeySeq *keySeq;
- if (r == 1)
- keySeq = i_keySeq1;
- else if (r == 2)
- keySeq = i_keySeq2;
- else // r == 0
- return;
- ASSERT(keySeq);
- generateKeySeqEvents(i_param->m_c, keySeq, Part_all);
-}
-
-//
-void Engine::funcEmacsEditKillLineFunc(FunctionParam *i_param)
-{
- if (!i_param->m_isPressed)
- return;
- m_emacsEditKillLine.func();
- m_emacsEditKillLine.m_doForceReset = false;
-}
-
-// clear log
-void Engine::funcLogClear(FunctionParam *i_param)
-{
- if (!i_param->m_isPressed)
- return;
- PostMessage(getAssociatedWndow(), WM_APP_engineNotify,
- EngineNotify_clearLog, 0);
-}
-
-// recenter
-void Engine::funcRecenter(FunctionParam *i_param)
-{
- if (!i_param->m_isPressed)
- return;
- if (m_hwndFocus)
- {
- UINT WM_MAYU_MESSAGE = RegisterWindowMessage(
- addSessionId(WM_MAYU_MESSAGE_NAME).c_str());
- PostMessage(m_hwndFocus, WM_MAYU_MESSAGE, MayuMessage_funcRecenter, 0);
- }
-}
-
-// set IME open status
-void Engine::funcSetImeStatus(FunctionParam *i_param, ToggleType i_toggle)
-{
- if (!i_param->m_isPressed)
- return;
- if (m_hwndFocus)
- {
- UINT WM_MAYU_MESSAGE = RegisterWindowMessage(
- addSessionId(WM_MAYU_MESSAGE_NAME).c_str());
- int status = -1;
- switch (i_toggle)
- {
- case ToggleType_toggle:
- status = -1;
- break;
- case ToggleType_off:
- status = 0;
- break;
- case ToggleType_on:
- status = 1;
- break;
- }
- PostMessage(m_hwndFocus, WM_MAYU_MESSAGE, MayuMessage_funcSetImeStatus, status);
- }
-}
-
-// set IME open status
-void Engine::funcSetImeString(FunctionParam *i_param, const StrExprArg &i_data)
-{
-#if defined(_WINNT)
- if (!i_param->m_isPressed)
- return;
- if (m_hwndFocus)
- {
- UINT WM_MAYU_MESSAGE = RegisterWindowMessage(
- addSessionId(WM_MAYU_MESSAGE_NAME).c_str());
- PostMessage(m_hwndFocus, WM_MAYU_MESSAGE, MayuMessage_funcSetImeString, i_data.eval().size() * sizeof(_TCHAR));
-
- DWORD len = 0;
- DWORD error;
- DisconnectNamedPipe(m_hookPipe);
- ConnectNamedPipe(m_hookPipe, NULL);
- error = WriteFile(m_hookPipe, i_data.eval().c_str(),
- i_data.eval().size() * sizeof(_TCHAR),
- &len, NULL);
-
- //FlushFileBuffers(m_hookPipe);
- }
-#else
- Acquire a(&m_log);
- m_log << _T("supported on only Windows NT/2000/XP") << std::endl;
-#endif
-}
-
-// Direct SSTP Server
-class DirectSSTPServer
-{
-public:
- tstring m_path;
- HWND m_hwnd;
- tstring m_name;
- tstring m_keroname;
-
-public:
- DirectSSTPServer()
- : m_hwnd(NULL)
- {
- }
-};
-
-
-class ParseDirectSSTPData
-{
- typedef boost::match_results<boost::regex::const_iterator> MR;
-
-public:
- typedef std::map<tstring, DirectSSTPServer> DirectSSTPServers;
-
-private:
- DirectSSTPServers *m_directSSTPServers;
-
-public:
- // constructor
- ParseDirectSSTPData(DirectSSTPServers *i_directSSTPServers)
- : m_directSSTPServers(i_directSSTPServers)
- {
- }
-
- bool operator()(const MR& i_what)
- {
-#ifdef _UNICODE
- tstring id(to_wstring(std::string(i_what[1].first, i_what[1].second)));
- tstring member(to_wstring(std::string(i_what[2].first, i_what[2].second)));
- tstring value(to_wstring(std::string(i_what[3].first, i_what[3].second)));
-#else
- tstring id(i_what[1].first, i_what[1].second);
- tstring member(i_what[2].first, i_what[2].second);
- tstring value(i_what[3].first, i_what[3].second);
-#endif
-
- if (member == _T("path"))
- (*m_directSSTPServers)[id].m_path = value;
- else if (member == _T("hwnd"))
- (*m_directSSTPServers)[id].m_hwnd =
- reinterpret_cast<HWND>(_ttoi(value.c_str()));
- else if (member == _T("name"))
- (*m_directSSTPServers)[id].m_name = value;
- else if (member == _T("keroname"))
- (*m_directSSTPServers)[id].m_keroname = value;
- return true;
- }
-};
-
-// Direct SSTP
-void Engine::funcDirectSSTP(FunctionParam *i_param,
- const tregex &i_name,
- const StrExprArg &i_protocol,
- const std::list<tstringq> &i_headers)
-{
- if (!i_param->m_isPressed)
- return;
-
- // check Direct SSTP server exist ?
- if (HANDLE hm = OpenMutex(MUTEX_ALL_ACCESS, FALSE, _T("sakura")))
- CloseHandle(hm);
- else
- {
- Acquire a(&m_log, 0);
- m_log << _T(" Error(1): Direct SSTP server does not exist.");
- return;
- }
-
- HANDLE hfm = OpenFileMapping(FILE_MAP_READ, FALSE, _T("Sakura"));
- if (!hfm)
- {
- Acquire a(&m_log, 0);
- m_log << _T(" Error(2): Direct SSTP server does not provide data.");
- return;
- }
-
- char *data =
- reinterpret_cast<char *>(MapViewOfFile(hfm, FILE_MAP_READ, 0, 0, 0));
- if (!data)
- {
- CloseHandle(hfm);
- Acquire a(&m_log, 0);
- m_log << _T(" Error(3): Direct SSTP server does not provide data.");
- return;
- }
-
- long length = *(long *)data;
- const char *begin = data + 4;
- const char *end = data + length;
- boost::regex getSakura("([0-9a-fA-F]{32})\\.([^\x01]+)\x01(.*?)\r\n");
-
- ParseDirectSSTPData::DirectSSTPServers servers;
- boost::regex_iterator<boost::regex::const_iterator>
- it(begin, end, getSakura), last;
- for (; it != last; ++it)
- ((ParseDirectSSTPData)(&servers))(*it);
-
- // make request
- tstring request;
- if (!i_protocol.eval().size())
- request += _T("NOTIFY SSTP/1.1");
- else
- request += i_protocol.eval();
- request += _T("\r\n");
-
- bool hasSender = false;
- for (std::list<tstringq>::const_iterator
- i = i_headers.begin(); i != i_headers.end(); ++ i)
- {
- if (_tcsnicmp(_T("Charset"), i->c_str(), 7) == 0 ||
- _tcsnicmp(_T("Hwnd"), i->c_str(), 4) == 0)
- continue;
- if (_tcsnicmp(_T("Sender"), i->c_str(), 6) == 0)
- hasSender = true;
- request += i->c_str();
- request += _T("\r\n");
- }
-
- if (!hasSender)
- {
- request += _T("Sender: ");
- request += loadString(IDS_mayu);
- request += _T("\r\n");
- }
-
- _TCHAR buf[100];
- _sntprintf(buf, NUMBER_OF(buf), _T("HWnd: %d\r\n"),
- reinterpret_cast<int>(m_hwndAssocWindow));
- request += buf;
-
-#ifdef _UNICODE
- request += _T("Charset: UTF-8\r\n");
-#else
- request += _T("Charset: Shift_JIS\r\n");
-#endif
- request += _T("\r\n");
-
-#ifdef _UNICODE
- std::string request_UTF_8 = to_UTF_8(request);
-#endif
-
- // send request to Direct SSTP Server which matches i_name;
- for (ParseDirectSSTPData::DirectSSTPServers::iterator
- i = servers.begin(); i != servers.end(); ++ i)
- {
- tsmatch what;
- if (boost::regex_match(i->second.m_name, what, i_name))
- {
- COPYDATASTRUCT cd;
- cd.dwData = 9801;
-#ifdef _UNICODE
- cd.cbData = request_UTF_8.size();
- cd.lpData = (void *)request_UTF_8.c_str();
-#else
- cd.cbData = request.size();
- cd.lpData = (void *)request.c_str();
-#endif
- DWORD result;
- SendMessageTimeout(i->second.m_hwnd, WM_COPYDATA,
- reinterpret_cast<WPARAM>(m_hwndAssocWindow),
- reinterpret_cast<LPARAM>(&cd),
- SMTO_ABORTIFHUNG | SMTO_BLOCK, 5000, &result);
- }
- }
-
- UnmapViewOfFile(data);
- CloseHandle(hfm);
-}
-
-
-namespace shu
-{
- class PlugIn
- {
- enum Type
- {
- Type_A,
- Type_W
- };
-
- private:
- HMODULE m_dll;
- FARPROC m_func;
- Type m_type;
- tstringq m_funcParam;
-
- public:
- PlugIn() : m_dll(NULL)
- {
- }
-
- ~PlugIn()
- {
- FreeLibrary(m_dll);
- }
-
- bool load(const tstringq &i_dllName, const tstringq &i_funcName,
- const tstringq &i_funcParam, tomsgstream &i_log)
- {
- m_dll = LoadLibrary((_T("Plugins\\") + i_dllName).c_str());
- if (!m_dll)
- {
- m_dll = LoadLibrary((_T("Plugin\\") + i_dllName).c_str());
- if (!m_dll)
- {
- m_dll = LoadLibrary(i_dllName.c_str());
- if (!m_dll)
- {
- Acquire a(&i_log);
- i_log << std::endl;
- i_log << _T("error: &PlugIn() failed to load ") << i_dllName << std::endl;
- return false;
- }
- }
- }
-
- // get function
-#ifdef UNICODE
-# define to_wstring
-#else
-# define to_string
-#endif
- m_type = Type_W;
- m_func = GetProcAddress(m_dll, to_string(_T("mayu") + i_funcName + _T("W")).c_str());
- if (!m_func)
- {
- m_type = Type_A;
- m_func
- = GetProcAddress(m_dll, to_string(_T("mayu") + i_funcName + _T("A")).c_str());
- if (!m_func)
- {
- m_func = GetProcAddress(m_dll, to_string(_T("mayu") + i_funcName).c_str());
- if (!m_func)
- {
- m_func = GetProcAddress(m_dll, to_string(i_funcName).c_str());
- if (!m_func)
- {
- Acquire a(&i_log);
- i_log << std::endl;
- i_log << _T("error: &PlugIn() failed to find function: ")
- << i_funcName << std::endl;
- return false;
- }
- }
- }
- }
-
- m_funcParam = i_funcParam;
- return true;
- }
-
- void exec()
- {
- ASSERT( m_dll );
- ASSERT( m_func );
-
- typedef void (WINAPI * PLUGIN_FUNCTION_A)(const char *i_arg);
- typedef void (WINAPI * PLUGIN_FUNCTION_W)(const wchar_t *i_arg);
- switch (m_type)
- {
- case Type_A:
- reinterpret_cast<PLUGIN_FUNCTION_A>(m_func)(to_string(m_funcParam).c_str());
- break;
- case Type_W:
- reinterpret_cast<PLUGIN_FUNCTION_W>(m_func)(to_wstring(m_funcParam).c_str());
- break;
- }
- }
-#undef to_string
-#undef to_wstring
- };
-
- static void plugInThread(void *i_plugin)
- {
- PlugIn *plugin = static_cast<PlugIn *>(i_plugin);
- plugin->exec();
- delete plugin;
- }
-}
-
-void Engine::funcPlugIn(FunctionParam *i_param,
- const StrExprArg &i_dllName,
- const StrExprArg &i_funcName,
- const StrExprArg &i_funcParam,
- BooleanType i_doesCreateThread)
-{
- if (!i_param->m_isPressed)
- return;
-
- shu::PlugIn *plugin = new shu::PlugIn();
- if (!plugin->load(i_dllName.eval(), i_funcName.eval(), i_funcParam.eval(), m_log))
- {
- delete plugin;
- return;
- }
- if (i_doesCreateThread)
- {
- if (_beginthread(shu::plugInThread, 0, plugin) == -1)
- {
- delete plugin;
- Acquire a(&m_log);
- m_log << std::endl;
- m_log << _T("error: &PlugIn() failed to create thread.");
- }
- return;
- }
- else
- plugin->exec();
-}
-
-
-void Engine::funcMouseHook(FunctionParam *i_param,
- MouseHookType i_hookType, int i_hookParam)
-{
- GetCursorPos(&g_hookData->m_mousePos);
- g_hookData->m_mouseHookType = i_hookType;
- g_hookData->m_mouseHookParam = i_hookParam;
-
- switch (i_hookType)
- {
- case MouseHookType_WindowMove:
- {
- // For this type, g_hookData->m_mouseHookParam means
- // target window type to move.
- HWND target;
- bool isMDI;
-
- // i_hooParam < 0 means target window to move is MDI.
- if (i_hookParam < 0)
- isMDI = true;
- else
- isMDI = false;
-
- // abs(i_hookParam) == 2: target is window under mouse cursor
- // otherwise: target is current focus window
- if (i_hookParam == 2 || i_hookParam == -2)
- target = WindowFromPoint(g_hookData->m_mousePos);
- else
- target = i_param->m_hwnd;
-
- g_hookData->m_hwndMouseHookTarget =
- getToplevelWindow(target, &isMDI);
- break;
- default:
- g_hookData->m_hwndMouseHookTarget = NULL;
- break;
- }
- }
- return;
-}
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// StrExpr
-class StrExpr
-{
-private:
- tstringq m_symbol;
-protected:
- static const Engine *s_engine;
-public:
- StrExpr(const tstringq &i_symbol) : m_symbol(i_symbol) {};
-
- virtual ~StrExpr() {};
-
- virtual StrExpr *clone() const
- {
- return new StrExpr(*this);
- }
-
- virtual tstringq eval() const
- {
- return m_symbol;
- }
-
- static void setEngine(const Engine *i_engine) { s_engine = i_engine; }
-};
-
-const Engine *StrExpr::s_engine = NULL;
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// StrExprClipboard
-class StrExprClipboard : public StrExpr
-{
-public:
- StrExprClipboard(const tstringq &i_symbol) : StrExpr(i_symbol) {};
-
- ~StrExprClipboard() {};
-
- StrExpr *clone() const
- {
- return new StrExprClipboard(*this);
- }
-
- tstringq eval() const
- {
- HGLOBAL g;
- const _TCHAR *text = getTextFromClipboard(&g);
- const tstring value(text == NULL ? _T("") : text);
- closeClipboard(g);
- return value;
- }
-};
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// StrExprWindowClassName
-class StrExprWindowClassName : public StrExpr
-{
-public:
- StrExprWindowClassName(const tstringq &i_symbol) : StrExpr(i_symbol) {};
-
- ~StrExprWindowClassName() {};
-
- StrExpr *clone() const
- {
- return new StrExprWindowClassName(*this);
- }
-
- tstringq eval() const
- {
- return s_engine->getCurrentWindowClassName();
- }
-};
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// StrExprWindowTitleName
-class StrExprWindowTitleName : public StrExpr
-{
-public:
- StrExprWindowTitleName(const tstringq &i_symbol) : StrExpr(i_symbol) {};
-
- ~StrExprWindowTitleName() {};
-
- StrExpr *clone() const
- {
- return new StrExprWindowTitleName(*this);
- }
-
- tstringq eval() const
- {
- return s_engine->getCurrentWindowTitleName();
- }
-};
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// StrExprArg
-
-
-// default constructor
-StrExprArg::StrExprArg()
-{
- m_expr = new StrExpr(_T(""));
-}
-
-
-// copy contructor
-StrExprArg::StrExprArg(const StrExprArg &i_data)
-{
- m_expr = i_data.m_expr->clone();
-}
-
-
-StrExprArg &StrExprArg::operator=(const StrExprArg &i_data)
-{
- if (i_data.m_expr == m_expr)
- return *this;
-
- delete m_expr;
- m_expr = i_data.m_expr->clone();
-
- return *this;
-}
-
-
-// initializer
-StrExprArg::StrExprArg(const tstringq &i_symbol, Type i_type)
-{
- switch (i_type)
- {
- case Literal:
- m_expr = new StrExpr(i_symbol);
- break;
- case Builtin:
- if (i_symbol == _T("Clipboard"))
- m_expr = new StrExprClipboard(i_symbol);
- else if (i_symbol == _T("WindowClassName"))
- m_expr = new StrExprWindowClassName(i_symbol);
- else if (i_symbol == _T("WindowTitleName"))
- m_expr = new StrExprWindowTitleName(i_symbol);
- break;
- default:
- break;
- }
-}
-
-
-StrExprArg::~StrExprArg()
-{
- delete m_expr;
-}
-
-
-tstringq StrExprArg::eval() const
-{
- return m_expr->eval();
-}
-
-void StrExprArg::setEngine(const Engine *i_engine)
-{
- StrExpr::setEngine(i_engine);
-}
-
-// stream output
-tostream &operator<<(tostream &i_ost, const StrExprArg &i_data)
-{
- i_ost << i_data.eval();
- return i_ost;
-}
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// function.cpp\r
+\r
+\r
+#include "engine.h"\r
+#include "hook.h"\r
+#include "mayu.h"\r
+#include "mayurc.h"\r
+#include "misc.h"\r
+#include "registry.h"\r
+#include "vkeytable.h"\r
+#include "windowstool.h"\r
+#include <algorithm>\r
+#include <process.h>\r
+\r
+#define FUNCTION_DATA\r
+#include "functions.h"\r
+#undef FUNCTION_DATA\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// TypeTable\r
+\r
+\r
+template <class T> class TypeTable\r
+{\r
+public:\r
+ T m_type;\r
+ const _TCHAR *m_name;\r
+};\r
+\r
+\r
+template <class T> static inline\r
+bool getTypeName(tstring *o_name, T i_type,\r
+ const TypeTable<T> *i_table, size_t i_n)\r
+{\r
+ for (size_t i = 0; i < i_n; ++ i)\r
+ if (i_table[i].m_type == i_type) {\r
+ *o_name = i_table[i].m_name;\r
+ return true;\r
+ }\r
+ return false;\r
+}\r
+\r
+template <class T> static inline\r
+bool getTypeValue(T *o_type, const tstringi &i_name,\r
+ const TypeTable<T> *i_table, size_t i_n)\r
+{\r
+ for (size_t i = 0; i < i_n; ++ i)\r
+ if (i_table[i].m_name == i_name) {\r
+ *o_type = i_table[i].m_type;\r
+ return true;\r
+ }\r
+ return false;\r
+}\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// VKey\r
+\r
+\r
+// stream output\r
+tostream &operator<<(tostream &i_ost, VKey i_data)\r
+{\r
+ if (i_data & VKey_extended)\r
+ i_ost << _T("E-");\r
+ if (i_data & VKey_released)\r
+ i_ost << _T("U-");\r
+ if (i_data & VKey_pressed)\r
+ i_ost << _T("D-");\r
+\r
+ u_int8 code = i_data & ~(VKey_extended | VKey_released | VKey_pressed);\r
+ const VKeyTable *vkt;\r
+ for (vkt = g_vkeyTable; vkt->m_name; ++ vkt)\r
+ if (vkt->m_code == code)\r
+ break;\r
+ if (vkt->m_name)\r
+ i_ost << vkt->m_name;\r
+ else\r
+ i_ost << _T("0x") << std::hex << code << std::dec;\r
+ return i_ost;\r
+}\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// ToWindowType\r
+\r
+\r
+// ToWindowType table\r
+typedef TypeTable<ToWindowType> TypeTable_ToWindowType;\r
+static const TypeTable_ToWindowType g_toWindowTypeTable[] = {\r
+ { ToWindowType_toOverlappedWindow, _T("toOverlappedWindow") },\r
+ { ToWindowType_toMainWindow, _T("toMainWindow") },\r
+ { ToWindowType_toItself, _T("toItself") },\r
+ { ToWindowType_toParentWindow, _T("toParentWindow") },\r
+};\r
+\r
+\r
+// stream output\r
+tostream &operator<<(tostream &i_ost, ToWindowType i_data)\r
+{\r
+ tstring name;\r
+ if (getTypeName(&name, i_data,\r
+ g_toWindowTypeTable, NUMBER_OF(g_toWindowTypeTable)))\r
+ i_ost << name;\r
+ else\r
+ i_ost << static_cast<int>(i_data);\r
+ return i_ost;\r
+}\r
+\r
+\r
+// get value of ToWindowType\r
+bool getTypeValue(ToWindowType *o_type, const tstring &i_name)\r
+{\r
+ return getTypeValue(o_type, i_name,\r
+ g_toWindowTypeTable, NUMBER_OF(g_toWindowTypeTable));\r
+}\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// GravityType\r
+\r
+\r
+// GravityType table\r
+typedef TypeTable<GravityType> TypeTable_GravityType;\r
+static const TypeTable_GravityType g_gravityTypeTable[] = {\r
+ { GravityType_C, _T("C") },\r
+ { GravityType_N, _T("N") },\r
+ { GravityType_E, _T("E") },\r
+ { GravityType_W, _T("W") },\r
+ { GravityType_S, _T("S") },\r
+ { GravityType_NW, _T("NW") },\r
+ { GravityType_NW, _T("WN") },\r
+ { GravityType_NE, _T("NE") },\r
+ { GravityType_NE, _T("EN") },\r
+ { GravityType_SW, _T("SW") },\r
+ { GravityType_SW, _T("WS") },\r
+ { GravityType_SE, _T("SE") },\r
+ { GravityType_SE, _T("ES") },\r
+};\r
+\r
+\r
+// stream output\r
+tostream &operator<<(tostream &i_ost, GravityType i_data)\r
+{\r
+ tstring name;\r
+ if (getTypeName(&name, i_data,\r
+ g_gravityTypeTable, NUMBER_OF(g_gravityTypeTable)))\r
+ i_ost << name;\r
+ else\r
+ i_ost << _T("(GravityType internal error)");\r
+ return i_ost;\r
+}\r
+\r
+\r
+// get value of GravityType\r
+bool getTypeValue(GravityType *o_type, const tstring &i_name)\r
+{\r
+ return getTypeValue(o_type, i_name,\r
+ g_gravityTypeTable, NUMBER_OF(g_gravityTypeTable));\r
+}\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// MouseHookType\r
+\r
+\r
+// MouseHookType table\r
+typedef TypeTable<MouseHookType> TypeTable_MouseHookType;\r
+static const TypeTable_MouseHookType g_mouseHookTypeTable[] = {\r
+ { MouseHookType_None, _T("None") },\r
+ { MouseHookType_Wheel, _T("Wheel") },\r
+ { MouseHookType_WindowMove, _T("WindowMove") },\r
+};\r
+\r
+\r
+// stream output\r
+tostream &operator<<(tostream &i_ost, MouseHookType i_data)\r
+{\r
+ tstring name;\r
+ if (getTypeName(&name, i_data,\r
+ g_mouseHookTypeTable, NUMBER_OF(g_mouseHookTypeTable)))\r
+ i_ost << name;\r
+ else\r
+ i_ost << _T("(MouseHookType internal error)");\r
+ return i_ost;\r
+}\r
+\r
+\r
+// get value of MouseHookType\r
+bool getTypeValue(MouseHookType *o_type, const tstring &i_name)\r
+{\r
+ return getTypeValue(o_type, i_name, g_mouseHookTypeTable,\r
+ NUMBER_OF(g_mouseHookTypeTable));\r
+}\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// MayuDialogType\r
+\r
+\r
+// ModifierLockType table\r
+typedef TypeTable<MayuDialogType> TypeTable_MayuDialogType;\r
+static const TypeTable_MayuDialogType g_mayuDialogTypeTable[] = {\r
+ { MayuDialogType_investigate, _T("investigate") },\r
+ { MayuDialogType_log, _T("log") },\r
+};\r
+\r
+\r
+// stream output\r
+tostream &operator<<(tostream &i_ost, MayuDialogType i_data)\r
+{\r
+ tstring name;\r
+ if (getTypeName(&name, i_data,\r
+ g_mayuDialogTypeTable, NUMBER_OF(g_mayuDialogTypeTable)))\r
+ i_ost << name;\r
+ else\r
+ i_ost << _T("(MayuDialogType internal error)");\r
+ return i_ost;\r
+}\r
+\r
+\r
+// get value of MayuDialogType\r
+bool getTypeValue(MayuDialogType *o_type, const tstring &i_name)\r
+{\r
+ return getTypeValue(o_type, i_name, g_mayuDialogTypeTable,\r
+ NUMBER_OF(g_mayuDialogTypeTable));\r
+}\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// ToggleType\r
+\r
+\r
+// ToggleType table\r
+typedef TypeTable<ToggleType> TypeTable_ToggleType;\r
+static const TypeTable_ToggleType g_toggleType[] = {\r
+ { ToggleType_toggle, _T("toggle") },\r
+ { ToggleType_off, _T("off") },\r
+ { ToggleType_off, _T("false") },\r
+ { ToggleType_off, _T("released") },\r
+ { ToggleType_on, _T("on") },\r
+ { ToggleType_on, _T("true") },\r
+ { ToggleType_on, _T("pressed") },\r
+};\r
+\r
+\r
+// stream output\r
+tostream &operator<<(tostream &i_ost, ToggleType i_data)\r
+{\r
+ tstring name;\r
+ if (getTypeName(&name, i_data, g_toggleType, NUMBER_OF(g_toggleType)))\r
+ i_ost << name;\r
+ else\r
+ i_ost << _T("(ToggleType internal error)");\r
+ return i_ost;\r
+}\r
+\r
+\r
+// get value of ToggleType\r
+bool getTypeValue(ToggleType *o_type, const tstring &i_name)\r
+{\r
+ return getTypeValue(o_type, i_name, g_toggleType,\r
+ NUMBER_OF(g_toggleType));\r
+}\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// ModifierLockType\r
+\r
+\r
+// ModifierLockType table\r
+typedef TypeTable<ModifierLockType> TypeTable_ModifierLockType;\r
+static const TypeTable_ModifierLockType g_modifierLockTypeTable[] = {\r
+ { ModifierLockType_Lock0, _T("lock0") },\r
+ { ModifierLockType_Lock1, _T("lock1") },\r
+ { ModifierLockType_Lock2, _T("lock2") },\r
+ { ModifierLockType_Lock3, _T("lock3") },\r
+ { ModifierLockType_Lock4, _T("lock4") },\r
+ { ModifierLockType_Lock5, _T("lock5") },\r
+ { ModifierLockType_Lock6, _T("lock6") },\r
+ { ModifierLockType_Lock7, _T("lock7") },\r
+ { ModifierLockType_Lock8, _T("lock8") },\r
+ { ModifierLockType_Lock9, _T("lock9") },\r
+};\r
+\r
+\r
+// stream output\r
+tostream &operator<<(tostream &i_ost, ModifierLockType i_data)\r
+{\r
+ tstring name;\r
+ if (getTypeName(&name, i_data,\r
+ g_modifierLockTypeTable, NUMBER_OF(g_modifierLockTypeTable)))\r
+ i_ost << name;\r
+ else\r
+ i_ost << _T("(ModifierLockType internal error)");\r
+ return i_ost;\r
+}\r
+\r
+\r
+// get value of ModifierLockType\r
+bool getTypeValue(ModifierLockType *o_type, const tstring &i_name)\r
+{\r
+ return getTypeValue(o_type, i_name, g_modifierLockTypeTable,\r
+ NUMBER_OF(g_modifierLockTypeTable));\r
+}\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// ShowCommandType\r
+\r
+\r
+// ShowCommandType table\r
+typedef TypeTable<ShowCommandType> TypeTable_ShowCommandType;\r
+static const TypeTable_ShowCommandType g_showCommandTypeTable[] = {\r
+ { ShowCommandType_hide, _T("hide") },\r
+ { ShowCommandType_maximize, _T("maximize") },\r
+ { ShowCommandType_minimize, _T("minimize") },\r
+ { ShowCommandType_restore, _T("restore") },\r
+ { ShowCommandType_show, _T("show") },\r
+ { ShowCommandType_showDefault, _T("showDefault") },\r
+ { ShowCommandType_showMaximized, _T("showMaximized") },\r
+ { ShowCommandType_showMinimized, _T("showMinimized") },\r
+ { ShowCommandType_showMinNoActive, _T("showMinNoActive") },\r
+ { ShowCommandType_showNA, _T("showNA") },\r
+ { ShowCommandType_showNoActivate, _T("showNoActivate") },\r
+ { ShowCommandType_showNormal, _T("showNormal") },\r
+};\r
+\r
+\r
+// stream output\r
+tostream &operator<<(tostream &i_ost, ShowCommandType i_data)\r
+{\r
+ tstring name;\r
+ if (getTypeName(&name, i_data,\r
+ g_showCommandTypeTable, NUMBER_OF(g_showCommandTypeTable)))\r
+ i_ost << name;\r
+ else\r
+ i_ost << _T("(ShowCommandType internal error)");\r
+ return i_ost;\r
+}\r
+\r
+\r
+// get value of ShowCommandType\r
+bool getTypeValue(ShowCommandType *o_type, const tstring &i_name)\r
+{\r
+ return getTypeValue(o_type, i_name, g_showCommandTypeTable,\r
+ NUMBER_OF(g_showCommandTypeTable));\r
+}\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// TargetWindowType\r
+\r
+\r
+// ModifierLockType table\r
+typedef TypeTable<TargetWindowType> TypeTable_TargetWindowType;\r
+static const TypeTable_TargetWindowType g_targetWindowType[] = {\r
+ { TargetWindowType_overlapped, _T("overlapped") },\r
+ { TargetWindowType_mdi, _T("mdi") },\r
+};\r
+\r
+\r
+// stream output\r
+tostream &operator<<(tostream &i_ost, TargetWindowType i_data)\r
+{\r
+ tstring name;\r
+ if (getTypeName(&name, i_data,\r
+ g_targetWindowType, NUMBER_OF(g_targetWindowType)))\r
+ i_ost << name;\r
+ else\r
+ i_ost << _T("(TargetWindowType internal error)");\r
+ return i_ost;\r
+}\r
+\r
+\r
+// get value of TargetWindowType\r
+bool getTypeValue(TargetWindowType *o_type, const tstring &i_name)\r
+{\r
+ return getTypeValue(o_type, i_name, g_targetWindowType,\r
+ NUMBER_OF(g_targetWindowType));\r
+}\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// BooleanType\r
+\r
+\r
+// BooleanType table\r
+typedef TypeTable<BooleanType> TypeTable_BooleanType;\r
+static const TypeTable_BooleanType g_booleanType[] = {\r
+ { BooleanType_false, _T("false") },\r
+ { BooleanType_true, _T("true") },\r
+};\r
+\r
+\r
+// stream output\r
+tostream &operator<<(tostream &i_ost, BooleanType i_data)\r
+{\r
+ tstring name;\r
+ if (getTypeName(&name, i_data, g_booleanType, NUMBER_OF(g_booleanType)))\r
+ i_ost << name;\r
+ else\r
+ i_ost << _T("(BooleanType internal error)");\r
+ return i_ost;\r
+}\r
+\r
+\r
+// get value of BooleanType\r
+bool getTypeValue(BooleanType *o_type, const tstring &i_name)\r
+{\r
+ return getTypeValue(o_type, i_name, g_booleanType,\r
+ NUMBER_OF(g_booleanType));\r
+}\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// LogicalOperatorType\r
+\r
+\r
+// LogicalOperatorType table\r
+typedef TypeTable<LogicalOperatorType> TypeTable_LogicalOperatorType;\r
+static const TypeTable_LogicalOperatorType g_logicalOperatorType[] = {\r
+ { LogicalOperatorType_or, _T("||") },\r
+ { LogicalOperatorType_and, _T("&&") },\r
+};\r
+\r
+\r
+// stream output\r
+tostream &operator<<(tostream &i_ost, LogicalOperatorType i_data)\r
+{\r
+ tstring name;\r
+ if (getTypeName(&name, i_data, g_logicalOperatorType,\r
+ NUMBER_OF(g_logicalOperatorType)))\r
+ i_ost << name;\r
+ else\r
+ i_ost << _T("(LogicalOperatorType internal error)");\r
+ return i_ost;\r
+}\r
+\r
+\r
+// get value of LogicalOperatorType\r
+bool getTypeValue(LogicalOperatorType *o_type, const tstring &i_name)\r
+{\r
+ return getTypeValue(o_type, i_name, g_logicalOperatorType,\r
+ NUMBER_OF(g_logicalOperatorType));\r
+}\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// WindowMonitorFromType\r
+\r
+\r
+// WindowMonitorFromType table\r
+typedef TypeTable<WindowMonitorFromType> TypeTable_WindowMonitorFromType;\r
+static const TypeTable_WindowMonitorFromType g_windowMonitorFromType[] = {\r
+ { WindowMonitorFromType_primary, _T("primary") },\r
+ { WindowMonitorFromType_current, _T("current") },\r
+};\r
+\r
+\r
+// stream output\r
+tostream &operator<<(tostream &i_ost, WindowMonitorFromType i_data)\r
+{\r
+ tstring name;\r
+ if (getTypeName(&name, i_data, g_windowMonitorFromType,\r
+ NUMBER_OF(g_windowMonitorFromType)))\r
+ i_ost << name;\r
+ else\r
+ i_ost << _T("(WindowMonitorFromType internal error)");\r
+ return i_ost;\r
+}\r
+\r
+\r
+// get value of WindowMonitorFromType\r
+bool getTypeValue(WindowMonitorFromType *o_type, const tstring &i_name)\r
+{\r
+ return getTypeValue(o_type, i_name, g_windowMonitorFromType,\r
+ NUMBER_OF(g_windowMonitorFromType));\r
+}\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// std::list<tstringq>\r
+\r
+\r
+/// stream output\r
+tostream &operator<<(tostream &i_ost, const std::list<tstringq> &i_data)\r
+{\r
+ for (std::list<tstringq>::const_iterator\r
+ i = i_data.begin(); i != i_data.end(); ++ i) {\r
+ i_ost << *i << _T(", ");\r
+ }\r
+ return i_ost;\r
+}\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// FunctionData\r
+\r
+\r
+//\r
+FunctionData::~FunctionData()\r
+{\r
+}\r
+\r
+\r
+// stream output\r
+tostream &operator<<(tostream &i_ost, const FunctionData *i_data)\r
+{\r
+ return i_data->output(i_ost);\r
+}\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// FunctionCreator\r
+\r
+\r
+///\r
+class FunctionCreator\r
+{\r
+public:\r
+ typedef FunctionData *(*Creator)(); ///\r
+\r
+public:\r
+ const _TCHAR *m_name; /// function name\r
+ Creator m_creator; /// function data creator\r
+};\r
+\r
+\r
+// create function\r
+FunctionData *createFunctionData(const tstring &i_name)\r
+{\r
+ static\r
+#define FUNCTION_CREATOR\r
+#include "functions.h"\r
+#undef FUNCTION_CREATOR\r
+ ;\r
+\r
+ for (size_t i = 0; i != NUMBER_OF(functionCreators); ++ i)\r
+ if (i_name == functionCreators[i].m_name)\r
+ return functionCreators[i].m_creator();\r
+ return NULL;\r
+}\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// misc. functions\r
+\r
+\r
+//\r
+bool getSuitableWindow(FunctionParam *i_param, HWND *o_hwnd)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return false;\r
+ *o_hwnd = getToplevelWindow(i_param->m_hwnd, NULL);\r
+ if (!*o_hwnd)\r
+ return false;\r
+ return true;\r
+}\r
+\r
+//\r
+bool getSuitableMdiWindow(FunctionParam *i_param, HWND *o_hwnd,\r
+ TargetWindowType *io_twt,\r
+ RECT *o_rcWindow = NULL, RECT *o_rcParent = NULL)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return false;\r
+ bool isMdi = *io_twt == TargetWindowType_mdi;\r
+ *o_hwnd = getToplevelWindow(i_param->m_hwnd, &isMdi);\r
+ *io_twt = isMdi ? TargetWindowType_mdi : TargetWindowType_overlapped;\r
+ if (!*o_hwnd)\r
+ return false;\r
+ switch (*io_twt) {\r
+ case TargetWindowType_overlapped:\r
+ if (o_rcWindow)\r
+ GetWindowRect(*o_hwnd, o_rcWindow);\r
+ if (o_rcParent) {\r
+ HMONITOR hm = monitorFromWindow(i_param->m_hwnd,\r
+ MONITOR_DEFAULTTONEAREST);\r
+ MONITORINFO mi;\r
+ mi.cbSize = sizeof(mi);\r
+ getMonitorInfo(hm, &mi);\r
+ *o_rcParent = mi.rcWork;\r
+ }\r
+ break;\r
+ case TargetWindowType_mdi:\r
+ if (o_rcWindow)\r
+ getChildWindowRect(*o_hwnd, o_rcWindow);\r
+ if (o_rcParent)\r
+ GetClientRect(GetParent(*o_hwnd), o_rcParent);\r
+ break;\r
+ }\r
+ return true;\r
+}\r
+\r
+// get clipboard text (you must call closeClopboard())\r
+static const _TCHAR *getTextFromClipboard(HGLOBAL *o_hdata)\r
+{\r
+ *o_hdata = NULL;\r
+\r
+ if (!OpenClipboard(NULL))\r
+ return NULL;\r
+\r
+#ifdef UNICODE\r
+ *o_hdata = GetClipboardData(CF_UNICODETEXT);\r
+#else\r
+ *o_hdata = GetClipboardData(CF_TEXT);\r
+#endif\r
+ if (!*o_hdata)\r
+ return NULL;\r
+\r
+ _TCHAR *data = reinterpret_cast<_TCHAR *>(GlobalLock(*o_hdata));\r
+ if (!data)\r
+ return NULL;\r
+ return data;\r
+}\r
+\r
+// close clipboard that opend by getTextFromClipboard()\r
+static void closeClipboard(HGLOBAL i_hdata, HGLOBAL i_hdataNew = NULL)\r
+{\r
+ if (i_hdata)\r
+ GlobalUnlock(i_hdata);\r
+ if (i_hdataNew) {\r
+ EmptyClipboard();\r
+#ifdef UNICODE\r
+ SetClipboardData(CF_UNICODETEXT, i_hdataNew);\r
+#else\r
+ SetClipboardData(CF_TEXT, i_hdataNew);\r
+#endif\r
+ }\r
+ CloseClipboard();\r
+}\r
+\r
+\r
+// EmacsEditKillLineFunc.\r
+// clear the contents of the clopboard\r
+// at that time, confirm if it is the result of the previous kill-line\r
+void Engine::EmacsEditKillLine::func()\r
+{\r
+ if (!m_buf.empty()) {\r
+ HGLOBAL g;\r
+ const _TCHAR *text = getTextFromClipboard(&g);\r
+ if (text == NULL || m_buf != text)\r
+ reset();\r
+ closeClipboard(g);\r
+ }\r
+ if (OpenClipboard(NULL)) {\r
+ EmptyClipboard();\r
+ CloseClipboard();\r
+ }\r
+}\r
+\r
+\r
+/** if the text of the clipboard is\r
+@doc\r
+<pre>\r
+1: EDIT Control (at EOL C-K): "" => buf + "\r\n", Delete\r
+0: EDIT Control (other C-K): "(.+)" => buf + "\1"\r
+0: IE FORM TEXTAREA (at EOL C-K): "\r\n" => buf + "\r\n"\r
+2: IE FORM TEXTAREA (other C-K): "(.+)\r\n" => buf + "\1", Return Left\r
+^retval\r
+</pre>\r
+*/\r
+HGLOBAL Engine::EmacsEditKillLine::makeNewKillLineBuf(\r
+ const _TCHAR *i_data, int *o_retval)\r
+{\r
+ size_t len = m_buf.size();\r
+ len += _tcslen(i_data) + 3;\r
+\r
+ HGLOBAL hdata = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,\r
+ len * sizeof(_TCHAR));\r
+ if (!hdata)\r
+ return NULL;\r
+ _TCHAR *dataNew = reinterpret_cast<_TCHAR *>(GlobalLock(hdata));\r
+ *dataNew = _T('\0');\r
+ if (!m_buf.empty())\r
+ _tcscpy(dataNew, m_buf.c_str());\r
+\r
+ len = _tcslen(i_data);\r
+ if (3 <= len &&\r
+ i_data[len - 2] == _T('\r') && i_data[len - 1] == _T('\n')) {\r
+ _tcscat(dataNew, i_data);\r
+ len = _tcslen(dataNew);\r
+ dataNew[len - 2] = _T('\0'); // chomp\r
+ *o_retval = 2;\r
+ } else if (len == 0) {\r
+ _tcscat(dataNew, _T("\r\n"));\r
+ *o_retval = 1;\r
+ } else {\r
+ _tcscat(dataNew, i_data);\r
+ *o_retval = 0;\r
+ }\r
+\r
+ m_buf = dataNew;\r
+\r
+ GlobalUnlock(hdata);\r
+ return hdata;\r
+}\r
+\r
+\r
+// EmacsEditKillLinePred\r
+int Engine::EmacsEditKillLine::pred()\r
+{\r
+ HGLOBAL g;\r
+ const _TCHAR *text = getTextFromClipboard(&g);\r
+ int retval;\r
+ HGLOBAL hdata = makeNewKillLineBuf(text ? text : _T(""), &retval);\r
+ closeClipboard(g, hdata);\r
+ return retval;\r
+}\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// functions\r
+\r
+\r
+// send a default key to Windows\r
+void Engine::funcDefault(FunctionParam *i_param)\r
+{\r
+ {\r
+ Acquire a(&m_log, 1);\r
+ m_log << std::endl;\r
+ i_param->m_doesNeedEndl = false;\r
+ }\r
+ if (i_param->m_isPressed)\r
+ generateModifierEvents(i_param->m_c.m_mkey.m_modifier);\r
+ generateKeyEvent(i_param->m_c.m_mkey.m_key, i_param->m_isPressed, true);\r
+}\r
+\r
+// use a corresponding key of a parent keymap\r
+void Engine::funcKeymapParent(FunctionParam *i_param)\r
+{\r
+ Current c(i_param->m_c);\r
+ c.m_keymap = c.m_keymap->getParentKeymap();\r
+ if (!c.m_keymap) {\r
+ funcDefault(i_param);\r
+ return;\r
+ }\r
+\r
+ {\r
+ Acquire a(&m_log, 1);\r
+ m_log << _T("(") << c.m_keymap->getName() << _T(")") << std::endl;\r
+ }\r
+ i_param->m_doesNeedEndl = false;\r
+ generateKeyboardEvents(c);\r
+}\r
+\r
+// use a corresponding key of a current window\r
+void Engine::funcKeymapWindow(FunctionParam *i_param)\r
+{\r
+ Current c(i_param->m_c);\r
+ c.m_keymap = m_currentFocusOfThread->m_keymaps.front();\r
+ c.m_i = m_currentFocusOfThread->m_keymaps.begin();\r
+ generateKeyboardEvents(c);\r
+}\r
+\r
+// use a corresponding key of the previous prefixed keymap\r
+void Engine::funcKeymapPrevPrefix(FunctionParam *i_param, int i_previous)\r
+{\r
+ Current c(i_param->m_c);\r
+ if (0 < i_previous && 0 <= m_keymapPrefixHistory.size() - i_previous) {\r
+ int n = i_previous - 1;\r
+ KeymapPtrList::reverse_iterator i = m_keymapPrefixHistory.rbegin();\r
+ while (0 < n && i != m_keymapPrefixHistory.rend())\r
+ --n, ++i;\r
+ c.m_keymap = *i;\r
+ generateKeyboardEvents(c);\r
+ }\r
+}\r
+\r
+// use a corresponding key of an other window class, or use a default key\r
+void Engine::funcOtherWindowClass(FunctionParam *i_param)\r
+{\r
+ Current c(i_param->m_c);\r
+ ++ c.m_i;\r
+ if (c.m_i == m_currentFocusOfThread->m_keymaps.end()) {\r
+ funcDefault(i_param);\r
+ return;\r
+ }\r
+\r
+ c.m_keymap = *c.m_i;\r
+ {\r
+ Acquire a(&m_log, 1);\r
+ m_log << _T("(") << c.m_keymap->getName() << _T(")") << std::endl;\r
+ }\r
+ i_param->m_doesNeedEndl = false;\r
+ generateKeyboardEvents(c);\r
+}\r
+\r
+// prefix key\r
+void Engine::funcPrefix(FunctionParam *i_param, const Keymap *i_keymap,\r
+ BooleanType i_doesIgnoreModifiers)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+\r
+ setCurrentKeymap(i_keymap, true);\r
+\r
+ // generate prefixed event\r
+ generateEvents(i_param->m_c, m_currentKeymap, &Event::prefixed);\r
+\r
+ m_isPrefix = true;\r
+ m_doesEditNextModifier = false;\r
+ m_doesIgnoreModifierForPrefix = !!i_doesIgnoreModifiers;\r
+\r
+ {\r
+ Acquire a(&m_log, 1);\r
+ m_log << _T("(") << i_keymap->getName() << _T(", ")\r
+ << (i_doesIgnoreModifiers ? _T("true") : _T("false")) << _T(")");\r
+ }\r
+}\r
+\r
+// other keymap's key\r
+void Engine::funcKeymap(FunctionParam *i_param, const Keymap *i_keymap)\r
+{\r
+ Current c(i_param->m_c);\r
+ c.m_keymap = i_keymap;\r
+ {\r
+ Acquire a(&m_log, 1);\r
+ m_log << _T("(") << c.m_keymap->getName() << _T(")") << std::endl;\r
+ i_param->m_doesNeedEndl = false;\r
+ }\r
+ generateKeyboardEvents(c);\r
+}\r
+\r
+// sync\r
+void Engine::funcSync(FunctionParam *i_param)\r
+{\r
+ if (i_param->m_isPressed)\r
+ generateModifierEvents(i_param->m_af->m_modifier);\r
+ if (!i_param->m_isPressed || m_currentFocusOfThread->m_isConsole)\r
+ return;\r
+\r
+ Key *sync = m_setting->m_keyboard.getSyncKey();\r
+ if (sync->getScanCodesSize() == 0)\r
+ return;\r
+ const ScanCode *sc = sync->getScanCodes();\r
+\r
+ // set variables exported from mayu.dll\r
+ g_hookData->m_syncKey = sc->m_scan;\r
+ g_hookData->m_syncKeyIsExtended = !!(sc->m_flags & ScanCode::E0E1);\r
+ m_isSynchronizing = true;\r
+ generateKeyEvent(sync, false, false);\r
+\r
+ m_cs.release();\r
+ DWORD r = WaitForSingleObject(m_eSync, 5000);\r
+ if (r == WAIT_TIMEOUT) {\r
+ Acquire a(&m_log, 0);\r
+ m_log << _T(" *FAILED*") << std::endl;\r
+ }\r
+ m_cs.acquire();\r
+ m_isSynchronizing = false;\r
+}\r
+\r
+// toggle lock\r
+void Engine::funcToggle(FunctionParam *i_param, ModifierLockType i_lock,\r
+ ToggleType i_toggle)\r
+{\r
+ if (i_param->m_isPressed) // ignore PRESS\r
+ return;\r
+\r
+ Modifier::Type mt = static_cast<Modifier::Type>(i_lock);\r
+ switch (i_toggle) {\r
+ case ToggleType_toggle:\r
+ m_currentLock.press(mt, !m_currentLock.isPressed(mt));\r
+ break;\r
+ case ToggleType_off:\r
+ m_currentLock.press(mt, false);\r
+ break;\r
+ case ToggleType_on:\r
+ m_currentLock.press(mt, true);\r
+ break;\r
+ }\r
+}\r
+\r
+// edit next user input key's modifier\r
+void Engine::funcEditNextModifier(FunctionParam *i_param,\r
+ const Modifier &i_modifier)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+\r
+ m_isPrefix = true;\r
+ m_doesEditNextModifier = true;\r
+ m_doesIgnoreModifierForPrefix = true;\r
+ m_modifierForNextKey = i_modifier;\r
+}\r
+\r
+// variable\r
+void Engine::funcVariable(FunctionParam *i_param, int i_mag, int i_inc)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+ m_variable *= i_mag;\r
+ m_variable += i_inc;\r
+}\r
+\r
+// repeat N times\r
+void Engine::funcRepeat(FunctionParam *i_param, const KeySeq *i_keySeq,\r
+ int i_max)\r
+{\r
+ if (i_param->m_isPressed) {\r
+ int end = MIN(m_variable, i_max);\r
+ for (int i = 0; i < end - 1; ++ i)\r
+ generateKeySeqEvents(i_param->m_c, i_keySeq, Part_all);\r
+ if (0 < end)\r
+ generateKeySeqEvents(i_param->m_c, i_keySeq, Part_down);\r
+ } else\r
+ generateKeySeqEvents(i_param->m_c, i_keySeq, Part_up);\r
+}\r
+\r
+// undefined (bell)\r
+void Engine::funcUndefined(FunctionParam *i_param)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+ MessageBeep(MB_OK);\r
+}\r
+\r
+// ignore\r
+void Engine::funcIgnore(FunctionParam *)\r
+{\r
+ // do nothing\r
+}\r
+\r
+// post message\r
+void Engine::funcPostMessage(FunctionParam *i_param, ToWindowType i_window,\r
+ UINT i_message, WPARAM i_wParam, LPARAM i_lParam)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+\r
+ int window = static_cast<int>(i_window);\r
+\r
+ HWND hwnd = i_param->m_hwnd;\r
+ if (0 < window) {\r
+ for (int i = 0; i < window; ++ i)\r
+ hwnd = GetParent(hwnd);\r
+ } else if (window == ToWindowType_toMainWindow) {\r
+ while (true) {\r
+ HWND p = GetParent(hwnd);\r
+ if (!p)\r
+ break;\r
+ hwnd = p;\r
+ }\r
+ } else if (window == ToWindowType_toOverlappedWindow) {\r
+ while (hwnd) {\r
+#ifdef MAYU64\r
+ LONG_PTR style = GetWindowLongPtr(hwnd, GWL_STYLE);\r
+#else\r
+ LONG style = GetWindowLong(hwnd, GWL_STYLE);\r
+#endif\r
+ if ((style & WS_CHILD) == 0)\r
+ break;\r
+ hwnd = GetParent(hwnd);\r
+ }\r
+ }\r
+\r
+ if (hwnd)\r
+ PostMessage(hwnd, i_message, i_wParam, i_lParam);\r
+}\r
+\r
+\r
+// ShellExecute\r
+void Engine::funcShellExecute(FunctionParam *i_param,\r
+ const StrExprArg &/*i_operation*/,\r
+ const StrExprArg &/*i_file*/,\r
+ const StrExprArg &/*i_parameters*/,\r
+ const StrExprArg &/*i_directory*/,\r
+ ShowCommandType /*i_showCommand*/)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+ m_afShellExecute = i_param->m_af;\r
+ PostMessage(m_hwndAssocWindow,\r
+ WM_APP_engineNotify, EngineNotify_shellExecute, 0);\r
+}\r
+\r
+\r
+// shell execute\r
+void Engine::shellExecute()\r
+{\r
+ Acquire a(&m_cs);\r
+\r
+ FunctionData_ShellExecute *fd =\r
+ reinterpret_cast<FunctionData_ShellExecute *>(\r
+ m_afShellExecute->m_functionData);\r
+\r
+ int r = (int)ShellExecute(\r
+ NULL,\r
+ fd->m_operation.eval().empty() ? _T("open") : fd->m_operation.eval().c_str(),\r
+ fd->m_file.eval().empty() ? NULL : fd->m_file.eval().c_str(),\r
+ fd->m_parameters.eval().empty() ? NULL : fd->m_parameters.eval().c_str(),\r
+ fd->m_directory.eval().empty() ? NULL : fd->m_directory.eval().c_str(),\r
+ fd->m_showCommand);\r
+ if (32 < r)\r
+ return; // success\r
+\r
+ typedef TypeTable<int> ErrorTable;\r
+ static const ErrorTable errorTable[] = {\r
+ { 0, _T("The operating system is out of memory or resources.") },\r
+ { ERROR_FILE_NOT_FOUND, _T("The specified file was not found.") },\r
+ { ERROR_PATH_NOT_FOUND, _T("The specified path was not found.") },\r
+ { ERROR_BAD_FORMAT, _T("The .exe file is invalid ")\r
+ _T("(non-Win32R .exe or error in .exe image).") },\r
+ { SE_ERR_ACCESSDENIED,\r
+ _T("The operating system denied access to the specified file.") },\r
+ { SE_ERR_ASSOCINCOMPLETE,\r
+ _T("The file name association is incomplete or invalid.") },\r
+ { SE_ERR_DDEBUSY,\r
+ _T("The DDE transaction could not be completed ")\r
+ _T("because other DDE transactions were being processed. ") },\r
+ { SE_ERR_DDEFAIL, _T("The DDE transaction failed.") },\r
+ { SE_ERR_DDETIMEOUT, _T("The DDE transaction could not be completed ")\r
+ _T("because the request timed out.") },\r
+ { SE_ERR_DLLNOTFOUND,\r
+ _T("The specified dynamic-link library was not found.") },\r
+ { SE_ERR_FNF, _T("The specified file was not found.") },\r
+ { SE_ERR_NOASSOC, _T("There is no application associated ")\r
+ _T("with the given file name extension.") },\r
+ { SE_ERR_OOM,\r
+ _T("There was not enough memory to complete the operation.") },\r
+ { SE_ERR_PNF, _T("The specified path was not found.") },\r
+ { SE_ERR_SHARE, _T("A sharing violation occurred.") },\r
+ };\r
+\r
+ tstring errorMessage(_T("Unknown error."));\r
+ getTypeName(&errorMessage, r, errorTable, NUMBER_OF(errorTable));\r
+\r
+ Acquire b(&m_log, 0);\r
+ m_log << _T("error: ") << fd << _T(": ") << errorMessage << std::endl;\r
+}\r
+\r
+\r
+struct EnumWindowsForSetForegroundWindowParam {\r
+ const FunctionData_SetForegroundWindow *m_fd;\r
+ HWND m_hwnd;\r
+\r
+public:\r
+ EnumWindowsForSetForegroundWindowParam(\r
+ const FunctionData_SetForegroundWindow *i_fd)\r
+ : m_fd(i_fd),\r
+ m_hwnd(NULL) {\r
+ }\r
+};\r
+\r
+\r
+/// enum windows for SetForegroundWindow\r
+static BOOL CALLBACK enumWindowsForSetForegroundWindow(\r
+ HWND i_hwnd, LPARAM i_lParam)\r
+{\r
+ EnumWindowsForSetForegroundWindowParam &ep =\r
+ *reinterpret_cast<EnumWindowsForSetForegroundWindowParam *>(i_lParam);\r
+\r
+ _TCHAR name[GANA_MAX_ATOM_LENGTH];\r
+ if (!GetClassName(i_hwnd, name, NUMBER_OF(name)))\r
+ return TRUE;\r
+ tsmatch what;\r
+ if (!boost::regex_search(tstring(name), what, ep.m_fd->m_windowClassName))\r
+ if (ep.m_fd->m_logicalOp == LogicalOperatorType_and)\r
+ return TRUE; // match failed\r
+\r
+ if (ep.m_fd->m_logicalOp == LogicalOperatorType_and) {\r
+ if (GetWindowText(i_hwnd, name, NUMBER_OF(name)) == 0)\r
+ name[0] = _T('\0');\r
+ if (!boost::regex_search(tstring(name), what,\r
+ ep.m_fd->m_windowTitleName))\r
+ return TRUE; // match failed\r
+ }\r
+\r
+ ep.m_hwnd = i_hwnd;\r
+ return FALSE;\r
+}\r
+\r
+\r
+/// SetForegroundWindow\r
+void Engine::funcSetForegroundWindow(FunctionParam *i_param, const tregex &,\r
+ LogicalOperatorType , const tregex &)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+ EnumWindowsForSetForegroundWindowParam\r
+ ep(static_cast<const FunctionData_SetForegroundWindow *>(\r
+ i_param->m_af->m_functionData));\r
+ EnumWindows(enumWindowsForSetForegroundWindow,\r
+ reinterpret_cast<LPARAM>(&ep));\r
+ if (ep.m_hwnd)\r
+ PostMessage(m_hwndAssocWindow,\r
+ WM_APP_engineNotify, EngineNotify_setForegroundWindow,\r
+ reinterpret_cast<LPARAM>(ep.m_hwnd));\r
+\r
+}\r
+\r
+\r
+// load setting\r
+void Engine::funcLoadSetting(FunctionParam *i_param, const StrExprArg &i_name)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+ if (!i_name.eval().empty()) {\r
+ // set MAYU_REGISTRY_ROOT\.mayuIndex which name is same with i_name\r
+ Registry reg(MAYU_REGISTRY_ROOT);\r
+\r
+ tregex split(_T("^([^;]*);([^;]*);(.*)$"));\r
+ tstringi dot_mayu;\r
+ for (size_t i = 0; i < MAX_MAYU_REGISTRY_ENTRIES; ++ i) {\r
+ _TCHAR buf[100];\r
+ _sntprintf(buf, NUMBER_OF(buf), _T(".mayu%d"), i);\r
+ if (!reg.read(buf, &dot_mayu))\r
+ break;\r
+\r
+ tsmatch what;\r
+ if (boost::regex_match(dot_mayu, what, split) &&\r
+ what.str(1) == i_name.eval()) {\r
+ reg.write(_T(".mayuIndex"), i);\r
+ goto success;\r
+ }\r
+ }\r
+\r
+ {\r
+ Acquire a(&m_log, 0);\r
+ m_log << _T("unknown setting name: ") << i_name;\r
+ }\r
+ return;\r
+\r
+success:\r
+ ;\r
+ }\r
+ PostMessage(m_hwndAssocWindow,\r
+ WM_APP_engineNotify, EngineNotify_loadSetting, 0);\r
+}\r
+\r
+// virtual key\r
+void Engine::funcVK(FunctionParam *i_param, VKey i_vkey)\r
+{\r
+ long key = static_cast<long>(i_vkey);\r
+ BYTE vkey = static_cast<BYTE>(i_vkey);\r
+ bool isExtended = !!(key & VKey_extended);\r
+ bool isUp = !i_param->m_isPressed && !!(key & VKey_released);\r
+ bool isDown = i_param->m_isPressed && !!(key & VKey_pressed);\r
+\r
+ if (vkey == VK_LBUTTON && isDown)\r
+ mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);\r
+ else if (vkey == VK_LBUTTON && isUp)\r
+ mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);\r
+ else if (vkey == VK_MBUTTON && isDown)\r
+ mouse_event(MOUSEEVENTF_MIDDLEDOWN, 0, 0, 0, 0);\r
+ else if (vkey == VK_MBUTTON && isUp)\r
+ mouse_event(MOUSEEVENTF_MIDDLEUP, 0, 0, 0, 0);\r
+ else if (vkey == VK_RBUTTON && isDown)\r
+ mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);\r
+ else if (vkey == VK_RBUTTON && isUp)\r
+ mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);\r
+ else if (vkey == VK_XBUTTON1 && isDown)\r
+ mouse_event(MOUSEEVENTF_XDOWN, 0, 0, XBUTTON1, 0);\r
+ else if (vkey == VK_XBUTTON1 && isUp)\r
+ mouse_event(MOUSEEVENTF_XUP, 0, 0, XBUTTON1, 0);\r
+ else if (vkey == VK_XBUTTON2 && isDown)\r
+ mouse_event(MOUSEEVENTF_XDOWN, 0, 0, XBUTTON2, 0);\r
+ else if (vkey == VK_XBUTTON2 && isUp)\r
+ mouse_event(MOUSEEVENTF_XUP, 0, 0, XBUTTON2, 0);\r
+ else if (isUp || isDown)\r
+ keybd_event(vkey,\r
+ static_cast<BYTE>(MapVirtualKey(vkey, 0)),\r
+ (isExtended ? KEYEVENTF_EXTENDEDKEY : 0) |\r
+ (i_param->m_isPressed ? 0 : KEYEVENTF_KEYUP), 0);\r
+}\r
+\r
+// wait\r
+void Engine::funcWait(FunctionParam *i_param, int i_milliSecond)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+ if (i_milliSecond < 0 || 5000 < i_milliSecond) // too long wait\r
+ return;\r
+\r
+ m_isSynchronizing = true;\r
+ m_cs.release();\r
+ Sleep(i_milliSecond);\r
+ m_cs.acquire();\r
+ m_isSynchronizing = false;\r
+}\r
+\r
+// investigate WM_COMMAND, WM_SYSCOMMAND\r
+void Engine::funcInvestigateCommand(FunctionParam *i_param)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+ Acquire a(&m_log, 0);\r
+ g_hookData->m_doesNotifyCommand = !g_hookData->m_doesNotifyCommand;\r
+ if (g_hookData->m_doesNotifyCommand)\r
+ m_log << _T(" begin") << std::endl;\r
+ else\r
+ m_log << _T(" end") << std::endl;\r
+}\r
+\r
+// show mayu dialog box\r
+void Engine::funcMayuDialog(FunctionParam *i_param, MayuDialogType i_dialog,\r
+ ShowCommandType i_showCommand)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+ PostMessage(getAssociatedWndow(), WM_APP_engineNotify, EngineNotify_showDlg,\r
+ static_cast<LPARAM>(i_dialog) |\r
+ static_cast<LPARAM>(i_showCommand));\r
+}\r
+\r
+// describe bindings\r
+void Engine::funcDescribeBindings(FunctionParam *i_param)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+ {\r
+ Acquire a(&m_log, 1);\r
+ m_log << std::endl;\r
+ }\r
+ describeBindings();\r
+}\r
+\r
+// show help message\r
+void Engine::funcHelpMessage(FunctionParam *i_param, const StrExprArg &i_title,\r
+ const StrExprArg &i_message)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+\r
+ m_helpTitle = i_title.eval();\r
+ m_helpMessage = i_message.eval();\r
+ bool doesShow = !(i_title.eval().size() == 0 && i_message.eval().size() == 0);\r
+ PostMessage(getAssociatedWndow(), WM_APP_engineNotify,\r
+ EngineNotify_helpMessage, doesShow);\r
+}\r
+\r
+// show variable\r
+void Engine::funcHelpVariable(FunctionParam *i_param, const StrExprArg &i_title)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+\r
+ _TCHAR buf[20];\r
+ _sntprintf(buf, NUMBER_OF(buf), _T("%d"), m_variable);\r
+\r
+ m_helpTitle = i_title.eval();\r
+ m_helpMessage = buf;\r
+ PostMessage(getAssociatedWndow(), WM_APP_engineNotify,\r
+ EngineNotify_helpMessage, true);\r
+}\r
+\r
+// raise window\r
+void Engine::funcWindowRaise(FunctionParam *i_param,\r
+ TargetWindowType i_twt)\r
+{\r
+ HWND hwnd;\r
+ if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt))\r
+ return;\r
+ SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,\r
+ SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSIZE);\r
+}\r
+\r
+// lower window\r
+void Engine::funcWindowLower(FunctionParam *i_param, TargetWindowType i_twt)\r
+{\r
+ HWND hwnd;\r
+ if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt))\r
+ return;\r
+ SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0,\r
+ SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSIZE);\r
+}\r
+\r
+// minimize window\r
+void Engine::funcWindowMinimize(FunctionParam *i_param, TargetWindowType i_twt)\r
+{\r
+ HWND hwnd;\r
+ if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt))\r
+ return;\r
+ PostMessage(hwnd, WM_SYSCOMMAND,\r
+ IsIconic(hwnd) ? SC_RESTORE : SC_MINIMIZE, 0);\r
+}\r
+\r
+// maximize window\r
+void Engine::funcWindowMaximize(FunctionParam *i_param, TargetWindowType i_twt)\r
+{\r
+ HWND hwnd;\r
+ if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt))\r
+ return;\r
+ PostMessage(hwnd, WM_SYSCOMMAND,\r
+ IsZoomed(hwnd) ? SC_RESTORE : SC_MAXIMIZE, 0);\r
+}\r
+\r
+// maximize horizontally or virtically\r
+void Engine::funcWindowHVMaximize(FunctionParam *i_param,\r
+ BooleanType i_isHorizontal,\r
+ TargetWindowType i_twt)\r
+{\r
+ HWND hwnd;\r
+ RECT rc, rcd;\r
+ if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt, &rc, &rcd))\r
+ return;\r
+\r
+ // erase non window\r
+ while (true) {\r
+ WindowPositions::iterator i = m_windowPositions.begin();\r
+ WindowPositions::iterator end = m_windowPositions.end();\r
+ for (; i != end; ++ i)\r
+ if (!IsWindow((*i).m_hwnd))\r
+ break;\r
+ if (i == end)\r
+ break;\r
+ m_windowPositions.erase(i);\r
+ }\r
+\r
+ // find target\r
+ WindowPositions::iterator i = m_windowPositions.begin();\r
+ WindowPositions::iterator end = m_windowPositions.end();\r
+ WindowPositions::iterator target = end;\r
+ for (; i != end; ++ i)\r
+ if ((*i).m_hwnd == hwnd) {\r
+ target = i;\r
+ break;\r
+ }\r
+\r
+ if (IsZoomed(hwnd))\r
+ PostMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0);\r
+ else {\r
+ WindowPosition::Mode mode = WindowPosition::Mode_normal;\r
+\r
+ if (target != end) {\r
+ WindowPosition &wp = *target;\r
+ rc = wp.m_rc;\r
+ if (wp.m_mode == WindowPosition::Mode_HV)\r
+ mode = wp.m_mode =\r
+ i_isHorizontal ? WindowPosition::Mode_V : WindowPosition::Mode_H;\r
+ else if (( i_isHorizontal && wp.m_mode == WindowPosition::Mode_V) ||\r
+ (!i_isHorizontal && wp.m_mode == WindowPosition::Mode_H))\r
+ mode = wp.m_mode = WindowPosition::Mode_HV;\r
+ else\r
+ m_windowPositions.erase(target);\r
+ } else {\r
+ mode = i_isHorizontal ? WindowPosition::Mode_H : WindowPosition::Mode_V;\r
+ m_windowPositions.push_front(WindowPosition(hwnd, rc, mode));\r
+ }\r
+\r
+ if (static_cast<int>(mode) & static_cast<int>(WindowPosition::Mode_H))\r
+ rc.left = rcd.left, rc.right = rcd.right;\r
+ if (static_cast<int>(mode) & static_cast<int>(WindowPosition::Mode_V))\r
+ rc.top = rcd.top, rc.bottom = rcd.bottom;\r
+\r
+ asyncMoveWindow(hwnd, rc.left, rc.top, rcWidth(&rc), rcHeight(&rc));\r
+ }\r
+}\r
+\r
+// maximize window horizontally\r
+void Engine::funcWindowHMaximize(FunctionParam *i_param,\r
+ TargetWindowType i_twt)\r
+{\r
+ funcWindowHVMaximize(i_param, BooleanType_true, i_twt);\r
+}\r
+\r
+// maximize window virtically\r
+void Engine::funcWindowVMaximize(FunctionParam *i_param,\r
+ TargetWindowType i_twt)\r
+{\r
+ funcWindowHVMaximize(i_param, BooleanType_false, i_twt);\r
+}\r
+\r
+// move window\r
+void Engine::funcWindowMove(FunctionParam *i_param, int i_dx, int i_dy,\r
+ TargetWindowType i_twt)\r
+{\r
+ funcWindowMoveTo(i_param, GravityType_C, i_dx, i_dy, i_twt);\r
+}\r
+\r
+// move window to ...\r
+void Engine::funcWindowMoveTo(FunctionParam *i_param,\r
+ GravityType i_gravityType,\r
+ int i_dx, int i_dy, TargetWindowType i_twt)\r
+{\r
+ HWND hwnd;\r
+ RECT rc, rcd;\r
+ if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt, &rc, &rcd))\r
+ return;\r
+\r
+ int x = rc.left + i_dx;\r
+ int y = rc.top + i_dy;\r
+\r
+ if (i_gravityType & GravityType_N)\r
+ y = i_dy + rcd.top;\r
+ if (i_gravityType & GravityType_E)\r
+ x = i_dx + rcd.right - rcWidth(&rc);\r
+ if (i_gravityType & GravityType_W)\r
+ x = i_dx + rcd.left;\r
+ if (i_gravityType & GravityType_S)\r
+ y = i_dy + rcd.bottom - rcHeight(&rc);\r
+ asyncMoveWindow(hwnd, x, y);\r
+}\r
+\r
+\r
+// move window visibly\r
+void Engine::funcWindowMoveVisibly(FunctionParam *i_param,\r
+ TargetWindowType i_twt)\r
+{\r
+ HWND hwnd;\r
+ RECT rc, rcd;\r
+ if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt, &rc, &rcd))\r
+ return;\r
+\r
+ int x = rc.left;\r
+ int y = rc.top;\r
+ if (rc.left < rcd.left)\r
+ x = rcd.left;\r
+ else if (rcd.right < rc.right)\r
+ x = rcd.right - rcWidth(&rc);\r
+ if (rc.top < rcd.top)\r
+ y = rcd.top;\r
+ else if (rcd.bottom < rc.bottom)\r
+ y = rcd.bottom - rcHeight(&rc);\r
+ asyncMoveWindow(hwnd, x, y);\r
+}\r
+\r
+\r
+struct EnumDisplayMonitorsForWindowMonitorToParam {\r
+ std::vector<HMONITOR> m_monitors;\r
+ std::vector<MONITORINFO> m_monitorinfos;\r
+ int m_primaryMonitorIdx;\r
+ int m_currentMonitorIdx;\r
+\r
+ HMONITOR m_hmon;\r
+\r
+public:\r
+ EnumDisplayMonitorsForWindowMonitorToParam(HMONITOR i_hmon)\r
+ : m_hmon(i_hmon),\r
+ m_primaryMonitorIdx(-1), m_currentMonitorIdx(-1) {\r
+ }\r
+};\r
+\r
+static BOOL CALLBACK enumDisplayMonitorsForWindowMonitorTo(\r
+ HMONITOR i_hmon, HDC i_hdc, LPRECT i_rcMonitor, LPARAM i_data)\r
+{\r
+ EnumDisplayMonitorsForWindowMonitorToParam &ep =\r
+ *reinterpret_cast<EnumDisplayMonitorsForWindowMonitorToParam *>(i_data);\r
+\r
+ ep.m_monitors.push_back(i_hmon);\r
+\r
+ MONITORINFO mi;\r
+ mi.cbSize = sizeof(mi);\r
+ getMonitorInfo(i_hmon, &mi);\r
+ ep.m_monitorinfos.push_back(mi);\r
+\r
+ if (mi.dwFlags & MONITORINFOF_PRIMARY)\r
+ ep.m_primaryMonitorIdx = ep.m_monitors.size() - 1;\r
+ if (i_hmon == ep.m_hmon)\r
+ ep.m_currentMonitorIdx = ep.m_monitors.size() - 1;\r
+\r
+ return TRUE;\r
+}\r
+\r
+/// move window to other monitor\r
+void Engine::funcWindowMonitorTo(\r
+ FunctionParam *i_param, WindowMonitorFromType i_fromType, int i_monitor,\r
+ BooleanType i_adjustPos, BooleanType i_adjustSize)\r
+{\r
+ HWND hwnd;\r
+ if (! getSuitableWindow(i_param, &hwnd))\r
+ return;\r
+\r
+ HMONITOR hmonCur;\r
+ hmonCur = monitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);\r
+\r
+ EnumDisplayMonitorsForWindowMonitorToParam ep(hmonCur);\r
+ enumDisplayMonitors(NULL, NULL, enumDisplayMonitorsForWindowMonitorTo,\r
+ reinterpret_cast<LPARAM>(&ep));\r
+ if (ep.m_monitors.size() < 1 ||\r
+ ep.m_primaryMonitorIdx < 0 || ep.m_currentMonitorIdx < 0)\r
+ return;\r
+\r
+ int targetIdx;\r
+ switch (i_fromType) {\r
+ case WindowMonitorFromType_primary:\r
+ targetIdx = (ep.m_primaryMonitorIdx + i_monitor) % ep.m_monitors.size();\r
+ break;\r
+\r
+ case WindowMonitorFromType_current:\r
+ targetIdx = (ep.m_currentMonitorIdx + i_monitor) % ep.m_monitors.size();\r
+ break;\r
+ }\r
+ if (ep.m_currentMonitorIdx == targetIdx)\r
+ return;\r
+\r
+ RECT rcCur, rcTarget, rcWin;\r
+ rcCur = ep.m_monitorinfos[ep.m_currentMonitorIdx].rcWork;\r
+ rcTarget = ep.m_monitorinfos[targetIdx].rcWork;\r
+ GetWindowRect(hwnd, &rcWin);\r
+\r
+ int x = rcTarget.left + (rcWin.left - rcCur.left);\r
+ int y = rcTarget.top + (rcWin.top - rcCur.top);\r
+ int w = rcWidth(&rcWin);\r
+ int h = rcHeight(&rcWin);\r
+\r
+ if (i_adjustPos) {\r
+ if (x + w > rcTarget.right)\r
+ x = rcTarget.right - w;\r
+ if (x < rcTarget.left)\r
+ x = rcTarget.left;\r
+ if (w > rcWidth(&rcTarget)) {\r
+ x = rcTarget.left;\r
+ w = rcWidth(&rcTarget);\r
+ }\r
+\r
+ if (y + h > rcTarget.bottom)\r
+ y = rcTarget.bottom - h;\r
+ if (y < rcTarget.top)\r
+ y = rcTarget.top;\r
+ if (h > rcHeight(&rcTarget)) {\r
+ y = rcTarget.top;\r
+ h = rcHeight(&rcTarget);\r
+ }\r
+ }\r
+\r
+ if (i_adjustPos && i_adjustSize) {\r
+ if (IsZoomed(hwnd))\r
+ PostMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0);\r
+ asyncMoveWindow(hwnd, x, y, w, h);\r
+ } else {\r
+ asyncMoveWindow(hwnd, x, y);\r
+ }\r
+}\r
+\r
+/// move window to other monitor\r
+void Engine::funcWindowMonitor(\r
+ FunctionParam *i_param, int i_monitor,\r
+ BooleanType i_adjustPos, BooleanType i_adjustSize)\r
+{\r
+ funcWindowMonitorTo(i_param, WindowMonitorFromType_primary, i_monitor,\r
+ i_adjustPos, i_adjustSize);\r
+}\r
+\r
+\r
+//\r
+void Engine::funcWindowClingToLeft(FunctionParam *i_param,\r
+ TargetWindowType i_twt)\r
+{\r
+ funcWindowMoveTo(i_param, GravityType_W, 0, 0, i_twt);\r
+}\r
+\r
+//\r
+void Engine::funcWindowClingToRight(FunctionParam *i_param,\r
+ TargetWindowType i_twt)\r
+{\r
+ funcWindowMoveTo(i_param, GravityType_E, 0, 0, i_twt);\r
+}\r
+\r
+//\r
+void Engine::funcWindowClingToTop(FunctionParam *i_param,\r
+ TargetWindowType i_twt)\r
+{\r
+ funcWindowMoveTo(i_param, GravityType_N, 0, 0, i_twt);\r
+}\r
+\r
+//\r
+void Engine::funcWindowClingToBottom(FunctionParam *i_param,\r
+ TargetWindowType i_twt)\r
+{\r
+ funcWindowMoveTo(i_param, GravityType_S, 0, 0, i_twt);\r
+}\r
+\r
+// close window\r
+void Engine::funcWindowClose(FunctionParam *i_param, TargetWindowType i_twt)\r
+{\r
+ HWND hwnd;\r
+ if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt))\r
+ return;\r
+ PostMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0);\r
+}\r
+\r
+// toggle top-most flag of the window\r
+void Engine::funcWindowToggleTopMost(FunctionParam *i_param)\r
+{\r
+ HWND hwnd;\r
+ if (!getSuitableWindow(i_param, &hwnd))\r
+ return;\r
+ SetWindowPos(\r
+ hwnd,\r
+#ifdef MAYU64\r
+ (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) ?\r
+#else\r
+ (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) ?\r
+#endif\r
+ HWND_NOTOPMOST : HWND_TOPMOST,\r
+ 0, 0, 0, 0,\r
+ SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSIZE);\r
+}\r
+\r
+// identify the window\r
+void Engine::funcWindowIdentify(FunctionParam *i_param)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+\r
+ _TCHAR className[GANA_MAX_ATOM_LENGTH];\r
+ bool ok = false;\r
+ if (GetClassName(i_param->m_hwnd, className, NUMBER_OF(className))) {\r
+ if (_tcsicmp(className, _T("ConsoleWindowClass")) == 0) {\r
+ _TCHAR titleName[1024];\r
+ if (GetWindowText(i_param->m_hwnd, titleName, NUMBER_OF(titleName)) == 0)\r
+ titleName[0] = _T('\0');\r
+ {\r
+ Acquire a(&m_log, 1);\r
+ m_log << _T("HWND:\t") << std::hex\r
+ << reinterpret_cast<int>(i_param->m_hwnd)\r
+ << std::dec << std::endl;\r
+ }\r
+ Acquire a(&m_log, 0);\r
+ m_log << _T("CLASS:\t") << className << std::endl;\r
+ m_log << _T("TITLE:\t") << titleName << std::endl;\r
+\r
+ HWND hwnd = getToplevelWindow(i_param->m_hwnd, NULL);\r
+ RECT rc;\r
+ GetWindowRect(hwnd, &rc);\r
+ m_log << _T("Toplevel Window Position/Size: (")\r
+ << rc.left << _T(", ") << rc.top << _T(") / (")\r
+ << rcWidth(&rc) << _T("x") << rcHeight(&rc)\r
+ << _T(")") << std::endl;\r
+\r
+ SystemParametersInfo(SPI_GETWORKAREA, 0, (void *)&rc, FALSE);\r
+ m_log << _T("Desktop Window Position/Size: (")\r
+ << rc.left << _T(", ") << rc.top << _T(") / (")\r
+ << rcWidth(&rc) << _T("x") << rcHeight(&rc)\r
+ << _T(")") << std::endl;\r
+\r
+ m_log << std::endl;\r
+ ok = true;\r
+ }\r
+ }\r
+ if (!ok) {\r
+ UINT WM_MAYU_MESSAGE = RegisterWindowMessage(\r
+ addSessionId(WM_MAYU_MESSAGE_NAME).c_str());\r
+ CHECK_TRUE( PostMessage(i_param->m_hwnd, WM_MAYU_MESSAGE,\r
+ MayuMessage_notifyName, 0) );\r
+ }\r
+}\r
+\r
+// set alpha blending parameter to the window\r
+void Engine::funcWindowSetAlpha(FunctionParam *i_param, int i_alpha)\r
+{\r
+ HWND hwnd;\r
+ if (!getSuitableWindow(i_param, &hwnd))\r
+ return;\r
+\r
+ if (i_alpha < 0) { // remove all alpha\r
+ for (WindowsWithAlpha::iterator i = m_windowsWithAlpha.begin();\r
+ i != m_windowsWithAlpha.end(); ++ i) {\r
+#ifdef MAYU64\r
+ SetWindowLongPtr(*i, GWL_EXSTYLE,\r
+ GetWindowLongPtr(*i, GWL_EXSTYLE) & ~WS_EX_LAYERED);\r
+#else\r
+ SetWindowLong(*i, GWL_EXSTYLE,\r
+ GetWindowLong(*i, GWL_EXSTYLE) & ~WS_EX_LAYERED);\r
+#endif\r
+ RedrawWindow(*i, NULL, NULL,\r
+ RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);\r
+ }\r
+ m_windowsWithAlpha.clear();\r
+ } else {\r
+#ifdef MAYU64\r
+ LONG_PTR exStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);\r
+#else\r
+ LONG exStyle = GetWindowLong(hwnd, GWL_EXSTYLE);\r
+#endif\r
+ if (exStyle & WS_EX_LAYERED) { // remove alpha\r
+ WindowsWithAlpha::iterator\r
+ i = std::find(m_windowsWithAlpha.begin(), m_windowsWithAlpha.end(),\r
+ hwnd);\r
+ if (i == m_windowsWithAlpha.end())\r
+ return; // already layered by the application\r
+\r
+ m_windowsWithAlpha.erase(i);\r
+\r
+#ifdef MAYU64\r
+ SetWindowLongPtr(hwnd, GWL_EXSTYLE, exStyle & ~WS_EX_LAYERED);\r
+#else\r
+ SetWindowLong(hwnd, GWL_EXSTYLE, exStyle & ~WS_EX_LAYERED);\r
+#endif\r
+ } else { // add alpha\r
+#ifdef MAYU64\r
+ SetWindowLongPtr(hwnd, GWL_EXSTYLE, exStyle | WS_EX_LAYERED);\r
+#else\r
+ SetWindowLong(hwnd, GWL_EXSTYLE, exStyle | WS_EX_LAYERED);\r
+#endif\r
+ i_alpha %= 101;\r
+ if (!setLayeredWindowAttributes(hwnd, 0,\r
+ (BYTE)(255 * i_alpha / 100), LWA_ALPHA)) {\r
+ Acquire a(&m_log, 0);\r
+ m_log << _T("error: &WindowSetAlpha(") << i_alpha\r
+ << _T(") failed for HWND: ") << std::hex\r
+ << hwnd << std::dec << std::endl;\r
+ return;\r
+ }\r
+ m_windowsWithAlpha.push_front(hwnd);\r
+ }\r
+ RedrawWindow(hwnd, NULL, NULL,\r
+ RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);\r
+ }\r
+}\r
+\r
+\r
+// redraw the window\r
+void Engine::funcWindowRedraw(FunctionParam *i_param)\r
+{\r
+ HWND hwnd;\r
+ if (!getSuitableWindow(i_param, &hwnd))\r
+ return;\r
+ RedrawWindow(hwnd, NULL, NULL,\r
+ RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);\r
+}\r
+\r
+// resize window to\r
+void Engine::funcWindowResizeTo(FunctionParam *i_param, int i_width,\r
+ int i_height, TargetWindowType i_twt)\r
+{\r
+ HWND hwnd;\r
+ RECT rc, rcd;\r
+ if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt, &rc, &rcd))\r
+ return;\r
+\r
+ if (i_width == 0)\r
+ i_width = rcWidth(&rc);\r
+ else if (i_width < 0)\r
+ i_width += rcWidth(&rcd);\r
+\r
+ if (i_height == 0)\r
+ i_height = rcHeight(&rc);\r
+ else if (i_height < 0)\r
+ i_height += rcHeight(&rcd);\r
+\r
+ asyncResize(hwnd, i_width, i_height);\r
+}\r
+\r
+// move the mouse cursor\r
+void Engine::funcMouseMove(FunctionParam *i_param, int i_dx, int i_dy)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+ POINT pt;\r
+ GetCursorPos(&pt);\r
+ SetCursorPos(pt.x + i_dx, pt.y + i_dy);\r
+}\r
+\r
+// send a mouse-wheel-message to Windows\r
+void Engine::funcMouseWheel(FunctionParam *i_param, int i_delta)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+ mouse_event(MOUSEEVENTF_WHEEL, 0, 0, i_delta, 0);\r
+}\r
+\r
+// convert the contents of the Clipboard to upper case\r
+void Engine::funcClipboardChangeCase(FunctionParam *i_param,\r
+ BooleanType i_doesConvertToUpperCase)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+\r
+ HGLOBAL hdata;\r
+ const _TCHAR *text = getTextFromClipboard(&hdata);\r
+ HGLOBAL hdataNew = NULL;\r
+ if (text) {\r
+ int size = static_cast<int>(GlobalSize(hdata));\r
+ hdataNew = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, size);\r
+ if (hdataNew) {\r
+ if (_TCHAR *dataNew = reinterpret_cast<_TCHAR *>(GlobalLock(hdataNew))) {\r
+ std::memcpy(dataNew, text, size);\r
+ _TCHAR *dataEnd = dataNew + size;\r
+ while (dataNew < dataEnd && *dataNew) {\r
+ _TCHAR c = *dataNew;\r
+ if (_istlead(c))\r
+ dataNew += 2;\r
+ else\r
+ *dataNew++ =\r
+ i_doesConvertToUpperCase ? _totupper(c) : _totlower(c);\r
+ }\r
+ GlobalUnlock(hdataNew);\r
+ }\r
+ }\r
+ }\r
+ closeClipboard(hdata, hdataNew);\r
+}\r
+\r
+// convert the contents of the Clipboard to upper case\r
+void Engine::funcClipboardUpcaseWord(FunctionParam *i_param)\r
+{\r
+ funcClipboardChangeCase(i_param, BooleanType_true);\r
+}\r
+\r
+// convert the contents of the Clipboard to lower case\r
+void Engine::funcClipboardDowncaseWord(FunctionParam *i_param)\r
+{\r
+ funcClipboardChangeCase(i_param, BooleanType_false);\r
+}\r
+\r
+// set the contents of the Clipboard to the string\r
+void Engine::funcClipboardCopy(FunctionParam *i_param, const StrExprArg &i_text)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+ if (!OpenClipboard(NULL))\r
+ return;\r
+\r
+ HGLOBAL hdataNew =\r
+ GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,\r
+ (i_text.eval().size() + 1) * sizeof(_TCHAR));\r
+ if (!hdataNew)\r
+ return;\r
+ _TCHAR *dataNew = reinterpret_cast<_TCHAR *>(GlobalLock(hdataNew));\r
+ _tcscpy(dataNew, i_text.eval().c_str());\r
+ GlobalUnlock(hdataNew);\r
+ closeClipboard(NULL, hdataNew);\r
+}\r
+\r
+//\r
+void Engine::funcEmacsEditKillLinePred(\r
+ FunctionParam *i_param, const KeySeq *i_keySeq1, const KeySeq *i_keySeq2)\r
+{\r
+ m_emacsEditKillLine.m_doForceReset = false;\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+\r
+ int r = m_emacsEditKillLine.pred();\r
+ const KeySeq *keySeq;\r
+ if (r == 1)\r
+ keySeq = i_keySeq1;\r
+ else if (r == 2)\r
+ keySeq = i_keySeq2;\r
+ else // r == 0\r
+ return;\r
+ ASSERT(keySeq);\r
+ generateKeySeqEvents(i_param->m_c, keySeq, Part_all);\r
+}\r
+\r
+//\r
+void Engine::funcEmacsEditKillLineFunc(FunctionParam *i_param)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+ m_emacsEditKillLine.func();\r
+ m_emacsEditKillLine.m_doForceReset = false;\r
+}\r
+\r
+// clear log\r
+void Engine::funcLogClear(FunctionParam *i_param)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+ PostMessage(getAssociatedWndow(), WM_APP_engineNotify,\r
+ EngineNotify_clearLog, 0);\r
+}\r
+\r
+// recenter\r
+void Engine::funcRecenter(FunctionParam *i_param)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+ if (m_hwndFocus) {\r
+ UINT WM_MAYU_MESSAGE = RegisterWindowMessage(\r
+ addSessionId(WM_MAYU_MESSAGE_NAME).c_str());\r
+ PostMessage(m_hwndFocus, WM_MAYU_MESSAGE, MayuMessage_funcRecenter, 0);\r
+ }\r
+}\r
+\r
+// set IME open status\r
+void Engine::funcSetImeStatus(FunctionParam *i_param, ToggleType i_toggle)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+ if (m_hwndFocus) {\r
+ UINT WM_MAYU_MESSAGE = RegisterWindowMessage(\r
+ addSessionId(WM_MAYU_MESSAGE_NAME).c_str());\r
+ int status = -1;\r
+ switch (i_toggle) {\r
+ case ToggleType_toggle:\r
+ status = -1;\r
+ break;\r
+ case ToggleType_off:\r
+ status = 0;\r
+ break;\r
+ case ToggleType_on:\r
+ status = 1;\r
+ break;\r
+ }\r
+ PostMessage(m_hwndFocus, WM_MAYU_MESSAGE, MayuMessage_funcSetImeStatus, status);\r
+ }\r
+}\r
+\r
+// set IME open status\r
+void Engine::funcSetImeString(FunctionParam *i_param, const StrExprArg &i_data)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+ if (m_hwndFocus) {\r
+ UINT WM_MAYU_MESSAGE = RegisterWindowMessage(\r
+ addSessionId(WM_MAYU_MESSAGE_NAME).c_str());\r
+ PostMessage(m_hwndFocus, WM_MAYU_MESSAGE, MayuMessage_funcSetImeString, i_data.eval().size() * sizeof(_TCHAR));\r
+\r
+ DWORD len = 0;\r
+ DWORD error;\r
+ DisconnectNamedPipe(m_hookPipe);\r
+ ConnectNamedPipe(m_hookPipe, NULL);\r
+ error = WriteFile(m_hookPipe, i_data.eval().c_str(),\r
+ i_data.eval().size() * sizeof(_TCHAR),\r
+ &len, NULL);\r
+\r
+ //FlushFileBuffers(m_hookPipe);\r
+ }\r
+}\r
+\r
+// Direct SSTP Server\r
+class DirectSSTPServer\r
+{\r
+public:\r
+ tstring m_path;\r
+ HWND m_hwnd;\r
+ tstring m_name;\r
+ tstring m_keroname;\r
+\r
+public:\r
+ DirectSSTPServer()\r
+ : m_hwnd(NULL) {\r
+ }\r
+};\r
+\r
+\r
+class ParseDirectSSTPData\r
+{\r
+ typedef boost::match_results<boost::regex::const_iterator> MR;\r
+\r
+public:\r
+ typedef std::map<tstring, DirectSSTPServer> DirectSSTPServers;\r
+\r
+private:\r
+ DirectSSTPServers *m_directSSTPServers;\r
+\r
+public:\r
+ // constructor\r
+ ParseDirectSSTPData(DirectSSTPServers *i_directSSTPServers)\r
+ : m_directSSTPServers(i_directSSTPServers) {\r
+ }\r
+\r
+ bool operator()(const MR& i_what) {\r
+#ifdef _UNICODE\r
+ tstring id(to_wstring(std::string(i_what[1].first, i_what[1].second)));\r
+ tstring member(to_wstring(std::string(i_what[2].first, i_what[2].second)));\r
+ tstring value(to_wstring(std::string(i_what[3].first, i_what[3].second)));\r
+#else\r
+ tstring id(i_what[1].first, i_what[1].second);\r
+ tstring member(i_what[2].first, i_what[2].second);\r
+ tstring value(i_what[3].first, i_what[3].second);\r
+#endif\r
+\r
+ if (member == _T("path"))\r
+ (*m_directSSTPServers)[id].m_path = value;\r
+ else if (member == _T("hwnd"))\r
+ (*m_directSSTPServers)[id].m_hwnd =\r
+ reinterpret_cast<HWND>(_ttoi(value.c_str()));\r
+ else if (member == _T("name"))\r
+ (*m_directSSTPServers)[id].m_name = value;\r
+ else if (member == _T("keroname"))\r
+ (*m_directSSTPServers)[id].m_keroname = value;\r
+ return true;\r
+ }\r
+};\r
+\r
+// Direct SSTP\r
+void Engine::funcDirectSSTP(FunctionParam *i_param,\r
+ const tregex &i_name,\r
+ const StrExprArg &i_protocol,\r
+ const std::list<tstringq> &i_headers)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+\r
+ // check Direct SSTP server exist ?\r
+ if (HANDLE hm = OpenMutex(MUTEX_ALL_ACCESS, FALSE, _T("sakura")))\r
+ CloseHandle(hm);\r
+ else {\r
+ Acquire a(&m_log, 0);\r
+ m_log << _T(" Error(1): Direct SSTP server does not exist.");\r
+ return;\r
+ }\r
+\r
+ HANDLE hfm = OpenFileMapping(FILE_MAP_READ, FALSE, _T("Sakura"));\r
+ if (!hfm) {\r
+ Acquire a(&m_log, 0);\r
+ m_log << _T(" Error(2): Direct SSTP server does not provide data.");\r
+ return;\r
+ }\r
+\r
+ char *data =\r
+ reinterpret_cast<char *>(MapViewOfFile(hfm, FILE_MAP_READ, 0, 0, 0));\r
+ if (!data) {\r
+ CloseHandle(hfm);\r
+ Acquire a(&m_log, 0);\r
+ m_log << _T(" Error(3): Direct SSTP server does not provide data.");\r
+ return;\r
+ }\r
+\r
+ long length = *(long *)data;\r
+ const char *begin = data + 4;\r
+ const char *end = data + length;\r
+ boost::regex getSakura("([0-9a-fA-F]{32})\\.([^\x01]+)\x01(.*?)\r\n");\r
+\r
+ ParseDirectSSTPData::DirectSSTPServers servers;\r
+ boost::regex_iterator<boost::regex::const_iterator>\r
+ it(begin, end, getSakura), last;\r
+ for (; it != last; ++it)\r
+ ((ParseDirectSSTPData)(&servers))(*it);\r
+\r
+ // make request\r
+ tstring request;\r
+ if (!i_protocol.eval().size())\r
+ request += _T("NOTIFY SSTP/1.1");\r
+ else\r
+ request += i_protocol.eval();\r
+ request += _T("\r\n");\r
+\r
+ bool hasSender = false;\r
+ for (std::list<tstringq>::const_iterator\r
+ i = i_headers.begin(); i != i_headers.end(); ++ i) {\r
+ if (_tcsnicmp(_T("Charset"), i->c_str(), 7) == 0 ||\r
+ _tcsnicmp(_T("Hwnd"), i->c_str(), 4) == 0)\r
+ continue;\r
+ if (_tcsnicmp(_T("Sender"), i->c_str(), 6) == 0)\r
+ hasSender = true;\r
+ request += i->c_str();\r
+ request += _T("\r\n");\r
+ }\r
+\r
+ if (!hasSender) {\r
+ request += _T("Sender: ");\r
+ request += loadString(IDS_mayu);\r
+ request += _T("\r\n");\r
+ }\r
+\r
+ _TCHAR buf[100];\r
+ _sntprintf(buf, NUMBER_OF(buf), _T("HWnd: %d\r\n"),\r
+ reinterpret_cast<int>(m_hwndAssocWindow));\r
+ request += buf;\r
+\r
+#ifdef _UNICODE\r
+ request += _T("Charset: UTF-8\r\n");\r
+#else\r
+ request += _T("Charset: Shift_JIS\r\n");\r
+#endif\r
+ request += _T("\r\n");\r
+\r
+#ifdef _UNICODE\r
+ std::string request_UTF_8 = to_UTF_8(request);\r
+#endif\r
+\r
+ // send request to Direct SSTP Server which matches i_name;\r
+ for (ParseDirectSSTPData::DirectSSTPServers::iterator\r
+ i = servers.begin(); i != servers.end(); ++ i) {\r
+ tsmatch what;\r
+ if (boost::regex_match(i->second.m_name, what, i_name)) {\r
+ COPYDATASTRUCT cd;\r
+ cd.dwData = 9801;\r
+#ifdef _UNICODE\r
+ cd.cbData = request_UTF_8.size();\r
+ cd.lpData = (void *)request_UTF_8.c_str();\r
+#else\r
+ cd.cbData = request.size();\r
+ cd.lpData = (void *)request.c_str();\r
+#endif\r
+#ifdef MAYU64\r
+ DWORD_PTR result;\r
+#else\r
+ DWORD result;\r
+#endif\r
+ SendMessageTimeout(i->second.m_hwnd, WM_COPYDATA,\r
+ reinterpret_cast<WPARAM>(m_hwndAssocWindow),\r
+ reinterpret_cast<LPARAM>(&cd),\r
+ SMTO_ABORTIFHUNG | SMTO_BLOCK, 5000, &result);\r
+ }\r
+ }\r
+\r
+ UnmapViewOfFile(data);\r
+ CloseHandle(hfm);\r
+}\r
+\r
+\r
+namespace shu\r
+{\r
+class PlugIn\r
+{\r
+ enum Type {\r
+ Type_A,\r
+ Type_W\r
+ };\r
+\r
+private:\r
+ HMODULE m_dll;\r
+ FARPROC m_func;\r
+ Type m_type;\r
+ tstringq m_funcParam;\r
+\r
+public:\r
+ PlugIn() : m_dll(NULL) {\r
+ }\r
+\r
+ ~PlugIn() {\r
+ FreeLibrary(m_dll);\r
+ }\r
+\r
+ bool load(const tstringq &i_dllName, const tstringq &i_funcName,\r
+ const tstringq &i_funcParam, tomsgstream &i_log) {\r
+ m_dll = LoadLibrary((_T("Plugins\\") + i_dllName).c_str());\r
+ if (!m_dll) {\r
+ m_dll = LoadLibrary((_T("Plugin\\") + i_dllName).c_str());\r
+ if (!m_dll) {\r
+ m_dll = LoadLibrary(i_dllName.c_str());\r
+ if (!m_dll) {\r
+ Acquire a(&i_log);\r
+ i_log << std::endl;\r
+ i_log << _T("error: &PlugIn() failed to load ") << i_dllName << std::endl;\r
+ return false;\r
+ }\r
+ }\r
+ }\r
+\r
+ // get function\r
+#ifdef UNICODE\r
+# define to_wstring\r
+#else\r
+# define to_string\r
+#endif\r
+ m_type = Type_W;\r
+ m_func = GetProcAddress(m_dll, to_string(_T("mayu") + i_funcName + _T("W")).c_str());\r
+ if (!m_func) {\r
+ m_type = Type_A;\r
+ m_func\r
+ = GetProcAddress(m_dll, to_string(_T("mayu") + i_funcName + _T("A")).c_str());\r
+ if (!m_func) {\r
+ m_func = GetProcAddress(m_dll, to_string(_T("mayu") + i_funcName).c_str());\r
+ if (!m_func) {\r
+ m_func = GetProcAddress(m_dll, to_string(i_funcName).c_str());\r
+ if (!m_func) {\r
+ Acquire a(&i_log);\r
+ i_log << std::endl;\r
+ i_log << _T("error: &PlugIn() failed to find function: ")\r
+ << i_funcName << std::endl;\r
+ return false;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ m_funcParam = i_funcParam;\r
+ return true;\r
+ }\r
+\r
+ void exec() {\r
+ ASSERT( m_dll );\r
+ ASSERT( m_func );\r
+\r
+ typedef void (WINAPI * PLUGIN_FUNCTION_A)(const char *i_arg);\r
+ typedef void (WINAPI * PLUGIN_FUNCTION_W)(const wchar_t *i_arg);\r
+ switch (m_type) {\r
+ case Type_A:\r
+ reinterpret_cast<PLUGIN_FUNCTION_A>(m_func)(to_string(m_funcParam).c_str());\r
+ break;\r
+ case Type_W:\r
+ reinterpret_cast<PLUGIN_FUNCTION_W>(m_func)(to_wstring(m_funcParam).c_str());\r
+ break;\r
+ }\r
+ }\r
+#undef to_string\r
+#undef to_wstring\r
+};\r
+\r
+static void plugInThread(void *i_plugin)\r
+{\r
+ PlugIn *plugin = static_cast<PlugIn *>(i_plugin);\r
+ plugin->exec();\r
+ delete plugin;\r
+}\r
+}\r
+\r
+void Engine::funcPlugIn(FunctionParam *i_param,\r
+ const StrExprArg &i_dllName,\r
+ const StrExprArg &i_funcName,\r
+ const StrExprArg &i_funcParam,\r
+ BooleanType i_doesCreateThread)\r
+{\r
+ if (!i_param->m_isPressed)\r
+ return;\r
+\r
+ shu::PlugIn *plugin = new shu::PlugIn();\r
+ if (!plugin->load(i_dllName.eval(), i_funcName.eval(), i_funcParam.eval(), m_log)) {\r
+ delete plugin;\r
+ return;\r
+ }\r
+ if (i_doesCreateThread) {\r
+ if (_beginthread(shu::plugInThread, 0, plugin) == -1) {\r
+ delete plugin;\r
+ Acquire a(&m_log);\r
+ m_log << std::endl;\r
+ m_log << _T("error: &PlugIn() failed to create thread.");\r
+ }\r
+ return;\r
+ } else\r
+ plugin->exec();\r
+}\r
+\r
+\r
+void Engine::funcMouseHook(FunctionParam *i_param,\r
+ MouseHookType i_hookType, int i_hookParam)\r
+{\r
+ GetCursorPos(&g_hookData->m_mousePos);\r
+ g_hookData->m_mouseHookType = i_hookType;\r
+ g_hookData->m_mouseHookParam = i_hookParam;\r
+\r
+ switch (i_hookType) {\r
+ case MouseHookType_WindowMove: {\r
+ // For this type, g_hookData->m_mouseHookParam means\r
+ // target window type to move.\r
+ HWND target;\r
+ bool isMDI;\r
+\r
+ // i_hooParam < 0 means target window to move is MDI.\r
+ if (i_hookParam < 0)\r
+ isMDI = true;\r
+ else\r
+ isMDI = false;\r
+\r
+ // abs(i_hookParam) == 2: target is window under mouse cursor\r
+ // otherwise: target is current focus window\r
+ if (i_hookParam == 2 || i_hookParam == -2)\r
+ target = WindowFromPoint(g_hookData->m_mousePos);\r
+ else\r
+ target = i_param->m_hwnd;\r
+\r
+ g_hookData->m_hwndMouseHookTarget =\r
+ reinterpret_cast<DWORD>(getToplevelWindow(target, &isMDI));\r
+ break;\r
+ default:\r
+ g_hookData->m_hwndMouseHookTarget = NULL;\r
+ break;\r
+ }\r
+ }\r
+ return;\r
+}\r
+\r
+\r
+// cancel prefix\r
+void Engine::funcCancelPrefix(FunctionParam *i_param)\r
+{\r
+ m_isPrefix = false;\r
+}\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// StrExpr\r
+class StrExpr\r
+{\r
+private:\r
+ tstringq m_symbol;\r
+protected:\r
+ static const Engine *s_engine;\r
+public:\r
+ StrExpr(const tstringq &i_symbol) : m_symbol(i_symbol) {};\r
+\r
+ virtual ~StrExpr() {};\r
+\r
+ virtual StrExpr *clone() const {\r
+ return new StrExpr(*this);\r
+ }\r
+\r
+ virtual tstringq eval() const {\r
+ return m_symbol;\r
+ }\r
+\r
+ static void setEngine(const Engine *i_engine) {\r
+ s_engine = i_engine;\r
+ }\r
+};\r
+\r
+const Engine *StrExpr::s_engine = NULL;\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// StrExprClipboard\r
+class StrExprClipboard : public StrExpr\r
+{\r
+public:\r
+ StrExprClipboard(const tstringq &i_symbol) : StrExpr(i_symbol) {};\r
+\r
+ ~StrExprClipboard() {};\r
+\r
+ StrExpr *clone() const {\r
+ return new StrExprClipboard(*this);\r
+ }\r
+\r
+ tstringq eval() const {\r
+ HGLOBAL g;\r
+ const _TCHAR *text = getTextFromClipboard(&g);\r
+ const tstring value(text == NULL ? _T("") : text);\r
+ closeClipboard(g);\r
+ return value;\r
+ }\r
+};\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// StrExprWindowClassName\r
+class StrExprWindowClassName : public StrExpr\r
+{\r
+public:\r
+ StrExprWindowClassName(const tstringq &i_symbol) : StrExpr(i_symbol) {};\r
+\r
+ ~StrExprWindowClassName() {};\r
+\r
+ StrExpr *clone() const {\r
+ return new StrExprWindowClassName(*this);\r
+ }\r
+\r
+ tstringq eval() const {\r
+ return s_engine->getCurrentWindowClassName();\r
+ }\r
+};\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// StrExprWindowTitleName\r
+class StrExprWindowTitleName : public StrExpr\r
+{\r
+public:\r
+ StrExprWindowTitleName(const tstringq &i_symbol) : StrExpr(i_symbol) {};\r
+\r
+ ~StrExprWindowTitleName() {};\r
+\r
+ StrExpr *clone() const {\r
+ return new StrExprWindowTitleName(*this);\r
+ }\r
+\r
+ tstringq eval() const {\r
+ return s_engine->getCurrentWindowTitleName();\r
+ }\r
+};\r
+\r
+\r
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// StrExprArg\r
+\r
+\r
+// default constructor\r
+StrExprArg::StrExprArg()\r
+{\r
+ m_expr = new StrExpr(_T(""));\r
+}\r
+\r
+\r
+// copy contructor\r
+StrExprArg::StrExprArg(const StrExprArg &i_data)\r
+{\r
+ m_expr = i_data.m_expr->clone();\r
+}\r
+\r
+\r
+StrExprArg &StrExprArg::operator=(const StrExprArg &i_data)\r
+{\r
+ if (i_data.m_expr == m_expr)\r
+ return *this;\r
+\r
+ delete m_expr;\r
+ m_expr = i_data.m_expr->clone();\r
+\r
+ return *this;\r
+}\r
+\r
+\r
+// initializer\r
+StrExprArg::StrExprArg(const tstringq &i_symbol, Type i_type)\r
+{\r
+ switch (i_type) {\r
+ case Literal:\r
+ m_expr = new StrExpr(i_symbol);\r
+ break;\r
+ case Builtin:\r
+ if (i_symbol == _T("Clipboard"))\r
+ m_expr = new StrExprClipboard(i_symbol);\r
+ else if (i_symbol == _T("WindowClassName"))\r
+ m_expr = new StrExprWindowClassName(i_symbol);\r
+ else if (i_symbol == _T("WindowTitleName"))\r
+ m_expr = new StrExprWindowTitleName(i_symbol);\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+}\r
+\r
+\r
+StrExprArg::~StrExprArg()\r
+{\r
+ delete m_expr;\r
+}\r
+\r
+\r
+tstringq StrExprArg::eval() const\r
+{\r
+ return m_expr->eval();\r
+}\r
+\r
+void StrExprArg::setEngine(const Engine *i_engine)\r
+{\r
+ StrExpr::setEngine(i_engine);\r
+}\r
+\r
+// stream output\r
+tostream &operator<<(tostream &i_ost, const StrExprArg &i_data)\r
+{\r
+ i_ost << i_data.eval();\r
+ return i_ost;\r
+}\r