1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
10 #include "registry.h"
\r
11 #include "vkeytable.h"
\r
12 #include "windowstool.h"
\r
13 #include <algorithm>
\r
14 #include <process.h>
\r
16 #define FUNCTION_DATA
\r
17 #include "functions.h"
\r
18 #undef FUNCTION_DATA
\r
21 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
25 template <class T> class TypeTable
\r
29 const _TCHAR *m_name;
\r
33 template <class T> static inline
\r
34 bool getTypeName(tstring *o_name, T i_type,
\r
35 const TypeTable<T> *i_table, size_t i_n)
\r
37 for (size_t i = 0; i < i_n; ++ i)
\r
38 if (i_table[i].m_type == i_type) {
\r
39 *o_name = i_table[i].m_name;
\r
45 template <class T> static inline
\r
46 bool getTypeValue(T *o_type, const tstringi &i_name,
\r
47 const TypeTable<T> *i_table, size_t i_n)
\r
49 for (size_t i = 0; i < i_n; ++ i)
\r
50 if (i_table[i].m_name == i_name) {
\r
51 *o_type = i_table[i].m_type;
\r
58 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
63 tostream &operator<<(tostream &i_ost, VKey i_data)
\r
65 if (i_data & VKey_extended)
\r
67 if (i_data & VKey_released)
\r
69 if (i_data & VKey_pressed)
\r
72 u_int8 code = i_data & ~(VKey_extended | VKey_released | VKey_pressed);
\r
73 const VKeyTable *vkt;
\r
74 for (vkt = g_vkeyTable; vkt->m_name; ++ vkt)
\r
75 if (vkt->m_code == code)
\r
78 i_ost << vkt->m_name;
\r
80 i_ost << _T("0x") << std::hex << code << std::dec;
\r
85 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
89 // ToWindowType table
\r
90 typedef TypeTable<ToWindowType> TypeTable_ToWindowType;
\r
91 static const TypeTable_ToWindowType g_toWindowTypeTable[] = {
\r
92 { ToWindowType_toOverlappedWindow, _T("toOverlappedWindow") },
\r
93 { ToWindowType_toMainWindow, _T("toMainWindow") },
\r
94 { ToWindowType_toItself, _T("toItself") },
\r
95 { ToWindowType_toParentWindow, _T("toParentWindow") },
\r
100 tostream &operator<<(tostream &i_ost, ToWindowType i_data)
\r
103 if (getTypeName(&name, i_data,
\r
104 g_toWindowTypeTable, NUMBER_OF(g_toWindowTypeTable)))
\r
107 i_ost << static_cast<int>(i_data);
\r
112 // get value of ToWindowType
\r
113 bool getTypeValue(ToWindowType *o_type, const tstring &i_name)
\r
115 return getTypeValue(o_type, i_name,
\r
116 g_toWindowTypeTable, NUMBER_OF(g_toWindowTypeTable));
\r
120 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
124 // GravityType table
\r
125 typedef TypeTable<GravityType> TypeTable_GravityType;
\r
126 static const TypeTable_GravityType g_gravityTypeTable[] = {
\r
127 { GravityType_C, _T("C") },
\r
128 { GravityType_N, _T("N") },
\r
129 { GravityType_E, _T("E") },
\r
130 { GravityType_W, _T("W") },
\r
131 { GravityType_S, _T("S") },
\r
132 { GravityType_NW, _T("NW") },
\r
133 { GravityType_NW, _T("WN") },
\r
134 { GravityType_NE, _T("NE") },
\r
135 { GravityType_NE, _T("EN") },
\r
136 { GravityType_SW, _T("SW") },
\r
137 { GravityType_SW, _T("WS") },
\r
138 { GravityType_SE, _T("SE") },
\r
139 { GravityType_SE, _T("ES") },
\r
144 tostream &operator<<(tostream &i_ost, GravityType i_data)
\r
147 if (getTypeName(&name, i_data,
\r
148 g_gravityTypeTable, NUMBER_OF(g_gravityTypeTable)))
\r
151 i_ost << _T("(GravityType internal error)");
\r
156 // get value of GravityType
\r
157 bool getTypeValue(GravityType *o_type, const tstring &i_name)
\r
159 return getTypeValue(o_type, i_name,
\r
160 g_gravityTypeTable, NUMBER_OF(g_gravityTypeTable));
\r
164 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
168 // MouseHookType table
\r
169 typedef TypeTable<MouseHookType> TypeTable_MouseHookType;
\r
170 static const TypeTable_MouseHookType g_mouseHookTypeTable[] = {
\r
171 { MouseHookType_None, _T("None") },
\r
172 { MouseHookType_Wheel, _T("Wheel") },
\r
173 { MouseHookType_WindowMove, _T("WindowMove") },
\r
178 tostream &operator<<(tostream &i_ost, MouseHookType i_data)
\r
181 if (getTypeName(&name, i_data,
\r
182 g_mouseHookTypeTable, NUMBER_OF(g_mouseHookTypeTable)))
\r
185 i_ost << _T("(MouseHookType internal error)");
\r
190 // get value of MouseHookType
\r
191 bool getTypeValue(MouseHookType *o_type, const tstring &i_name)
\r
193 return getTypeValue(o_type, i_name, g_mouseHookTypeTable,
\r
194 NUMBER_OF(g_mouseHookTypeTable));
\r
198 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
202 // ModifierLockType table
\r
203 typedef TypeTable<MayuDialogType> TypeTable_MayuDialogType;
\r
204 static const TypeTable_MayuDialogType g_mayuDialogTypeTable[] = {
\r
205 { MayuDialogType_investigate, _T("investigate") },
\r
206 { MayuDialogType_log, _T("log") },
\r
211 tostream &operator<<(tostream &i_ost, MayuDialogType i_data)
\r
214 if (getTypeName(&name, i_data,
\r
215 g_mayuDialogTypeTable, NUMBER_OF(g_mayuDialogTypeTable)))
\r
218 i_ost << _T("(MayuDialogType internal error)");
\r
223 // get value of MayuDialogType
\r
224 bool getTypeValue(MayuDialogType *o_type, const tstring &i_name)
\r
226 return getTypeValue(o_type, i_name, g_mayuDialogTypeTable,
\r
227 NUMBER_OF(g_mayuDialogTypeTable));
\r
231 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
235 // ToggleType table
\r
236 typedef TypeTable<ToggleType> TypeTable_ToggleType;
\r
237 static const TypeTable_ToggleType g_toggleType[] = {
\r
238 { ToggleType_toggle, _T("toggle") },
\r
239 { ToggleType_off, _T("off") },
\r
240 { ToggleType_off, _T("false") },
\r
241 { ToggleType_off, _T("released") },
\r
242 { ToggleType_on, _T("on") },
\r
243 { ToggleType_on, _T("true") },
\r
244 { ToggleType_on, _T("pressed") },
\r
249 tostream &operator<<(tostream &i_ost, ToggleType i_data)
\r
252 if (getTypeName(&name, i_data, g_toggleType, NUMBER_OF(g_toggleType)))
\r
255 i_ost << _T("(ToggleType internal error)");
\r
260 // get value of ToggleType
\r
261 bool getTypeValue(ToggleType *o_type, const tstring &i_name)
\r
263 return getTypeValue(o_type, i_name, g_toggleType,
\r
264 NUMBER_OF(g_toggleType));
\r
268 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
269 // ModifierLockType
\r
272 // ModifierLockType table
\r
273 typedef TypeTable<ModifierLockType> TypeTable_ModifierLockType;
\r
274 static const TypeTable_ModifierLockType g_modifierLockTypeTable[] = {
\r
275 { ModifierLockType_Lock0, _T("lock0") },
\r
276 { ModifierLockType_Lock1, _T("lock1") },
\r
277 { ModifierLockType_Lock2, _T("lock2") },
\r
278 { ModifierLockType_Lock3, _T("lock3") },
\r
279 { ModifierLockType_Lock4, _T("lock4") },
\r
280 { ModifierLockType_Lock5, _T("lock5") },
\r
281 { ModifierLockType_Lock6, _T("lock6") },
\r
282 { ModifierLockType_Lock7, _T("lock7") },
\r
283 { ModifierLockType_Lock8, _T("lock8") },
\r
284 { ModifierLockType_Lock9, _T("lock9") },
\r
289 tostream &operator<<(tostream &i_ost, ModifierLockType i_data)
\r
292 if (getTypeName(&name, i_data,
\r
293 g_modifierLockTypeTable, NUMBER_OF(g_modifierLockTypeTable)))
\r
296 i_ost << _T("(ModifierLockType internal error)");
\r
301 // get value of ModifierLockType
\r
302 bool getTypeValue(ModifierLockType *o_type, const tstring &i_name)
\r
304 return getTypeValue(o_type, i_name, g_modifierLockTypeTable,
\r
305 NUMBER_OF(g_modifierLockTypeTable));
\r
309 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
313 // ShowCommandType table
\r
314 typedef TypeTable<ShowCommandType> TypeTable_ShowCommandType;
\r
315 static const TypeTable_ShowCommandType g_showCommandTypeTable[] = {
\r
316 { ShowCommandType_hide, _T("hide") },
\r
317 { ShowCommandType_maximize, _T("maximize") },
\r
318 { ShowCommandType_minimize, _T("minimize") },
\r
319 { ShowCommandType_restore, _T("restore") },
\r
320 { ShowCommandType_show, _T("show") },
\r
321 { ShowCommandType_showDefault, _T("showDefault") },
\r
322 { ShowCommandType_showMaximized, _T("showMaximized") },
\r
323 { ShowCommandType_showMinimized, _T("showMinimized") },
\r
324 { ShowCommandType_showMinNoActive, _T("showMinNoActive") },
\r
325 { ShowCommandType_showNA, _T("showNA") },
\r
326 { ShowCommandType_showNoActivate, _T("showNoActivate") },
\r
327 { ShowCommandType_showNormal, _T("showNormal") },
\r
332 tostream &operator<<(tostream &i_ost, ShowCommandType i_data)
\r
335 if (getTypeName(&name, i_data,
\r
336 g_showCommandTypeTable, NUMBER_OF(g_showCommandTypeTable)))
\r
339 i_ost << _T("(ShowCommandType internal error)");
\r
344 // get value of ShowCommandType
\r
345 bool getTypeValue(ShowCommandType *o_type, const tstring &i_name)
\r
347 return getTypeValue(o_type, i_name, g_showCommandTypeTable,
\r
348 NUMBER_OF(g_showCommandTypeTable));
\r
352 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
353 // TargetWindowType
\r
356 // ModifierLockType table
\r
357 typedef TypeTable<TargetWindowType> TypeTable_TargetWindowType;
\r
358 static const TypeTable_TargetWindowType g_targetWindowType[] = {
\r
359 { TargetWindowType_overlapped, _T("overlapped") },
\r
360 { TargetWindowType_mdi, _T("mdi") },
\r
365 tostream &operator<<(tostream &i_ost, TargetWindowType i_data)
\r
368 if (getTypeName(&name, i_data,
\r
369 g_targetWindowType, NUMBER_OF(g_targetWindowType)))
\r
372 i_ost << _T("(TargetWindowType internal error)");
\r
377 // get value of TargetWindowType
\r
378 bool getTypeValue(TargetWindowType *o_type, const tstring &i_name)
\r
380 return getTypeValue(o_type, i_name, g_targetWindowType,
\r
381 NUMBER_OF(g_targetWindowType));
\r
385 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
389 // BooleanType table
\r
390 typedef TypeTable<BooleanType> TypeTable_BooleanType;
\r
391 static const TypeTable_BooleanType g_booleanType[] = {
\r
392 { BooleanType_false, _T("false") },
\r
393 { BooleanType_true, _T("true") },
\r
398 tostream &operator<<(tostream &i_ost, BooleanType i_data)
\r
401 if (getTypeName(&name, i_data, g_booleanType, NUMBER_OF(g_booleanType)))
\r
404 i_ost << _T("(BooleanType internal error)");
\r
409 // get value of BooleanType
\r
410 bool getTypeValue(BooleanType *o_type, const tstring &i_name)
\r
412 return getTypeValue(o_type, i_name, g_booleanType,
\r
413 NUMBER_OF(g_booleanType));
\r
417 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
418 // LogicalOperatorType
\r
421 // LogicalOperatorType table
\r
422 typedef TypeTable<LogicalOperatorType> TypeTable_LogicalOperatorType;
\r
423 static const TypeTable_LogicalOperatorType g_logicalOperatorType[] = {
\r
424 { LogicalOperatorType_or, _T("||") },
\r
425 { LogicalOperatorType_and, _T("&&") },
\r
430 tostream &operator<<(tostream &i_ost, LogicalOperatorType i_data)
\r
433 if (getTypeName(&name, i_data, g_logicalOperatorType,
\r
434 NUMBER_OF(g_logicalOperatorType)))
\r
437 i_ost << _T("(LogicalOperatorType internal error)");
\r
442 // get value of LogicalOperatorType
\r
443 bool getTypeValue(LogicalOperatorType *o_type, const tstring &i_name)
\r
445 return getTypeValue(o_type, i_name, g_logicalOperatorType,
\r
446 NUMBER_OF(g_logicalOperatorType));
\r
450 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
451 // WindowMonitorFromType
\r
454 // WindowMonitorFromType table
\r
455 typedef TypeTable<WindowMonitorFromType> TypeTable_WindowMonitorFromType;
\r
456 static const TypeTable_WindowMonitorFromType g_windowMonitorFromType[] = {
\r
457 { WindowMonitorFromType_primary, _T("primary") },
\r
458 { WindowMonitorFromType_current, _T("current") },
\r
463 tostream &operator<<(tostream &i_ost, WindowMonitorFromType i_data)
\r
466 if (getTypeName(&name, i_data, g_windowMonitorFromType,
\r
467 NUMBER_OF(g_windowMonitorFromType)))
\r
470 i_ost << _T("(WindowMonitorFromType internal error)");
\r
475 // get value of WindowMonitorFromType
\r
476 bool getTypeValue(WindowMonitorFromType *o_type, const tstring &i_name)
\r
478 return getTypeValue(o_type, i_name, g_windowMonitorFromType,
\r
479 NUMBER_OF(g_windowMonitorFromType));
\r
483 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
484 // std::list<tstringq>
\r
488 tostream &operator<<(tostream &i_ost, const std::list<tstringq> &i_data)
\r
490 for (std::list<tstringq>::const_iterator
\r
491 i = i_data.begin(); i != i_data.end(); ++ i) {
\r
492 i_ost << *i << _T(", ");
\r
498 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
503 FunctionData::~FunctionData()
\r
509 tostream &operator<<(tostream &i_ost, const FunctionData *i_data)
\r
511 return i_data->output(i_ost);
\r
515 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
520 class FunctionCreator
\r
523 typedef FunctionData *(*Creator)(); ///
\r
526 const _TCHAR *m_name; /// function name
\r
527 Creator m_creator; /// function data creator
\r
532 FunctionData *createFunctionData(const tstring &i_name)
\r
535 #define FUNCTION_CREATOR
\r
536 #include "functions.h"
\r
537 #undef FUNCTION_CREATOR
\r
540 for (size_t i = 0; i != NUMBER_OF(functionCreators); ++ i)
\r
541 if (i_name == functionCreators[i].m_name)
\r
542 return functionCreators[i].m_creator();
\r
547 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
552 bool getSuitableWindow(FunctionParam *i_param, HWND *o_hwnd)
\r
554 if (!i_param->m_isPressed)
\r
556 *o_hwnd = getToplevelWindow(i_param->m_hwnd, NULL);
\r
563 bool getSuitableMdiWindow(FunctionParam *i_param, HWND *o_hwnd,
\r
564 TargetWindowType *io_twt,
\r
565 RECT *o_rcWindow = NULL, RECT *o_rcParent = NULL)
\r
567 if (!i_param->m_isPressed)
\r
569 bool isMdi = *io_twt == TargetWindowType_mdi;
\r
570 *o_hwnd = getToplevelWindow(i_param->m_hwnd, &isMdi);
\r
571 *io_twt = isMdi ? TargetWindowType_mdi : TargetWindowType_overlapped;
\r
575 case TargetWindowType_overlapped:
\r
577 GetWindowRect(*o_hwnd, o_rcWindow);
\r
579 HMONITOR hm = monitorFromWindow(i_param->m_hwnd,
\r
580 MONITOR_DEFAULTTONEAREST);
\r
582 mi.cbSize = sizeof(mi);
\r
583 getMonitorInfo(hm, &mi);
\r
584 *o_rcParent = mi.rcWork;
\r
587 case TargetWindowType_mdi:
\r
589 getChildWindowRect(*o_hwnd, o_rcWindow);
\r
591 GetClientRect(GetParent(*o_hwnd), o_rcParent);
\r
597 // get clipboard text (you must call closeClopboard())
\r
598 static const _TCHAR *getTextFromClipboard(HGLOBAL *o_hdata)
\r
602 if (!OpenClipboard(NULL))
\r
606 *o_hdata = GetClipboardData(CF_UNICODETEXT);
\r
608 *o_hdata = GetClipboardData(CF_TEXT);
\r
613 _TCHAR *data = reinterpret_cast<_TCHAR *>(GlobalLock(*o_hdata));
\r
619 // close clipboard that opend by getTextFromClipboard()
\r
620 static void closeClipboard(HGLOBAL i_hdata, HGLOBAL i_hdataNew = NULL)
\r
623 GlobalUnlock(i_hdata);
\r
627 SetClipboardData(CF_UNICODETEXT, i_hdataNew);
\r
629 SetClipboardData(CF_TEXT, i_hdataNew);
\r
636 // EmacsEditKillLineFunc.
\r
637 // clear the contents of the clopboard
\r
638 // at that time, confirm if it is the result of the previous kill-line
\r
639 void Engine::EmacsEditKillLine::func()
\r
641 if (!m_buf.empty()) {
\r
643 const _TCHAR *text = getTextFromClipboard(&g);
\r
644 if (text == NULL || m_buf != text)
\r
648 if (OpenClipboard(NULL)) {
\r
655 /** if the text of the clipboard is
\r
658 1: EDIT Control (at EOL C-K): "" => buf + "\r\n", Delete
\r
659 0: EDIT Control (other C-K): "(.+)" => buf + "\1"
\r
660 0: IE FORM TEXTAREA (at EOL C-K): "\r\n" => buf + "\r\n"
\r
661 2: IE FORM TEXTAREA (other C-K): "(.+)\r\n" => buf + "\1", Return Left
\r
665 HGLOBAL Engine::EmacsEditKillLine::makeNewKillLineBuf(
\r
666 const _TCHAR *i_data, int *o_retval)
\r
668 size_t len = m_buf.size();
\r
669 len += _tcslen(i_data) + 3;
\r
671 HGLOBAL hdata = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
\r
672 len * sizeof(_TCHAR));
\r
675 _TCHAR *dataNew = reinterpret_cast<_TCHAR *>(GlobalLock(hdata));
\r
676 *dataNew = _T('\0');
\r
677 if (!m_buf.empty())
\r
678 _tcscpy(dataNew, m_buf.c_str());
\r
680 len = _tcslen(i_data);
\r
682 i_data[len - 2] == _T('\r') && i_data[len - 1] == _T('\n')) {
\r
683 _tcscat(dataNew, i_data);
\r
684 len = _tcslen(dataNew);
\r
685 dataNew[len - 2] = _T('\0'); // chomp
\r
687 } else if (len == 0) {
\r
688 _tcscat(dataNew, _T("\r\n"));
\r
691 _tcscat(dataNew, i_data);
\r
697 GlobalUnlock(hdata);
\r
702 // EmacsEditKillLinePred
\r
703 int Engine::EmacsEditKillLine::pred()
\r
706 const _TCHAR *text = getTextFromClipboard(&g);
\r
708 HGLOBAL hdata = makeNewKillLineBuf(text ? text : _T(""), &retval);
\r
709 closeClipboard(g, hdata);
\r
714 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
718 // send a default key to Windows
\r
719 void Engine::funcDefault(FunctionParam *i_param)
\r
722 Acquire a(&m_log, 1);
\r
723 m_log << std::endl;
\r
724 i_param->m_doesNeedEndl = false;
\r
726 if (i_param->m_isPressed)
\r
727 generateModifierEvents(i_param->m_c.m_mkey.m_modifier);
\r
728 generateKeyEvent(i_param->m_c.m_mkey.m_key, i_param->m_isPressed, true);
\r
731 // use a corresponding key of a parent keymap
\r
732 void Engine::funcKeymapParent(FunctionParam *i_param)
\r
734 Current c(i_param->m_c);
\r
735 c.m_keymap = c.m_keymap->getParentKeymap();
\r
737 funcDefault(i_param);
\r
742 Acquire a(&m_log, 1);
\r
743 m_log << _T("(") << c.m_keymap->getName() << _T(")") << std::endl;
\r
745 i_param->m_doesNeedEndl = false;
\r
746 generateKeyboardEvents(c);
\r
749 // use a corresponding key of a current window
\r
750 void Engine::funcKeymapWindow(FunctionParam *i_param)
\r
752 Current c(i_param->m_c);
\r
753 c.m_keymap = m_currentFocusOfThread->m_keymaps.front();
\r
754 c.m_i = m_currentFocusOfThread->m_keymaps.begin();
\r
755 generateKeyboardEvents(c);
\r
758 // use a corresponding key of the previous prefixed keymap
\r
759 void Engine::funcKeymapPrevPrefix(FunctionParam *i_param, int i_previous)
\r
761 Current c(i_param->m_c);
\r
762 if (0 < i_previous && 0 <= m_keymapPrefixHistory.size() - i_previous) {
\r
763 int n = i_previous - 1;
\r
764 KeymapPtrList::reverse_iterator i = m_keymapPrefixHistory.rbegin();
\r
765 while (0 < n && i != m_keymapPrefixHistory.rend())
\r
768 generateKeyboardEvents(c);
\r
772 // use a corresponding key of an other window class, or use a default key
\r
773 void Engine::funcOtherWindowClass(FunctionParam *i_param)
\r
775 Current c(i_param->m_c);
\r
777 if (c.m_i == m_currentFocusOfThread->m_keymaps.end()) {
\r
778 funcDefault(i_param);
\r
782 c.m_keymap = *c.m_i;
\r
784 Acquire a(&m_log, 1);
\r
785 m_log << _T("(") << c.m_keymap->getName() << _T(")") << std::endl;
\r
787 i_param->m_doesNeedEndl = false;
\r
788 generateKeyboardEvents(c);
\r
792 void Engine::funcPrefix(FunctionParam *i_param, const Keymap *i_keymap,
\r
793 BooleanType i_doesIgnoreModifiers)
\r
795 if (!i_param->m_isPressed)
\r
798 setCurrentKeymap(i_keymap, true);
\r
800 // generate prefixed event
\r
801 generateEvents(i_param->m_c, m_currentKeymap, &Event::prefixed);
\r
804 m_doesEditNextModifier = false;
\r
805 m_doesIgnoreModifierForPrefix = !!i_doesIgnoreModifiers;
\r
808 Acquire a(&m_log, 1);
\r
809 m_log << _T("(") << i_keymap->getName() << _T(", ")
\r
810 << (i_doesIgnoreModifiers ? _T("true") : _T("false")) << _T(")");
\r
814 // other keymap's key
\r
815 void Engine::funcKeymap(FunctionParam *i_param, const Keymap *i_keymap)
\r
817 Current c(i_param->m_c);
\r
818 c.m_keymap = i_keymap;
\r
820 Acquire a(&m_log, 1);
\r
821 m_log << _T("(") << c.m_keymap->getName() << _T(")") << std::endl;
\r
822 i_param->m_doesNeedEndl = false;
\r
824 generateKeyboardEvents(c);
\r
828 void Engine::funcSync(FunctionParam *i_param)
\r
830 if (i_param->m_isPressed)
\r
831 generateModifierEvents(i_param->m_af->m_modifier);
\r
832 if (!i_param->m_isPressed || m_currentFocusOfThread->m_isConsole)
\r
835 Key *sync = m_setting->m_keyboard.getSyncKey();
\r
836 if (sync->getScanCodesSize() == 0)
\r
838 const ScanCode *sc = sync->getScanCodes();
\r
840 // set variables exported from mayu.dll
\r
841 g_hookData->m_syncKey = sc->m_scan;
\r
842 g_hookData->m_syncKeyIsExtended = !!(sc->m_flags & ScanCode::E0E1);
\r
843 m_isSynchronizing = true;
\r
844 generateKeyEvent(sync, false, false);
\r
847 DWORD r = WaitForSingleObject(m_eSync, 5000);
\r
848 if (r == WAIT_TIMEOUT) {
\r
849 Acquire a(&m_log, 0);
\r
850 m_log << _T(" *FAILED*") << std::endl;
\r
853 m_isSynchronizing = false;
\r
857 void Engine::funcToggle(FunctionParam *i_param, ModifierLockType i_lock,
\r
858 ToggleType i_toggle)
\r
860 if (i_param->m_isPressed) // ignore PRESS
\r
863 Modifier::Type mt = static_cast<Modifier::Type>(i_lock);
\r
864 switch (i_toggle) {
\r
865 case ToggleType_toggle:
\r
866 m_currentLock.press(mt, !m_currentLock.isPressed(mt));
\r
868 case ToggleType_off:
\r
869 m_currentLock.press(mt, false);
\r
871 case ToggleType_on:
\r
872 m_currentLock.press(mt, true);
\r
877 // edit next user input key's modifier
\r
878 void Engine::funcEditNextModifier(FunctionParam *i_param,
\r
879 const Modifier &i_modifier)
\r
881 if (!i_param->m_isPressed)
\r
885 m_doesEditNextModifier = true;
\r
886 m_doesIgnoreModifierForPrefix = true;
\r
887 m_modifierForNextKey = i_modifier;
\r
891 void Engine::funcVariable(FunctionParam *i_param, int i_mag, int i_inc)
\r
893 if (!i_param->m_isPressed)
\r
895 m_variable *= i_mag;
\r
896 m_variable += i_inc;
\r
900 void Engine::funcRepeat(FunctionParam *i_param, const KeySeq *i_keySeq,
\r
903 if (i_param->m_isPressed) {
\r
904 int end = MIN(m_variable, i_max);
\r
905 for (int i = 0; i < end - 1; ++ i)
\r
906 generateKeySeqEvents(i_param->m_c, i_keySeq, Part_all);
\r
908 generateKeySeqEvents(i_param->m_c, i_keySeq, Part_down);
\r
910 generateKeySeqEvents(i_param->m_c, i_keySeq, Part_up);
\r
913 // undefined (bell)
\r
914 void Engine::funcUndefined(FunctionParam *i_param)
\r
916 if (!i_param->m_isPressed)
\r
918 MessageBeep(MB_OK);
\r
922 void Engine::funcIgnore(FunctionParam *)
\r
928 void Engine::funcPostMessage(FunctionParam *i_param, ToWindowType i_window,
\r
929 UINT i_message, WPARAM i_wParam, LPARAM i_lParam)
\r
931 if (!i_param->m_isPressed)
\r
934 int window = static_cast<int>(i_window);
\r
936 HWND hwnd = i_param->m_hwnd;
\r
938 for (int i = 0; i < window; ++ i)
\r
939 hwnd = GetParent(hwnd);
\r
940 } else if (window == ToWindowType_toMainWindow) {
\r
942 HWND p = GetParent(hwnd);
\r
947 } else if (window == ToWindowType_toOverlappedWindow) {
\r
950 LONG_PTR style = GetWindowLongPtr(hwnd, GWL_STYLE);
\r
952 LONG style = GetWindowLong(hwnd, GWL_STYLE);
\r
954 if ((style & WS_CHILD) == 0)
\r
956 hwnd = GetParent(hwnd);
\r
961 PostMessage(hwnd, i_message, i_wParam, i_lParam);
\r
966 void Engine::funcShellExecute(FunctionParam *i_param,
\r
967 const StrExprArg &/*i_operation*/,
\r
968 const StrExprArg &/*i_file*/,
\r
969 const StrExprArg &/*i_parameters*/,
\r
970 const StrExprArg &/*i_directory*/,
\r
971 ShowCommandType /*i_showCommand*/)
\r
973 if (!i_param->m_isPressed)
\r
975 m_afShellExecute = i_param->m_af;
\r
976 PostMessage(m_hwndAssocWindow,
\r
977 WM_APP_engineNotify, EngineNotify_shellExecute, 0);
\r
982 void Engine::shellExecute()
\r
986 FunctionData_ShellExecute *fd =
\r
987 reinterpret_cast<FunctionData_ShellExecute *>(
\r
988 m_afShellExecute->m_functionData);
\r
990 int r = (int)ShellExecute(
\r
992 fd->m_operation.eval().empty() ? _T("open") : fd->m_operation.eval().c_str(),
\r
993 fd->m_file.eval().empty() ? NULL : fd->m_file.eval().c_str(),
\r
994 fd->m_parameters.eval().empty() ? NULL : fd->m_parameters.eval().c_str(),
\r
995 fd->m_directory.eval().empty() ? NULL : fd->m_directory.eval().c_str(),
\r
996 fd->m_showCommand);
\r
1000 typedef TypeTable<int> ErrorTable;
\r
1001 static const ErrorTable errorTable[] = {
\r
1002 { 0, _T("The operating system is out of memory or resources.") },
\r
1003 { ERROR_FILE_NOT_FOUND, _T("The specified file was not found.") },
\r
1004 { ERROR_PATH_NOT_FOUND, _T("The specified path was not found.") },
\r
1005 { ERROR_BAD_FORMAT, _T("The .exe file is invalid ")
\r
1006 _T("(non-Win32R .exe or error in .exe image).") },
\r
1007 { SE_ERR_ACCESSDENIED,
\r
1008 _T("The operating system denied access to the specified file.") },
\r
1009 { SE_ERR_ASSOCINCOMPLETE,
\r
1010 _T("The file name association is incomplete or invalid.") },
\r
1012 _T("The DDE transaction could not be completed ")
\r
1013 _T("because other DDE transactions were being processed. ") },
\r
1014 { SE_ERR_DDEFAIL, _T("The DDE transaction failed.") },
\r
1015 { SE_ERR_DDETIMEOUT, _T("The DDE transaction could not be completed ")
\r
1016 _T("because the request timed out.") },
\r
1017 { SE_ERR_DLLNOTFOUND,
\r
1018 _T("The specified dynamic-link library was not found.") },
\r
1019 { SE_ERR_FNF, _T("The specified file was not found.") },
\r
1020 { SE_ERR_NOASSOC, _T("There is no application associated ")
\r
1021 _T("with the given file name extension.") },
\r
1023 _T("There was not enough memory to complete the operation.") },
\r
1024 { SE_ERR_PNF, _T("The specified path was not found.") },
\r
1025 { SE_ERR_SHARE, _T("A sharing violation occurred.") },
\r
1028 tstring errorMessage(_T("Unknown error."));
\r
1029 getTypeName(&errorMessage, r, errorTable, NUMBER_OF(errorTable));
\r
1031 Acquire b(&m_log, 0);
\r
1032 m_log << _T("error: ") << fd << _T(": ") << errorMessage << std::endl;
\r
1036 struct EnumWindowsForSetForegroundWindowParam {
\r
1037 const FunctionData_SetForegroundWindow *m_fd;
\r
1041 EnumWindowsForSetForegroundWindowParam(
\r
1042 const FunctionData_SetForegroundWindow *i_fd)
\r
1049 /// enum windows for SetForegroundWindow
\r
1050 static BOOL CALLBACK enumWindowsForSetForegroundWindow(
\r
1051 HWND i_hwnd, LPARAM i_lParam)
\r
1053 EnumWindowsForSetForegroundWindowParam &ep =
\r
1054 *reinterpret_cast<EnumWindowsForSetForegroundWindowParam *>(i_lParam);
\r
1056 _TCHAR name[GANA_MAX_ATOM_LENGTH];
\r
1057 if (!GetClassName(i_hwnd, name, NUMBER_OF(name)))
\r
1060 if (!boost::regex_search(tstring(name), what, ep.m_fd->m_windowClassName))
\r
1061 if (ep.m_fd->m_logicalOp == LogicalOperatorType_and)
\r
1062 return TRUE; // match failed
\r
1064 if (ep.m_fd->m_logicalOp == LogicalOperatorType_and) {
\r
1065 if (GetWindowText(i_hwnd, name, NUMBER_OF(name)) == 0)
\r
1066 name[0] = _T('\0');
\r
1067 if (!boost::regex_search(tstring(name), what,
\r
1068 ep.m_fd->m_windowTitleName))
\r
1069 return TRUE; // match failed
\r
1072 ep.m_hwnd = i_hwnd;
\r
1077 /// SetForegroundWindow
\r
1078 void Engine::funcSetForegroundWindow(FunctionParam *i_param, const tregex &,
\r
1079 LogicalOperatorType , const tregex &)
\r
1081 if (!i_param->m_isPressed)
\r
1083 EnumWindowsForSetForegroundWindowParam
\r
1084 ep(static_cast<const FunctionData_SetForegroundWindow *>(
\r
1085 i_param->m_af->m_functionData));
\r
1086 EnumWindows(enumWindowsForSetForegroundWindow,
\r
1087 reinterpret_cast<LPARAM>(&ep));
\r
1089 PostMessage(m_hwndAssocWindow,
\r
1090 WM_APP_engineNotify, EngineNotify_setForegroundWindow,
\r
1091 reinterpret_cast<LPARAM>(ep.m_hwnd));
\r
1097 void Engine::funcLoadSetting(FunctionParam *i_param, const StrExprArg &i_name)
\r
1099 if (!i_param->m_isPressed)
\r
1101 if (!i_name.eval().empty()) {
\r
1102 // set MAYU_REGISTRY_ROOT\.mayuIndex which name is same with i_name
\r
1103 Registry reg(MAYU_REGISTRY_ROOT);
\r
1105 tregex split(_T("^([^;]*);([^;]*);(.*)$"));
\r
1106 tstringi dot_mayu;
\r
1107 for (size_t i = 0; i < MAX_MAYU_REGISTRY_ENTRIES; ++ i) {
\r
1109 _sntprintf(buf, NUMBER_OF(buf), _T(".mayu%d"), i);
\r
1110 if (!reg.read(buf, &dot_mayu))
\r
1114 if (boost::regex_match(dot_mayu, what, split) &&
\r
1115 what.str(1) == i_name.eval()) {
\r
1116 reg.write(_T(".mayuIndex"), i);
\r
1122 Acquire a(&m_log, 0);
\r
1123 m_log << _T("unknown setting name: ") << i_name;
\r
1130 PostMessage(m_hwndAssocWindow,
\r
1131 WM_APP_engineNotify, EngineNotify_loadSetting, 0);
\r
1135 void Engine::funcVK(FunctionParam *i_param, VKey i_vkey)
\r
1137 long key = static_cast<long>(i_vkey);
\r
1138 BYTE vkey = static_cast<BYTE>(i_vkey);
\r
1139 bool isExtended = !!(key & VKey_extended);
\r
1140 bool isUp = !i_param->m_isPressed && !!(key & VKey_released);
\r
1141 bool isDown = i_param->m_isPressed && !!(key & VKey_pressed);
\r
1143 if (vkey == VK_LBUTTON && isDown)
\r
1144 mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
\r
1145 else if (vkey == VK_LBUTTON && isUp)
\r
1146 mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
\r
1147 else if (vkey == VK_MBUTTON && isDown)
\r
1148 mouse_event(MOUSEEVENTF_MIDDLEDOWN, 0, 0, 0, 0);
\r
1149 else if (vkey == VK_MBUTTON && isUp)
\r
1150 mouse_event(MOUSEEVENTF_MIDDLEUP, 0, 0, 0, 0);
\r
1151 else if (vkey == VK_RBUTTON && isDown)
\r
1152 mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);
\r
1153 else if (vkey == VK_RBUTTON && isUp)
\r
1154 mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
\r
1155 else if (vkey == VK_XBUTTON1 && isDown)
\r
1156 mouse_event(MOUSEEVENTF_XDOWN, 0, 0, XBUTTON1, 0);
\r
1157 else if (vkey == VK_XBUTTON1 && isUp)
\r
1158 mouse_event(MOUSEEVENTF_XUP, 0, 0, XBUTTON1, 0);
\r
1159 else if (vkey == VK_XBUTTON2 && isDown)
\r
1160 mouse_event(MOUSEEVENTF_XDOWN, 0, 0, XBUTTON2, 0);
\r
1161 else if (vkey == VK_XBUTTON2 && isUp)
\r
1162 mouse_event(MOUSEEVENTF_XUP, 0, 0, XBUTTON2, 0);
\r
1163 else if (isUp || isDown)
\r
1165 static_cast<BYTE>(MapVirtualKey(vkey, 0)),
\r
1166 (isExtended ? KEYEVENTF_EXTENDEDKEY : 0) |
\r
1167 (i_param->m_isPressed ? 0 : KEYEVENTF_KEYUP), 0);
\r
1171 void Engine::funcWait(FunctionParam *i_param, int i_milliSecond)
\r
1173 if (!i_param->m_isPressed)
\r
1175 if (i_milliSecond < 0 || 5000 < i_milliSecond) // too long wait
\r
1178 m_isSynchronizing = true;
\r
1180 Sleep(i_milliSecond);
\r
1182 m_isSynchronizing = false;
\r
1185 // investigate WM_COMMAND, WM_SYSCOMMAND
\r
1186 void Engine::funcInvestigateCommand(FunctionParam *i_param)
\r
1188 if (!i_param->m_isPressed)
\r
1190 Acquire a(&m_log, 0);
\r
1191 g_hookData->m_doesNotifyCommand = !g_hookData->m_doesNotifyCommand;
\r
1192 if (g_hookData->m_doesNotifyCommand)
\r
1193 m_log << _T(" begin") << std::endl;
\r
1195 m_log << _T(" end") << std::endl;
\r
1198 // show mayu dialog box
\r
1199 void Engine::funcMayuDialog(FunctionParam *i_param, MayuDialogType i_dialog,
\r
1200 ShowCommandType i_showCommand)
\r
1202 if (!i_param->m_isPressed)
\r
1204 PostMessage(getAssociatedWndow(), WM_APP_engineNotify, EngineNotify_showDlg,
\r
1205 static_cast<LPARAM>(i_dialog) |
\r
1206 static_cast<LPARAM>(i_showCommand));
\r
1209 // describe bindings
\r
1210 void Engine::funcDescribeBindings(FunctionParam *i_param)
\r
1212 if (!i_param->m_isPressed)
\r
1215 Acquire a(&m_log, 1);
\r
1216 m_log << std::endl;
\r
1218 describeBindings();
\r
1221 // show help message
\r
1222 void Engine::funcHelpMessage(FunctionParam *i_param, const StrExprArg &i_title,
\r
1223 const StrExprArg &i_message)
\r
1225 if (!i_param->m_isPressed)
\r
1228 m_helpTitle = i_title.eval();
\r
1229 m_helpMessage = i_message.eval();
\r
1230 bool doesShow = !(i_title.eval().size() == 0 && i_message.eval().size() == 0);
\r
1231 PostMessage(getAssociatedWndow(), WM_APP_engineNotify,
\r
1232 EngineNotify_helpMessage, doesShow);
\r
1236 void Engine::funcHelpVariable(FunctionParam *i_param, const StrExprArg &i_title)
\r
1238 if (!i_param->m_isPressed)
\r
1242 _sntprintf(buf, NUMBER_OF(buf), _T("%d"), m_variable);
\r
1244 m_helpTitle = i_title.eval();
\r
1245 m_helpMessage = buf;
\r
1246 PostMessage(getAssociatedWndow(), WM_APP_engineNotify,
\r
1247 EngineNotify_helpMessage, true);
\r
1251 void Engine::funcWindowRaise(FunctionParam *i_param,
\r
1252 TargetWindowType i_twt)
\r
1255 if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt))
\r
1257 SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,
\r
1258 SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSIZE);
\r
1262 void Engine::funcWindowLower(FunctionParam *i_param, TargetWindowType i_twt)
\r
1265 if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt))
\r
1267 SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0,
\r
1268 SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSIZE);
\r
1271 // minimize window
\r
1272 void Engine::funcWindowMinimize(FunctionParam *i_param, TargetWindowType i_twt)
\r
1275 if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt))
\r
1277 PostMessage(hwnd, WM_SYSCOMMAND,
\r
1278 IsIconic(hwnd) ? SC_RESTORE : SC_MINIMIZE, 0);
\r
1281 // maximize window
\r
1282 void Engine::funcWindowMaximize(FunctionParam *i_param, TargetWindowType i_twt)
\r
1285 if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt))
\r
1287 PostMessage(hwnd, WM_SYSCOMMAND,
\r
1288 IsZoomed(hwnd) ? SC_RESTORE : SC_MAXIMIZE, 0);
\r
1291 // maximize horizontally or virtically
\r
1292 void Engine::funcWindowHVMaximize(FunctionParam *i_param,
\r
1293 BooleanType i_isHorizontal,
\r
1294 TargetWindowType i_twt)
\r
1298 if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt, &rc, &rcd))
\r
1301 // erase non window
\r
1303 WindowPositions::iterator i = m_windowPositions.begin();
\r
1304 WindowPositions::iterator end = m_windowPositions.end();
\r
1305 for (; i != end; ++ i)
\r
1306 if (!IsWindow((*i).m_hwnd))
\r
1310 m_windowPositions.erase(i);
\r
1314 WindowPositions::iterator i = m_windowPositions.begin();
\r
1315 WindowPositions::iterator end = m_windowPositions.end();
\r
1316 WindowPositions::iterator target = end;
\r
1317 for (; i != end; ++ i)
\r
1318 if ((*i).m_hwnd == hwnd) {
\r
1323 if (IsZoomed(hwnd))
\r
1324 PostMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0);
\r
1326 WindowPosition::Mode mode = WindowPosition::Mode_normal;
\r
1328 if (target != end) {
\r
1329 WindowPosition &wp = *target;
\r
1331 if (wp.m_mode == WindowPosition::Mode_HV)
\r
1332 mode = wp.m_mode =
\r
1333 i_isHorizontal ? WindowPosition::Mode_V : WindowPosition::Mode_H;
\r
1334 else if (( i_isHorizontal && wp.m_mode == WindowPosition::Mode_V) ||
\r
1335 (!i_isHorizontal && wp.m_mode == WindowPosition::Mode_H))
\r
1336 mode = wp.m_mode = WindowPosition::Mode_HV;
\r
1338 m_windowPositions.erase(target);
\r
1340 mode = i_isHorizontal ? WindowPosition::Mode_H : WindowPosition::Mode_V;
\r
1341 m_windowPositions.push_front(WindowPosition(hwnd, rc, mode));
\r
1344 if (static_cast<int>(mode) & static_cast<int>(WindowPosition::Mode_H))
\r
1345 rc.left = rcd.left, rc.right = rcd.right;
\r
1346 if (static_cast<int>(mode) & static_cast<int>(WindowPosition::Mode_V))
\r
1347 rc.top = rcd.top, rc.bottom = rcd.bottom;
\r
1349 asyncMoveWindow(hwnd, rc.left, rc.top, rcWidth(&rc), rcHeight(&rc));
\r
1353 // maximize window horizontally
\r
1354 void Engine::funcWindowHMaximize(FunctionParam *i_param,
\r
1355 TargetWindowType i_twt)
\r
1357 funcWindowHVMaximize(i_param, BooleanType_true, i_twt);
\r
1360 // maximize window virtically
\r
1361 void Engine::funcWindowVMaximize(FunctionParam *i_param,
\r
1362 TargetWindowType i_twt)
\r
1364 funcWindowHVMaximize(i_param, BooleanType_false, i_twt);
\r
1368 void Engine::funcWindowMove(FunctionParam *i_param, int i_dx, int i_dy,
\r
1369 TargetWindowType i_twt)
\r
1371 funcWindowMoveTo(i_param, GravityType_C, i_dx, i_dy, i_twt);
\r
1374 // move window to ...
\r
1375 void Engine::funcWindowMoveTo(FunctionParam *i_param,
\r
1376 GravityType i_gravityType,
\r
1377 int i_dx, int i_dy, TargetWindowType i_twt)
\r
1381 if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt, &rc, &rcd))
\r
1384 int x = rc.left + i_dx;
\r
1385 int y = rc.top + i_dy;
\r
1387 if (i_gravityType & GravityType_N)
\r
1388 y = i_dy + rcd.top;
\r
1389 if (i_gravityType & GravityType_E)
\r
1390 x = i_dx + rcd.right - rcWidth(&rc);
\r
1391 if (i_gravityType & GravityType_W)
\r
1392 x = i_dx + rcd.left;
\r
1393 if (i_gravityType & GravityType_S)
\r
1394 y = i_dy + rcd.bottom - rcHeight(&rc);
\r
1395 asyncMoveWindow(hwnd, x, y);
\r
1399 // move window visibly
\r
1400 void Engine::funcWindowMoveVisibly(FunctionParam *i_param,
\r
1401 TargetWindowType i_twt)
\r
1405 if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt, &rc, &rcd))
\r
1410 if (rc.left < rcd.left)
\r
1412 else if (rcd.right < rc.right)
\r
1413 x = rcd.right - rcWidth(&rc);
\r
1414 if (rc.top < rcd.top)
\r
1416 else if (rcd.bottom < rc.bottom)
\r
1417 y = rcd.bottom - rcHeight(&rc);
\r
1418 asyncMoveWindow(hwnd, x, y);
\r
1422 struct EnumDisplayMonitorsForWindowMonitorToParam {
\r
1423 std::vector<HMONITOR> m_monitors;
\r
1424 std::vector<MONITORINFO> m_monitorinfos;
\r
1425 int m_primaryMonitorIdx;
\r
1426 int m_currentMonitorIdx;
\r
1431 EnumDisplayMonitorsForWindowMonitorToParam(HMONITOR i_hmon)
\r
1433 m_primaryMonitorIdx(-1), m_currentMonitorIdx(-1) {
\r
1437 static BOOL CALLBACK enumDisplayMonitorsForWindowMonitorTo(
\r
1438 HMONITOR i_hmon, HDC i_hdc, LPRECT i_rcMonitor, LPARAM i_data)
\r
1440 EnumDisplayMonitorsForWindowMonitorToParam &ep =
\r
1441 *reinterpret_cast<EnumDisplayMonitorsForWindowMonitorToParam *>(i_data);
\r
1443 ep.m_monitors.push_back(i_hmon);
\r
1446 mi.cbSize = sizeof(mi);
\r
1447 getMonitorInfo(i_hmon, &mi);
\r
1448 ep.m_monitorinfos.push_back(mi);
\r
1450 if (mi.dwFlags & MONITORINFOF_PRIMARY)
\r
1451 ep.m_primaryMonitorIdx = ep.m_monitors.size() - 1;
\r
1452 if (i_hmon == ep.m_hmon)
\r
1453 ep.m_currentMonitorIdx = ep.m_monitors.size() - 1;
\r
1458 /// move window to other monitor
\r
1459 void Engine::funcWindowMonitorTo(
\r
1460 FunctionParam *i_param, WindowMonitorFromType i_fromType, int i_monitor,
\r
1461 BooleanType i_adjustPos, BooleanType i_adjustSize)
\r
1464 if (! getSuitableWindow(i_param, &hwnd))
\r
1468 hmonCur = monitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
\r
1470 EnumDisplayMonitorsForWindowMonitorToParam ep(hmonCur);
\r
1471 enumDisplayMonitors(NULL, NULL, enumDisplayMonitorsForWindowMonitorTo,
\r
1472 reinterpret_cast<LPARAM>(&ep));
\r
1473 if (ep.m_monitors.size() < 1 ||
\r
1474 ep.m_primaryMonitorIdx < 0 || ep.m_currentMonitorIdx < 0)
\r
1478 switch (i_fromType) {
\r
1479 case WindowMonitorFromType_primary:
\r
1480 targetIdx = (ep.m_primaryMonitorIdx + i_monitor) % ep.m_monitors.size();
\r
1483 case WindowMonitorFromType_current:
\r
1484 targetIdx = (ep.m_currentMonitorIdx + i_monitor) % ep.m_monitors.size();
\r
1487 if (ep.m_currentMonitorIdx == targetIdx)
\r
1490 RECT rcCur, rcTarget, rcWin;
\r
1491 rcCur = ep.m_monitorinfos[ep.m_currentMonitorIdx].rcWork;
\r
1492 rcTarget = ep.m_monitorinfos[targetIdx].rcWork;
\r
1493 GetWindowRect(hwnd, &rcWin);
\r
1495 int x = rcTarget.left + (rcWin.left - rcCur.left);
\r
1496 int y = rcTarget.top + (rcWin.top - rcCur.top);
\r
1497 int w = rcWidth(&rcWin);
\r
1498 int h = rcHeight(&rcWin);
\r
1500 if (i_adjustPos) {
\r
1501 if (x + w > rcTarget.right)
\r
1502 x = rcTarget.right - w;
\r
1503 if (x < rcTarget.left)
\r
1504 x = rcTarget.left;
\r
1505 if (w > rcWidth(&rcTarget)) {
\r
1506 x = rcTarget.left;
\r
1507 w = rcWidth(&rcTarget);
\r
1510 if (y + h > rcTarget.bottom)
\r
1511 y = rcTarget.bottom - h;
\r
1512 if (y < rcTarget.top)
\r
1514 if (h > rcHeight(&rcTarget)) {
\r
1516 h = rcHeight(&rcTarget);
\r
1520 if (i_adjustPos && i_adjustSize) {
\r
1521 if (IsZoomed(hwnd))
\r
1522 PostMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0);
\r
1523 asyncMoveWindow(hwnd, x, y, w, h);
\r
1525 asyncMoveWindow(hwnd, x, y);
\r
1529 /// move window to other monitor
\r
1530 void Engine::funcWindowMonitor(
\r
1531 FunctionParam *i_param, int i_monitor,
\r
1532 BooleanType i_adjustPos, BooleanType i_adjustSize)
\r
1534 funcWindowMonitorTo(i_param, WindowMonitorFromType_primary, i_monitor,
\r
1535 i_adjustPos, i_adjustSize);
\r
1540 void Engine::funcWindowClingToLeft(FunctionParam *i_param,
\r
1541 TargetWindowType i_twt)
\r
1543 funcWindowMoveTo(i_param, GravityType_W, 0, 0, i_twt);
\r
1547 void Engine::funcWindowClingToRight(FunctionParam *i_param,
\r
1548 TargetWindowType i_twt)
\r
1550 funcWindowMoveTo(i_param, GravityType_E, 0, 0, i_twt);
\r
1554 void Engine::funcWindowClingToTop(FunctionParam *i_param,
\r
1555 TargetWindowType i_twt)
\r
1557 funcWindowMoveTo(i_param, GravityType_N, 0, 0, i_twt);
\r
1561 void Engine::funcWindowClingToBottom(FunctionParam *i_param,
\r
1562 TargetWindowType i_twt)
\r
1564 funcWindowMoveTo(i_param, GravityType_S, 0, 0, i_twt);
\r
1568 void Engine::funcWindowClose(FunctionParam *i_param, TargetWindowType i_twt)
\r
1571 if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt))
\r
1573 PostMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0);
\r
1576 // toggle top-most flag of the window
\r
1577 void Engine::funcWindowToggleTopMost(FunctionParam *i_param)
\r
1580 if (!getSuitableWindow(i_param, &hwnd))
\r
1585 (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) ?
\r
1587 (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) ?
\r
1589 HWND_NOTOPMOST : HWND_TOPMOST,
\r
1591 SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSIZE);
\r
1594 // identify the window
\r
1595 void Engine::funcWindowIdentify(FunctionParam *i_param)
\r
1597 if (!i_param->m_isPressed)
\r
1600 _TCHAR className[GANA_MAX_ATOM_LENGTH];
\r
1602 if (GetClassName(i_param->m_hwnd, className, NUMBER_OF(className))) {
\r
1603 if (_tcsicmp(className, _T("ConsoleWindowClass")) == 0) {
\r
1604 _TCHAR titleName[1024];
\r
1605 if (GetWindowText(i_param->m_hwnd, titleName, NUMBER_OF(titleName)) == 0)
\r
1606 titleName[0] = _T('\0');
\r
1608 Acquire a(&m_log, 1);
\r
1609 m_log << _T("HWND:\t") << std::hex
\r
1610 << reinterpret_cast<int>(i_param->m_hwnd)
\r
1611 << std::dec << std::endl;
\r
1613 Acquire a(&m_log, 0);
\r
1614 m_log << _T("CLASS:\t") << className << std::endl;
\r
1615 m_log << _T("TITLE:\t") << titleName << std::endl;
\r
1617 HWND hwnd = getToplevelWindow(i_param->m_hwnd, NULL);
\r
1619 GetWindowRect(hwnd, &rc);
\r
1620 m_log << _T("Toplevel Window Position/Size: (")
\r
1621 << rc.left << _T(", ") << rc.top << _T(") / (")
\r
1622 << rcWidth(&rc) << _T("x") << rcHeight(&rc)
\r
1623 << _T(")") << std::endl;
\r
1625 SystemParametersInfo(SPI_GETWORKAREA, 0, (void *)&rc, FALSE);
\r
1626 m_log << _T("Desktop Window Position/Size: (")
\r
1627 << rc.left << _T(", ") << rc.top << _T(") / (")
\r
1628 << rcWidth(&rc) << _T("x") << rcHeight(&rc)
\r
1629 << _T(")") << std::endl;
\r
1631 m_log << std::endl;
\r
1636 UINT WM_MAYU_MESSAGE = RegisterWindowMessage(
\r
1637 addSessionId(WM_MAYU_MESSAGE_NAME).c_str());
\r
1638 CHECK_TRUE( PostMessage(i_param->m_hwnd, WM_MAYU_MESSAGE,
\r
1639 MayuMessage_notifyName, 0) );
\r
1643 // set alpha blending parameter to the window
\r
1644 void Engine::funcWindowSetAlpha(FunctionParam *i_param, int i_alpha)
\r
1647 if (!getSuitableWindow(i_param, &hwnd))
\r
1650 if (i_alpha < 0) { // remove all alpha
\r
1651 for (WindowsWithAlpha::iterator i = m_windowsWithAlpha.begin();
\r
1652 i != m_windowsWithAlpha.end(); ++ i) {
\r
1654 SetWindowLongPtr(*i, GWL_EXSTYLE,
\r
1655 GetWindowLongPtr(*i, GWL_EXSTYLE) & ~WS_EX_LAYERED);
\r
1657 SetWindowLong(*i, GWL_EXSTYLE,
\r
1658 GetWindowLong(*i, GWL_EXSTYLE) & ~WS_EX_LAYERED);
\r
1660 RedrawWindow(*i, NULL, NULL,
\r
1661 RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
\r
1663 m_windowsWithAlpha.clear();
\r
1666 LONG_PTR exStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
\r
1668 LONG exStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
\r
1670 if (exStyle & WS_EX_LAYERED) { // remove alpha
\r
1671 WindowsWithAlpha::iterator
\r
1672 i = std::find(m_windowsWithAlpha.begin(), m_windowsWithAlpha.end(),
\r
1674 if (i == m_windowsWithAlpha.end())
\r
1675 return; // already layered by the application
\r
1677 m_windowsWithAlpha.erase(i);
\r
1680 SetWindowLongPtr(hwnd, GWL_EXSTYLE, exStyle & ~WS_EX_LAYERED);
\r
1682 SetWindowLong(hwnd, GWL_EXSTYLE, exStyle & ~WS_EX_LAYERED);
\r
1684 } else { // add alpha
\r
1686 SetWindowLongPtr(hwnd, GWL_EXSTYLE, exStyle | WS_EX_LAYERED);
\r
1688 SetWindowLong(hwnd, GWL_EXSTYLE, exStyle | WS_EX_LAYERED);
\r
1691 if (!setLayeredWindowAttributes(hwnd, 0,
\r
1692 (BYTE)(255 * i_alpha / 100), LWA_ALPHA)) {
\r
1693 Acquire a(&m_log, 0);
\r
1694 m_log << _T("error: &WindowSetAlpha(") << i_alpha
\r
1695 << _T(") failed for HWND: ") << std::hex
\r
1696 << hwnd << std::dec << std::endl;
\r
1699 m_windowsWithAlpha.push_front(hwnd);
\r
1701 RedrawWindow(hwnd, NULL, NULL,
\r
1702 RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
\r
1707 // redraw the window
\r
1708 void Engine::funcWindowRedraw(FunctionParam *i_param)
\r
1711 if (!getSuitableWindow(i_param, &hwnd))
\r
1713 RedrawWindow(hwnd, NULL, NULL,
\r
1714 RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
\r
1717 // resize window to
\r
1718 void Engine::funcWindowResizeTo(FunctionParam *i_param, int i_width,
\r
1719 int i_height, TargetWindowType i_twt)
\r
1723 if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt, &rc, &rcd))
\r
1727 i_width = rcWidth(&rc);
\r
1728 else if (i_width < 0)
\r
1729 i_width += rcWidth(&rcd);
\r
1731 if (i_height == 0)
\r
1732 i_height = rcHeight(&rc);
\r
1733 else if (i_height < 0)
\r
1734 i_height += rcHeight(&rcd);
\r
1736 asyncResize(hwnd, i_width, i_height);
\r
1739 // move the mouse cursor
\r
1740 void Engine::funcMouseMove(FunctionParam *i_param, int i_dx, int i_dy)
\r
1742 if (!i_param->m_isPressed)
\r
1745 GetCursorPos(&pt);
\r
1746 SetCursorPos(pt.x + i_dx, pt.y + i_dy);
\r
1749 // send a mouse-wheel-message to Windows
\r
1750 void Engine::funcMouseWheel(FunctionParam *i_param, int i_delta)
\r
1752 if (!i_param->m_isPressed)
\r
1754 mouse_event(MOUSEEVENTF_WHEEL, 0, 0, i_delta, 0);
\r
1757 // convert the contents of the Clipboard to upper case
\r
1758 void Engine::funcClipboardChangeCase(FunctionParam *i_param,
\r
1759 BooleanType i_doesConvertToUpperCase)
\r
1761 if (!i_param->m_isPressed)
\r
1765 const _TCHAR *text = getTextFromClipboard(&hdata);
\r
1766 HGLOBAL hdataNew = NULL;
\r
1768 int size = static_cast<int>(GlobalSize(hdata));
\r
1769 hdataNew = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, size);
\r
1771 if (_TCHAR *dataNew = reinterpret_cast<_TCHAR *>(GlobalLock(hdataNew))) {
\r
1772 std::memcpy(dataNew, text, size);
\r
1773 _TCHAR *dataEnd = dataNew + size;
\r
1774 while (dataNew < dataEnd && *dataNew) {
\r
1775 _TCHAR c = *dataNew;
\r
1780 i_doesConvertToUpperCase ? _totupper(c) : _totlower(c);
\r
1782 GlobalUnlock(hdataNew);
\r
1786 closeClipboard(hdata, hdataNew);
\r
1789 // convert the contents of the Clipboard to upper case
\r
1790 void Engine::funcClipboardUpcaseWord(FunctionParam *i_param)
\r
1792 funcClipboardChangeCase(i_param, BooleanType_true);
\r
1795 // convert the contents of the Clipboard to lower case
\r
1796 void Engine::funcClipboardDowncaseWord(FunctionParam *i_param)
\r
1798 funcClipboardChangeCase(i_param, BooleanType_false);
\r
1801 // set the contents of the Clipboard to the string
\r
1802 void Engine::funcClipboardCopy(FunctionParam *i_param, const StrExprArg &i_text)
\r
1804 if (!i_param->m_isPressed)
\r
1806 if (!OpenClipboard(NULL))
\r
1809 HGLOBAL hdataNew =
\r
1810 GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
\r
1811 (i_text.eval().size() + 1) * sizeof(_TCHAR));
\r
1814 _TCHAR *dataNew = reinterpret_cast<_TCHAR *>(GlobalLock(hdataNew));
\r
1815 _tcscpy(dataNew, i_text.eval().c_str());
\r
1816 GlobalUnlock(hdataNew);
\r
1817 closeClipboard(NULL, hdataNew);
\r
1821 void Engine::funcEmacsEditKillLinePred(
\r
1822 FunctionParam *i_param, const KeySeq *i_keySeq1, const KeySeq *i_keySeq2)
\r
1824 m_emacsEditKillLine.m_doForceReset = false;
\r
1825 if (!i_param->m_isPressed)
\r
1828 int r = m_emacsEditKillLine.pred();
\r
1829 const KeySeq *keySeq;
\r
1831 keySeq = i_keySeq1;
\r
1833 keySeq = i_keySeq2;
\r
1837 generateKeySeqEvents(i_param->m_c, keySeq, Part_all);
\r
1841 void Engine::funcEmacsEditKillLineFunc(FunctionParam *i_param)
\r
1843 if (!i_param->m_isPressed)
\r
1845 m_emacsEditKillLine.func();
\r
1846 m_emacsEditKillLine.m_doForceReset = false;
\r
1850 void Engine::funcLogClear(FunctionParam *i_param)
\r
1852 if (!i_param->m_isPressed)
\r
1854 PostMessage(getAssociatedWndow(), WM_APP_engineNotify,
\r
1855 EngineNotify_clearLog, 0);
\r
1859 void Engine::funcRecenter(FunctionParam *i_param)
\r
1861 if (!i_param->m_isPressed)
\r
1863 if (m_hwndFocus) {
\r
1864 UINT WM_MAYU_MESSAGE = RegisterWindowMessage(
\r
1865 addSessionId(WM_MAYU_MESSAGE_NAME).c_str());
\r
1866 PostMessage(m_hwndFocus, WM_MAYU_MESSAGE, MayuMessage_funcRecenter, 0);
\r
1870 // set IME open status
\r
1871 void Engine::funcSetImeStatus(FunctionParam *i_param, ToggleType i_toggle)
\r
1873 if (!i_param->m_isPressed)
\r
1875 if (m_hwndFocus) {
\r
1876 UINT WM_MAYU_MESSAGE = RegisterWindowMessage(
\r
1877 addSessionId(WM_MAYU_MESSAGE_NAME).c_str());
\r
1879 switch (i_toggle) {
\r
1880 case ToggleType_toggle:
\r
1883 case ToggleType_off:
\r
1886 case ToggleType_on:
\r
1890 PostMessage(m_hwndFocus, WM_MAYU_MESSAGE, MayuMessage_funcSetImeStatus, status);
\r
1894 // set IME open status
\r
1895 void Engine::funcSetImeString(FunctionParam *i_param, const StrExprArg &i_data)
\r
1897 if (!i_param->m_isPressed)
\r
1899 if (m_hwndFocus) {
\r
1900 UINT WM_MAYU_MESSAGE = RegisterWindowMessage(
\r
1901 addSessionId(WM_MAYU_MESSAGE_NAME).c_str());
\r
1902 PostMessage(m_hwndFocus, WM_MAYU_MESSAGE, MayuMessage_funcSetImeString, i_data.eval().size() * sizeof(_TCHAR));
\r
1906 DisconnectNamedPipe(m_hookPipe);
\r
1907 ConnectNamedPipe(m_hookPipe, NULL);
\r
1908 error = WriteFile(m_hookPipe, i_data.eval().c_str(),
\r
1909 i_data.eval().size() * sizeof(_TCHAR),
\r
1912 //FlushFileBuffers(m_hookPipe);
\r
1916 // Direct SSTP Server
\r
1917 class DirectSSTPServer
\r
1923 tstring m_keroname;
\r
1926 DirectSSTPServer()
\r
1932 class ParseDirectSSTPData
\r
1934 typedef boost::match_results<boost::regex::const_iterator> MR;
\r
1937 typedef std::map<tstring, DirectSSTPServer> DirectSSTPServers;
\r
1940 DirectSSTPServers *m_directSSTPServers;
\r
1944 ParseDirectSSTPData(DirectSSTPServers *i_directSSTPServers)
\r
1945 : m_directSSTPServers(i_directSSTPServers) {
\r
1948 bool operator()(const MR& i_what) {
\r
1950 tstring id(to_wstring(std::string(i_what[1].first, i_what[1].second)));
\r
1951 tstring member(to_wstring(std::string(i_what[2].first, i_what[2].second)));
\r
1952 tstring value(to_wstring(std::string(i_what[3].first, i_what[3].second)));
\r
1954 tstring id(i_what[1].first, i_what[1].second);
\r
1955 tstring member(i_what[2].first, i_what[2].second);
\r
1956 tstring value(i_what[3].first, i_what[3].second);
\r
1959 if (member == _T("path"))
\r
1960 (*m_directSSTPServers)[id].m_path = value;
\r
1961 else if (member == _T("hwnd"))
\r
1962 (*m_directSSTPServers)[id].m_hwnd =
\r
1963 reinterpret_cast<HWND>(_ttoi(value.c_str()));
\r
1964 else if (member == _T("name"))
\r
1965 (*m_directSSTPServers)[id].m_name = value;
\r
1966 else if (member == _T("keroname"))
\r
1967 (*m_directSSTPServers)[id].m_keroname = value;
\r
1973 void Engine::funcDirectSSTP(FunctionParam *i_param,
\r
1974 const tregex &i_name,
\r
1975 const StrExprArg &i_protocol,
\r
1976 const std::list<tstringq> &i_headers)
\r
1978 if (!i_param->m_isPressed)
\r
1981 // check Direct SSTP server exist ?
\r
1982 if (HANDLE hm = OpenMutex(MUTEX_ALL_ACCESS, FALSE, _T("sakura")))
\r
1985 Acquire a(&m_log, 0);
\r
1986 m_log << _T(" Error(1): Direct SSTP server does not exist.");
\r
1990 HANDLE hfm = OpenFileMapping(FILE_MAP_READ, FALSE, _T("Sakura"));
\r
1992 Acquire a(&m_log, 0);
\r
1993 m_log << _T(" Error(2): Direct SSTP server does not provide data.");
\r
1998 reinterpret_cast<char *>(MapViewOfFile(hfm, FILE_MAP_READ, 0, 0, 0));
\r
2001 Acquire a(&m_log, 0);
\r
2002 m_log << _T(" Error(3): Direct SSTP server does not provide data.");
\r
2006 long length = *(long *)data;
\r
2007 const char *begin = data + 4;
\r
2008 const char *end = data + length;
\r
2009 boost::regex getSakura("([0-9a-fA-F]{32})\\.([^\x01]+)\x01(.*?)\r\n");
\r
2011 ParseDirectSSTPData::DirectSSTPServers servers;
\r
2012 boost::regex_iterator<boost::regex::const_iterator>
\r
2013 it(begin, end, getSakura), last;
\r
2014 for (; it != last; ++it)
\r
2015 ((ParseDirectSSTPData)(&servers))(*it);
\r
2019 if (!i_protocol.eval().size())
\r
2020 request += _T("NOTIFY SSTP/1.1");
\r
2022 request += i_protocol.eval();
\r
2023 request += _T("\r\n");
\r
2025 bool hasSender = false;
\r
2026 for (std::list<tstringq>::const_iterator
\r
2027 i = i_headers.begin(); i != i_headers.end(); ++ i) {
\r
2028 if (_tcsnicmp(_T("Charset"), i->c_str(), 7) == 0 ||
\r
2029 _tcsnicmp(_T("Hwnd"), i->c_str(), 4) == 0)
\r
2031 if (_tcsnicmp(_T("Sender"), i->c_str(), 6) == 0)
\r
2033 request += i->c_str();
\r
2034 request += _T("\r\n");
\r
2038 request += _T("Sender: ");
\r
2039 request += loadString(IDS_mayu);
\r
2040 request += _T("\r\n");
\r
2044 _sntprintf(buf, NUMBER_OF(buf), _T("HWnd: %d\r\n"),
\r
2045 reinterpret_cast<int>(m_hwndAssocWindow));
\r
2049 request += _T("Charset: UTF-8\r\n");
\r
2051 request += _T("Charset: Shift_JIS\r\n");
\r
2053 request += _T("\r\n");
\r
2056 std::string request_UTF_8 = to_UTF_8(request);
\r
2059 // send request to Direct SSTP Server which matches i_name;
\r
2060 for (ParseDirectSSTPData::DirectSSTPServers::iterator
\r
2061 i = servers.begin(); i != servers.end(); ++ i) {
\r
2063 if (boost::regex_match(i->second.m_name, what, i_name)) {
\r
2064 COPYDATASTRUCT cd;
\r
2067 cd.cbData = request_UTF_8.size();
\r
2068 cd.lpData = (void *)request_UTF_8.c_str();
\r
2070 cd.cbData = request.size();
\r
2071 cd.lpData = (void *)request.c_str();
\r
2078 SendMessageTimeout(i->second.m_hwnd, WM_COPYDATA,
\r
2079 reinterpret_cast<WPARAM>(m_hwndAssocWindow),
\r
2080 reinterpret_cast<LPARAM>(&cd),
\r
2081 SMTO_ABORTIFHUNG | SMTO_BLOCK, 5000, &result);
\r
2085 UnmapViewOfFile(data);
\r
2103 tstringq m_funcParam;
\r
2106 PlugIn() : m_dll(NULL) {
\r
2110 FreeLibrary(m_dll);
\r
2113 bool load(const tstringq &i_dllName, const tstringq &i_funcName,
\r
2114 const tstringq &i_funcParam, tomsgstream &i_log) {
\r
2115 m_dll = LoadLibrary((_T("Plugins\\") + i_dllName).c_str());
\r
2117 m_dll = LoadLibrary((_T("Plugin\\") + i_dllName).c_str());
\r
2119 m_dll = LoadLibrary(i_dllName.c_str());
\r
2121 Acquire a(&i_log);
\r
2122 i_log << std::endl;
\r
2123 i_log << _T("error: &PlugIn() failed to load ") << i_dllName << std::endl;
\r
2131 # define to_wstring
\r
2133 # define to_string
\r
2136 m_func = GetProcAddress(m_dll, to_string(_T("mayu") + i_funcName + _T("W")).c_str());
\r
2140 = GetProcAddress(m_dll, to_string(_T("mayu") + i_funcName + _T("A")).c_str());
\r
2142 m_func = GetProcAddress(m_dll, to_string(_T("mayu") + i_funcName).c_str());
\r
2144 m_func = GetProcAddress(m_dll, to_string(i_funcName).c_str());
\r
2146 Acquire a(&i_log);
\r
2147 i_log << std::endl;
\r
2148 i_log << _T("error: &PlugIn() failed to find function: ")
\r
2149 << i_funcName << std::endl;
\r
2156 m_funcParam = i_funcParam;
\r
2164 typedef void (WINAPI * PLUGIN_FUNCTION_A)(const char *i_arg);
\r
2165 typedef void (WINAPI * PLUGIN_FUNCTION_W)(const wchar_t *i_arg);
\r
2168 reinterpret_cast<PLUGIN_FUNCTION_A>(m_func)(to_string(m_funcParam).c_str());
\r
2171 reinterpret_cast<PLUGIN_FUNCTION_W>(m_func)(to_wstring(m_funcParam).c_str());
\r
2179 static void plugInThread(void *i_plugin)
\r
2181 PlugIn *plugin = static_cast<PlugIn *>(i_plugin);
\r
2187 void Engine::funcPlugIn(FunctionParam *i_param,
\r
2188 const StrExprArg &i_dllName,
\r
2189 const StrExprArg &i_funcName,
\r
2190 const StrExprArg &i_funcParam,
\r
2191 BooleanType i_doesCreateThread)
\r
2193 if (!i_param->m_isPressed)
\r
2196 shu::PlugIn *plugin = new shu::PlugIn();
\r
2197 if (!plugin->load(i_dllName.eval(), i_funcName.eval(), i_funcParam.eval(), m_log)) {
\r
2201 if (i_doesCreateThread) {
\r
2202 if (_beginthread(shu::plugInThread, 0, plugin) == -1) {
\r
2204 Acquire a(&m_log);
\r
2205 m_log << std::endl;
\r
2206 m_log << _T("error: &PlugIn() failed to create thread.");
\r
2214 void Engine::funcMouseHook(FunctionParam *i_param,
\r
2215 MouseHookType i_hookType, int i_hookParam)
\r
2217 GetCursorPos(&g_hookData->m_mousePos);
\r
2218 g_hookData->m_mouseHookType = i_hookType;
\r
2219 g_hookData->m_mouseHookParam = i_hookParam;
\r
2221 switch (i_hookType) {
\r
2222 case MouseHookType_WindowMove: {
\r
2223 // For this type, g_hookData->m_mouseHookParam means
\r
2224 // target window type to move.
\r
2228 // i_hooParam < 0 means target window to move is MDI.
\r
2229 if (i_hookParam < 0)
\r
2234 // abs(i_hookParam) == 2: target is window under mouse cursor
\r
2235 // otherwise: target is current focus window
\r
2236 if (i_hookParam == 2 || i_hookParam == -2)
\r
2237 target = WindowFromPoint(g_hookData->m_mousePos);
\r
2239 target = i_param->m_hwnd;
\r
2241 g_hookData->m_hwndMouseHookTarget =
\r
2242 reinterpret_cast<DWORD>(getToplevelWindow(target, &isMDI));
\r
2245 g_hookData->m_hwndMouseHookTarget = NULL;
\r
2254 void Engine::funcCancelPrefix(FunctionParam *i_param)
\r
2256 m_isPrefix = false;
\r
2259 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
2264 tstringq m_symbol;
\r
2266 static const Engine *s_engine;
\r
2268 StrExpr(const tstringq &i_symbol) : m_symbol(i_symbol) {};
\r
2270 virtual ~StrExpr() {};
\r
2272 virtual StrExpr *clone() const {
\r
2273 return new StrExpr(*this);
\r
2276 virtual tstringq eval() const {
\r
2280 static void setEngine(const Engine *i_engine) {
\r
2281 s_engine = i_engine;
\r
2285 const Engine *StrExpr::s_engine = NULL;
\r
2287 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
2288 // StrExprClipboard
\r
2289 class StrExprClipboard : public StrExpr
\r
2292 StrExprClipboard(const tstringq &i_symbol) : StrExpr(i_symbol) {};
\r
2294 ~StrExprClipboard() {};
\r
2296 StrExpr *clone() const {
\r
2297 return new StrExprClipboard(*this);
\r
2300 tstringq eval() const {
\r
2302 const _TCHAR *text = getTextFromClipboard(&g);
\r
2303 const tstring value(text == NULL ? _T("") : text);
\r
2304 closeClipboard(g);
\r
2310 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
2311 // StrExprWindowClassName
\r
2312 class StrExprWindowClassName : public StrExpr
\r
2315 StrExprWindowClassName(const tstringq &i_symbol) : StrExpr(i_symbol) {};
\r
2317 ~StrExprWindowClassName() {};
\r
2319 StrExpr *clone() const {
\r
2320 return new StrExprWindowClassName(*this);
\r
2323 tstringq eval() const {
\r
2324 return s_engine->getCurrentWindowClassName();
\r
2329 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
2330 // StrExprWindowTitleName
\r
2331 class StrExprWindowTitleName : public StrExpr
\r
2334 StrExprWindowTitleName(const tstringq &i_symbol) : StrExpr(i_symbol) {};
\r
2336 ~StrExprWindowTitleName() {};
\r
2338 StrExpr *clone() const {
\r
2339 return new StrExprWindowTitleName(*this);
\r
2342 tstringq eval() const {
\r
2343 return s_engine->getCurrentWindowTitleName();
\r
2348 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
2352 // default constructor
\r
2353 StrExprArg::StrExprArg()
\r
2355 m_expr = new StrExpr(_T(""));
\r
2359 // copy contructor
\r
2360 StrExprArg::StrExprArg(const StrExprArg &i_data)
\r
2362 m_expr = i_data.m_expr->clone();
\r
2366 StrExprArg &StrExprArg::operator=(const StrExprArg &i_data)
\r
2368 if (i_data.m_expr == m_expr)
\r
2372 m_expr = i_data.m_expr->clone();
\r
2379 StrExprArg::StrExprArg(const tstringq &i_symbol, Type i_type)
\r
2383 m_expr = new StrExpr(i_symbol);
\r
2386 if (i_symbol == _T("Clipboard"))
\r
2387 m_expr = new StrExprClipboard(i_symbol);
\r
2388 else if (i_symbol == _T("WindowClassName"))
\r
2389 m_expr = new StrExprWindowClassName(i_symbol);
\r
2390 else if (i_symbol == _T("WindowTitleName"))
\r
2391 m_expr = new StrExprWindowTitleName(i_symbol);
\r
2399 StrExprArg::~StrExprArg()
\r
2405 tstringq StrExprArg::eval() const
\r
2407 return m_expr->eval();
\r
2410 void StrExprArg::setEngine(const Engine *i_engine)
\r
2412 StrExpr::setEngine(i_engine);
\r
2416 tostream &operator<<(tostream &i_ost, const StrExprArg &i_data)
\r
2418 i_ost << i_data.eval();
\r