📄 launcherdlg.cpp
字号:
//
// 儔儞僠儍乕僟僀傾儘僌僋儔僗
//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include <stdlib.h>
#include <mbstring.h>
#include <shlwapi.h>
#include <list>
#include <vector>
#include <string>
using namespace std;
#include "typedef.h"
#include "macro.h"
#include "VirtuaNESres.h"
#include "DebugOut.h"
#include "App.h"
#include "Pathlib.h"
#include "Crclib.h"
#include "Config.h"
#include "Archive.h"
#include "Wnd.h"
#include "LauncherDlg.h"
#include "rom.h"
#include "romdb.h"
// 儊僢僙乕僕
DLG_MESSAGE_BEGIN(CLauncherDlg)
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
DLG_ON_MESSAGE( WM_DESTROY, OnDestroy )
DLG_ON_MESSAGE( WM_CLOSE, OnClose )
DLG_ON_MESSAGE( WM_ACTIVATE, OnActivate )
DLG_ON_MESSAGE( WM_SETCURSOR, OnSetCursor )
DLG_ON_MESSAGE( WM_SIZE, OnSize )
DLG_ON_MESSAGE( WM_TIMER, OnTimer )
DLG_ON_MESSAGE( WM_INITMENUPOPUP, OnInitMenuPopup )
// 僐儅儞僪
DLG_COMMAND_BEGIN()
DLG_ON_COMMAND( IDOK, OnOK )
DLG_ON_COMMAND( IDCANCEL, OnCancel )
DLG_ON_COMMAND( ID_LCH_REFRESH, OnRefresh )
DLG_ON_COMMAND( ID_LCH_DISPEDIT, OnDispEdit )
DLG_ON_COMMAND( ID_LCH_HEADEREDIT, OnHeaderEdit )
DLG_ON_COMMAND( ID_LCH_FOLDER, OnFolder )
DLG_ON_COMMAND_RANGE( ID_LCH_LIST0, ID_LCH_LIST9, OnListSelect )
DLG_COMMAND_END()
// Notify 儊僢僙乕僕
DLG_NOTIFY_BEGIN()
DLG_ON_NOTIFY( IDC_LCH_LIST, LVN_KEYDOWN, OnKeyDownListView )
DLG_ON_NOTIFY( IDC_LCH_LIST, NM_RETURN, OnReturnListView )
DLG_ON_NOTIFY( IDC_LCH_LIST, NM_DBLCLK, OnDoubleClickListView )
DLG_ON_NOTIFY( IDC_LCH_LIST, LVN_COLUMNCLICK, OnColumnClickListView )
DLG_ON_NOTIFY( IDC_LCH_LIST, LVN_ITEMCHANGED, OnItemChangedListView )
DLG_NOTIFY_END()
DLG_MESSAGE_END()
// 僗僞僥傿僢僋儊儞僶
BOOL CLauncherDlg::m_bSortDir = FALSE;
INT CLauncherDlg::m_FileListNum = 0;
vector<FILELIST> CLauncherDlg::m_FileList;
CHAR CLauncherDlg::m_LaunchPath[_MAX_PATH];
#define LAUNCHHEADER_MAX 15
INT CLauncherDlg::m_HeaderID[] = {
IDS_LCH_FILENAME,
IDS_LCH_PATH,
IDS_LCH_MAPPER,
IDS_LCH_PRG,
IDS_LCH_CHR,
IDS_LCH_ALLCRC,
IDS_LCH_PRGCRC,
IDS_LCH_INFO,
IDS_LCH_DATABASE,
IDS_LCH_TITLE,
IDS_LCH_COUNTRY,
IDS_LCH_MANUFACTURER,
IDS_LCH_SALEDATE,
IDS_LCH_PRICE,
IDS_LCH_GENRE,
};
BOOL CLauncherDlg::Create( HWND hWndParent )
{
m_hImageList = NULL;
m_hImageListHdr = NULL;
// 恊偼僨僗僋僩僢僾偵偡傞
m_hWnd = ::CreateDialogParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_LAUNCHER),
NULL, g_DlgProc, (LPARAM)this );
if( !m_hWnd )
return FALSE;
// 儌乕僪儗僗僟僀傾儘僌儕僗僩偵壛偊傞
CWndList::Add( this );
return TRUE;
}
void CLauncherDlg::Destroy()
{
if( m_hWnd ) {
// 儌乕僪儗僗僟僀傾儘僌儕僗僩偐傜嶍彍
CWndList::Del( this );
HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_LCH_LIST );
INT i;
INT Order[16];
INT nCount = Header_GetItemCount( ListView_GetHeader( hWndCtrl ) );
ListView_GetColumnOrderArray( hWndCtrl, nCount, Order );
INT OrderTemp[16];
for( i = 0; i < LAUNCHHEADER_MAX; i++ ) {
OrderTemp[i] = Config.launcher.nHeaderOrder[i];
}
for( i = 0; i < nCount; i++ ) {
Config.launcher.nHeaderOrder[i] = OrderTemp[Order[i]];
Config.launcher.nHeaderWidth[Config.launcher.nHeaderOrder[i]] = ListView_GetColumnWidth( hWndCtrl, Order[i] );
}
OnUpdateStop();
::GetWindowRect( m_hWnd, &Config.launcher.rcWindowPos );
if( !m_FileListNum ) {
Config.launcher.szLastSelect[0] = '\0';
} else {
FILELIST& fl = m_FileList[m_SelectPos];
string Path = CPathlib::MakePath( fl.path.c_str(), fl.fname.c_str() );
::strcpy( Config.launcher.szLastSelect, Path.c_str() );
}
if( !m_bFileLoaded ) {
SaveFileList();
}
::DestroyWindow( m_hWnd );
m_hWnd = NULL;
}
}
INT CALLBACK CLauncherDlg::ListViewCompare( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort )
{
//DEBUGOUT( "L1:%08X L2:%08X PA:%d\n", lParam1, lParam2, lParamSort );
FILELIST& fl1 = m_FileList[lParam1];
FILELIST& fl2 = m_FileList[lParam2];
CHAR szTemp[_MAX_PATH];
string s1, s2;
INT n1, n2;
INT ret = 0;
switch( lParamSort ) {
case COLUMN_FILENAME:
#if 1
::strcpy( szTemp, fl1.fname.c_str() );
s1 = (CHAR*)::_mbsupr( (UCHAR*)szTemp );
::strcpy( szTemp, fl2.fname.c_str() );
s2 = (CHAR*)::_mbsupr( (UCHAR*)szTemp );
if( !Config.launcher.bSortDir ) {
ret = s1.compare( s2.c_str() );
} else {
ret = s2.compare( s1.c_str() );
}
#else
{
INT cmpresult = ::CompareString( LOCALE_USER_DEFAULT, NORM_IGNORECASE|NORM_IGNOREKANATYPE|NORM_IGNOREWIDTH,
fl1.fname.c_str(), fl1.fname.size(), fl2.fname.c_str(), fl1.fname.size() );
if( cmpresult == CSTR_LESS_THAN )
ret = -1;
if( cmpresult == CSTR_EQUAL )
ret = 0;
if( cmpresult == CSTR_GREATER_THAN )
ret = 1;
}
#endif
if( ret == 0 ) {
return ListViewCompare( lParam1, lParam2, COLUMN_PATH );
}
return ret;
case COLUMN_PATH:
::strcpy( szTemp, fl1.path.c_str() );
s1 = (CHAR*)::_mbsupr( (UCHAR*)szTemp );
::strcpy( szTemp, fl2.path.c_str() );
s2 = (CHAR*)::_mbsupr( (UCHAR*)szTemp );
if( !Config.launcher.bSortDir ) {
ret = s1.compare( s2.c_str() );
} else {
ret = s2.compare( s1.c_str() );
}
return ret;
case COLUMN_MAPPER:
n1 = fl1.mapper & 0x0FFF;
n2 = fl2.mapper & 0x0FFF;
goto _Compare_Num;
case COLUMN_PRG:
n1 = fl1.prg_size;
n2 = fl2.prg_size;
goto _Compare_Num;
case COLUMN_CHR:
n1 = fl1.chr_size;
n2 = fl2.chr_size;
goto _Compare_Num;
case COLUMN_ALLCRC:
n1 = fl1.crcall;
n2 = fl2.crcall;
goto _Compare_Num;
case COLUMN_PRGCRC:
n1 = fl1.crc;
n2 = fl2.crc;
goto _Compare_Num;
case COLUMN_INFO:
s1 = fl1.info;
s2 = fl2.info;
goto _Compare_Str;
case COLUMN_DB:
s1 = fl1.db;
s2 = fl2.db;
goto _Compare_Str;
case COLUMN_TITLE:
s1 = fl1.title;
s2 = fl2.title;
goto _Compare_Str;
case COLUMN_COUNTRY:
s1 = fl1.country;
s2 = fl2.country;
goto _Compare_Str;
case COLUMN_MANUFACTURER:
s1 = fl1.manufacturer;
s2 = fl2.manufacturer;
goto _Compare_Str;
case COLUMN_SALEDATE:
s1 = fl1.saledate;
s2 = fl2.saledate;
goto _Compare_Str;
case COLUMN_PRICE:
s1 = fl1.price;
s2 = fl2.price;
goto _Compare_Str;
case COLUMN_GENRE:
s1 = fl1.genre;
s2 = fl2.genre;
goto _Compare_Str;
_Compare_Num:
if( n1 == n2 ) {
return ListViewCompare( lParam1, lParam2, COLUMN_FILENAME );
}
if( !Config.launcher.bSortDir ) {
if( n1 < n2 ) ret = -1;
else ret = 1;
} else {
if( n1 < n2 ) ret = 1;
else ret = -1;
}
return ret;
_Compare_Str:
#if 1
::strcpy( szTemp, s1.c_str() );
s1 = (CHAR*)::_mbsupr( (UCHAR*)szTemp );
::strcpy( szTemp, s2.c_str() );
s2 = (CHAR*)::_mbsupr( (UCHAR*)szTemp );
if( !Config.launcher.bSortDir ) {
ret = s1.compare( s2.c_str() );
} else {
ret = s2.compare( s1.c_str() );
}
#else
{
INT cmpresult = ::CompareString( LOCALE_USER_DEFAULT, NORM_IGNORECASE|NORM_IGNOREKANATYPE|NORM_IGNOREWIDTH,
s1.c_str(), s1.size(), s2.c_str(), s2.size() );
if( cmpresult == CSTR_LESS_THAN )
ret = -1;
if( cmpresult == CSTR_EQUAL )
ret = 0;
if( cmpresult == CSTR_GREATER_THAN )
ret = 1;
}
#endif
if( ret == 0 ) {
return ListViewCompare( lParam1, lParam2, COLUMN_FILENAME );
}
return ret;
default:
break;
}
return 0;
}
void CLauncherDlg::ResetListViewHeader()
{
HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_LCH_LIST );
INT i;
for( i = 0; i < LAUNCHHEADER_MAX; i++ ) {
ListView_DeleteColumn( hWndCtrl, 0 );
}
LV_COLUMN lvColumn;
lvColumn.mask = LVCF_FMT|LVCF_TEXT|LVCF_SUBITEM|LVCF_WIDTH;
INT no = 0;
for( i = 0; i < LAUNCHHEADER_MAX; i++ ) {
if( Config.launcher.bHeaderView[Config.launcher.nHeaderOrder[i]] ) {
// if( Config.launcher.nHeaderOrder[i] >= 2 && Config.launcher.nHeaderOrder[i] <= 6 ) {
// lvColumn.fmt = LVCFMT_RIGHT;
// } else {
// lvColumn.fmt = LVCFMT_LEFT;
// }
lvColumn.fmt = LVCFMT_LEFT;
CHAR szStr[64];
CApp::LoadString( m_HeaderID[Config.launcher.nHeaderOrder[i]], szStr, sizeof(szStr) );
lvColumn.iSubItem = no;
lvColumn.pszText = szStr;
lvColumn.cx = Config.launcher.nHeaderWidth[Config.launcher.nHeaderOrder[i]];
ListView_InsertColumn( hWndCtrl, no, &lvColumn );
no++;
}
}
}
void CLauncherDlg::ResetListView()
{
HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_LCH_LIST );
ListView_DeleteAllItems( hWndCtrl );
FILELIST fl;
LVITEM lvitem;
lvitem.mask = LVIF_TEXT|LVIF_PARAM;
lvitem.iSubItem = 0;
lvitem.pszText = "";
::SendMessage( hWndCtrl, WM_SETREDRAW, (WPARAM)FALSE, 0 );
for( INT index = 0; index < m_FileListNum; index++ ) {
lvitem.iItem = index;
lvitem.lParam = (LPARAM)index;
ListView_InsertItem( hWndCtrl, &lvitem );
fl = m_FileList[index];
// 儕僗僩價儏乕傊偺僼傽僀儖忣曬偺愝掕
SetListView( index, fl );
}
::SendMessage( hWndCtrl, WM_SETREDRAW, (WPARAM)TRUE, 0 );
::InvalidateRect( hWndCtrl, NULL, TRUE );
}
void CLauncherDlg::SetListView( INT index, FILELIST& fl )
{
HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_LCH_LIST );
CHAR szStr[256];
INT RealOrder[16];
INT i;
for( i = 0; i < LAUNCHHEADER_MAX; i++ ) {
RealOrder[Config.launcher.nHeaderOrder[i]] = i;
}
szStr[0] = '\0';
// File name
if( Config.launcher.bHeaderView[0] ) {
ListView_SetItemText( hWndCtrl, index, RealOrder[0], (LPSTR)fl.fname.c_str() );
}
// Path
if( Config.launcher.bHeaderView[1] ) {
ListView_SetItemText( hWndCtrl, index, RealOrder[1], (LPSTR)fl.path.c_str() );
}
// Mapper
if( Config.launcher.bHeaderView[2] ) {
INT Mapper = fl.mapper & 0x0FFF;
INT image = 0;
if( Mapper == 20 ) {
::strcpy( szStr, "FDS" );
if( fl.mapper&0xF000 )
image = 4;
else
image = 3;
} else if( Mapper == 0x100 ) {
::strcpy( szStr, "NSF" );
image = 5;
} else if( Mapper > 0x100 ) {
::strcpy( szStr, "Unknown" );
image = 0;
} else {
::wsprintf( szStr, "%d", fl.mapper&0xFF );
if( fl.mapper&0xF000 )
image = 2;
else
image = 1;
}
ListView_SetItemText( hWndCtrl, index, RealOrder[2], szStr );
// Image(State)
ListView_SetItemState( hWndCtrl, index, INDEXTOSTATEIMAGEMASK(image+1), LVIS_STATEIMAGEMASK );
}
// PRG size
if( Config.launcher.bHeaderView[3] ) {
if( (fl.mapper&0x0FFF) == 20 ) {
// FDS
::wsprintf( szStr, "%d", fl.prg_size );
} else if( (fl.mapper&0x0FFF) == 0x100 ) {
// NSF
::wsprintf( szStr, "%d", fl.prg_size );
} else if( (fl.mapper&0x0FFF) < 0x100 ) {
// NES
::wsprintf( szStr, "%d", 16*fl.prg_size );
} else {
// Bad file
::strcpy( szStr, "0" );
}
ListView_SetItemText( hWndCtrl, index, RealOrder[3], szStr );
}
// CHR size
if( Config.launcher.bHeaderView[4] ) {
if( (fl.mapper&0x0FFF) == 0x100 ) {
// NSF
::wsprintf( szStr, "%d", fl.chr_size );
} else if( (fl.mapper&0x0FFF) < 0x100 ) {
// NES
::wsprintf( szStr, "%d", 8*fl.chr_size );
}
// ::wsprintf( szStr, "%d", 8*fl.chr_size );
ListView_SetItemText( hWndCtrl, index, RealOrder[4], szStr );
}
// CRC ALL
if( Config.launcher.bHeaderView[5] ) {
::wsprintf( szStr, "%08X", fl.crcall );
ListView_SetItemText( hWndCtrl, index, RealOrder[5], szStr );
}
// CRC
if( Config.launcher.bHeaderView[6] ) {
::wsprintf( szStr, "%08X", fl.crc );
ListView_SetItemText( hWndCtrl, index, RealOrder[6], szStr );
}
// Info
if( Config.launcher.bHeaderView[7] ) {
ListView_SetItemText( hWndCtrl, index, RealOrder[7], (LPSTR)fl.info.c_str() );
}
// DB
if( Config.launcher.bHeaderView[8] ) {
ListView_SetItemText( hWndCtrl, index, RealOrder[8], (LPSTR)fl.db.c_str() );
}
// TITLE
if( Config.launcher.bHeaderView[9] ) {
ListView_SetItemText( hWndCtrl, index, RealOrder[9], (LPSTR)fl.title.c_str() );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -