OSDN Git Service

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