1 #include "stdafx.h"
2 #include "vba.h"
3 #include "AccelEditor.h"
4 #include "CmdAccelOb.h"
5 
6 #ifdef _DEBUG
7 #define new DEBUG_NEW
8 #undef THIS_FILE
9 static char THIS_FILE[] = __FILE__;
10 #endif
11 
12 /////////////////////////////////////////////////////////////////////////////
13 // AccelEditor dialog
14 
15 
AccelEditor(CWnd * pParent)16 AccelEditor::AccelEditor(CWnd* pParent /*=NULL*/)
17   : ResizeDlg(AccelEditor::IDD, pParent)
18 {
19   //{{AFX_DATA_INIT(AccelEditor)
20   // NOTE: the ClassWizard will add member initialization here
21   //}}AFX_DATA_INIT
22   mgr = theApp.winAccelMgr;
23 }
24 
25 
DoDataExchange(CDataExchange * pDX)26 void AccelEditor::DoDataExchange(CDataExchange* pDX)
27 {
28   CDialog::DoDataExchange(pDX);
29   //{{AFX_DATA_MAP(AccelEditor)
30   DDX_Control(pDX, IDC_CURRENTS, m_currents);
31   DDX_Control(pDX, IDC_ALREADY_AFFECTED, m_alreadyAffected);
32   DDX_Control(pDX, IDC_COMMANDS, m_commands);
33   DDX_Control(pDX, IDC_EDIT_KEY, m_key);
34   //}}AFX_DATA_MAP
35 }
36 
37 
BEGIN_MESSAGE_MAP(AccelEditor,CDialog)38 BEGIN_MESSAGE_MAP(AccelEditor, CDialog)
39   //{{AFX_MSG_MAP(AccelEditor)
40   ON_BN_CLICKED(ID_OK, OnOk)
41   ON_LBN_SELCHANGE(IDC_COMMANDS, OnSelchangeCommands)
42   ON_BN_CLICKED(IDC_RESET, OnReset)
43   ON_BN_CLICKED(IDC_ASSIGN, OnAssign)
44   ON_BN_CLICKED(ID_CANCEL, OnCancel)
45   ON_BN_CLICKED(IDC_REMOVE, OnRemove)
46   //}}AFX_MSG_MAP
47   END_MESSAGE_MAP()
48 
49   /////////////////////////////////////////////////////////////////////////////
50 // AccelEditor message handlers
51 
52 BOOL AccelEditor::OnInitDialog()
53 {
54   CDialog::OnInitDialog();
55 
56   DIALOG_SIZER_START( sz )
57     DIALOG_SIZER_ENTRY( IDC_STATIC1, DS_MoveX)
58     DIALOG_SIZER_ENTRY( IDC_STATIC2, DS_MoveY)
59     DIALOG_SIZER_ENTRY( IDC_STATIC3, DS_MoveX | DS_MoveY)
60     DIALOG_SIZER_ENTRY( IDC_ALREADY_AFFECTED, DS_MoveY)
61     DIALOG_SIZER_ENTRY( ID_OK, DS_MoveX)
62     DIALOG_SIZER_ENTRY( ID_CANCEL, DS_MoveX)
63     DIALOG_SIZER_ENTRY( IDC_ASSIGN, DS_MoveX)
64     DIALOG_SIZER_ENTRY( IDC_REMOVE, DS_MoveX)
65     DIALOG_SIZER_ENTRY( IDC_RESET, DS_MoveX)
66     DIALOG_SIZER_ENTRY( IDC_CLOSE, DS_MoveY)
67     DIALOG_SIZER_ENTRY( IDC_COMMANDS, DS_SizeX | DS_SizeY)
68     DIALOG_SIZER_ENTRY( IDC_CURRENTS, DS_MoveX | DS_SizeY)
69     DIALOG_SIZER_ENTRY( IDC_EDIT_KEY, DS_MoveX | DS_MoveY)
70     DIALOG_SIZER_END()
71 
72     SetData(sz,
73             TRUE,
74             HKEY_CURRENT_USER,
75             "Software\\Emulators\\VisualBoyAdvance\\Viewer\\AccelEditor",
76             NULL);
77 
78   InitCommands();
79 
80   return TRUE;  // return TRUE unless you set the focus to a control
81                 // EXCEPTION: OCX Property Pages should return FALSE
82 }
83 
InitCommands()84 void AccelEditor::InitCommands()
85 {
86   m_commands.ResetContent();
87   m_alreadyAffected.SetWindowText("");
88 
89   POSITION pos = mgr.m_mapAccelString.GetStartPosition();
90 
91   while(pos != NULL) {
92     CString command;
93     WORD wID;
94     mgr.m_mapAccelString.GetNextAssoc(pos, command, wID);
95 
96     int index = m_commands.AddString(command);
97     m_commands.SetItemData(index, wID);
98   }
99 
100   // Update the currents accels associated with the selected command
101   if (m_commands.SetCurSel(0) != LB_ERR)
102     OnSelchangeCommands();
103 }
104 
OnCancel()105 void AccelEditor::OnCancel()
106 {
107   EndDialog(FALSE);
108 }
109 
OnOk()110 void AccelEditor::OnOk()
111 {
112   EndDialog(TRUE);
113 }
114 
OnSelchangeCommands()115 void AccelEditor::OnSelchangeCommands()
116 {
117   // Check if some commands exist.
118   int index = m_commands.GetCurSel();
119   if (index == LB_ERR)
120     return;
121 
122   WORD wIDCommand = LOWORD(m_commands.GetItemData(index));
123   m_currents.ResetContent();
124 
125   CCmdAccelOb* pCmdAccel;
126 
127   if (mgr.m_mapAccelTable.Lookup(wIDCommand, pCmdAccel)) {
128     CAccelsOb* pAccel;
129     CString szBuffer;
130     POSITION pos = pCmdAccel->m_Accels.GetHeadPosition();
131 
132     // Add the keys to the 'currents keys' listbox.
133     while (pos != NULL) {
134       pAccel = pCmdAccel->m_Accels.GetNext(pos);
135       pAccel->GetString(szBuffer);
136       index = m_currents.AddString(szBuffer);
137       // and a pointer to the accel object.
138       m_currents.SetItemData(index, (DWORD_PTR)pAccel);
139     }
140   }
141   // Init the key editor
142   //  m_pKey->ResetKey();
143 
144 }
145 
OnReset()146 void AccelEditor::OnReset()
147 {
148   mgr.Default();
149   InitCommands(); // update the listboxes.
150 }
151 
OnAssign()152 void AccelEditor::OnAssign()
153 {
154   // Control if it's not already affected
155   CCmdAccelOb* pCmdAccel;
156   CAccelsOb* pAccel;
157   WORD wIDCommand;
158   POSITION pos;
159 
160   WORD wKey;
161   bool bCtrl, bAlt, bShift;
162 
163   if (!m_key.GetAccelKey(wKey, bCtrl, bAlt, bShift))
164     return; // no valid key, abort
165 
166   int count = m_commands.GetCount();
167   int index;
168   for (index = 0; index < count; index++) {
169 
170     wIDCommand = LOWORD(m_commands.GetItemData(index));
171     mgr.m_mapAccelTable.Lookup(wIDCommand, pCmdAccel);
172 
173     pos = pCmdAccel->m_Accels.GetHeadPosition();
174     while (pos != NULL) {
175       pAccel = pCmdAccel->m_Accels.GetNext(pos);
176       if (pAccel->IsEqual(wKey, bCtrl, bAlt, bShift)) {
177         // the key is already affected (in the same or other command)
178         m_alreadyAffected.SetWindowText(pCmdAccel->m_szCommand);
179         m_key.SetSel(0, -1);
180         return; // abort
181       }
182     }
183   }
184 
185   // OK, we can add the accel key in the currently selected group
186   index = m_commands.GetCurSel();
187   if (index == LB_ERR)
188     return;
189 
190   // Get the object who manage the accels list, associated to the command.
191   wIDCommand = LOWORD(m_commands.GetItemData(index));
192 
193   if (mgr.m_mapAccelTable.Lookup(wIDCommand, pCmdAccel) != TRUE)
194     return;
195 
196   BYTE cVirt = 0;
197   if (bCtrl)
198     cVirt |= FCONTROL;
199   if (bAlt)
200     cVirt |= FALT;
201   if (bShift)
202     cVirt |= FSHIFT;
203 
204   cVirt |= FVIRTKEY;
205 
206   // Create the new key...
207   pAccel = new CAccelsOb(cVirt, wKey, false);
208   ASSERT(pAccel != NULL);
209   // ...and add in the list.
210   pCmdAccel->m_Accels.AddTail(pAccel);
211 
212   // Update the listbox.
213   CString szBuffer;
214   pAccel->GetString(szBuffer);
215 
216   index = m_currents.AddString(szBuffer);
217   m_currents.SetItemData(index, (DWORD_PTR)pAccel);
218 
219   // Reset the key editor.
220   m_key.ResetKey();
221 }
222 
OnRemove()223 void AccelEditor::OnRemove()
224 {
225   // Some controls
226   int indexCurrent = m_currents.GetCurSel();
227   if (indexCurrent == LB_ERR)
228     return;
229 
230   // 2nd part.
231   int indexCmd = m_commands.GetCurSel();
232   if (indexCmd == LB_ERR)
233     return;
234 
235   // Ref to the ID command
236   WORD wIDCommand = LOWORD(m_commands.GetItemData(indexCmd));
237 
238   // Run through the accels,and control if it can be deleted.
239   CCmdAccelOb* pCmdAccel;
240   if (mgr.m_mapAccelTable.Lookup(wIDCommand, pCmdAccel) == TRUE) {
241     CAccelsOb* pAccel;
242     CAccelsOb* pAccelCurrent = (CAccelsOb*)(m_currents.GetItemData(indexCurrent));
243     CString szBuffer;
244     POSITION pos = pCmdAccel->m_Accels.GetHeadPosition();
245     POSITION PrevPos;
246     while (pos != NULL) {
247       PrevPos = pos;
248       pAccel = pCmdAccel->m_Accels.GetNext(pos);
249       if (pAccel == pAccelCurrent) {
250         if (!pAccel->m_bLocked) {
251           // not locked, so we delete the key
252           pCmdAccel->m_Accels.RemoveAt(PrevPos);
253           delete pAccel;
254           // and update the listboxes/key editor/static text
255           m_currents.DeleteString(indexCurrent);
256           m_key.ResetKey();
257           m_alreadyAffected.SetWindowText("");
258           return;
259         } else {
260           systemMessage(0,"Unable to remove this\naccelerator (Locked)");
261           return;
262         }
263       }
264     }
265     systemMessage(0,"internal error (CAccelDlgHelper::Remove : pAccel unavailable)");
266     return;
267   }
268   systemMessage(0,"internal error (CAccelDlgHelper::Remove : Lookup failed)");
269 }
270