1 // PropertiesAdvanced.cpp : implementation file
\r
5 #include "xkeymacs.h"
\r
6 #include "DotXkeymacs.h"
\r
8 #include "Properties.h"
\r
9 #include "PropertiesAdvanced.h"
\r
12 #define new DEBUG_NEW
\r
14 static char THIS_FILE[] = __FILE__;
\r
17 /////////////////////////////////////////////////////////////////////////////
\r
18 // CPropertiesAdvanced property page
\r
19 int CPropertiesAdvanced::m_nAppID = 0;
\r
20 int CPropertiesAdvanced::m_nCommandID = 0;
\r
21 CEdit * CPropertiesAdvanced::m_pNewKey = NULL;
\r
22 CButton * CPropertiesAdvanced::m_pAssign = NULL;
\r
23 CStatic * CPropertiesAdvanced::m_pCurrentlyAssigned = NULL;
\r
24 CListBox * CPropertiesAdvanced::m_pCurrentKeys = NULL;
\r
25 HHOOK CPropertiesAdvanced::m_hKeyboardHook = NULL;
\r
26 BOOL CPropertiesAdvanced::m_bC_x = FALSE;
\r
27 BOOL CPropertiesAdvanced::m_bC = TRUE;
\r
28 BOOL CPropertiesAdvanced::m_bM = TRUE;
\r
29 BOOL CPropertiesAdvanced::m_bShift = TRUE;
\r
30 int CPropertiesAdvanced::m_nAssignCommandType = 0;
\r
31 int CPropertiesAdvanced::m_nAssignKey = 0;
\r
32 int CPropertiesAdvanced::m_nCommandIDs[MAX_COMMAND_TYPE][MAX_KEY] = {'\0'};
\r
34 IMPLEMENT_DYNCREATE(CPropertiesAdvanced, CPropertyPage)
\r
36 CPropertiesAdvanced::CPropertiesAdvanced() : CPropertyPage(CPropertiesAdvanced::IDD)
\r
38 //{{AFX_DATA_INIT(CPropertiesAdvanced)
\r
39 m_bEnableCUA = FALSE;
\r
43 CPropertiesAdvanced::~CPropertiesAdvanced()
\r
47 void CPropertiesAdvanced::DoDataExchange(CDataExchange* pDX)
\r
49 CPropertyPage::DoDataExchange(pDX);
\r
50 //{{AFX_DATA_MAP(CPropertiesAdvanced)
\r
51 DDX_Control(pDX, IDC_CURRENTLY_ASSIGNED, m_cCurrentlyAssigned);
\r
52 DDX_Control(pDX, IDC_RESET_ALL, m_cResetAll);
\r
53 DDX_Control(pDX, IDC_REMOVE, m_cRemove);
\r
54 DDX_Control(pDX, IDC_NEW_KEY, m_cNewKey);
\r
55 DDX_Control(pDX, IDC_DESCRIPTION, m_cDescription);
\r
56 DDX_Control(pDX, IDC_CURRENT_KEYS, m_cCurrentKeys);
\r
57 DDX_Control(pDX, IDC_COMMANDS, m_cCommands);
\r
58 DDX_Control(pDX, IDC_CATEGORY, m_cCategory);
\r
59 DDX_Control(pDX, IDC_ASSIGN, m_cAssign);
\r
60 DDX_Check(pDX, IDC_ENABLE_CUA, m_bEnableCUA);
\r
65 BEGIN_MESSAGE_MAP(CPropertiesAdvanced, CPropertyPage)
\r
66 //{{AFX_MSG_MAP(CPropertiesAdvanced)
\r
68 ON_CBN_SELCHANGE(IDC_CATEGORY, OnSelchangeCategory)
\r
69 ON_LBN_SELCHANGE(IDC_COMMANDS, OnSelchangeCommands)
\r
70 ON_LBN_SELCHANGE(IDC_CURRENT_KEYS, OnSelchangeCurrentKeys)
\r
71 ON_EN_SETFOCUS(IDC_NEW_KEY, OnSetfocusNewKey)
\r
72 ON_BN_CLICKED(IDC_ASSIGN, OnAssign)
\r
73 ON_BN_CLICKED(IDC_REMOVE, OnRemove)
\r
74 ON_BN_CLICKED(IDC_RESET_ALL, OnResetAll)
\r
75 ON_BN_CLICKED(IDC_C_X, OnCX)
\r
76 ON_EN_KILLFOCUS(IDC_NEW_KEY, OnKillfocusNewKey)
\r
77 ON_BN_CLICKED(IDC_ENABLE_CUA, OnEnableCua)
\r
81 /////////////////////////////////////////////////////////////////////////////
\r
82 // CPropertiesAdvanced message handlers
\r
84 BOOL CPropertiesAdvanced::OnSetActive()
\r
86 m_pProperties->EnableControl(ADVANCED_TAB);
\r
89 return CPropertyPage::OnSetActive();
\r
92 void CPropertiesAdvanced::SetDialogData()
\r
94 m_nAppID = m_pProperties->GetApplicationID();
\r
95 if (m_nAppID == MAX_APP)
\r
98 m_bEnableCUA = CProfile::GetEnableCUA(m_nAppID);
\r
103 void CPropertiesAdvanced::GetDialogData()
\r
108 int CPropertiesAdvanced::OnCreate(LPCREATESTRUCT lpCreateStruct)
\r
110 if (CPropertyPage::OnCreate(lpCreateStruct) == -1)
\r
113 m_pProperties = (CProperties *)GetParent()->GetParent();
\r
118 BOOL CPropertiesAdvanced::OnKillActive()
\r
122 return CPropertyPage::OnKillActive();
\r
125 void CPropertiesAdvanced::EnableControl()
\r
127 BOOL bEnable = m_pProperties->IsEnableControl();
\r
129 m_cCategory.EnableWindow(bEnable);
\r
130 m_cCommands.EnableWindow(bEnable);
\r
131 m_cCurrentKeys.EnableWindow(bEnable);
\r
132 m_cNewKey.EnableWindow(bEnable);
\r
134 m_cAssign.EnableWindow(FALSE);
\r
135 m_cRemove.EnableWindow(FALSE);
\r
136 m_cResetAll.EnableWindow(bEnable);
\r
139 BOOL CPropertiesAdvanced::OnInitDialog()
\r
141 CPropertyPage::OnInitDialog();
\r
143 m_nAppID = m_pProperties->GetApplicationID();
\r
144 InitCategoryList();
\r
149 m_cAssign.EnableWindow(FALSE);
\r
150 m_cRemove.EnableWindow(FALSE);
\r
152 m_cCurrentlyAssigned.SetWindowText(_T(""));
\r
154 return TRUE; // return TRUE unless you set the focus to a control
\r
155 // EXCEPTION: OCX Property Pages should return FALSE
\r
158 void CPropertiesAdvanced::InitCategoryList()
\r
160 int nCategoryIDs[128] = {'\0'};
\r
162 // get all category type
\r
163 m_cCategory.ResetContent();
\r
164 for (int nComID = 1; nComID < MAX_COMMAND; ++nComID) {
\r
165 CString szCommandName = CCommands::GetCommandName(nComID);
\r
166 if (szCommandName.IsEmpty()) {
\r
169 int nCategoryID = CCommands::GetCategoryID(nComID);
\r
170 if (!nCategoryID) {
\r
174 BOOL bExist = FALSE;
\r
176 for (i = 0; nCategoryIDs[i]; ++i) {
\r
177 if (nCategoryIDs[i] == nCategoryID) {
\r
182 nCategoryIDs[i] = nCategoryID;
\r
186 // sort category type in combo box
\r
187 int nMinimumID = 0;
\r
188 for (int i = 0; nCategoryIDs[i]; ++i) {
\r
190 for (int j = 0; nCategoryIDs[j]; ++j) {
\r
191 if (nMinimumID < nCategoryIDs[j]
\r
192 && (nID == 0 || nCategoryIDs[j] < nID)) {
\r
193 nID = nCategoryIDs[j];
\r
196 m_cCategory.InsertString(-1, CString(MAKEINTRESOURCE(nID)));
\r
200 if (CDotXkeymacs::GetFunctionNumber()) {
\r
201 m_cCategory.InsertString(-1, CString(MAKEINTRESOURCE(IDS_ORIGINAL)));
\r
204 m_cCategory.SetCurSel(0);
\r
207 void CPropertiesAdvanced::SetCommands()
\r
209 m_cCommands.ResetContent();
\r
211 CString szCategory;
\r
212 m_cCategory.GetLBText(m_cCategory.GetCurSel(), szCategory);
\r
213 if (szCategory.Compare(CString(MAKEINTRESOURCE(IDS_ORIGINAL)))) {
\r
214 for (int nComID = 1; nComID < MAX_COMMAND; ++nComID) {
\r
215 CString szCommandName = CCommands::GetCommandName(nComID);
\r
216 if (szCommandName.IsEmpty()) {
\r
220 if (szCategory == CString(MAKEINTRESOURCE(CCommands::GetCategoryID(nComID)))) {
\r
221 m_cCommands.AddString(szCommandName);
\r
225 for (int nFuncID = 0; nFuncID < CDotXkeymacs::GetFunctionNumber(); ++nFuncID) {
\r
226 BOOL bOriginal = TRUE;
\r
227 for (int nComID = 1; nComID < MAX_COMMAND; ++nComID) {
\r
228 CString szCommandName = CCommands::GetCommandName(nComID);
\r
229 if (szCommandName.IsEmpty()) {
\r
233 if (szCommandName == CDotXkeymacs::GetFunctionSymbol(nFuncID)) {
\r
234 bOriginal = FALSE; // overwriting build-in keybindings
\r
239 m_cCommands.AddString(CDotXkeymacs::GetFunctionSymbol(nFuncID));
\r
244 m_cCommands.SetCurSel(0);
\r
248 void CPropertiesAdvanced::SetCurrentKeys()
\r
250 m_cCurrentKeys.ResetContent();
\r
251 m_cRemove.EnableWindow(FALSE);
\r
253 CString szCategory;
\r
254 m_cCategory.GetLBText(m_cCategory.GetCurSel(), szCategory);
\r
256 CString szCurrentCommandName;
\r
257 m_cCommands.GetText(m_cCommands.GetCurSel(), szCurrentCommandName);
\r
259 if (szCategory.Compare(CString(MAKEINTRESOURCE(IDS_ORIGINAL)))) {
\r
260 for (int nType = 0; nType < MAX_COMMAND_TYPE; ++nType) {
\r
261 for (int nKey = 0; nKey < MAX_KEY; ++nKey) {
\r
262 if (CCommands::GetCommandName(CProfile::GetCommandID(m_nAppID, nType, nKey)) == szCurrentCommandName) {
\r
264 sz.Format(_T("%s%s"), CProfile::CommandType2String(nType), CProfile::Key2String(nKey));
\r
265 m_cCurrentKeys.AddString(sz);
\r
270 CString szCommandName;
\r
271 for (int nComID = 0; nComID < MAX_COMMAND; ++nComID) {
\r
272 szCommandName = CCommands::GetCommandName(nComID);
\r
273 if (szCommandName.IsEmpty()) {
\r
276 if (szCommandName == szCurrentCommandName) {
\r
277 m_nCommandID = nComID;
\r
282 m_cDescription.SetWindowText(CString(MAKEINTRESOURCE(CCommands::GetDescriptionID(m_nCommandID))));
\r
284 // overwrite by original command's description if needed
\r
285 for (int nFuncID = 0; nFuncID < CDotXkeymacs::GetFunctionNumber(); ++nFuncID) {
\r
286 if (szCommandName == CDotXkeymacs::GetFunctionSymbol(nFuncID)) {
\r
287 m_cDescription.SetWindowText(CDotXkeymacs::GetFunctionDefinition(szCurrentCommandName));
\r
292 const int nIndex = CDotXkeymacs::GetIndex(szCurrentCommandName);
\r
293 for (int nKeyID = 0; nKeyID < CDotXkeymacs::GetKeyNumber(nIndex, m_nAppID); ++nKeyID) {
\r
296 CDotXkeymacs::GetKey(nIndex, m_nAppID, nKeyID, &nType, &nKey);
\r
299 sz.Format(_T("%s%s"), CProfile::CommandType2String(nType), CProfile::Key2String(nKey));
\r
300 m_cCurrentKeys.AddString(sz);
\r
303 m_cDescription.SetWindowText(CDotXkeymacs::GetFunctionDefinition(szCurrentCommandName));
\r
307 void CPropertiesAdvanced::OnSelchangeCategory()
\r
313 void CPropertiesAdvanced::OnSelchangeCommands()
\r
315 BOOL bEnableWindow = FALSE;
\r
316 CString szCurrentCommandName;
\r
317 m_cCommands.GetText(m_cCommands.GetCurSel(), szCurrentCommandName);
\r
318 if (szCurrentCommandName.CompareNoCase(_T("C-"))
\r
319 && szCurrentCommandName.CompareNoCase(_T("Meta for Alt"))
\r
320 && szCurrentCommandName.CompareNoCase(_T("Pass Through"))) {
\r
321 bEnableWindow = TRUE;
\r
323 GetDlgItem(IDC_C_X)->EnableWindow(bEnableWindow);
\r
324 m_bC = bEnableWindow;
\r
325 m_bM = bEnableWindow;
\r
326 m_bShift = bEnableWindow;
\r
332 void CPropertiesAdvanced::OnSelchangeCurrentKeys()
\r
334 TCHAR szKeyBind[128] = {'\0'};
\r
335 m_cCurrentKeys.GetText(m_cCurrentKeys.GetCurSel(), szKeyBind);
\r
336 CProfile::ReadKeyBind(m_nRemoveCommandType, m_nRemoveKey, szKeyBind);
\r
337 m_cRemove.EnableWindow();
\r
340 void CPropertiesAdvanced::OnSetfocusNewKey()
\r
342 m_pNewKey = &m_cNewKey;
\r
343 m_pAssign = &m_cAssign;
\r
344 m_pCurrentlyAssigned = &m_cCurrentlyAssigned;
\r
345 m_pCurrentKeys = &m_cCurrentKeys;
\r
346 m_hKeyboardHook = ::SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)CPropertiesAdvanced::KeyboardProc, NULL, AfxGetApp()->m_nThreadID);
\r
348 m_bC_x = IsDlgButtonChecked(IDC_C_X) && GetDlgItem(IDC_C_X)->IsWindowEnabled();
\r
351 void CPropertiesAdvanced::OnAssign()
\r
353 // Remove Current Setting
\r
354 CProfile::SetCommandID(m_nAppID, m_nAssignCommandType, m_nAssignKey, 0);
\r
355 SetCommandID(m_nAssignCommandType, m_nAssignKey, 0);
\r
356 CDotXkeymacs::RemoveKey(m_nAppID, m_nAssignCommandType, m_nAssignKey);
\r
358 // Assign New Setting
\r
360 szItem.Format(_T("%s%s"), CProfile::CommandType2String(m_nAssignCommandType), CProfile::Key2String(m_nAssignKey));
\r
361 if (m_cCurrentKeys.FindString(-1, szItem) == LB_ERR) { // This key bind has not assignd to the same command yet.
\r
362 CString szCategory;
\r
363 m_cCategory.GetLBText(m_cCategory.GetCurSel(), szCategory);
\r
365 if (szCategory.Compare(CString(MAKEINTRESOURCE(IDS_ORIGINAL)))) {
\r
366 CProfile::SetCommandID(m_nAppID, m_nAssignCommandType, m_nAssignKey, m_nCommandID);
\r
367 SetCommandID(m_nAssignCommandType, m_nAssignKey, m_nCommandID);
\r
369 CString szCurrentCommandName;
\r
370 m_cCommands.GetText(m_cCommands.GetCurSel(), szCurrentCommandName);
\r
371 CDotXkeymacs::SetKey(CDotXkeymacs::GetIndex(szCurrentCommandName), m_nAppID, m_nAssignCommandType, m_nAssignKey);
\r
373 m_cCurrentKeys.AddString(szItem);
\r
379 void CPropertiesAdvanced::OnRemove()
\r
381 CString szCategory;
\r
382 m_cCategory.GetLBText(m_cCategory.GetCurSel(), szCategory);
\r
384 if (szCategory.Compare(CString(MAKEINTRESOURCE(IDS_ORIGINAL)))) {
\r
385 CProfile::SetCommandID(m_nAppID, m_nRemoveCommandType, m_nRemoveKey, 0);
\r
386 SetCommandID(m_nRemoveCommandType, m_nRemoveKey, 0);
\r
388 CString szCurrentCommandName;
\r
389 m_cCommands.GetText(m_cCommands.GetCurSel(), szCurrentCommandName);
\r
390 CDotXkeymacs::RemoveKey(CDotXkeymacs::GetIndex(szCurrentCommandName), m_nAppID, m_nRemoveCommandType, m_nRemoveKey);
\r
393 m_cCurrentKeys.DeleteString(m_cCurrentKeys.GetCurSel());
\r
394 m_cRemove.EnableWindow(FALSE);
\r
395 m_nRemoveCommandType = 0;
\r
399 void CPropertiesAdvanced::OnResetAll()
\r
401 CProfile::LoadData();
\r
406 void CPropertiesAdvanced::ClearNewKey()
\r
408 m_cNewKey.SetWindowText(_T(""));
\r
409 m_cAssign.EnableWindow(FALSE);
\r
410 m_nAssignCommandType = 0;
\r
412 m_cCurrentlyAssigned.SetWindowText(_T(""));
\r
415 LRESULT CALLBACK CPropertiesAdvanced::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
\r
417 if (code < 0 || code == HC_NOREMOVE) {
\r
418 return ::CallNextHookEx(m_hKeyboardHook, code, wParam, lParam);
\r
421 if (lParam & BEING_RELEASED) { // Key Up
\r
422 } else { // Key Down
\r
425 if (lParam & EXTENDED_KEY) {
\r
426 wParam = VK_RCONTROL;
\r
428 wParam = VK_LCONTROL;
\r
432 if (lParam & EXTENDED_KEY) {
\r
439 if (lParam & EXTENDED_KEY) {
\r
440 wParam = VK_RSHIFT;
\r
442 wParam = VK_LSHIFT;
\r
448 m_nAssignKey = wParam;
\r
455 void CPropertiesAdvanced::SetNewKey()
\r
461 szNewKey += _T("Ctrl+X ");
\r
464 if (IsCtrlDown()) {
\r
465 szNewKey += _T("Ctrl+");
\r
468 if (IsMetaDown()) {
\r
469 szNewKey += _T("Meta+");
\r
472 if (IsShiftDown()) {
\r
473 szNewKey += _T("Shift+");
\r
477 m_nAssignCommandType = nType;
\r
479 szNewKey += CProfile::Key2String(m_nAssignKey);
\r
481 m_pNewKey->SetWindowText(szNewKey);
\r
485 BOOL bEnable = TRUE;
\r
487 && m_pCurrentKeys->FindString(-1, szNewKey) != LB_ERR) { // This key bind is already assigned.
\r
490 m_pAssign->EnableWindow(bEnable);
\r
493 if (m_pCurrentlyAssigned) {
\r
494 CString szCurrentlyAssigned(_T("Currently assigned to:\n"));
\r
496 if (m_nCommandIDs[m_nAssignCommandType][m_nAssignKey] || CDotXkeymacs::GetIndex(m_nAppID, m_nAssignCommandType, m_nAssignKey) == -1) {
\r
497 szCurrentlyAssigned += CCommands::GetCommandName(m_nCommandIDs[m_nAssignCommandType][m_nAssignKey]);
\r
499 szCurrentlyAssigned += CDotXkeymacs::GetFunctionSymbol(CDotXkeymacs::GetIndex(m_nAppID, m_nAssignCommandType, m_nAssignKey));
\r
501 m_pCurrentlyAssigned->SetWindowText(szCurrentlyAssigned);
\r
505 void CPropertiesAdvanced::SetCommandID(int nType, int nKey, int nComID)
\r
507 m_nCommandIDs[nType][nKey] = nComID;
\r
509 // Set C-x if it is needed.
\r
510 if ((nType & CONTROLX)) {
\r
511 // Get CommandID of C-x.
\r
512 int nCommandIDofC_x;
\r
513 for (nCommandIDofC_x = 0; nCommandIDofC_x < MAX_COMMAND; ++nCommandIDofC_x) {
\r
514 if (!_tcsicmp(CCommands::GetCommandName(nCommandIDofC_x), _T("C-x"))) {
\r
520 m_nCommandIDs[CONTROL]['X'] = nCommandIDofC_x;
\r
522 for (int i = 0; i < MAX_COMMAND_TYPE; ++i) { // i is command-type.
\r
523 if (!(i & CONTROLX)) {
\r
526 for (int j = 0; j < MAX_KEY; ++j) { // j is key.
\r
527 if (m_nCommandIDs[i][j]) {
\r
528 m_nCommandIDs[CONTROL]['X'] = nCommandIDofC_x; // needless
\r
533 m_nCommandIDs[CONTROL]['X'] = 0;
\r
538 void CPropertiesAdvanced::InitCommandIDs()
\r
540 for (int nType = 0; nType < MAX_COMMAND_TYPE; ++nType) {
\r
541 for (int nKey = 0; nKey < MAX_KEY; ++nKey) {
\r
542 SetCommandID(nType, nKey, CProfile::GetCommandID(m_nAppID, nType, nKey));
\r
547 void CPropertiesAdvanced::OnCX()
\r
549 if (m_nAssignKey) {
\r
550 OnSetfocusNewKey();
\r
555 void CPropertiesAdvanced::OnKillfocusNewKey()
\r
557 if (m_hKeyboardHook) {
\r
558 ::UnhookWindowsHookEx(m_hKeyboardHook);
\r
560 m_hKeyboardHook = NULL;
\r
563 void CPropertiesAdvanced::OnEnableCua()
\r
566 CProfile::SetEnableCUA(m_nAppID, m_bEnableCUA);
\r
569 BOOL CPropertiesAdvanced::IsCtrlDown()
\r
571 return m_bC && IsFooDown(CString(_T("C-")));
\r
574 BOOL CPropertiesAdvanced::IsMetaDown()
\r
576 return m_bM && IsFooDown(CString(_T("Meta for Alt")));
\r
579 BOOL CPropertiesAdvanced::IsShiftDown()
\r
583 && (GetKeyState(VK_SHIFT ) < 0
\r
584 || GetKeyState(VK_LSHIFT) < 0
\r
585 || GetKeyState(VK_RSHIFT) < 0);
\r
587 // return m_bShift && IsFooDown(CString("Foo"));
\r
590 BOOL CPropertiesAdvanced::IsFooDown(CString szCommandName)
\r
592 for (int nKey = 0; nKey < MAX_KEY; ++nKey) {
\r
593 if (CCommands::GetCommandName(CProfile::GetCommandID(0, NONE, nKey)) == szCommandName) { // FIXME
\r
594 if (GetKeyState(nKey) < 0) {
\r