OSDN Git Service

8a553ca98d18e9fb016a3ea6ecf727843dd0efbf
[xkeymacs/xkeymacs.git] / xkeymacs / mainfrm.cpp
1 // MainFrm.cpp : implementation of the CMainFrame class\r
2 //\r
3 \r
4 #include "mainfrm.h"\r
5 #include "xkeymacs.h"\r
6 #include "profile.h"\r
7 #include "../xkeymacsdll/xkeymacsdll.h"\r
8 \r
9 #ifdef _DEBUG\r
10 #define new DEBUG_NEW\r
11 #undef THIS_FILE\r
12 static char THIS_FILE[] = __FILE__;\r
13 #endif\r
14 \r
15 #define WM_USER_NTFYICON (WM_USER+100)\r
16 \r
17 /////////////////////////////////////////////////////////////////////////////\r
18 // CMainFrame\r
19 \r
20 IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)\r
21 \r
22 BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)\r
23         //{{AFX_MSG_MAP(CMainFrame)\r
24         ON_WM_CREATE()\r
25         ON_COMMAND(IDC_ABOUT, OnAbout)\r
26         ON_COMMAND(IDC_QUIT, OnQuit)\r
27         ON_COMMAND(IDC_DISABLE, OnDisable)\r
28         ON_COMMAND(IDC_PROPERTIES, OnProperties)\r
29         ON_COMMAND(IDC_OPTIONS, OnOptions)\r
30         ON_COMMAND(IDC_KEYBOARD, OnKeyboard)\r
31         ON_COMMAND(IDC_IMPORT, OnImport)\r
32         ON_COMMAND(IDC_EXPORT, OnExport)\r
33         ON_COMMAND(IDC_RESET, OnReset)\r
34         ON_COMMAND(ID_HELP_FINDER, OnHelpFinder)\r
35         ON_COMMAND(IDC_KEYBOARD_ANY_USER, OnKeyboardAnyUser)\r
36         //}}AFX_MSG_MAP\r
37         ON_MESSAGE(WM_POWERBROADCAST, OnPowerBroadCast)\r
38 END_MESSAGE_MAP()\r
39 \r
40 /////////////////////////////////////////////////////////////////////////////\r
41 // CMainFrame construction/destruction\r
42 \r
43 CMainFrame::CMainFrame()\r
44 {\r
45         m_pPropertiesDlg                = new CProperties;\r
46         m_nResultPropertiesDlg  = -1;\r
47         m_bPropertiesDlgExist   = FALSE;\r
48         m_pAboutDlg                             = new CAboutDlg;\r
49         m_nResultAboutDlg               = -1;\r
50         m_bAboutDlgExist                = FALSE;\r
51         m_pOptionsDlg                   = new COptionsDlg;\r
52         m_nResultOptionsDlg             = -1;\r
53         m_bOptionsDlgExist              = FALSE;\r
54         memset(m_p104KeyboardDlg, 0, sizeof(m_p104KeyboardDlg));\r
55         memset(m_p109KeyboardDlg, 0, sizeof(m_p109KeyboardDlg));\r
56         for (int i = 0; i < MAX_HKEY_TYPE; ++i) {\r
57                 m_p104KeyboardDlg[i] = new C104Keyboard((HKEY_TYPE) i);\r
58                 m_p109KeyboardDlg[i] = new C109Keyboard((HKEY_TYPE) i);\r
59         }\r
60         memset(m_nResultKeyboardDlg, -1, sizeof(m_nResultKeyboardDlg));\r
61         memset(m_bKeyboardDlgExist, 0, sizeof(m_bKeyboardDlgExist));\r
62         memset(m_stOldNtfyIcon, 0, sizeof(m_stOldNtfyIcon));\r
63         memset(m_dwOldMessage, 0, sizeof(m_dwOldMessage));\r
64 \r
65         // register window class\r
66         WNDCLASS        stWndClass;\r
67         CString szClassName(MAKEINTRESOURCE(AFX_IDS_APP_TITLE));\r
68 \r
69         stWndClass.style                        = CS_BYTEALIGNWINDOW;\r
70         stWndClass.lpfnWndProc          = &AfxWndProc;\r
71         stWndClass.cbClsExtra           = 0;\r
72         stWndClass.cbWndExtra           = 0;\r
73         stWndClass.hInstance            = AfxGetInstanceHandle();\r
74         stWndClass.hIcon                        = NULL;\r
75         stWndClass.hCursor                      = NULL;\r
76         stWndClass.hbrBackground        = (HBRUSH)COLOR_BACKGROUND;\r
77         stWndClass.lpszMenuName         = NULL;\r
78         stWndClass.lpszClassName        = szClassName;\r
79 \r
80         AfxRegisterClass(&stWndClass);\r
81 \r
82         // make window\r
83         CRect   rect(0, 0, 100, 100);\r
84 \r
85         Create(szClassName, CString(MAKEINTRESOURCE(AFX_IDS_APP_TITLE)), WS_OVERLAPPEDWINDOW | WS_MINIMIZE, rect);\r
86 }\r
87 \r
88 CMainFrame::~CMainFrame()\r
89 {\r
90         delete m_pPropertiesDlg;\r
91         m_pPropertiesDlg = NULL;\r
92 \r
93         delete m_pAboutDlg;\r
94         m_pAboutDlg = NULL;\r
95 \r
96         delete m_pOptionsDlg;\r
97         m_pOptionsDlg = NULL;\r
98 \r
99         for (int i = 0; i < MAX_HKEY_TYPE; ++i) {\r
100                 delete m_p104KeyboardDlg[i];\r
101                 m_p104KeyboardDlg[i] = NULL;\r
102 \r
103                 delete m_p109KeyboardDlg[i];\r
104                 m_p109KeyboardDlg[i] = NULL;\r
105         }\r
106 }\r
107 \r
108 int CMainFrame::OnCreate(const LPCREATESTRUCT lpCreateStruct)\r
109 {\r
110         if (CFrameWnd::OnCreate(lpCreateStruct) == -1) {\r
111                 return -1;\r
112         }\r
113 \r
114         // init notify icon data\r
115         NOTIFYICONDATA notifyIconData[MAX_ICON_TYPE] = {\r
116                 { sizeof(NOTIFYICONDATA), m_hWnd, MAIN_ICON, NIF_MESSAGE | NIF_ICON | NIF_TIP, WM_USER_NTFYICON,\r
117                   (HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 16, 16, LR_SHARED) },\r
118                 { sizeof(NOTIFYICONDATA), m_hWnd, CX_ICON, NIF_MESSAGE | NIF_ICON | NIF_TIP, WM_USER_NTFYICON,\r
119                   AfxGetApp()->LoadIcon(IDI_CX_OFF) },\r
120                 { sizeof(NOTIFYICONDATA), m_hWnd, MX_ICON, NIF_MESSAGE | NIF_ICON | NIF_TIP, WM_USER_NTFYICON,\r
121                   AfxGetApp()->LoadIcon(IDI_MX_OFF) },\r
122                 { sizeof(NOTIFYICONDATA), m_hWnd, META_ICON, NIF_MESSAGE | NIF_ICON | NIF_TIP, WM_USER_NTFYICON,\r
123                   AfxGetApp()->LoadIcon(IDI_META_OFF) },\r
124                 { sizeof(NOTIFYICONDATA), m_hWnd, SHIFT_ICON, NIF_MESSAGE | NIF_ICON | NIF_TIP, WM_USER_NTFYICON,\r
125                   AfxGetApp()->LoadIcon(IDI_SHIFT_OFF) },\r
126                 { sizeof(NOTIFYICONDATA), m_hWnd, CTRL_ICON, NIF_MESSAGE | NIF_ICON | NIF_TIP, WM_USER_NTFYICON,\r
127                   AfxGetApp()->LoadIcon(IDI_CTRL_OFF) },\r
128                 { sizeof(NOTIFYICONDATA), m_hWnd, ALT_ICON, NIF_MESSAGE | NIF_ICON | NIF_TIP, WM_USER_NTFYICON,\r
129                   AfxGetApp()->LoadIcon(IDI_ALT_OFF) },\r
130         };\r
131         LoadString(AfxGetInstanceHandle(), AFX_IDS_APP_TITLE, notifyIconData[MAIN_ICON].szTip,\r
132                            sizeof(notifyIconData[MAIN_ICON].szTip));\r
133         LoadString(AfxGetInstanceHandle(), IDS_TIP_CX, notifyIconData[CX_ICON].szTip,\r
134                            sizeof(notifyIconData[CX_ICON].szTip));\r
135         LoadString(AfxGetInstanceHandle(), IDS_TIP_MX, notifyIconData[MX_ICON].szTip,\r
136                            sizeof(notifyIconData[MX_ICON].szTip));\r
137         LoadString(AfxGetInstanceHandle(), IDS_TIP_META, notifyIconData[META_ICON].szTip,\r
138                            sizeof(notifyIconData[META_ICON].szTip));\r
139         LoadString(AfxGetInstanceHandle(), IDS_TIP_SHIFT, notifyIconData[SHIFT_ICON].szTip,\r
140                            sizeof(notifyIconData[SHIFT_ICON].szTip));\r
141         LoadString(AfxGetInstanceHandle(), IDS_TIP_CTRL, notifyIconData[CTRL_ICON].szTip,\r
142                            sizeof(notifyIconData[CTRL_ICON].szTip));\r
143         LoadString(AfxGetInstanceHandle(), IDS_TIP_ALT, notifyIconData[ALT_ICON].szTip,\r
144                            sizeof(notifyIconData[ALT_ICON].szTip));\r
145 \r
146         // set notify icon data\r
147         m_hIcon[MAIN_ICON][STATUS_ENABLE] = (HICON)LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 16, 16, LR_SHARED),\r
148         m_hIcon[MAIN_ICON][STATUS_DISABLE_TMP] = (HICON)LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAIN_DISABLE_TMP), IMAGE_ICON, 16, 16, LR_SHARED);\r
149         m_hIcon[MAIN_ICON][STATUS_DISABLE_WOCQ] = (HICON)LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAIN_DISABLE_WOCQ), IMAGE_ICON, 16, 16, LR_SHARED);\r
150         m_hIcon[MAIN_ICON][STATUS_DISABLE] = (HICON)LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAIN_DISABLE), IMAGE_ICON, 16, 16, LR_SHARED);\r
151         m_bIcon[MAIN_ICON] = AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_MAIN)), 1);\r
152         m_stNtfyIcon[MAIN_ICON] = notifyIconData[MAIN_ICON];\r
153         AddShell_NotifyIcon(MAIN_ICON);\r
154 \r
155         // set notify ^X icon data\r
156         m_hIcon[CX_ICON][ON_ICON] = AfxGetApp()->LoadIcon(IDI_CX_ON);\r
157         m_hIcon[CX_ICON][OFF_ICON] = AfxGetApp()->LoadIcon(IDI_CX_OFF);\r
158         m_bIcon[CX_ICON] = AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_CX)), 0);\r
159         m_stNtfyIcon[CX_ICON] = notifyIconData[CX_ICON];\r
160         AddShell_NotifyIcon(CX_ICON);\r
161 \r
162         // set notify M-x icon data\r
163         m_hIcon[MX_ICON][ON_ICON] = AfxGetApp()->LoadIcon(IDI_MX_ON);\r
164         m_hIcon[MX_ICON][OFF_ICON] = AfxGetApp()->LoadIcon(IDI_MX_OFF);\r
165         m_bIcon[MX_ICON] = AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_MX)), 0);\r
166         m_stNtfyIcon[MX_ICON] = notifyIconData[MX_ICON];\r
167         AddShell_NotifyIcon(MX_ICON);\r
168 \r
169         // set notify Meta icon data\r
170         m_hIcon[META_ICON][ON_ICON] = AfxGetApp()->LoadIcon(IDI_META_ON);\r
171         m_hIcon[META_ICON][OFF_ICON] = AfxGetApp()->LoadIcon(IDI_META_OFF);\r
172         m_bIcon[META_ICON] = AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_META)), 0);\r
173         m_stNtfyIcon[META_ICON] = notifyIconData[META_ICON];\r
174         AddShell_NotifyIcon(META_ICON);\r
175 \r
176         // set notify Shift icon data\r
177         m_hIcon[SHIFT_ICON][ON_ICON] = AfxGetApp()->LoadIcon(IDI_SHIFT_ON);\r
178         m_hIcon[SHIFT_ICON][OFF_ICON] = AfxGetApp()->LoadIcon(IDI_SHIFT_OFF);\r
179         m_bIcon[SHIFT_ICON] = AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_SHIFT)), 0);\r
180         m_stNtfyIcon[SHIFT_ICON] = notifyIconData[SHIFT_ICON];\r
181         AddShell_NotifyIcon(SHIFT_ICON);\r
182 \r
183         // set notify Ctrl icon data\r
184         m_hIcon[CTRL_ICON][ON_ICON] = AfxGetApp()->LoadIcon(IDI_CTRL_ON);\r
185         m_hIcon[CTRL_ICON][OFF_ICON] = AfxGetApp()->LoadIcon(IDI_CTRL_OFF);\r
186         m_bIcon[CTRL_ICON] = AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_CTRL)), 0);\r
187         m_stNtfyIcon[CTRL_ICON] = notifyIconData[CTRL_ICON];\r
188         AddShell_NotifyIcon(CTRL_ICON);\r
189 \r
190         // set notify Alt icon data\r
191         m_hIcon[ALT_ICON][ON_ICON] = AfxGetApp()->LoadIcon(IDI_ALT_ON);\r
192         m_hIcon[ALT_ICON][OFF_ICON] = AfxGetApp()->LoadIcon(IDI_ALT_OFF);\r
193         m_bIcon[ALT_ICON] = AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_ALT)), 0);\r
194         m_stNtfyIcon[ALT_ICON] = notifyIconData[ALT_ICON];\r
195         AddShell_NotifyIcon(ALT_ICON);\r
196         \r
197         CXkeymacsDll::SetKeyboardSpeed(CProfile::GetKeyboardSpeed());\r
198         CXkeymacsDll::SetAccelerate(AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_ACCELERATE)), 1));\r
199 \r
200         CXkeymacsDll::SetCursorData((HCURSOR)::LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED),\r
201                                                                   (HCURSOR)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDC_DISABLE_TMP_CURSOR), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED),\r
202                                                                   (HCURSOR)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDC_DISABLE_WOCQ_CURSOR), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED),\r
203                                                                   (HCURSOR)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDC_DISABLE_CURSOR), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED),\r
204                                                                   AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_CHANGE_CURSOR)), 0));\r
205 \r
206         CXkeymacsDll::SetHooks();\r
207         StartPollThread();\r
208 \r
209         return 0;\r
210 }\r
211 \r
212 void CMainFrame::StartPollThread()\r
213 {\r
214         m_bPollIconMessage = TRUE;\r
215         m_hThread = CreateThread(NULL, 0, PollIconMessage, this, 0, NULL);\r
216 }\r
217 \r
218 void CMainFrame::TerminatePollThread()\r
219 {\r
220         m_bPollIconMessage = FALSE;\r
221         ICONMSG nul = {MAIN_ICON,};\r
222         if (CXkeymacsDll::SendIconMessage(&nul, 1))\r
223                 WaitForSingleObject(m_hThread, 5000);\r
224         CloseHandle(m_hThread);\r
225 }\r
226 \r
227 DWORD WINAPI CMainFrame::PollIconMessage(LPVOID lpParam)\r
228 {\r
229         CMainFrame *pThis = reinterpret_cast<CMainFrame *>(lpParam);\r
230         HANDLE hPipe = CreateNamedPipe(ICON_PIPE, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, 1,\r
231                                                                         sizeof(DWORD), sizeof(ICONMSG) * MAX_ICON_TYPE, 0, NULL);\r
232         if (hPipe == INVALID_HANDLE_VALUE)\r
233                 return 1;\r
234         for (; ;) {\r
235                 if (ConnectNamedPipe(hPipe, NULL) ? FALSE : (GetLastError() != ERROR_PIPE_CONNECTED))\r
236                         break;\r
237                 ICONMSG msg[MAX_ICON_TYPE];\r
238                 DWORD read;\r
239                 if (!ReadFile(hPipe, msg, sizeof(msg), &read, NULL))\r
240                         break;\r
241                 DWORD written, ack = 0;\r
242                 // return ack ASAP to release hooks from blocking state.\r
243                 if (!WriteFile(hPipe, &ack, sizeof(DWORD), &written, NULL) || written != sizeof(DWORD) ||\r
244                                 !FlushFileBuffers(hPipe) || !DisconnectNamedPipe(hPipe))\r
245                         break;\r
246                 if (!pThis->m_bPollIconMessage)\r
247                         break;\r
248                 for (DWORD i = 0; i < read / sizeof(ICONMSG); ++i) {\r
249                         pThis->m_stNtfyIcon[msg[i].nType].hIcon = pThis->m_hIcon[msg[i].nType][msg[i].nState];\r
250                         if (msg[i].nType == MX_ICON && msg[i].szTip[0] != 0)\r
251                                 memcpy(pThis->m_stNtfyIcon[MX_ICON].szTip, msg[i].szTip, 128);\r
252                         pThis->DoShell_NotifyIcon(msg[i].nType, NIM_MODIFY);\r
253                 }\r
254         }\r
255         CloseHandle(hPipe);\r
256         return 0;\r
257 }\r
258 \r
259 BOOL CMainFrame::DoShell_NotifyIcon(ICON_TYPE icon, DWORD dwMessage)\r
260 {\r
261         if (m_bIcon[icon]\r
262          &&     (m_dwOldMessage[icon] != dwMessage\r
263           || memcmp(&m_stOldNtfyIcon[icon], &m_stNtfyIcon[icon], sizeof(m_stNtfyIcon[icon])))) {\r
264                 m_dwOldMessage[icon] = dwMessage;\r
265                 m_stOldNtfyIcon[icon] = m_stNtfyIcon[icon];\r
266 \r
267                 BOOL rc = FALSE;\r
268                 for (int retry_count = 0; retry_count < 20; ++retry_count) { // retry for timeout\r
269                         rc = Shell_NotifyIcon(dwMessage, &m_stNtfyIcon[icon]);\r
270                         if (dwMessage != NIM_ADD || rc || (GetLastError() != ERROR_TIMEOUT && 5 < retry_count)) {\r
271                                 break;\r
272                         }\r
273                         Sleep(1000); // 1sec\r
274                         if ((rc = Shell_NotifyIcon(NIM_MODIFY, &m_stNtfyIcon[icon])) != FALSE) {\r
275                                 break; // ERROR_TIMEOUT was returned but the icon was also added.\r
276                         }\r
277                 }\r
278                 return rc;\r
279         } else {\r
280                 return TRUE;\r
281         }\r
282 }\r
283 \r
284 void CMainFrame::EnableShell_NotifyIcon(ICON_TYPE icon, BOOL bEnable)\r
285 {\r
286         DeleteShell_NotifyIcon(icon);\r
287         m_bIcon[icon] = bEnable;\r
288         AddShell_NotifyIcon(icon);\r
289 }\r
290 \r
291 void CMainFrame::AddShell_NotifyIcon(ICON_TYPE icon)\r
292 {\r
293         DoShell_NotifyIcon(icon, NIM_ADD);\r
294 }\r
295 \r
296 void CMainFrame::DeleteShell_NotifyIcon(ICON_TYPE icon)\r
297 {\r
298         DoShell_NotifyIcon(icon, NIM_DELETE);\r
299 }\r
300 \r
301 void CMainFrame::DeleteAllShell_NotifyIcon()\r
302 {\r
303         for (int icon = 0; icon < MAX_ICON_TYPE; ++icon) {\r
304                 DeleteShell_NotifyIcon((ICON_TYPE)icon);\r
305         }\r
306 }\r
307 \r
308 void CMainFrame::AddAllShell_NotifyIcon()\r
309 {\r
310         for (int icon = 0; icon < MAX_ICON_TYPE; ++icon) {\r
311                 AddShell_NotifyIcon((ICON_TYPE)icon);\r
312         }\r
313 }\r
314 \r
315 /////////////////////////////////////////////////////////////////////////////\r
316 // CMainFrame diagnostics\r
317 \r
318 #ifdef _DEBUG\r
319 void CMainFrame::AssertValid() const\r
320 {\r
321         CFrameWnd::AssertValid();\r
322 }\r
323 \r
324 void CMainFrame::Dump(CDumpContext& dc) const\r
325 {\r
326         CFrameWnd::Dump(dc);\r
327 }\r
328 \r
329 #endif //_DEBUG\r
330 \r
331 /////////////////////////////////////////////////////////////////////////////\r
332 // CMainFrame message handlers\r
333 \r
334 void CMainFrame::SetForegroundTheDialog(CDialog *const pDialog)\r
335 {\r
336         if (pDialog) {\r
337                 pDialog->SetForegroundWindow();\r
338         }\r
339 }\r
340 \r
341 void CMainFrame::SetForegroundSomeDialog()\r
342 {\r
343         CDialog *pDialog = NULL;\r
344 \r
345         if (m_bPropertiesDlgExist) {\r
346                 pDialog = m_pPropertiesDlg;\r
347         } else if (m_bOptionsDlgExist) {\r
348                 pDialog = m_pOptionsDlg;\r
349         } else if (m_bKeyboardDlgExist[ENGLISH_KEYBOARD][CURRENT_USER]) {\r
350                 pDialog = m_p104KeyboardDlg[CURRENT_USER];\r
351         } else if (m_bKeyboardDlgExist[ENGLISH_KEYBOARD][LOCAL_MACHINE]) {\r
352                 pDialog = m_p104KeyboardDlg[LOCAL_MACHINE];\r
353         } else if (m_bKeyboardDlgExist[JAPANESE_KEYBOARD][CURRENT_USER]) {\r
354                 pDialog = m_p109KeyboardDlg[CURRENT_USER];\r
355         } else if (m_bKeyboardDlgExist[JAPANESE_KEYBOARD][LOCAL_MACHINE]) {\r
356                 pDialog = m_p109KeyboardDlg[LOCAL_MACHINE];\r
357         } else if (m_bAboutDlgExist) {\r
358                 pDialog = m_pAboutDlg;\r
359         } else {\r
360                 EnableWindow(FALSE);\r
361                 return;\r
362         }\r
363 \r
364         SetForegroundTheDialog(pDialog);\r
365         return;\r
366 }\r
367 \r
368 void CMainFrame::PopUpDialog(CDialog *const pDialog, int *const pnResultDialog, BOOL *const pbDialogExist)\r
369 {\r
370         if (pDialog                     == NULL\r
371          || pnResultDialog      == NULL\r
372          || pbDialogExist       == NULL) {\r
373                 return;\r
374         }\r
375 \r
376         if (!*pbDialogExist) {\r
377                 *pbDialogExist = TRUE;\r
378                 *pnResultDialog = pDialog->DoModal();\r
379                 *pbDialogExist = FALSE;\r
380                 *pnResultDialog = -1;\r
381 \r
382                 SetForegroundSomeDialog();\r
383         } else {\r
384                 SetForegroundTheDialog(pDialog);\r
385         }\r
386 }\r
387 \r
388 void CMainFrame::PopUpPropertiesDialog()\r
389 {\r
390         PopUpDialog(m_pPropertiesDlg, &m_nResultPropertiesDlg, &m_bPropertiesDlgExist);\r
391 }\r
392 \r
393 // show right menu on icon in system tray\r
394 void CMainFrame::ShowRightMenu(const ICON_TYPE icon)\r
395 {\r
396         CMenu rightMenu;\r
397         rightMenu.LoadMenu(IDR_RIGHT_MENU);\r
398 \r
399         CMenu *popUp = rightMenu.GetSubMenu(0);\r
400 \r
401         if (icon == MAIN_ICON) {\r
402                 popUp->SetDefaultItem(IDC_PROPERTIES);\r
403 \r
404                 CString szDisable(MAKEINTRESOURCE(IDS_ENABLE));\r
405                 if (CXkeymacsDll::IsKeyboardHook()) {\r
406                         szDisable.LoadString(IDS_DISABLE);\r
407                 }\r
408                 szDisable += _T("\tCtrl+Q");\r
409                 popUp->ModifyMenu(IDC_DISABLE, MF_STRING, IDC_DISABLE, szDisable);\r
410 \r
411                 TCHAR szUserName[UNLEN + 1] = {'0'};\r
412                 DWORD nSize = UNLEN + 1;\r
413                 if (GetUserName(szUserName, &nSize)) {\r
414                         CString szFor;\r
415                         szFor.Format(IDS_KEYBOARD, szUserName);\r
416                         popUp->ModifyMenu(IDC_KEYBOARD, MF_STRING, IDC_KEYBOARD, szFor);\r
417                 }\r
418 \r
419                 if (CProfile::IsVistaOrLater()) {\r
420                         popUp->DeleteMenu(IDC_KEYBOARD_ANY_USER, MF_BYCOMMAND);\r
421                 }\r
422         } else {\r
423                 popUp->SetDefaultItem(IDC_OPTIONS);\r
424 \r
425                 popUp->DeleteMenu(IDC_PROPERTIES, MF_BYCOMMAND);\r
426                 popUp->DeleteMenu(IDC_IMPORT, MF_BYCOMMAND);\r
427                 popUp->DeleteMenu(IDC_EXPORT, MF_BYCOMMAND);\r
428                 popUp->DeleteMenu(IDC_KEYBOARD, MF_BYCOMMAND);\r
429                 popUp->DeleteMenu(IDC_KEYBOARD_ANY_USER, MF_BYCOMMAND);\r
430                 popUp->DeleteMenu(IDC_DISABLE, MF_BYCOMMAND);\r
431                 popUp->DeleteMenu(IDC_RESET, MF_BYCOMMAND);\r
432                 popUp->DeleteMenu(IDC_QUIT, MF_BYCOMMAND);\r
433                 popUp->DeleteMenu(0, MF_BYPOSITION);    // Delete separator\r
434                 popUp->DeleteMenu(1, MF_BYPOSITION);    // Delete separator\r
435                 popUp->DeleteMenu(2, MF_BYPOSITION);    // Delete popup menu of Keyboard Layout\r
436         }\r
437 \r
438         SetForegroundWindow();\r
439 \r
440         CPoint pt;\r
441         GetCursorPos(&pt);\r
442         popUp->TrackPopupMenu(TPM_RIGHTBUTTON, pt.x, pt.y, this);\r
443 }\r
444 \r
445 // get message of icon on system tray\r
446 LRESULT CMainFrame::WindowProc(const UINT message, const WPARAM wParam, const LPARAM lParam) \r
447 {\r
448         static UINT s_uTaskbarRestart;\r
449 \r
450         switch (message) {\r
451         case WM_CREATE:\r
452                 s_uTaskbarRestart = RegisterWindowMessage(_T("TaskbarCreated"));\r
453                 break;\r
454         case WM_USER_NTFYICON:\r
455                 switch (lParam) {\r
456                 case WM_LBUTTONUP:\r
457                         SetForegroundSomeDialog();\r
458                         break;\r
459                 case WM_LBUTTONDBLCLK:\r
460                         if (wParam == MAIN_ICON) {\r
461                                 PopUpPropertiesDialog();\r
462                         } else {\r
463                                 PopUpOptionsDialog();\r
464                         }\r
465                         break;\r
466                 case WM_RBUTTONUP:\r
467                         ShowRightMenu((ICON_TYPE)wParam);\r
468                         break;\r
469                 default:\r
470                         break;\r
471                 }\r
472         default:\r
473                 if (message == s_uTaskbarRestart) {\r
474                         AddAllShell_NotifyIcon();\r
475                 }\r
476                 break;\r
477         }\r
478         \r
479         return CFrameWnd::WindowProc(message, wParam, lParam);\r
480 }\r
481 \r
482 void CMainFrame::OnProperties()\r
483 {\r
484         PopUpPropertiesDialog();\r
485 }\r
486 \r
487 void CMainFrame::PopUpOptionsDialog()\r
488 {\r
489         PopUpDialog(m_pOptionsDlg, &m_nResultOptionsDlg, &m_bOptionsDlgExist);\r
490 }\r
491 \r
492 void CMainFrame::OnOptions() \r
493 {\r
494         PopUpOptionsDialog();\r
495 }\r
496 \r
497 // stop/start keyboard hook\r
498 void CMainFrame::OnDisable() \r
499 {\r
500         CXkeymacsDll::ToggleKeyboardHookState();\r
501 }\r
502 \r
503 // Close the Dialog if it is opened.\r
504 void CMainFrame::CloseDialog(CDialog *const pDialog, int *const pnResult)\r
505 {\r
506         if (*pnResult != -1) {\r
507                 pDialog->EndDialog(*pnResult);\r
508                 *pnResult = -1;\r
509         }\r
510 }\r
511 \r
512 void CMainFrame::OnQuit() \r
513 {\r
514         CloseDialog(m_pAboutDlg, &m_nResultAboutDlg);\r
515         CloseDialog(m_pPropertiesDlg, &m_nResultPropertiesDlg);\r
516         CloseDialog(m_pOptionsDlg, &m_nResultOptionsDlg);\r
517         for (int i = 0; i < MAX_HKEY_TYPE; ++i) {\r
518                 CloseDialog(m_p104KeyboardDlg[i], &m_nResultKeyboardDlg[ENGLISH_KEYBOARD][i]);\r
519                 CloseDialog(m_p109KeyboardDlg[i], &m_nResultKeyboardDlg[JAPANESE_KEYBOARD][i]);\r
520         }\r
521 \r
522         CXkeymacsDll::ReleaseHooks();\r
523         TerminatePollThread();\r
524         static_cast<CXkeymacsApp *>(AfxGetApp())->SendIPCMessage(XKEYMACS_EXIT);\r
525         DeleteAllShell_NotifyIcon();\r
526 \r
527         PostQuitMessage(0);\r
528 }\r
529 \r
530 void CMainFrame::PopUpAboutDialog()\r
531 {\r
532         PopUpDialog(m_pAboutDlg, &m_nResultAboutDlg, &m_bAboutDlgExist);\r
533 }\r
534 \r
535 void CMainFrame::OnAbout() \r
536 {\r
537         PopUpAboutDialog();\r
538 }\r
539 \r
540 void CMainFrame::OnKeyboard() \r
541 {\r
542         PopUpKeyboardDialog(CURRENT_USER);\r
543 }\r
544 \r
545 void CMainFrame::OnKeyboardAnyUser() \r
546 {\r
547         PopUpKeyboardDialog(LOCAL_MACHINE);\r
548 }\r
549 \r
550 void CMainFrame::PopUpKeyboardDialog(const HKEY_TYPE hkeyType)\r
551 {\r
552         if (CProfile::Is106Keyboard()) {\r
553                 PopUpDialog(m_p109KeyboardDlg[hkeyType], &m_nResultKeyboardDlg[JAPANESE_KEYBOARD][hkeyType], &m_bKeyboardDlgExist[JAPANESE_KEYBOARD][hkeyType]);\r
554         } else {\r
555                 PopUpDialog(m_p104KeyboardDlg[hkeyType], &m_nResultKeyboardDlg[ENGLISH_KEYBOARD][hkeyType], &m_bKeyboardDlgExist[ENGLISH_KEYBOARD][hkeyType]);\r
556         }\r
557 }\r
558 \r
559 void CMainFrame::OnImport() \r
560 {\r
561         CProfile::ImportProperties();\r
562         CProfile::InitDllData();\r
563 }\r
564 \r
565 void CMainFrame::OnExport() \r
566 {\r
567         CProfile::ExportProperties();\r
568 }\r
569 \r
570 void CMainFrame::OnReset() \r
571 {\r
572         TerminatePollThread();\r
573         CXkeymacsDll::ResetHooks();\r
574         StartPollThread();\r
575         CXkeymacsApp *pApp = static_cast<CXkeymacsApp *>(AfxGetApp());\r
576         if (!pApp->SendIPCMessage(XKEYMACS_RESET))\r
577                 pApp->Start64bitProcess(); // try to restart 64bit app\r
578 }\r
579 \r
580 void CMainFrame::OnHelpFinder() \r
581 {\r
582         TCHAR szPath[MAX_PATH] = {'\0'};\r
583         const TCHAR szExt[] = _T("txt");\r
584         _tmakepath_s(szPath, NULL, NULL, CString(MAKEINTRESOURCE(IDS_README)), szExt);\r
585 \r
586         TCHAR szModuleFileName[MAX_PATH] = {'\0'};\r
587         if (GetModuleFileName(NULL, szModuleFileName, sizeof(szModuleFileName))) {\r
588                 TCHAR szDrive[_MAX_DRIVE] = {'\0'};\r
589                 TCHAR szDir[_MAX_DIR] = {'\0'};\r
590                 _tsplitpath_s(szModuleFileName, szDrive, _MAX_DRIVE, szDir, _MAX_DIR, NULL, 0, NULL, 0);\r
591                 _tmakepath_s(szPath, szDrive, szDir, CString(MAKEINTRESOURCE(IDS_README)), szExt);\r
592         }\r
593 \r
594         ShellExecute(NULL, NULL, szPath, NULL, NULL, SW_SHOWNORMAL);\r
595 }\r
596 \r
597 LRESULT CMainFrame::OnPowerBroadCast(WPARAM wParam, LPARAM)\r
598 {\r
599         switch (wParam) {\r
600         case PBT_APMRESUMECRITICAL:\r
601         case PBT_APMRESUMESUSPEND:\r
602         case PBT_APMRESUMEAUTOMATIC:\r
603                 CXkeymacsDll::ResetHooks();\r
604         }\r
605         return TRUE;\r
606 }\r