⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 launcherdlg.cpp

📁 著名的任天堂FC游戏机模拟器VirtuaNes 085版的源码!
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
// 儔儞僠儍乕僟僀傾儘僌僋儔僗
//
#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 + -