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