rtoss - Blame information for rev 310

Subversion Repositories:
Rev:
Rev Author Line No. Line
280 roytam 1 // EncDlg.cpp : 实现文件
2 //
3  
4 #include "stdafx.h"
5 #include "PokemonRomViewer.h"
6 #include "EncDlg.h"
7  
8 // CEncDlg 对话框
9  
10 IMPLEMENT_DYNAMIC(CEncDlg, CBaseDialog)
11 CEncDlg::CEncDlg()
12 {
13         m_uTemplateId = CEncDlg::IDD;
14         m_dwSortOrder = 0;
15  
16         m_dwCurSel = -1;
17         m_dwCurEnc = -1;
18         m_dwCurPage = -1;
19         m_bFindEditChanged = FALSE;
20  
21         m_pageLand.m_szPageName = _T("陆上");
22         m_rgpPages[0] = &m_pageLand;
23  
24         m_pageWater.m_szPageName = _T("水上");
25         m_rgpPages[1] = &m_pageWater;
26  
27         m_pageStone.m_szPageName = _T("碎岩");
28         m_rgpPages[2] = &m_pageStone;
29  
30         m_pageFish.m_szPageName = _T("垂钓");
31         m_rgpPages[3] = &m_pageFish;
32 }
33  
34 CEncDlg::~CEncDlg()
35 {
36 }
37  
38 void CEncDlg::DoDataExchange(CDataExchange* pDX)
39 {
40         CBaseDialog::DoDataExchange(pDX);
41         DDX_Control(pDX, IDC_ENC_LIST, m_ctrlEncList);
42         DDX_Control(pDX, IDC_TAB, m_ctrlTab);
43         DDX_Control(pDX, IDC_CONFIRM, m_ctrlConfirm);
44 }
45  
46  
47 BEGIN_MESSAGE_MAP(CEncDlg, CBaseDialog)
48         ON_NOTIFY(LVN_ITEMCHANGED, IDC_ENC_LIST, OnLvnItemchangedEncList)
49         ON_BN_CLICKED(IDC_REFRESH, OnBnClickedRefresh)
50         ON_BN_CLICKED(IDC_CONFIRM, OnBnClickedConfirm)
51         ON_NOTIFY(TCN_SELCHANGE, IDC_TAB, OnTcnSelchangeTab)
52         ON_NOTIFY(HDN_ITEMCLICK, 0, OnHdnItemclickEncList)
53         ON_BN_CLICKED(IDC_ENC_FIND, OnBnClickedEncFind)
54         ON_EN_CHANGE(IDC_ENC_FIND_EDIT, OnEnChangeEncFindEdit)
55 END_MESSAGE_MAP()
56  
57  
58 // CEncDlg 消息处理程序
59 INT CALLBACK CEncDlg::EncListSortFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
60 {
61         INT             iResult = 0;
62         WORD    wAreaId1, wAreaId2;
63  
64         if(rom.m_bOpened)
65         {
66                 wAreaId1 = rom.m_pEncAddressList[lParam1].wAreaId;
67                 wAreaId2 = rom.m_pEncAddressList[lParam2].wAreaId;
68  
69                 switch(lParamSort)
70                 {
71                 case 0:
72                         iResult = (wAreaId1 & 0xFF) - (wAreaId2 & 0xFF);
73                         if(iResult == 0)
74                         {
75                                 iResult = (wAreaId1 & 0xFF00) - (wAreaId2 & 0xFF00);
76                         }
77                         break;
78  
79                 case 1:
80                         iResult = (INT)(lParam1 - lParam2);
81                         break;
82                 }
83         }
84  
85         return iResult;
86 }
87  
88 void CEncDlg::RefreshEncList()
89 {
90         DWORD   dwIndex, dwEncCount, dwListCount;
91         LVITEM  lvi;
92         WORD    wAreaId;
93         StringEntry *pStringEntry = NULL;
94         CString szText;
95         POSITION        pos;
96  
97         if(!rom.m_bOpened)
98                 return;
99  
100         dwEncCount = rom.GetEncCount();
101         dwListCount = m_ctrlEncList.GetItemCount();
102  
103         lvi.mask = LVIF_TEXT;
104  
105         for(dwIndex = 0; dwIndex < dwEncCount; ++dwIndex)
106         {
107                 lvi.iItem = dwIndex;
108  
109                 lvi.iSubItem = 0;
110                 wAreaId = rom.m_pEncAddressList[dwIndex].wAreaId;
310 roytam 111                 szText.Format(_T("%02d-%03d"), wAreaId & 0xFF, wAreaId >> 8 & 0xFF);
280 roytam 112  
113                 lvi.pszText = szText.GetBuffer();
114                 if(dwIndex < dwListCount)
115                         m_ctrlEncList.SetItem(&lvi);
116                 else
117                         m_ctrlEncList.InsertItem(&lvi);
118                 szText.ReleaseBuffer();
119  
120                 lvi.iSubItem = 1;
121                 pStringEntry = GetEncNameEntry(wAreaId);
122                 szText = pStringEntry ? pStringEntry->rgszText[cfg.dwLang] : _T("???");
123                 lvi.pszText = szText.GetBuffer();
124                 m_ctrlEncList.SetItem(&lvi);
125                 szText.ReleaseBuffer();
126  
127                 m_ctrlEncList.SetItemData(dwIndex, dwIndex);
128         }
129  
130         for(dwIndex = dwEncCount; dwIndex < dwListCount; ++dwIndex)
131         {
132                 m_ctrlEncList.DeleteItem(dwEncCount);
133         }
134  
135         m_ctrlEncList.SortItems(EncListSortFunc, m_dwSortOrder);
136  
137         pos = m_ctrlEncList.GetFirstSelectedItemPosition();
138         if(pos)
139         {
140                 m_dwCurSel = m_ctrlEncList.GetNextSelectedItem(pos);
141                 m_dwCurEnc = (DWORD)(m_ctrlEncList.GetItemData(m_dwCurSel));
142                 m_ctrlEncList.EnsureVisible(m_dwCurSel, FALSE);
143         }
144         else
145         {
146                 m_dwCurSel = -1;
147                 m_dwCurEnc = -1;
148         }
149 }
150  
151 void CEncDlg::OnConfigChanged(BOOL bRomChanged, BOOL bUILangChanged)
152 {
153         static DWORD dwPreRomVersion = -1;
154         BOOL    bChangeSortOrder = TRUE;
155         DWORD   dwRomVersion;
156         DWORD   dwIndex;
157         DWORD   dwListCount;
158  
159         if(!rom.m_bOpened)
160                 return;
161  
162         /////////////////////////////////////////////
163         // change sort order of enc list if necessary
164         if(bRomChanged)
165         {
166                 m_ctrlConfirm.EnableWindow(!rom.m_bIsFileReadOnly);
167  
168                 dwRomVersion = rom.GetRomVersion();
169  
170                 // if the new rom is the same as the previous rom, then there's no need to sort enc list
171                 if(dwRomVersion >= CPokemonRom::rom_ruby_jp && dwRomVersion <= CPokemonRom::rom_sapphire_en &&
172                         dwPreRomVersion >= CPokemonRom::rom_ruby_jp && dwPreRomVersion <= CPokemonRom::rom_sapphire_en)
173                 {
174                         bChangeSortOrder = FALSE;
175                 }
176                 else if(dwRomVersion >= CPokemonRom::rom_fire_jp && dwRomVersion <= CPokemonRom::rom_leaf_en &&
177                         dwPreRomVersion >= CPokemonRom::rom_fire_jp && dwPreRomVersion <= CPokemonRom::rom_leaf_en)
178                 {
179                         bChangeSortOrder = FALSE;
180                 }
181                 else if(dwRomVersion == CPokemonRom::rom_emerald_jp &&
182                                 dwPreRomVersion == CPokemonRom::rom_emerald_jp)
183                 {
184                         bChangeSortOrder = FALSE;
185                 }
186  
187                 dwPreRomVersion = dwRomVersion;
188  
189                 /////////////////////////////////////////
190                 // check for sanity
191                 dwListCount = m_ctrlEncList.GetItemCount();
192                 if(!bChangeSortOrder)
193                 {
194                         if(m_dwCurEnc >= dwListCount)
195                         {
196                                 // this is no necessary, but good for preventing errors
197                                 bChangeSortOrder = TRUE;
198                         }
199                 }
200  
201                 /////////////////////////////////////////
202                 // change sort order: use the default order
203                 if(bChangeSortOrder)
204                         m_dwSortOrder = 0;
205         }
206  
207         /////////////////////////////////////////////
208         // refresh enc list
209         RefreshEncList();
210  
211         if(bRomChanged)
212         {
213                 if(!bChangeSortOrder)
214                 {
215                         // this is no necessary, but good for preventing errors
216                         m_dwCurEnc = (DWORD)(m_ctrlEncList.GetItemData(m_dwCurSel));
217                 }
218                 else
219                 {
220                         // unselect previous selection (this prevents getting data from controls)
221                         if(m_dwCurSel < dwListCount)
222                                 m_ctrlEncList.SetItemState(m_dwCurSel, 0, LVIS_SELECTED | LVIS_FOCUSED);
223  
224                         // select the first item in enc list
225                         m_dwCurSel = -1;
226                         m_dwCurEnc = -1;
227                         m_ctrlEncList.SetItemState(0, -1, LVIS_SELECTED | LVIS_FOCUSED);
228  
229                         m_ctrlEncList.EnsureVisible(m_dwCurSel, FALSE);
230                 }
231         }
232  
233         /////////////////////////////////////////////
234         // refresh each page
235         for(dwIndex = 0; dwIndex < ENC_PAGE_COUNT; ++dwIndex)
236         {
237                 m_rgpPages[dwIndex]->OnConfigChanged(bRomChanged, bUILangChanged);
238         }
239  
240         /////////////////////////////////////////////
241         // show the 1st page if no page is showing
242         if(m_dwCurPage >= ENC_PAGE_COUNT)
243                 ShowTabPage(0);
244 }
245  
246 BOOL CEncDlg::OnInitDialog()
247 {
248         CBaseDialog::OnInitDialog();
249  
250         // TODO:  在此添加额外的初始化
251         DWORD   dwIndex;
252         RECT    rect;
253  
254         for(dwIndex = 0; dwIndex < ENC_PAGE_COUNT; ++dwIndex)
255         {
256                 m_ctrlTab.InsertItem(dwIndex, m_rgpPages[dwIndex]->m_szPageName);
257         }
258  
259         m_ctrlTab.GetWindowRect(&rect);
260         m_ctrlTab.AdjustRect(FALSE, &rect);
261         m_ctrlTab.ScreenToClient(&rect);
262  
263         for(dwIndex = 0; dwIndex < ENC_PAGE_COUNT; ++dwIndex)
264         {
265                 m_rgpPages[dwIndex]->Create(m_rgpPages[dwIndex]->m_uTemplateId, &m_ctrlTab);
266                 m_rgpPages[dwIndex]->ShowWindow(SW_HIDE);
267                 m_rgpPages[dwIndex]->MoveWindow(&rect);
268         }
269  
270         m_ctrlEncList.InsertColumn(0, _T("编号"), LVCFMT_LEFT, 50, 0);
271         m_ctrlEncList.InsertColumn(1, _T("地区名称"), LVCFMT_LEFT, 200, 1);
272         m_ctrlEncList.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_HEADERDRAGDROP | LVS_EX_LABELTIP);
273  
274         return TRUE;  // return TRUE unless you set the focus to a control
275         // 异常: OCX 属性页应返回 FALSE
276 }
277  
278 void CEncDlg::ShowTabPage(DWORD dwIndex)
279 {
280         DWORD * pdwAddress = NULL;
281  
282         if(!rom.m_bOpened)
283                 return;
284  
285         pdwAddress = &(rom.m_pEncAddressList[m_dwCurEnc].dwLandEncAddress);
286  
287         if(m_dwCurPage < ENC_PAGE_COUNT &&
288                 (m_dwCurPage != dwIndex || pdwAddress[m_dwCurPage] == 0))
289         {
290                 m_rgpPages[m_dwCurPage]->ShowWindow(SW_HIDE);
291         }
292  
293         m_dwCurPage = dwIndex;
294  
295         if(m_dwCurPage < ENC_PAGE_COUNT)
296         {
297                 if(pdwAddress[m_dwCurPage] == 0)
298                         m_rgpPages[m_dwCurPage]->ShowWindow(SW_HIDE);
299                 else
300                         m_rgpPages[m_dwCurPage]->ShowWindow(SW_SHOW);
301         }
302 }
303  
304 void CEncDlg::TransData(BOOL bToControls)
305 {
306         DWORD   dwIndex;
307  
308         if(!rom.m_bOpened)
309                 return;
310  
311         if(bToControls)
312         {
313                 SetTabPageNames();
314         }
315  
316         for(dwIndex = 0; dwIndex < ENC_PAGE_COUNT; ++dwIndex)
317         {
318                 m_rgpPages[dwIndex]->TransData(bToControls);
319         }
320  
321         if(bToControls)
322         {
323                 ShowTabPage(m_dwCurPage);
324         }
325 }
326  
327 void CEncDlg::SetTabPageNames()
328 {
329         DWORD   dwIndex;
330         DWORD * pdwAddress = NULL;
331         TCITEM  tci;
332  
333         if(!rom.m_bOpened)
334                 return;
335  
336         tci.mask = TCIF_TEXT;
337  
338         pdwAddress = &(rom.m_pEncAddressList[m_dwCurEnc].dwLandEncAddress);
339         for(dwIndex = 0; dwIndex < ENC_PAGE_COUNT; ++dwIndex)
340         {
341                 if(pdwAddress[dwIndex])
342                 {
343                         tci.pszText = const_cast<LPTSTR>(m_rgpPages[dwIndex]->m_szPageName);
344                 }
345                 else
346                 {
347                         tci.pszText = _T("没有");
348                 }
349  
350                 m_ctrlTab.SetItem(dwIndex, &tci);
351         }
352  
353         if(m_dwCurPage < ENC_PAGE_COUNT)
354         {
355                 m_rgpPages[m_dwCurPage]->RedrawWindow();
356         }
357 }
358  
359 void CEncDlg::OnLvnItemchangedEncList(NMHDR *pNMHDR, LRESULT *pResult)
360 {
361         LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
362         // TODO: 在此添加控件通知处理程序代码
363         *pResult = 0;
364  
365         if(!rom.m_bOpened)
366                 return;
367  
368         DWORD   dwEncCount = rom.GetEncCount();
369  
370         if((pNMLV->uNewState & (LVIS_SELECTED | LVIS_FOCUSED)) &&
371                 pNMLV->iItem != m_dwCurSel)
372         {
373                 if(m_dwCurSel < dwEncCount)
374                 {
375                         TransData(FALSE);
376                 }
377  
378                 m_dwCurSel = pNMLV->iItem;
379  
380                 if(m_dwCurSel < dwEncCount)
381                 {
382                         m_dwCurEnc = (DWORD)(m_ctrlEncList.GetItemData(m_dwCurSel));
383                         TransData(TRUE);
384                 }
385                 else
386                 {
387                         m_dwCurEnc = -1;
388                 }
389         }
390 }
391  
392 void CEncDlg::OnBnClickedRefresh()
393 {
394         // TODO: 在此添加控件通知处理程序代码
395         if(!rom.ReadEncList())
396         {
397                 AfxMessageBox(IDS_ERR_ROM_READ);
398         }
399         else
400         {
401                 TransData(TRUE);
402         }
403 }
404  
405 void CEncDlg::OnBnClickedConfirm()
406 {
407         // TODO: 在此添加控件通知处理程序代码
408         TransData(FALSE);
409  
410         if(!rom.SaveEncList())
411         {
412                 AfxMessageBox(IDS_ERR_ROM_WRITE);
413         }
414 }
415  
416 void CEncDlg::OnTcnSelchangeTab(NMHDR *pNMHDR, LRESULT *pResult)
417 {
418         // TODO: 在此添加控件通知处理程序代码
419         *pResult = 0;
420  
421         ShowTabPage(m_ctrlTab.GetCurSel());
422 }
423  
424 void CEncDlg::OnHdnItemclickEncList(NMHDR *pNMHDR, LRESULT *pResult)
425 {
426         LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
427         // TODO: 在此添加控件通知处理程序代码
428         *pResult = 0;
429  
430         if(!rom.m_bOpened ||
431                 phdr->iItem == 1)       // 地区名称
432                 return;
433  
434         m_dwSortOrder = (m_dwSortOrder + 1) & 1;
435         m_ctrlEncList.SortItems(EncListSortFunc, m_dwSortOrder);
436  
437         POSITION        pos;
438         DWORD           dwCurSel;
439  
440         pos = m_ctrlEncList.GetFirstSelectedItemPosition();
441         if(pos)
442         {
443                 dwCurSel = m_ctrlEncList.GetNextSelectedItem(pos);
444                 m_ctrlEncList.EnsureVisible(dwCurSel, FALSE);
445                 m_dwCurSel = dwCurSel;
446                 m_dwCurEnc = (DWORD)(m_ctrlEncList.GetItemData(m_dwCurSel));
447         }
448         else
449         {
450                 m_dwCurSel = -1;
451                 m_dwCurEnc = -1;
452         }
453 }
454  
455 BOOL CEncDlg::FindBreedInEnc(WORD wBreed, DWORD dwEncIndex, DWORD &dwEncType, DWORD &dwEncEntryIndex)
456 {
457         BOOL    bFound = FALSE;
458         DWORD   dwEncEntryCount;
459         EncEntry *      pEncEntryList = NULL;
460  
461         if(rom.m_bOpened && wBreed > 0 && wBreed < BREED_COUNT)
462         {
463                 for(; dwEncType < ENC_PAGE_COUNT; ++dwEncType)
464                 {
465                         pEncEntryList = rom.GetEncList(dwEncIndex, dwEncType);
466                         if(pEncEntryList)
467                         {
468                                 dwEncEntryCount = rom.GetEncListEntryCount(dwEncType);
469                                 for(; dwEncEntryIndex < dwEncEntryCount; ++dwEncEntryIndex)
470                                 {
471                                         if(pEncEntryList[dwEncEntryIndex].wBreed == wBreed)
472                                         {
473                                                 bFound = TRUE;
474                                                 break;
475                                         }
476                                 }
477  
478                         }
479  
480                         if(bFound)
481                                 break;
482                         else
483                                 dwEncEntryIndex = 0;
484                 }
485         }
486  
487         return bFound;
488 }
489  
490 void CEncDlg::OnEnChangeEncFindEdit()
491 {
492         // TODO:  在此添加控件通知处理程序代码
493         m_bFindEditChanged = TRUE;
494 }
495  
496 void CEncDlg::OnBnClickedEncFind()
497 {
498         // TODO: 在此添加控件通知处理程序代码
499         static WORD wBreed = 0;
500         DWORD   dwItemCount, dwItemIndex;
501         DWORD   dwEncIndex, dwPageIndex, dwEncEntryCount, dwEncEntryIndex;
502  
503         if(m_bFindEditChanged)
504         {
505                 CString szText;
506  
507                 GetDlgItemText(IDC_ENC_FIND_EDIT, szText);
508                 szText.Trim();
509                 wBreed = TextToBreed(szText);
510  
511                 m_bFindEditChanged = FALSE;
512         }
513  
514         dwItemCount = rom.GetEncCount();
515         dwPageIndex = m_dwCurPage;
516  
517         dwEncEntryCount = rom.GetEncListEntryCount(dwPageIndex);
518         dwEncEntryIndex = m_rgpPages[dwPageIndex]->m_dwFocusedEntry + 1;
519         if(dwEncEntryIndex >= dwEncEntryCount)
520         {
521                 ++dwPageIndex;
522                 dwEncEntryIndex = 0;
523         }
524  
525         for(dwItemIndex = m_dwCurSel; dwItemIndex < dwItemCount; ++dwItemIndex)
526         {
527                 dwEncIndex = (DWORD)(m_ctrlEncList.GetItemData(dwItemIndex));
528                 if(FindBreedInEnc(wBreed, dwEncIndex, dwPageIndex, dwEncEntryIndex))
529                 {
530                         m_ctrlEncList.SetItemState(dwItemIndex, -1, LVIS_SELECTED | LVIS_FOCUSED);
531                         m_ctrlEncList.EnsureVisible(dwItemIndex, FALSE);
532                         m_ctrlTab.SetCurSel(dwPageIndex);
533                         ShowTabPage(dwPageIndex);
534                         m_rgpPages[dwPageIndex]->SetFocusedEntry(dwEncEntryIndex);
535                         break;
536                 }
537                 dwPageIndex = 0;
538                 dwEncEntryIndex = 0;
539         }
540         if(dwItemIndex >= dwItemCount)
541                 MessageBox(_T("搜索完毕!"), _T("查找"), MB_OK | MB_ICONINFORMATION);
542 }