OSDN Git Service

enable command notify on x64
[yamy/yamy.git] / engine.h
1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
2 // engine.h\r
3 \r
4 \r
5 #ifndef _ENGINE_H\r
6 #  define _ENGINE_H\r
7 \r
8 #  include "multithread.h"\r
9 #  include "setting.h"\r
10 #  include "msgstream.h"\r
11 #  include "hook.h"\r
12 #  include <set>\r
13 #  include <queue>\r
14 \r
15 \r
16 enum {\r
17         ///\r
18         WM_APP_engineNotify = WM_APP + 110,\r
19 };\r
20 \r
21 \r
22 ///\r
23 enum EngineNotify {\r
24         EngineNotify_shellExecute,                      ///\r
25         EngineNotify_loadSetting,                       ///\r
26         EngineNotify_showDlg,                           ///\r
27         EngineNotify_helpMessage,                       ///\r
28         EngineNotify_setForegroundWindow,               ///\r
29         EngineNotify_clearLog,                  ///\r
30 };\r
31 \r
32 \r
33 ///\r
34 class Engine\r
35 {\r
36 private:\r
37         enum {\r
38                 MAX_GENERATE_KEYBOARD_EVENTS_RECURSION_COUNT = 64, ///\r
39                 MAX_KEYMAP_PREFIX_HISTORY = 64, ///\r
40         };\r
41 \r
42         typedef Keymaps::KeymapPtrList KeymapPtrList;   ///\r
43 \r
44         /// focus of a thread\r
45         class FocusOfThread\r
46         {\r
47         public:\r
48                 DWORD m_threadId;                               /// thread id\r
49                 HWND m_hwndFocus;                               /** window that has focus on\r
50                                                     the thread */\r
51                 tstringi m_className;                   /// class name of hwndFocus\r
52                 tstringi m_titleName;                   /// title name of hwndFocus\r
53                 bool m_isConsole;                               /// is hwndFocus console ?\r
54                 KeymapPtrList m_keymaps;                        /// keymaps\r
55 \r
56         public:\r
57                 ///\r
58                 FocusOfThread() : m_threadId(0), m_hwndFocus(NULL), m_isConsole(false) { }\r
59         };\r
60         typedef std::map<DWORD /*ThreadId*/, FocusOfThread> FocusOfThreads;     ///\r
61 \r
62         typedef std::list<DWORD /*ThreadId*/> DetachedThreadIds;        ///\r
63 \r
64         /// current status in generateKeyboardEvents\r
65         class Current\r
66         {\r
67         public:\r
68                 const Keymap *m_keymap;                 /// current keymap\r
69                 ModifiedKey m_mkey;             /// current processing key that user inputed\r
70                 /// index in currentFocusOfThread-&gt;keymaps\r
71                 Keymaps::KeymapPtrList::iterator m_i;\r
72 \r
73         public:\r
74                 ///\r
75                 bool isPressed() const {\r
76                         return m_mkey.m_modifier.isOn(Modifier::Type_Down);\r
77                 }\r
78         };\r
79 \r
80         friend class FunctionParam;\r
81 \r
82         /// part of keySeq\r
83         enum Part {\r
84                 Part_all,                                       ///\r
85                 Part_up,                                        ///\r
86                 Part_down,                                      ///\r
87         };\r
88 \r
89         ///\r
90         class EmacsEditKillLine\r
91         {\r
92                 tstring m_buf;  /// previous kill-line contents\r
93 \r
94         public:\r
95                 bool m_doForceReset;    ///\r
96 \r
97         private:\r
98                 ///\r
99                 HGLOBAL makeNewKillLineBuf(const _TCHAR *i_data, int *i_retval);\r
100 \r
101         public:\r
102                 ///\r
103                 void reset() {\r
104                         m_buf.resize(0);\r
105                 }\r
106                 /** EmacsEditKillLineFunc.\r
107                 clear the contents of the clopboard\r
108                 at that time, confirm if it is the result of the previous kill-line\r
109                 */\r
110                 void func();\r
111                 /// EmacsEditKillLinePred\r
112                 int pred();\r
113         };\r
114 \r
115         /// window positon for &amp;WindowHMaximize, &amp;WindowVMaximize\r
116         class WindowPosition\r
117         {\r
118         public:\r
119                 ///\r
120                 enum Mode {\r
121                         Mode_normal,                            ///\r
122                         Mode_H,                                 ///\r
123                         Mode_V,                                 ///\r
124                         Mode_HV,                                        ///\r
125                 };\r
126 \r
127         public:\r
128                 HWND m_hwnd;                            ///\r
129                 RECT m_rc;                                      ///\r
130                 Mode m_mode;                            ///\r
131 \r
132         public:\r
133                 ///\r
134                 WindowPosition(HWND i_hwnd, const RECT &i_rc, Mode i_mode)\r
135                                 : m_hwnd(i_hwnd), m_rc(i_rc), m_mode(i_mode) { }\r
136         };\r
137         typedef std::list<WindowPosition> WindowPositions;\r
138 \r
139         typedef std::list<HWND> WindowsWithAlpha; /// windows for &amp;WindowSetAlpha\r
140 \r
141         enum InterruptThreadReason {\r
142                 InterruptThreadReason_Terminate,\r
143                 InterruptThreadReason_Pause,\r
144                 InterruptThreadReason_Resume,\r
145         };\r
146 \r
147         ///\r
148         class InputHandler {\r
149         public:\r
150                 typedef int (*INSTALL_HOOK)(INPUT_DETOUR i_keyboardDetour, Engine *i_engine, bool i_install);\r
151 \r
152                 static unsigned int WINAPI run(void *i_this);\r
153 \r
154                 InputHandler(INSTALL_HOOK i_installHook, INPUT_DETOUR i_inputDetour);\r
155 \r
156                 ~InputHandler();\r
157 \r
158                 void run();\r
159 \r
160                 int start(Engine *i_engine);\r
161 \r
162                 int stop();\r
163 \r
164         private:\r
165                 unsigned m_threadId;\r
166                 HANDLE m_hThread;\r
167                 HANDLE m_hEvent; \r
168                 INSTALL_HOOK m_installHook;\r
169                 INPUT_DETOUR m_inputDetour;\r
170                 Engine *m_engine;\r
171         };\r
172 \r
173 private:\r
174         CriticalSection m_cs;                           /// criticalSection\r
175 \r
176         // setting\r
177         HWND m_hwndAssocWindow;                 /** associated window (we post\r
178                                                     message to it) */\r
179         Setting * volatile m_setting;                   /// setting\r
180 \r
181         // engine thread state\r
182         HANDLE m_threadHandle;\r
183         unsigned m_threadId;\r
184         std::deque<KEYBOARD_INPUT_DATA> *m_inputQueue;\r
185         HANDLE m_queueMutex;\r
186         MSLLHOOKSTRUCT m_msllHookCurrent;\r
187         bool m_buttonPressed;\r
188         bool m_dragging;\r
189         InputHandler m_keyboardHandler;\r
190         InputHandler m_mouseHandler;\r
191         HANDLE m_readEvent;                             /** reading from mayu device\r
192                                                     has been completed */\r
193         OVERLAPPED m_ol;                                /** for async read/write of\r
194                                                     mayu device */\r
195         HANDLE m_hookPipe;                              /// named pipe for &SetImeString\r
196         HMODULE m_sts4mayu;                             /// DLL module for ThumbSense\r
197         HMODULE m_cts4mayu;                             /// DLL module for ThumbSense\r
198         bool volatile m_isLogMode;                      /// is logging mode ?\r
199         bool volatile m_isEnabled;                      /// is enabled  ?\r
200         bool volatile m_isSynchronizing;                /// is synchronizing ?\r
201         HANDLE m_eSync;                         /// event for synchronization\r
202         int m_generateKeyboardEventsRecursionGuard;     /** guard against too many\r
203                                                     recursion */\r
204 \r
205         // current key state\r
206         Modifier m_currentLock;                 /// current lock key's state\r
207         int m_currentKeyPressCount;                     /** how many keys are pressed\r
208                                                     phisically ? */\r
209         int m_currentKeyPressCountOnWin32;              /** how many keys are pressed\r
210                                                     on win32 ? */\r
211         Key *m_lastGeneratedKey;                        /// last generated key\r
212         Key *m_lastPressedKey[2];                       /// last pressed key\r
213         ModifiedKey m_oneShotKey;                       /// one shot key\r
214         unsigned int m_oneShotRepeatableRepeatCount; /// repeat count of one shot key\r
215         bool m_isPrefix;                                /// is prefix ?\r
216         bool m_doesIgnoreModifierForPrefix;             /** does ignore modifier key\r
217                                                     when prefixed ? */\r
218         bool m_doesEditNextModifier;                    /** does edit next user input\r
219                                                     key's modifier ? */\r
220         Modifier m_modifierForNextKey;          /** modifier for next key if\r
221                                                     above is true */\r
222 \r
223         /** current keymaps.\r
224             <dl>\r
225             <dt>when &amp;OtherWindowClass\r
226             <dd>currentKeymap becoms currentKeymaps[++ Current::i]\r
227             <dt>when &amp;KeymapParent\r
228             <dd>currentKeymap becoms currentKeyamp-&gt;parentKeymap\r
229             <dt>other\r
230             <dd>currentKeyamp becoms *Current::i\r
231             </dl>\r
232         */\r
233         const Keymap * volatile m_currentKeymap;        /// current keymap\r
234         FocusOfThreads /*volatile*/ m_focusOfThreads;   ///\r
235         FocusOfThread * volatile m_currentFocusOfThread; ///\r
236         FocusOfThread m_globalFocus;                    ///\r
237         HWND m_hwndFocus;                               /// current focus window\r
238         DetachedThreadIds m_detachedThreadIds;  ///\r
239 \r
240         // for functions\r
241         KeymapPtrList m_keymapPrefixHistory;            /// for &amp;KeymapPrevPrefix\r
242         EmacsEditKillLine m_emacsEditKillLine;  /// for &amp;EmacsEditKillLine\r
243         const ActionFunction *m_afShellExecute; /// for &amp;ShellExecute\r
244 \r
245         WindowPositions m_windowPositions;              ///\r
246         WindowsWithAlpha m_windowsWithAlpha;            ///\r
247 \r
248         tstring m_helpMessage;                  /// for &amp;HelpMessage\r
249         tstring m_helpTitle;                            /// for &amp;HelpMessage\r
250         int m_variable;                         /// for &amp;Variable,\r
251         ///  &amp;Repeat\r
252 \r
253 public:\r
254         tomsgstream &m_log;                             /** log stream (output to log\r
255                                                     dialog's edit) */\r
256 \r
257 public:\r
258         /// keyboard handler thread\r
259         static unsigned int WINAPI keyboardDetour(Engine *i_this, WPARAM i_wParam, LPARAM i_lParam);\r
260         /// mouse handler thread\r
261         static unsigned int WINAPI mouseDetour(Engine *i_this, WPARAM i_wParam, LPARAM i_lParam);\r
262 private:\r
263         ///\r
264         unsigned int keyboardDetour(KBDLLHOOKSTRUCT *i_kid);\r
265         ///\r
266         unsigned int mouseDetour(WPARAM i_message, MSLLHOOKSTRUCT *i_mid);\r
267         ///\r
268         unsigned int injectInput(const KEYBOARD_INPUT_DATA *i_kid, const KBDLLHOOKSTRUCT *i_kidRaw);\r
269 \r
270 private:\r
271         /// keyboard handler thread\r
272         static unsigned int WINAPI keyboardHandler(void *i_this);\r
273         ///\r
274         void keyboardHandler();\r
275 \r
276         /// check focus window\r
277         void checkFocusWindow();\r
278         /// is modifier pressed ?\r
279         bool isPressed(Modifier::Type i_mt);\r
280         /// fix modifier key\r
281         bool fixModifierKey(ModifiedKey *io_mkey, Keymap::AssignMode *o_am);\r
282 \r
283         /// output to log\r
284         void outputToLog(const Key *i_key, const ModifiedKey &i_mkey,\r
285                                          int i_debugLevel);\r
286 \r
287         /// genete modifier events\r
288         void generateModifierEvents(const Modifier &i_mod);\r
289 \r
290         /// genete event\r
291         void generateEvents(Current i_c, const Keymap *i_keymap, Key *i_event);\r
292 \r
293         /// generate keyboard event\r
294         void generateKeyEvent(Key *i_key, bool i_doPress, bool i_isByAssign);\r
295         ///\r
296         void generateActionEvents(const Current &i_c, const Action *i_a,\r
297                                                           bool i_doPress);\r
298         ///\r
299         void generateKeySeqEvents(const Current &i_c, const KeySeq *i_keySeq,\r
300                                                           Part i_part);\r
301         ///\r
302         void generateKeyboardEvents(const Current &i_c);\r
303         ///\r
304         void beginGeneratingKeyboardEvents(const Current &i_c, bool i_isModifier);\r
305 \r
306         /// pop all pressed key on win32\r
307         void keyboardResetOnWin32();\r
308 \r
309         /// get current modifiers\r
310         Modifier getCurrentModifiers(Key *i_key, bool i_isPressed);\r
311 \r
312         /// describe bindings\r
313         void describeBindings();\r
314 \r
315         /// update m_lastPressedKey\r
316         void updateLastPressedKey(Key *i_key);\r
317 \r
318         /// set current keymap\r
319         void setCurrentKeymap(const Keymap *i_keymap,\r
320                                                   bool i_doesAddToHistory = false);\r
321         /** open mayu device\r
322             @return true if mayu device successfully is opened\r
323         */\r
324         bool open();\r
325 \r
326         /// close mayu device\r
327         void close();\r
328 \r
329         /// load/unload [sc]ts4mayu.dll\r
330         void manageTs4mayu(TCHAR *i_ts4mayuDllName, TCHAR *i_dependDllName,\r
331                                            bool i_load, HMODULE *i_pTs4mayu);\r
332 \r
333 private:\r
334         // BEGINING OF FUNCTION DEFINITION\r
335         /// send a default key to Windows\r
336         void funcDefault(FunctionParam *i_param);\r
337         /// use a corresponding key of a parent keymap\r
338         void funcKeymapParent(FunctionParam *i_param);\r
339         /// use a corresponding key of a current window\r
340         void funcKeymapWindow(FunctionParam *i_param);\r
341         /// use a corresponding key of the previous prefixed keymap\r
342         void funcKeymapPrevPrefix(FunctionParam *i_param, int i_previous);\r
343         /// use a corresponding key of an other window class, or use a default key\r
344         void funcOtherWindowClass(FunctionParam *i_param);\r
345         /// prefix key\r
346         void funcPrefix(FunctionParam *i_param, const Keymap *i_keymap,\r
347                                         BooleanType i_doesIgnoreModifiers = BooleanType_true);\r
348         /// other keymap's key\r
349         void funcKeymap(FunctionParam *i_param, const Keymap *i_keymap);\r
350         /// sync\r
351         void funcSync(FunctionParam *i_param);\r
352         /// toggle lock\r
353         void funcToggle(FunctionParam *i_param, ModifierLockType i_lock,\r
354                                         ToggleType i_toggle = ToggleType_toggle);\r
355         /// edit next user input key's modifier\r
356         void funcEditNextModifier(FunctionParam *i_param,\r
357                                                           const Modifier &i_modifier);\r
358         /// variable\r
359         void funcVariable(FunctionParam *i_param, int i_mag, int i_inc);\r
360         /// repeat N times\r
361         void funcRepeat(FunctionParam *i_param, const KeySeq *i_keySeq,\r
362                                         int i_max = 10);\r
363         /// undefined (bell)\r
364         void funcUndefined(FunctionParam *i_param);\r
365         /// ignore\r
366         void funcIgnore(FunctionParam *i_param);\r
367         /// post message\r
368         void funcPostMessage(FunctionParam *i_param, ToWindowType i_window,\r
369                                                  UINT i_message, WPARAM i_wParam, LPARAM i_lParam);\r
370         /// ShellExecute\r
371         void funcShellExecute(FunctionParam *i_param, const StrExprArg &i_operation,\r
372                                                   const StrExprArg &i_file, const StrExprArg &i_parameters,\r
373                                                   const StrExprArg &i_directory,\r
374                                                   ShowCommandType i_showCommand);\r
375         /// SetForegroundWindow\r
376         void funcSetForegroundWindow(FunctionParam *i_param,\r
377                                                                  const tregex &i_windowClassName,\r
378                                                                  LogicalOperatorType i_logicalOp\r
379                                                                  = LogicalOperatorType_and,\r
380                                                                  const tregex &i_windowTitleName\r
381                                                                  = tregex(_T(".*")));\r
382         /// load setting\r
383         void funcLoadSetting(FunctionParam *i_param,\r
384                                                  const StrExprArg &i_name = StrExprArg());\r
385         /// virtual key\r
386         void funcVK(FunctionParam *i_param, VKey i_vkey);\r
387         /// wait\r
388         void funcWait(FunctionParam *i_param, int i_milliSecond);\r
389         /// investigate WM_COMMAND, WM_SYSCOMMAND\r
390         void funcInvestigateCommand(FunctionParam *i_param);\r
391         /// show mayu dialog box\r
392         void funcMayuDialog(FunctionParam *i_param, MayuDialogType i_dialog,\r
393                                                 ShowCommandType i_showCommand);\r
394         /// describe bindings\r
395         void funcDescribeBindings(FunctionParam *i_param);\r
396         /// show help message\r
397         void funcHelpMessage(FunctionParam *i_param,\r
398                                                  const StrExprArg &i_title = StrExprArg(),\r
399                                                  const StrExprArg &i_message = StrExprArg());\r
400         /// show variable\r
401         void funcHelpVariable(FunctionParam *i_param, const StrExprArg &i_title);\r
402         /// raise window\r
403         void funcWindowRaise(FunctionParam *i_param,\r
404                                                  TargetWindowType i_twt = TargetWindowType_overlapped);\r
405         /// lower window\r
406         void funcWindowLower(FunctionParam *i_param,\r
407                                                  TargetWindowType i_twt = TargetWindowType_overlapped);\r
408         /// minimize window\r
409         void funcWindowMinimize(FunctionParam *i_param, TargetWindowType i_twt\r
410                                                         = TargetWindowType_overlapped);\r
411         /// maximize window\r
412         void funcWindowMaximize(FunctionParam *i_param, TargetWindowType i_twt\r
413                                                         = TargetWindowType_overlapped);\r
414         /// maximize window horizontally\r
415         void funcWindowHMaximize(FunctionParam *i_param, TargetWindowType i_twt\r
416                                                          = TargetWindowType_overlapped);\r
417         /// maximize window virtically\r
418         void funcWindowVMaximize(FunctionParam *i_param, TargetWindowType i_twt\r
419                                                          = TargetWindowType_overlapped);\r
420         /// maximize window virtically or horizontally\r
421         void funcWindowHVMaximize(FunctionParam *i_param, BooleanType i_isHorizontal,\r
422                                                           TargetWindowType i_twt\r
423                                                           = TargetWindowType_overlapped);\r
424         /// move window\r
425         void funcWindowMove(FunctionParam *i_param, int i_dx, int i_dy,\r
426                                                 TargetWindowType i_twt\r
427                                                 = TargetWindowType_overlapped);\r
428         /// move window to ...\r
429         void funcWindowMoveTo(FunctionParam *i_param, GravityType i_gravityType,\r
430                                                   int i_dx, int i_dy, TargetWindowType i_twt\r
431                                                   = TargetWindowType_overlapped);\r
432         /// move window visibly\r
433         void funcWindowMoveVisibly(FunctionParam *i_param,\r
434                                                            TargetWindowType i_twt\r
435                                                            = TargetWindowType_overlapped);\r
436         /// move window to other monitor\r
437         void funcWindowMonitorTo(FunctionParam *i_param,\r
438                                                          WindowMonitorFromType i_fromType, int i_monitor,\r
439                                                          BooleanType i_adjustPos = BooleanType_true,\r
440                                                          BooleanType i_adjustSize = BooleanType_false);\r
441         /// move window to other monitor\r
442         void funcWindowMonitor(FunctionParam *i_param, int i_monitor,\r
443                                                    BooleanType i_adjustPos = BooleanType_true,\r
444                                                    BooleanType i_adjustSize = BooleanType_false);\r
445         ///\r
446         void funcWindowClingToLeft(FunctionParam *i_param,\r
447                                                            TargetWindowType i_twt\r
448                                                            = TargetWindowType_overlapped);\r
449         ///\r
450         void funcWindowClingToRight(FunctionParam *i_param,\r
451                                                                 TargetWindowType i_twt\r
452                                                                 = TargetWindowType_overlapped);\r
453         ///\r
454         void funcWindowClingToTop(FunctionParam *i_param,\r
455                                                           TargetWindowType i_twt\r
456                                                           = TargetWindowType_overlapped);\r
457         ///\r
458         void funcWindowClingToBottom(FunctionParam *i_param,\r
459                                                                  TargetWindowType i_twt\r
460                                                                  = TargetWindowType_overlapped);\r
461         /// close window\r
462         void funcWindowClose(FunctionParam *i_param,\r
463                                                  TargetWindowType i_twt = TargetWindowType_overlapped);\r
464         /// toggle top-most flag of the window\r
465         void funcWindowToggleTopMost(FunctionParam *i_param);\r
466         /// identify the window\r
467         void funcWindowIdentify(FunctionParam *i_param);\r
468         /// set alpha blending parameter to the window\r
469         void funcWindowSetAlpha(FunctionParam *i_param, int i_alpha);\r
470         /// redraw the window\r
471         void funcWindowRedraw(FunctionParam *i_param);\r
472         /// resize window to\r
473         void funcWindowResizeTo(FunctionParam *i_param, int i_width, int i_height,\r
474                                                         TargetWindowType i_twt\r
475                                                         = TargetWindowType_overlapped);\r
476         /// move the mouse cursor\r
477         void funcMouseMove(FunctionParam *i_param, int i_dx, int i_dy);\r
478         /// send a mouse-wheel-message to Windows\r
479         void funcMouseWheel(FunctionParam *i_param, int i_delta);\r
480         /// convert the contents of the Clipboard to upper case or lower case\r
481         void funcClipboardChangeCase(FunctionParam *i_param,\r
482                                                                  BooleanType i_doesConvertToUpperCase);\r
483         /// convert the contents of the Clipboard to upper case\r
484         void funcClipboardUpcaseWord(FunctionParam *i_param);\r
485         /// convert the contents of the Clipboard to lower case\r
486         void funcClipboardDowncaseWord(FunctionParam *i_param);\r
487         /// set the contents of the Clipboard to the string\r
488         void funcClipboardCopy(FunctionParam *i_param, const StrExprArg &i_text);\r
489         ///\r
490         void funcEmacsEditKillLinePred(FunctionParam *i_param,\r
491                                                                    const KeySeq *i_keySeq1,\r
492                                                                    const KeySeq *i_keySeq2);\r
493         ///\r
494         void funcEmacsEditKillLineFunc(FunctionParam *i_param);\r
495         /// clear log\r
496         void funcLogClear(FunctionParam *i_param);\r
497         /// recenter\r
498         void funcRecenter(FunctionParam *i_param);\r
499         /// Direct SSTP\r
500         void funcDirectSSTP(FunctionParam *i_param,\r
501                                                 const tregex &i_name,\r
502                                                 const StrExprArg &i_protocol,\r
503                                                 const std::list<tstringq> &i_headers);\r
504         /// PlugIn\r
505         void funcPlugIn(FunctionParam *i_param,\r
506                                         const StrExprArg &i_dllName,\r
507                                         const StrExprArg &i_funcName = StrExprArg(),\r
508                                         const StrExprArg &i_funcParam = StrExprArg(),\r
509                                         BooleanType i_doesCreateThread = BooleanType_false);\r
510         /// set IME open status\r
511         void funcSetImeStatus(FunctionParam *i_param, ToggleType i_toggle = ToggleType_toggle);\r
512         /// set string to IME\r
513         void funcSetImeString(FunctionParam *i_param, const StrExprArg &i_data);\r
514         /// enter to mouse event hook mode\r
515         void funcMouseHook(FunctionParam *i_param, MouseHookType i_hookType, int i_hookParam);\r
516         /// cancel prefix\r
517         void funcCancelPrefix(FunctionParam *i_param);\r
518 \r
519         // END OF FUNCTION DEFINITION\r
520 #  define FUNCTION_FRIEND\r
521 #  include "functions.h"\r
522 #  undef FUNCTION_FRIEND\r
523 \r
524 public:\r
525         ///\r
526         Engine(tomsgstream &i_log);\r
527         ///\r
528         ~Engine();\r
529 \r
530         /// start/stop keyboard handler thread\r
531         void start();\r
532         ///\r
533         void stop();\r
534 \r
535         /// pause keyboard handler thread and close device\r
536         bool pause();\r
537 \r
538         /// resume keyboard handler thread and re-open device\r
539         bool resume();\r
540 \r
541         /// do some procedure before quit which must be done synchronously\r
542         /// (i.e. not on WM_QUIT)\r
543         bool prepairQuit();\r
544 \r
545         /// logging mode\r
546         void enableLogMode(bool i_isLogMode = true) {\r
547                 m_isLogMode = i_isLogMode;\r
548         }\r
549         ///\r
550         void disableLogMode() {\r
551                 m_isLogMode = false;\r
552         }\r
553 \r
554         /// enable/disable engine\r
555         void enable(bool i_isEnabled = true) {\r
556                 m_isEnabled = i_isEnabled;\r
557         }\r
558         ///\r
559         void disable() {\r
560                 m_isEnabled = false;\r
561         }\r
562         ///\r
563         bool getIsEnabled() const {\r
564                 return m_isEnabled;\r
565         }\r
566 \r
567         /// associated window\r
568         void setAssociatedWndow(HWND i_hwnd) {\r
569                 m_hwndAssocWindow = i_hwnd;\r
570         }\r
571 \r
572         /// associated window\r
573         HWND getAssociatedWndow() const {\r
574                 return m_hwndAssocWindow;\r
575         }\r
576 \r
577         /// setting\r
578         bool setSetting(Setting *i_setting);\r
579 \r
580         /// focus\r
581         bool setFocus(HWND i_hwndFocus, DWORD i_threadId,\r
582                                   const tstringi &i_className,\r
583                                   const tstringi &i_titleName, bool i_isConsole);\r
584 \r
585         /// lock state\r
586         bool setLockState(bool i_isNumLockToggled, bool i_isCapsLockToggled,\r
587                                           bool i_isScrollLockToggled, bool i_isKanaLockToggled,\r
588                                           bool i_isImeLockToggled, bool i_isImeCompToggled);\r
589 \r
590         /// show\r
591         void checkShow(HWND i_hwnd);\r
592         bool setShow(bool i_isMaximized, bool i_isMinimized, bool i_isMDI);\r
593 \r
594         /// sync\r
595         bool syncNotify();\r
596 \r
597         /// thread detach notify\r
598         bool threadDetachNotify(DWORD i_threadId);\r
599 \r
600         /// shell execute\r
601         void shellExecute();\r
602 \r
603         /// get help message\r
604         void getHelpMessages(tstring *o_helpMessage, tstring *o_helpTitle);\r
605 \r
606         /// command notify\r
607         template <typename WPARAM_T, typename LPARAM_T>\r
608         void commandNotify(HWND i_hwnd, UINT i_message, WPARAM_T i_wParam,\r
609                                            LPARAM_T i_lParam)\r
610         {\r
611                 Acquire b(&m_log, 0);\r
612                 HWND hf = m_hwndFocus;\r
613                 if (!hf)\r
614                         return;\r
615 \r
616                 if (GetWindowThreadProcessId(hf, NULL) ==\r
617                                 GetWindowThreadProcessId(m_hwndAssocWindow, NULL))\r
618                         return; // inhibit the investigation of MADO TSUKAI NO YUUTSU\r
619 \r
620                 const _TCHAR *target = NULL;\r
621                 int number_target = 0;\r
622 \r
623                 if (i_hwnd == hf)\r
624                         target = _T("ToItself");\r
625                 else if (i_hwnd == GetParent(hf))\r
626                         target = _T("ToParentWindow");\r
627                 else {\r
628                         // Function::toMainWindow\r
629                         HWND h = hf;\r
630                         while (true) {\r
631                                 HWND p = GetParent(h);\r
632                                 if (!p)\r
633                                         break;\r
634                                 h = p;\r
635                         }\r
636                         if (i_hwnd == h)\r
637                                 target = _T("ToMainWindow");\r
638                         else {\r
639                                 // Function::toOverlappedWindow\r
640                                 HWND h = hf;\r
641                                 while (h) {\r
642 #ifdef MAYU64\r
643                                         LONG_PTR style = GetWindowLongPtr(h, GWL_STYLE);\r
644 #else\r
645                                         LONG style = GetWindowLong(h, GWL_STYLE);\r
646 #endif\r
647                                         if ((style & WS_CHILD) == 0)\r
648                                                 break;\r
649                                         h = GetParent(h);\r
650                                 }\r
651                                 if (i_hwnd == h)\r
652                                         target = _T("ToOverlappedWindow");\r
653                                 else {\r
654                                         // number\r
655                                         HWND h = hf;\r
656                                         for (number_target = 0; h; number_target ++, h = GetParent(h))\r
657                                                 if (i_hwnd == h)\r
658                                                         break;\r
659                                         return;\r
660                                 }\r
661                         }\r
662                 }\r
663 \r
664                 m_log << _T("&PostMessage(");\r
665                 if (target)\r
666                         m_log << target;\r
667                 else\r
668                         m_log << number_target;\r
669                 m_log << _T(", ") << i_message\r
670                 << _T(", 0x") << std::hex << i_wParam\r
671                 << _T(", 0x") << i_lParam << _T(") # hwnd = ")\r
672                 << reinterpret_cast<int>(i_hwnd) << _T(", ")\r
673                 << _T("message = ") << std::dec;\r
674                 if (i_message == WM_COMMAND)\r
675                         m_log << _T("WM_COMMAND, ");\r
676                 else if (i_message == WM_SYSCOMMAND)\r
677                         m_log << _T("WM_SYSCOMMAND, ");\r
678                 else\r
679                         m_log << i_message << _T(", ");\r
680                 m_log << _T("wNotifyCode = ") << HIWORD(i_wParam) << _T(", ")\r
681                 << _T("wID = ") << LOWORD(i_wParam) << _T(", ")\r
682                 << _T("hwndCtrl = 0x") << std::hex << i_lParam << std::dec << std::endl;\r
683         }\r
684 \r
685         /// get current window class name\r
686         const tstringi &getCurrentWindowClassName() const {\r
687                 return m_currentFocusOfThread->m_className;\r
688         }\r
689 \r
690         /// get current window title name\r
691         const tstringi &getCurrentWindowTitleName() const {\r
692                 return m_currentFocusOfThread->m_titleName;\r
693         }\r
694 };\r
695 \r
696 \r
697 ///\r
698 class FunctionParam\r
699 {\r
700 public:\r
701         bool m_isPressed;                               /// is key pressed ?\r
702         HWND m_hwnd;                                    ///\r
703         Engine::Current m_c;                            /// new context\r
704         bool m_doesNeedEndl;                            /// need endl ?\r
705         const ActionFunction *m_af;                     ///\r
706 };\r
707 \r
708 \r
709 #endif // !_ENGINE_H\r