• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

XKeymacs for 64bit Windows


Commit MetaInfo

Revisionb48f885d91b15ee2bccbabaf2793d7b104dd2e04 (tree)
Time2011-05-27 08:38:36
AuthorKazuhiro Fujieda <fujieda@user...>
CommiterKazuhiro Fujieda

Log Message

CMainFrame handles notify icons instead of CXkeymacsDll.

CXkeymacsDll changes notify icons through a named pipe.
It changes all modifier icons and the M-x tip at the same time.
CMainFrame creates a thread to receive messages from CXkeymacsDll.

Change Summary

Incremental Difference

--- a/xkeymacs/mainfrm.cpp
+++ b/xkeymacs/mainfrm.cpp
@@ -5,7 +5,6 @@
55 #include <Lmcons.h>
66 #include "xkeymacs.h"
77 #include "Profile.h"
8-
98 #include "MainFrm.h"
109
1110 #ifdef _DEBUG
@@ -60,6 +59,8 @@ CMainFrame::CMainFrame()
6059 }
6160 memset(m_nResultKeyboardDlg, -1, sizeof(m_nResultKeyboardDlg));
6261 memset(m_bKeyboardDlgExist, 0, sizeof(m_bKeyboardDlgExist));
62+ memset(m_stOldNtfyIcon, 0, sizeof(m_stOldNtfyIcon));
63+ memset(m_dwOldMessage, 0, sizeof(m_dwOldMessage));
6364
6465 // register window class
6566 WNDCLASS stWndClass;
@@ -145,43 +146,56 @@ int CMainFrame::OnCreate(const LPCREATESTRUCT lpCreateStruct)
145146 sizeof(notifyIconData[ALT_ICON].szTip));
146147
147148 // set notify icon data
148- CXkeymacsDll::SetNotifyIconData(MAIN_ICON, notifyIconData[MAIN_ICON],
149- (HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 16, 16, LR_SHARED),
150- (HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAIN_DISABLE_TMP), IMAGE_ICON, 16, 16, LR_SHARED),
151- (HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAIN_DISABLE_WOCQ), IMAGE_ICON, 16, 16, LR_SHARED), // disable without C-q
152- (HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAIN_DISABLE), IMAGE_ICON, 16, 16, LR_SHARED),
153- AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_MAIN)), 1));
149+ m_hIcon[MAIN_ICON][STATUS_ENABLE] = (HICON)LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 16, 16, LR_SHARED),
150+ m_hIcon[MAIN_ICON][STATUS_DISABLE_TMP] = (HICON)LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAIN_DISABLE_TMP), IMAGE_ICON, 16, 16, LR_SHARED);
151+ m_hIcon[MAIN_ICON][STATUS_DISABLE_WOCQ] = (HICON)LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAIN_DISABLE_WOCQ), IMAGE_ICON, 16, 16, LR_SHARED);
152+ m_hIcon[MAIN_ICON][STATUS_DISABLE] = (HICON)LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAIN_DISABLE), IMAGE_ICON, 16, 16, LR_SHARED);
153+ m_bIcon[MAIN_ICON] = AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_MAIN)), 1);
154+ m_stNtfyIcon[MAIN_ICON] = notifyIconData[MAIN_ICON];
155+ AddShell_NotifyIcon(MAIN_ICON);
154156
155157 // set notify ^X icon data
156- CXkeymacsDll::SetNotifyIconData(CX_ICON, notifyIconData[CX_ICON], AfxGetApp()->LoadIcon(IDI_CX_ON),
157- AfxGetApp()->LoadIcon(IDI_CX_OFF),
158- AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_CX)), 0));
158+ m_hIcon[CX_ICON][ON_ICON] = AfxGetApp()->LoadIcon(IDI_CX_ON);
159+ m_hIcon[CX_ICON][OFF_ICON] = AfxGetApp()->LoadIcon(IDI_CX_OFF);
160+ m_bIcon[CX_ICON] = AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_CX)), 0);
161+ m_stNtfyIcon[CX_ICON] = notifyIconData[CX_ICON];
162+ AddShell_NotifyIcon(CX_ICON);
159163
160164 // set notify M-x icon data
161- CXkeymacsDll::SetNotifyIconData(MX_ICON, notifyIconData[MX_ICON], AfxGetApp()->LoadIcon(IDI_MX_ON),
162- AfxGetApp()->LoadIcon(IDI_MX_OFF),
163- AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_MX)), 0));
165+ m_hIcon[MX_ICON][ON_ICON] = AfxGetApp()->LoadIcon(IDI_MX_ON);
166+ m_hIcon[MX_ICON][OFF_ICON] = AfxGetApp()->LoadIcon(IDI_MX_OFF);
167+ m_bIcon[MX_ICON] = AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_MX)), 0);
168+ m_stNtfyIcon[MX_ICON] = notifyIconData[MX_ICON];
169+ AddShell_NotifyIcon(MX_ICON);
164170
165171 // set notify Meta icon data
166- CXkeymacsDll::SetNotifyIconData(META_ICON, notifyIconData[META_ICON], AfxGetApp()->LoadIcon(IDI_META_ON),
167- AfxGetApp()->LoadIcon(IDI_META_OFF),
168- AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_META)), 0));
172+ m_hIcon[META_ICON][ON_ICON] = AfxGetApp()->LoadIcon(IDI_META_ON);
173+ m_hIcon[META_ICON][OFF_ICON] = AfxGetApp()->LoadIcon(IDI_META_OFF);
174+ m_bIcon[META_ICON] = AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_META)), 0);
175+ m_stNtfyIcon[META_ICON] = notifyIconData[META_ICON];
176+ AddShell_NotifyIcon(META_ICON);
169177
170178 // set notify Shift icon data
171- CXkeymacsDll::SetNotifyIconData(SHIFT_ICON, notifyIconData[SHIFT_ICON], AfxGetApp()->LoadIcon(IDI_SHIFT_ON),
172- AfxGetApp()->LoadIcon(IDI_SHIFT_OFF),
173- AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_SHIFT)), 0));
179+ m_hIcon[SHIFT_ICON][ON_ICON] = AfxGetApp()->LoadIcon(IDI_SHIFT_ON);
180+ m_hIcon[SHIFT_ICON][OFF_ICON] = AfxGetApp()->LoadIcon(IDI_SHIFT_OFF);
181+ m_bIcon[SHIFT_ICON] = AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_SHIFT)), 0);
182+ m_stNtfyIcon[SHIFT_ICON] = notifyIconData[SHIFT_ICON];
183+ AddShell_NotifyIcon(SHIFT_ICON);
174184
175185 // set notify Ctrl icon data
176- CXkeymacsDll::SetNotifyIconData(CTRL_ICON, notifyIconData[CTRL_ICON], AfxGetApp()->LoadIcon(IDI_CTRL_ON),
177- AfxGetApp()->LoadIcon(IDI_CTRL_OFF),
178- AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_CTRL)), 0));
186+ m_hIcon[CTRL_ICON][ON_ICON] = AfxGetApp()->LoadIcon(IDI_CTRL_ON);
187+ m_hIcon[CTRL_ICON][OFF_ICON] = AfxGetApp()->LoadIcon(IDI_CTRL_OFF);
188+ m_bIcon[CTRL_ICON] = AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_CTRL)), 0);
189+ m_stNtfyIcon[CTRL_ICON] = notifyIconData[CTRL_ICON];
190+ AddShell_NotifyIcon(CTRL_ICON);
179191
180192 // set notify Alt icon data
181- CXkeymacsDll::SetNotifyIconData(ALT_ICON, notifyIconData[ALT_ICON], AfxGetApp()->LoadIcon(IDI_ALT_ON),
182- AfxGetApp()->LoadIcon(IDI_ALT_OFF),
183- AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_ALT)), 0));
184-
193+ m_hIcon[ALT_ICON][ON_ICON] = AfxGetApp()->LoadIcon(IDI_ALT_ON);
194+ m_hIcon[ALT_ICON][OFF_ICON] = AfxGetApp()->LoadIcon(IDI_ALT_OFF);
195+ m_bIcon[ALT_ICON] = AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_ALT)), 0);
196+ m_stNtfyIcon[ALT_ICON] = notifyIconData[ALT_ICON];
197+ AddShell_NotifyIcon(ALT_ICON);
198+
185199 CXkeymacsDll::SetKeyboardSpeed(CProfile::GetKeyboardSpeed());
186200 CXkeymacsDll::SetAccelerate(AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_ACCELERATE)), 1));
187201
@@ -192,10 +206,114 @@ int CMainFrame::OnCreate(const LPCREATESTRUCT lpCreateStruct)
192206 AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_CHANGE_CURSOR)), 0));
193207
194208 CXkeymacsDll::SetHooks();
209+ StartPollThread();
210+
211+ return 0;
212+}
213+
214+void CMainFrame::StartPollThread()
215+{
216+ m_bPollIconMessage = TRUE;
217+ m_hThread = CreateThread(NULL, 0, PollIconMessage, this, 0, NULL);
218+}
219+
220+void CMainFrame::TerminatePollThread()
221+{
222+ m_bPollIconMessage = FALSE;
223+ ICONMSG nul = {MAIN_ICON,};
224+ if (CXkeymacsDll::SendIconMessage(&nul, 1))
225+ WaitForSingleObject(m_hThread, 5000);
226+ CloseHandle(m_hThread);
227+}
195228
229+DWORD WINAPI CMainFrame::PollIconMessage(LPVOID lpParam)
230+{
231+ CMainFrame *pThis = reinterpret_cast<CMainFrame *>(lpParam);
232+ HANDLE hPipe = CreateNamedPipe(ICON_PIPE, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, 1,
233+ sizeof(DWORD), sizeof(ICONMSG) * MAX_ICON_TYPE, 0, NULL);
234+ if (hPipe == INVALID_HANDLE_VALUE)
235+ return 1;
236+ for (; ;) {
237+ if (ConnectNamedPipe(hPipe, NULL) ? FALSE : (GetLastError() != ERROR_PIPE_CONNECTED))
238+ break;
239+ ICONMSG msg[MAX_ICON_TYPE];
240+ DWORD read;
241+ if (!ReadFile(hPipe, msg, sizeof(msg), &read, NULL))
242+ break;
243+ DWORD written, ack = 0;
244+ // return ack ASAP to release hooks from blocking state.
245+ if (!WriteFile(hPipe, &ack, sizeof(DWORD), &written, NULL) || written != sizeof(DWORD) ||
246+ !FlushFileBuffers(hPipe) || !DisconnectNamedPipe(hPipe))
247+ break;
248+ if (!pThis->m_bPollIconMessage)
249+ break;
250+ for (DWORD i = 0; i < read / sizeof(ICONMSG); i++) {
251+ pThis->m_stNtfyIcon[msg[i].nType].hIcon = pThis->m_hIcon[msg[i].nType][msg[i].nState];
252+ if (msg[i].nType == MX_ICON && msg[i].szTip[0] != 0)
253+ memcpy(pThis->m_stNtfyIcon[MX_ICON].szTip, msg[i].szTip, 128);
254+ pThis->DoShell_NotifyIcon(msg[i].nType, NIM_MODIFY);
255+ }
256+ }
257+ CloseHandle(hPipe);
196258 return 0;
197259 }
198260
261+BOOL CMainFrame::DoShell_NotifyIcon(ICON_TYPE icon, DWORD dwMessage)
262+{
263+ if (m_bIcon[icon]
264+ && (m_dwOldMessage[icon] != dwMessage
265+ || memcmp(&m_stOldNtfyIcon[icon], &m_stNtfyIcon[icon], sizeof(m_stNtfyIcon[icon])))) {
266+ m_dwOldMessage[icon] = dwMessage;
267+ m_stOldNtfyIcon[icon] = m_stNtfyIcon[icon];
268+
269+ BOOL rc = FALSE;
270+ for (int retry_count = 0; retry_count < 20; ++retry_count) { // retry for timeout
271+ rc = Shell_NotifyIcon(dwMessage, &m_stNtfyIcon[icon]);
272+ if (dwMessage != NIM_ADD || rc || (GetLastError() != ERROR_TIMEOUT && 5 < retry_count)) {
273+ break;
274+ }
275+ Sleep(1000); // 1sec
276+ if ((rc = Shell_NotifyIcon(NIM_MODIFY, &m_stNtfyIcon[icon])) != FALSE) {
277+ break; // ERROR_TIMEOUT was returned but the icon was also added.
278+ }
279+ }
280+ return rc;
281+ } else {
282+ return TRUE;
283+ }
284+}
285+
286+void CMainFrame::EnableShell_NotifyIcon(ICON_TYPE icon, BOOL bEnable)
287+{
288+ DeleteShell_NotifyIcon(icon);
289+ m_bIcon[icon] = bEnable;
290+ AddShell_NotifyIcon(icon);
291+}
292+
293+void CMainFrame::AddShell_NotifyIcon(ICON_TYPE icon)
294+{
295+ DoShell_NotifyIcon(icon, NIM_ADD);
296+}
297+
298+void CMainFrame::DeleteShell_NotifyIcon(ICON_TYPE icon)
299+{
300+ DoShell_NotifyIcon(icon, NIM_DELETE);
301+}
302+
303+void CMainFrame::DeleteAllShell_NotifyIcon()
304+{
305+ for (int icon = 0; icon < MAX_ICON_TYPE; ++icon) {
306+ DeleteShell_NotifyIcon((ICON_TYPE)icon);
307+ }
308+}
309+
310+void CMainFrame::AddAllShell_NotifyIcon()
311+{
312+ for (int icon = 0; icon < MAX_ICON_TYPE; ++icon) {
313+ AddShell_NotifyIcon((ICON_TYPE)icon);
314+ }
315+}
316+
199317 /////////////////////////////////////////////////////////////////////////////
200318 // CMainFrame diagnostics
201319
@@ -355,7 +473,7 @@ LRESULT CMainFrame::WindowProc(const UINT message, const WPARAM wParam, const LP
355473 }
356474 default:
357475 if (message == s_uTaskbarRestart) {
358- CXkeymacsDll::AddAllShell_NotifyIcon();
476+ AddAllShell_NotifyIcon();
359477 }
360478 break;
361479 }
@@ -408,7 +526,8 @@ void CMainFrame::OnQuit()
408526 }
409527
410528 CXkeymacsDll::ReleaseHooks();
411- CXkeymacsDll::DeleteAllShell_NotifyIcon();
529+ TerminatePollThread();
530+ DeleteAllShell_NotifyIcon();
412531
413532 PostQuitMessage(0);
414533 }
@@ -457,6 +576,8 @@ void CMainFrame::OnReset()
457576 {
458577 CXkeymacsDll::ReleaseHooks();
459578 CXkeymacsDll::SetHooks();
579+ TerminatePollThread();
580+ StartPollThread();
460581 }
461582
462583 void CMainFrame::OnHelpFinder()
--- a/xkeymacs/mainfrm.h
+++ b/xkeymacs/mainfrm.h
@@ -87,6 +87,24 @@ private:
8787 int m_nResultAboutDlg;
8888 int m_nResultPropertiesDlg;
8989 CProperties *m_pPropertiesDlg;
90+ // notify icons
91+ BOOL m_bIcon[MAX_ICON_TYPE];
92+ HICON m_hIcon[MAX_ICON_TYPE][MAX_STATUS];
93+ DWORD m_dwOldMessage[MAX_ICON_TYPE];
94+ NOTIFYICONDATA m_stNtfyIcon[MAX_ICON_TYPE];
95+ NOTIFYICONDATA m_stOldNtfyIcon[MAX_ICON_TYPE];
96+ void AddShell_NotifyIcon(ICON_TYPE icon);
97+ void DeleteShell_NotifyIcon(ICON_TYPE icon);
98+ BOOL DoShell_NotifyIcon(ICON_TYPE icon, DWORD dwMessage);
99+ void DeleteAllShell_NotifyIcon();
100+ void AddAllShell_NotifyIcon();
101+ BOOL m_bPollIconMessage;
102+ HANDLE m_hThread;
103+ void StartPollThread();
104+ void TerminatePollThread();
105+ static DWORD WINAPI PollIconMessage(LPVOID lpParam);
106+public:
107+ void EnableShell_NotifyIcon(ICON_TYPE icon, BOOL bEnable);
90108 };
91109
92110 /////////////////////////////////////////////////////////////////////////////
--- a/xkeymacs/optionsdlg.cpp
+++ b/xkeymacs/optionsdlg.cpp
@@ -160,12 +160,13 @@ void COptionsDlg::OnOK()
160160 AfxGetApp()->WriteProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_ALT)), m_cAlt.GetCheck());
161161
162162 // set dll data
163- CXkeymacsDll::EnableShell_NotifyIcon(CX_ICON, m_cCx.GetCheck());
164- CXkeymacsDll::EnableShell_NotifyIcon(MX_ICON, m_cMx.GetCheck());
165- CXkeymacsDll::EnableShell_NotifyIcon(META_ICON, m_cM_.GetCheck());
166- CXkeymacsDll::EnableShell_NotifyIcon(SHIFT_ICON, m_cShift.GetCheck());
167- CXkeymacsDll::EnableShell_NotifyIcon(CTRL_ICON, m_cCtrl.GetCheck());
168- CXkeymacsDll::EnableShell_NotifyIcon(ALT_ICON, m_cAlt.GetCheck());
163+ CMainFrame *pMainFrame = static_cast<CMainFrame*>(AfxGetMainWnd());
164+ pMainFrame->EnableShell_NotifyIcon(CX_ICON, m_cCx.GetCheck());
165+ pMainFrame->EnableShell_NotifyIcon(MX_ICON, m_cMx.GetCheck());
166+ pMainFrame->EnableShell_NotifyIcon(META_ICON, m_cM_.GetCheck());
167+ pMainFrame->EnableShell_NotifyIcon(SHIFT_ICON, m_cShift.GetCheck());
168+ pMainFrame->EnableShell_NotifyIcon(CTRL_ICON, m_cCtrl.GetCheck());
169+ pMainFrame->EnableShell_NotifyIcon(ALT_ICON, m_cAlt.GetCheck());
169170 }
170171
171172 CDialog::OnOK();
--- a/xkeymacsdll/Commands.cpp
+++ b/xkeymacsdll/Commands.cpp
@@ -1600,7 +1600,6 @@ BOOL CCommands::bC_()
16001600 void CCommands::bC_(BOOL b)
16011601 {
16021602 m_bC_ = b;
1603- CXkeymacsDll::ModifyShell_NotifyIcon(CTRL_ICON, m_bC_);
16041603 }
16051604
16061605 BOOL CCommands::bC_x()
@@ -1611,7 +1610,6 @@ BOOL CCommands::bC_x()
16111610 void CCommands::bC_x(BOOL b)
16121611 {
16131612 m_bC_x = b;
1614- CXkeymacsDll::ModifyShell_NotifyIcon(CX_ICON, m_bC_x);
16151613 }
16161614
16171615 BOOL CCommands::bM_x()
@@ -1624,9 +1622,9 @@ void CCommands::bM_x(const BOOL b)
16241622 m_bM_x = b;
16251623
16261624 if (b) {
1627- CXkeymacsDll::ModifyM_xTip("");
1625+ CXkeymacsDll::SetM_xTip("");
16281626 } else {
1629- CXkeymacsDll::ModifyM_xTip(NULL);
1627+ CXkeymacsDll::SetM_xTip(NULL);
16301628 }
16311629 }
16321630
@@ -1804,7 +1802,6 @@ int CCommands::Ignore()
18041802 void CCommands::bM_(BOOL b)
18051803 {
18061804 m_bM_ = b;
1807- CXkeymacsDll::ModifyShell_NotifyIcon(META_ICON, m_bM_);
18081805 }
18091806
18101807 BOOL CCommands::bM_()
--- /dev/null
+++ b/xkeymacsdll/ipc.h
@@ -0,0 +1,15 @@
1+#ifndef IPC_H_INCLUDED
2+#define IPC_H_INCLUDED
3+
4+#if _MSC_VER > 1000
5+#pragma once
6+#endif // _MSC_VER > 1000
7+
8+struct ICONMSG {
9+ ICON_TYPE nType;
10+ int nState;
11+ TCHAR szTip[128];
12+};
13+
14+#define ICON_PIPE _T("\\\\.\\pipe\\XKEYMACS_ICON")
15+#endif
--- a/xkeymacsdll/xkeymacsdll-vc10.vcxproj
+++ b/xkeymacsdll/xkeymacsdll-vc10.vcxproj
@@ -200,6 +200,7 @@
200200 <ClInclude Include="ClipboardSnap.h" />
201201 <ClInclude Include="Commands.h" />
202202 <ClInclude Include="FunctionDefinition.h" />
203+ <ClInclude Include="ipc.h" />
203204 <ClInclude Include="resource.h" />
204205 <ClInclude Include="StdAfx.h" />
205206 <ClInclude Include="Utils.h" />
--- a/xkeymacsdll/xkeymacsdll-vc10.vcxproj.filters
+++ b/xkeymacsdll/xkeymacsdll-vc10.vcxproj.filters
@@ -70,6 +70,9 @@
7070 <ClInclude Include="xkeymacsdll.h">
7171 <Filter>Header Files</Filter>
7272 </ClInclude>
73+ <ClInclude Include="ipc.h">
74+ <Filter>Header Files</Filter>
75+ </ClInclude>
7376 </ItemGroup>
7477 <ItemGroup>
7578 <ResourceCompile Include="xkeymacsdll.rc">
--- a/xkeymacsdll/xkeymacsdll.cpp
+++ b/xkeymacsdll/xkeymacsdll.cpp
@@ -152,7 +152,7 @@ DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
152152 switch (dwReason) {
153153 case DLL_PROCESS_ATTACH:
154154 TRACE0("XKEYMACSDLL.DLL Initializing!\n");
155-
155+
156156 // Extension DLL one-time initialization
157157 if (!AfxInitExtensionModule(XkeymacsdllDLL, hInstance)) {
158158 return 0;
@@ -211,11 +211,6 @@ DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
211211 BOOL CXkeymacsDll::m_bRightShift = FALSE;
212212 BOOL CXkeymacsDll::m_bHook = TRUE;
213213 BOOL CXkeymacsDll::m_bDefiningMacro = FALSE;
214- DWORD CXkeymacsDll::m_dwOldMessage[MAX_ICON_TYPE] = {'\0'};
215- NOTIFYICONDATA CXkeymacsDll::m_stNtfyIcon[MAX_ICON_TYPE] = {'\0'};
216- NOTIFYICONDATA CXkeymacsDll::m_stOldNtfyIcon[MAX_ICON_TYPE] = {'\0'};
217- HICON CXkeymacsDll::m_hIcon[MAX_ICON_TYPE][MAX_STATUS] = {'\0'};
218- BOOL CXkeymacsDll::m_bIcon[MAX_ICON_TYPE] = {'\0'};
219214 int CXkeymacsDll::m_nKillRingMax[MAX_APP] = {'\0'};
220215 BOOL CXkeymacsDll::m_bUseDialogSetting[MAX_APP] = {'\0'};
221216 CList<CClipboardSnap *, CClipboardSnap *> CXkeymacsDll::m_oKillRing;
@@ -238,6 +233,7 @@ DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
238233 BOOL CXkeymacsDll::m_bCursor = FALSE;
239234 BOOL CXkeymacsDll::m_b326Compatible[MAX_APP] = {'\0'};
240235 BOOL CXkeymacsDll::m_b106Keyboard = FALSE;
236+ TCHAR CXkeymacsDll::m_M_xTip[128] = "";
241237 #pragma data_seg()
242238
243239 //////////////////////////////////////////////////////////////////////
@@ -254,81 +250,6 @@ CXkeymacsDll::~CXkeymacsDll()
254250
255251 }
256252
257-int CXkeymacsDll::ModifyShell_NotifyIcon(ICON_TYPE icon, BOOL bNewStatus, BOOL bForce)
258-{
259- if (m_stNtfyIcon[icon].hIcon == (bNewStatus ? m_hIcon[icon][ON_ICON] : m_hIcon[icon][OFF_ICON])) {
260- if (!bForce) {
261- return TRUE;
262- }
263- } else {
264- m_stNtfyIcon[icon].hIcon = (bNewStatus ? m_hIcon[icon][ON_ICON] : m_hIcon[icon][OFF_ICON]);
265- }
266- return DoShell_NotifyIcon(icon, NIM_MODIFY);
267-}
268-
269-void CXkeymacsDll::SetNotifyIconData(ICON_TYPE icon, NOTIFYICONDATA stNtfyIcon, HICON hEnable, HICON hDisableTMP, HICON hDisableWOCQ, HICON hDisable, BOOL bEnable)
270-{
271- m_hIcon[icon][STATUS_ENABLE] = hEnable;
272- m_hIcon[icon][STATUS_DISABLE_TMP] = hDisableTMP;
273- m_hIcon[icon][STATUS_DISABLE_WOCQ] = hDisableWOCQ;
274- m_hIcon[icon][STATUS_DISABLE] = hDisable;
275- m_bIcon[icon] = bEnable;
276- m_stNtfyIcon[icon] = stNtfyIcon;
277- AddShell_NotifyIcon(icon);
278-}
279-
280-void CXkeymacsDll::SetNotifyIconData(ICON_TYPE icon, NOTIFYICONDATA stNtfyIcon, HICON hOn, HICON hOff, BOOL bEnable)
281-{
282- m_hIcon[icon][ON_ICON] = hOn;
283- m_hIcon[icon][OFF_ICON] = hOff;
284- m_bIcon[icon] = bEnable;
285- m_stNtfyIcon[icon] = stNtfyIcon;
286- AddShell_NotifyIcon(icon);
287-}
288-
289-void CXkeymacsDll::EnableShell_NotifyIcon(ICON_TYPE icon, BOOL bEnable)
290-{
291- DeleteShell_NotifyIcon(icon);
292- m_bIcon[icon] = bEnable;
293- AddShell_NotifyIcon(icon);
294-}
295-
296-
297-BOOL CXkeymacsDll::DoShell_NotifyIcon(ICON_TYPE icon, DWORD dwMessage)
298-{
299- if (m_bIcon[icon]
300- && (m_dwOldMessage[icon] != dwMessage
301- || memcmp(&m_stOldNtfyIcon[icon], &m_stNtfyIcon[icon], sizeof(m_stNtfyIcon[icon])))) {
302- m_dwOldMessage[icon] = dwMessage;
303- m_stOldNtfyIcon[icon] = m_stNtfyIcon[icon];
304-
305- BOOL rc = FALSE;
306- for (int retry_count = 0; retry_count < 20; ++retry_count) { // retry for timeout
307- rc = Shell_NotifyIcon(dwMessage, &m_stNtfyIcon[icon]);
308- if (dwMessage != NIM_ADD || rc || (GetLastError() != ERROR_TIMEOUT && 5 < retry_count)) {
309- break;
310- }
311- Sleep(1000); // 1sec
312- if ((rc = Shell_NotifyIcon(NIM_MODIFY, &m_stNtfyIcon[icon])) != FALSE) {
313- break; // ERROR_TIMEOUT was returned but the icon was also added.
314- }
315- }
316- return rc;
317- } else {
318- return TRUE;
319- }
320-}
321-
322-void CXkeymacsDll::AddShell_NotifyIcon(ICON_TYPE icon)
323-{
324- DoShell_NotifyIcon(icon, NIM_ADD);
325-}
326-
327-void CXkeymacsDll::DeleteShell_NotifyIcon(ICON_TYPE icon)
328-{
329- DoShell_NotifyIcon(icon, NIM_DELETE);
330-}
331-
332253 // set hooks
333254 void CXkeymacsDll::SetHooks()
334255 {
@@ -373,26 +294,25 @@ void CXkeymacsDll::ReleaseKeyboardHook()
373294 void CXkeymacsDll::SetKeyboardHookFlag(BOOL bFlag)
374295 {
375296 m_bHook = bFlag;
376-
297+ ICONMSG msg = {MAIN_ICON,};
377298 if (m_bHook) {
378299 if (CCommands::IsTemporarilyDisableXKeymacs()) {
379- m_stNtfyIcon[MAIN_ICON].hIcon = m_hIcon[MAIN_ICON][STATUS_DISABLE_TMP];
300+ msg.nState = STATUS_DISABLE_TMP;
380301 m_hCurrentCursor = m_hCursor[STATUS_DISABLE_TMP];
381302 } else {
382- m_stNtfyIcon[MAIN_ICON].hIcon = m_hIcon[MAIN_ICON][STATUS_ENABLE];
303+ msg.nState = STATUS_ENABLE;
383304 m_hCurrentCursor = m_hCursor[STATUS_ENABLE];
384305 }
385306 } else {
386- m_stNtfyIcon[MAIN_ICON].hIcon = m_hIcon[MAIN_ICON][STATUS_DISABLE_WOCQ];
387- m_hCurrentCursor = m_hCursor[STATUS_DISABLE_WOCQ];
307+ msg.nState = STATUS_DISABLE_WOCQ;
388308 }
389309 if (m_nSettingStyle[m_nApplicationID] == SETTING_DISABLE
390310 || (!_tcsicmp(m_szSpecialApp[m_nApplicationID], _T("Default"))
391311 && CUtils::IsDefaultIgnoreApplication())) {
392- m_stNtfyIcon[MAIN_ICON].hIcon = m_hIcon[MAIN_ICON][STATUS_DISABLE];
312+ msg.nState = STATUS_DISABLE;
393313 m_hCurrentCursor = m_hCursor[STATUS_DISABLE];
394314 }
395- DoShell_NotifyIcon(MAIN_ICON, NIM_MODIFY);
315+ SendIconMessage(&msg, 1);
396316 DoSetCursor();
397317 }
398318
@@ -792,9 +712,12 @@ void CXkeymacsDll::InitKeyboardProc(BOOL bImeComposition)
792712 }
793713 }
794714
795- ModifyShell_NotifyIcon(CX_ICON, FALSE);
796- ModifyShell_NotifyIcon(MX_ICON, FALSE);
797- ModifyShell_NotifyIcon(META_ICON, FALSE);
715+ ICONMSG msg[3] = {
716+ {CX_ICON, OFF_ICON, ""},
717+ {MX_ICON, OFF_ICON, ""},
718+ {META_ICON, OFF_ICON, ""}
719+ };
720+ SendIconMessage(msg, 3);
798721 CCommands::SetMark(FALSE);
799722 CCommands::SetTemporarilyDisableXKeymacs(FALSE);
800723 CCommands::Reset();
@@ -1025,13 +948,13 @@ LRESULT CALLBACK CXkeymacsDll::KeyboardProc(int nCode, WPARAM wParam, LPARAM lPa
1025948 if (index) {
1026949 --index;
1027950 memmove(&szPath[index], &szPath[index + 1], _tcslen(szPath) - index);
1028- ModifyM_xTip(szPath);
951+ SetM_xTip(szPath);
1029952 }
1030953 goto HOOKX;
1031954 } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::DeleteChar) {
1032955 if (index < _tcslen(szPath)) {
1033956 memmove(&szPath[index], &szPath[index + 1], _tcslen(szPath) - index);
1034- ModifyM_xTip(szPath);
957+ SetM_xTip(szPath);
1035958 }
1036959 goto HOOKX;
1037960 } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::EndOfLine) {
@@ -1065,7 +988,7 @@ LRESULT CALLBACK CXkeymacsDll::KeyboardProc(int nCode, WPARAM wParam, LPARAM lPa
1065988 }
1066989 szPath[index++] = nAscii;
1067990 // CUtils::Log("M-x: %c(%#04x)", nAscii, nAscii);
1068- ModifyM_xTip(szPath);
991+ SetM_xTip(szPath);
1069992 goto HOOKX;
1070993 }
1071994 }
@@ -1225,10 +1148,7 @@ RECURSIVE_COMMAND:
12251148 }
12261149
12271150 DO_NOTHING:
1228- ModifyShell_NotifyIcon(SHIFT_ICON, IsDown(VK_SHIFT));
1229- ModifyShell_NotifyIcon(CTRL_ICON, IsControl());
1230- ModifyShell_NotifyIcon(ALT_ICON, IsDown(VK_MENU));
1231-
1151+ SetModifierIcons();
12321152 {
12331153 static BOOL bDefiningMacro = FALSE;
12341154 if (m_bDefiningMacro) {
@@ -1271,22 +1191,31 @@ DO_NOTHING:
12711191
12721192 RECURSIVE:
12731193 Kdu(RECURSIVE_KEY, 1, FALSE);
1274- ModifyShell_NotifyIcon(SHIFT_ICON, IsDown(VK_SHIFT));
1275- ModifyShell_NotifyIcon(CTRL_ICON, IsControl());
1276- ModifyShell_NotifyIcon(ALT_ICON, IsDown(VK_MENU));
1277- return TRUE;
1278-
1194+ goto HOOKX;
12791195 HOOK:
12801196 CCommands::SetLastCommand(fCommand);
12811197 HOOK0_9:
12821198 HOOKX:
1283- ModifyShell_NotifyIcon(SHIFT_ICON, IsDown(VK_SHIFT));
1284- ModifyShell_NotifyIcon(CTRL_ICON, IsControl());
1285- ModifyShell_NotifyIcon(ALT_ICON, IsDown(VK_MENU));
1199+ SetModifierIcons();
12861200 HOOK_RECURSIVE_KEY:
12871201 return TRUE;
12881202 }
12891203
1204+void CXkeymacsDll::SetModifierIcons()
1205+{
1206+#define IconState(x) ((x) ? ON_ICON : OFF_ICON)
1207+ ICONMSG msg[6] = {
1208+ {MX_ICON, IconState(CCommands::bM_x()), ""},
1209+ {CX_ICON, IconState(CCommands::bC_x()), ""},
1210+ {META_ICON, IconState(CCommands::bM_()), ""},
1211+ {SHIFT_ICON, IconState(IsDown(VK_SHIFT)), ""},
1212+ {CTRL_ICON, IconState(IsControl()), ""},
1213+ {ALT_ICON, IconState(IsDown(VK_MENU)), ""}
1214+ };
1215+ _tcscpy_s(msg[0].szTip, m_M_xTip);
1216+ SendIconMessage(msg, 6);
1217+}
1218+
12901219 void CXkeymacsDll::SetApplicationName(int nApplicationID, CString szApplicationName)
12911220 {
12921221 ZeroMemory(m_szSpecialApp[nApplicationID], sizeof(m_szSpecialApp[nApplicationID]));
@@ -2088,20 +2017,6 @@ BYTE CXkeymacsDll::a2v(TCHAR nAscii)
20882017 }
20892018 }
20902019
2091-void CXkeymacsDll::DeleteAllShell_NotifyIcon()
2092-{
2093- for (int icon = 0; icon < MAX_ICON_TYPE; ++icon) {
2094- DeleteShell_NotifyIcon((ICON_TYPE)icon);
2095- }
2096-}
2097-
2098-void CXkeymacsDll::AddAllShell_NotifyIcon()
2099-{
2100- for (int icon = 0; icon < MAX_ICON_TYPE; ++icon) {
2101- AddShell_NotifyIcon((ICON_TYPE)icon);
2102- }
2103-}
2104-
21052020 BOOL CXkeymacsDll::IsMatchWindowText(CString szWindowText)
21062021 {
21072022 BOOL bIsMatchWindowText = TRUE;
@@ -2210,17 +2125,15 @@ void CXkeymacsDll::InvokeM_x(const TCHAR *const szPath)
22102125 }
22112126 }
22122127
2213-void CXkeymacsDll::ModifyM_xTip(const TCHAR *const szPath)
2128+void CXkeymacsDll::SetM_xTip(const TCHAR *const szPath)
22142129 {
2215- if (szPath) {
2216- if (_tcslen(szPath) < sizeof(m_stNtfyIcon[MX_ICON].szTip) / sizeof(m_stNtfyIcon[MX_ICON].szTip[0]) - 5) {
2217- memset(m_stNtfyIcon[MX_ICON].szTip, 0, sizeof(m_stNtfyIcon[MX_ICON].szTip));
2218- _stprintf(m_stNtfyIcon[MX_ICON].szTip, "M-x %s", szPath);
2219- }
2220- } else {
2221- memset(m_stNtfyIcon[MX_ICON].szTip, 0, sizeof(m_stNtfyIcon[MX_ICON].szTip));
2222- _stprintf(m_stNtfyIcon[MX_ICON].szTip, "M-x LED");
2223- }
2130+ _tcscpy_s(m_M_xTip, "M-x LED");
2131+ if (szPath && _tcslen(szPath) < 128 - 5)
2132+ _stprintf_s(m_M_xTip, "M-x %s", szPath);
2133+}
22242134
2225- ModifyShell_NotifyIcon(MX_ICON, CCommands::bM_x(), TRUE);
2135+BOOL CXkeymacsDll::SendIconMessage(ICONMSG *pMsg, DWORD num)
2136+{
2137+ DWORD ack, read;
2138+ return CallNamedPipe(ICON_PIPE, pMsg, sizeof(ICONMSG) * num, &ack, sizeof(DWORD), &read, NMPWAIT_NOWAIT);
22262139 }
--- a/xkeymacsdll/xkeymacsdll.h
+++ b/xkeymacsdll/xkeymacsdll.h
@@ -35,6 +35,8 @@ enum { EXTENDED_KEY = 0x01000000 };
3535 enum { REPEATED_KEY = 0x40000000 };
3636 enum { BEING_RELEASED = 0x80000000 };
3737
38+#include "ipc.h"
39+
3840 struct KeyBind
3941 {
4042 int nCommandType;
@@ -51,7 +53,7 @@ struct KeyName
5153 class AFX_EXT_CLASS CXkeymacsDll
5254 {
5355 public:
54- static void ModifyM_xTip(const TCHAR *const szPath);
56+ static void SetM_xTip(const TCHAR *const szPath);
5557 static BOOL Get326Compatible();
5658 static void Set326Compatible(int nApplicationID, BOOL b326Compatible);
5759 static void SetCursorData(HCURSOR hEnable, HCURSOR hDisableTMP, HCURSOR hDisableWOCQ, HICON hDisable, BOOL bEnable);
@@ -60,12 +62,7 @@ public:
6062 static int GetAccelerate(void);
6163 static void SetAccelerate(int nAccelerate);
6264 static void SetWindowText(int nApplicationID, CString szWindowText);
63- static void AddAllShell_NotifyIcon();
64- static void DeleteAllShell_NotifyIcon();
6565 static void SetKillRingMax(int nApplicationID, int nKillRingMax);
66- static void EnableShell_NotifyIcon(ICON_TYPE icon, BOOL bEnable);
67- static void SetNotifyIconData(ICON_TYPE icon, NOTIFYICONDATA stNtfyIcon, HICON hEnable, HICON hDisableTMP, HICON hDisableWOCQ, HICON hDisable, BOOL bEnable);
68- static void SetNotifyIconData(ICON_TYPE icon, NOTIFYICONDATA stNtfyIcon, HICON hOn, HICON hOff, BOOL bEnable);
6966 static void Clear(int nApplicationID);
7067 static BOOL IsKeyboardHook();
7168 static void SetCommandID(int nApplicationID, int nCommandType, int nKey, int nCommandID);
@@ -90,7 +87,6 @@ public:
9087 static void IncreaseKillRingIndex(int nKillRing = 1);
9188 static BOOL IsDown(BYTE bVk, BOOL bPhysicalKey = TRUE);
9289 static void Kdu(BYTE bVk, DWORD n = 1, BOOL bOriginal = TRUE);
93- static int ModifyShell_NotifyIcon(ICON_TYPE icon, BOOL bNewStatus, BOOL bForce = TRUE);
9490 static void ReleaseKey(BYTE bVk);
9591 static void SetFunctionDefinition(int nFunctionID, CString szDefinition);
9692 static void SetFunctionKey(int nFunctionID, int nApplicationID, int nCommandType, int nKey);
@@ -98,9 +94,11 @@ public:
9894 static void SetKeyboardHookFlag(BOOL bFlag);
9995 static BOOL Is106Keyboard();
10096 static void Set106Keyboard(BOOL b106Keyboard);
97+ static BOOL SendIconMessage(ICONMSG *pMsg, DWORD num);
10198 CXkeymacsDll();
10299 virtual ~CXkeymacsDll();
103100 private:
101+ static TCHAR m_M_xTip[128];
104102 static void InvokeM_x(const TCHAR* const szPath);
105103 static BOOL m_b326Compatible[MAX_APP];
106104 static void LogCallWndProcMessage(WPARAM wParam, LPARAM lParam);
@@ -118,11 +116,10 @@ private:
118116 static HHOOK m_hHookCallWnd;
119117 static HHOOK m_hHookGetMessage;
120118 static HHOOK m_hHookShell;
121- static void AddShell_NotifyIcon(ICON_TYPE icon);
122- static void DeleteShell_NotifyIcon(ICON_TYPE icon);
123119 static BOOL DefiningMacro();
124120 static BOOL IsControl();
125121 static BOOL IsMeta();
122+ static void SetModifierIcons();
126123 static void DoKeybd_event(BYTE bVk, DWORD dwFlags);
127124 static LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
128125 static LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam);
@@ -145,7 +142,6 @@ private:
145142 static BOOL m_bDefiningMacro;
146143 static void Original(int nCommandType, BYTE bVk, int nOriginal);
147144 static int Original(int nCommandType, BYTE bVk);
148- static HICON m_hIcon[MAX_ICON_TYPE][MAX_STATUS];
149145 static BOOL m_bUseDialogSetting[MAX_APP];
150146 static void InitKeyboardProc(BOOL bImeComposition);
151147 static BOOL m_bIgnoreUndefinedC_x[MAX_APP];
@@ -157,11 +153,6 @@ private:
157153 static CList<CClipboardSnap *, CClipboardSnap *> m_oKillRing;
158154 static int m_nKillRingMax[MAX_APP];
159155 static int GetMickey(int nDifferential, int nThreshold1, int nThreshold2, int nAcceleration, int nSpeed);
160- static BOOL DoShell_NotifyIcon(ICON_TYPE icon, DWORD dwMessage);
161- static BOOL m_bIcon[MAX_ICON_TYPE];
162- static DWORD m_dwOldMessage[MAX_ICON_TYPE];
163- static NOTIFYICONDATA m_stNtfyIcon[MAX_ICON_TYPE];
164- static NOTIFYICONDATA m_stOldNtfyIcon[MAX_ICON_TYPE];
165156 static BOOL m_bHook;
166157 static BOOL m_bRightShift;
167158 static BOOL m_bRightAlt;