added features to package manager, and renamed "Skins" dir to "NoteSkins"
This commit is contained in:
@@ -1,3 +1,15 @@
|
|||||||
|
------------------------CVS after 3.00 beta 6----------------
|
||||||
|
NEW FEATURE: Package Exporter now can export Announcers, BGAnimations,
|
||||||
|
Courses, NoteSkins, RandomMovies, Themes, and Visualizations.
|
||||||
|
NEW FEATURE: Package Exporter now has two options: "Export As One", and
|
||||||
|
"Export As Individual". Export As One will create a package of all
|
||||||
|
selected items, and Export As Individual will create packages for each
|
||||||
|
of the selected items.
|
||||||
|
CHANGE: Renamed "Skins" folder to "NoteSkins" to avoid confusion with DWI
|
||||||
|
and KIU.
|
||||||
|
NEW FEATURE: F6 during gameplay to toggle assist tick.
|
||||||
|
CHANGE: While AutoPlay is ON, life will not change and score/dance points
|
||||||
|
will not accumulate.
|
||||||
NEW FEATURE: Song list can handle any number of groups.
|
NEW FEATURE: Song list can handle any number of groups.
|
||||||
BUG FIX: Fix joystick Y axis.
|
BUG FIX: Fix joystick Y axis.
|
||||||
NEW FEATURE: Add level 8 judge difficulty.
|
NEW FEATURE: Add level 8 judge difficulty.
|
||||||
|
|||||||
@@ -119,13 +119,15 @@ void Background::LoadFromSong( Song* pSong )
|
|||||||
m_BackgroundMode = MODE_ANIMATIONS;
|
m_BackgroundMode = MODE_ANIMATIONS;
|
||||||
|
|
||||||
|
|
||||||
|
const CString sSongBackgroundPath = sSongBackgroundPath;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Load the static background that will before notes start and after notes end
|
// Load the static background that will before notes start and after notes end
|
||||||
//
|
//
|
||||||
BackgroundAnimation* pTempBGA;
|
BackgroundAnimation* pTempBGA;
|
||||||
|
|
||||||
pTempBGA = new BackgroundAnimation;
|
pTempBGA = new BackgroundAnimation;
|
||||||
pTempBGA->LoadFromStaticGraphic( pSong->HasBackground() ? pSong->GetBackgroundPath() : THEME->GetPathTo("Graphics","fallback background") );
|
pTempBGA->LoadFromStaticGraphic( sSongBackgroundPath );
|
||||||
m_BackgroundAnimations.Add( pTempBGA );
|
m_BackgroundAnimations.Add( pTempBGA );
|
||||||
|
|
||||||
|
|
||||||
@@ -153,7 +155,7 @@ void Background::LoadFromSong( Song* pSong )
|
|||||||
if( asFiles.GetSize() > 0 )
|
if( asFiles.GetSize() > 0 )
|
||||||
{
|
{
|
||||||
pTempBGA = new BackgroundAnimation;
|
pTempBGA = new BackgroundAnimation;
|
||||||
pTempBGA->LoadFromMovie( asFiles[0], true, true );
|
pTempBGA->LoadFromMovie( asFiles[0], true, true, i==0/*first BGChange*/, sSongBackgroundPath );
|
||||||
m_BackgroundAnimations.Add( pTempBGA );
|
m_BackgroundAnimations.Add( pTempBGA );
|
||||||
|
|
||||||
m_aBGSegments.Add( BGSegment(aniseg.m_fStartBeat, m_BackgroundAnimations.GetSize()-1) ); // add to the plan
|
m_aBGSegments.Add( BGSegment(aniseg.m_fStartBeat, m_BackgroundAnimations.GetSize()-1) ); // add to the plan
|
||||||
@@ -165,7 +167,7 @@ void Background::LoadFromSong( Song* pSong )
|
|||||||
if( asFiles.GetSize() > 0 )
|
if( asFiles.GetSize() > 0 )
|
||||||
{
|
{
|
||||||
pTempBGA = new BackgroundAnimation;
|
pTempBGA = new BackgroundAnimation;
|
||||||
pTempBGA->LoadFromAniDir( asFiles[0], pSong->HasBackground() ? pSong->GetBackgroundPath() : THEME->GetPathTo("Graphics","fallback background") );
|
pTempBGA->LoadFromAniDir( asFiles[0], sSongBackgroundPath );
|
||||||
m_BackgroundAnimations.Add( pTempBGA );
|
m_BackgroundAnimations.Add( pTempBGA );
|
||||||
|
|
||||||
m_aBGSegments.Add( BGSegment(aniseg.m_fStartBeat, m_BackgroundAnimations.GetSize()-1) ); // add to the plan
|
m_aBGSegments.Add( BGSegment(aniseg.m_fStartBeat, m_BackgroundAnimations.GetSize()-1) ); // add to the plan
|
||||||
@@ -179,7 +181,7 @@ void Background::LoadFromSong( Song* pSong )
|
|||||||
if( asFiles.GetSize() > 0 )
|
if( asFiles.GetSize() > 0 )
|
||||||
{
|
{
|
||||||
pTempBGA = new BackgroundAnimation;
|
pTempBGA = new BackgroundAnimation;
|
||||||
pTempBGA->LoadFromMovie( asFiles[0], true, false );
|
pTempBGA->LoadFromMovie( asFiles[0], true, false, i==0/*first BGChange*/, sSongBackgroundPath );
|
||||||
m_BackgroundAnimations.Add( pTempBGA );
|
m_BackgroundAnimations.Add( pTempBGA );
|
||||||
|
|
||||||
m_aBGSegments.Add( BGSegment(aniseg.m_fStartBeat, m_BackgroundAnimations.GetSize()-1) ); // add to the plan
|
m_aBGSegments.Add( BGSegment(aniseg.m_fStartBeat, m_BackgroundAnimations.GetSize()-1) ); // add to the plan
|
||||||
@@ -191,18 +193,20 @@ void Background::LoadFromSong( Song* pSong )
|
|||||||
if( asFiles.GetSize() > 0 )
|
if( asFiles.GetSize() > 0 )
|
||||||
{
|
{
|
||||||
pTempBGA = new BackgroundAnimation;
|
pTempBGA = new BackgroundAnimation;
|
||||||
pTempBGA->LoadFromAniDir( asFiles[0], pSong->HasBackground() ? pSong->GetBackgroundPath() : THEME->GetPathTo("Graphics","fallback background") );
|
pTempBGA->LoadFromAniDir( asFiles[0], sSongBackgroundPath );
|
||||||
m_BackgroundAnimations.Add( pTempBGA );
|
m_BackgroundAnimations.Add( pTempBGA );
|
||||||
|
|
||||||
m_aBGSegments.Add( BGSegment(aniseg.m_fStartBeat, m_BackgroundAnimations.GetSize()-1) ); // add to the plan
|
m_aBGSegments.Add( BGSegment(aniseg.m_fStartBeat, m_BackgroundAnimations.GetSize()-1) ); // add to the plan
|
||||||
continue; // stop looking for this background
|
continue; // stop looking for this background
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if we make it here, ignore the background change
|
||||||
}
|
}
|
||||||
|
|
||||||
// end showing the static song background
|
// end showing the static song background
|
||||||
m_aBGSegments.Add( BGSegment(pSong->m_fLastBeat,0) );
|
m_aBGSegments.Add( BGSegment(pSong->m_fLastBeat,0) );
|
||||||
|
|
||||||
SortBGSegmentArray( m_aBGSegments ); // Need to sort in case the song has a background change after the last beat
|
SortBGSegmentArray( m_aBGSegments ); // Need to sort in case there is a background change after the last beat (not likely)
|
||||||
}
|
}
|
||||||
else // pSong doesn't have an animation plan
|
else // pSong doesn't have an animation plan
|
||||||
{
|
{
|
||||||
@@ -230,7 +234,7 @@ void Background::LoadFromSong( Song* pSong )
|
|||||||
{
|
{
|
||||||
int index = rand() % arrayPossibleMovies.GetSize();
|
int index = rand() % arrayPossibleMovies.GetSize();
|
||||||
pTempBGA = new BackgroundAnimation;
|
pTempBGA = new BackgroundAnimation;
|
||||||
pTempBGA->LoadFromVisualization( arrayPossibleMovies[index], pSong->HasBackground() ? pSong->GetBackgroundPath() : THEME->GetPathTo("Graphics","fallback background") );
|
pTempBGA->LoadFromVisualization( arrayPossibleMovies[index], sSongBackgroundPath );
|
||||||
m_BackgroundAnimations.Add( pTempBGA );
|
m_BackgroundAnimations.Add( pTempBGA );
|
||||||
arrayPossibleMovies.RemoveAt( index );
|
arrayPossibleMovies.RemoveAt( index );
|
||||||
}
|
}
|
||||||
@@ -244,7 +248,7 @@ void Background::LoadFromSong( Song* pSong )
|
|||||||
{
|
{
|
||||||
int index = rand() % arrayPossibleAnims.GetSize();
|
int index = rand() % arrayPossibleAnims.GetSize();
|
||||||
pTempBGA = new BackgroundAnimation;
|
pTempBGA = new BackgroundAnimation;
|
||||||
pTempBGA->LoadFromAniDir( arrayPossibleAnims[index], pSong->HasBackground() ? pSong->GetBackgroundPath() : THEME->GetPathTo("Graphics","fallback background") );
|
pTempBGA->LoadFromAniDir( arrayPossibleAnims[index], sSongBackgroundPath );
|
||||||
m_BackgroundAnimations.Add( pTempBGA );
|
m_BackgroundAnimations.Add( pTempBGA );
|
||||||
arrayPossibleAnims.RemoveAt( index );
|
arrayPossibleAnims.RemoveAt( index );
|
||||||
}
|
}
|
||||||
@@ -260,7 +264,7 @@ void Background::LoadFromSong( Song* pSong )
|
|||||||
{
|
{
|
||||||
int index = rand() % arrayPossibleMovies.GetSize();
|
int index = rand() % arrayPossibleMovies.GetSize();
|
||||||
pTempBGA = new BackgroundAnimation;
|
pTempBGA = new BackgroundAnimation;
|
||||||
pTempBGA->LoadFromMovie( arrayPossibleMovies[index], true, false );
|
pTempBGA->LoadFromMovie( arrayPossibleMovies[index], true, false, false, "" );
|
||||||
m_BackgroundAnimations.Add( pTempBGA );
|
m_BackgroundAnimations.Add( pTempBGA );
|
||||||
arrayPossibleMovies.RemoveAt( index );
|
arrayPossibleMovies.RemoveAt( index );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ CString GameDef::ElementToGraphicSuffix( const SkinElement gbg ) const
|
|||||||
|
|
||||||
CString GameDef::GetPathToGraphic( const CString sSkinName, const CString sButtonName, const SkinElement gbg ) const
|
CString GameDef::GetPathToGraphic( const CString sSkinName, const CString sButtonName, const SkinElement gbg ) const
|
||||||
{
|
{
|
||||||
const CString sSkinDir = ssprintf("Skins\\%s\\%s\\", m_szName, sSkinName);
|
const CString sSkinDir = ssprintf("NoteSkins\\%s\\%s\\", m_szName, sSkinName);
|
||||||
const CString sGraphicSuffix = ElementToGraphicSuffix( gbg );
|
const CString sGraphicSuffix = ElementToGraphicSuffix( gbg );
|
||||||
|
|
||||||
CStringArray arrayPossibleFileNames; // fill this with the possible files
|
CStringArray arrayPossibleFileNames; // fill this with the possible files
|
||||||
|
|||||||
@@ -362,6 +362,10 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
|
|||||||
max_grade = max( max_grade, grade[p] );
|
max_grade = max( max_grade, grade[p] );
|
||||||
|
|
||||||
|
|
||||||
|
bool bNewRecord[NUM_PLAYERS];
|
||||||
|
for( p=0; p<NUM_PLAYERS; p++ )
|
||||||
|
bNewRecord[p] = false;
|
||||||
|
|
||||||
////////////////////////
|
////////////////////////
|
||||||
// update persistent statistics
|
// update persistent statistics
|
||||||
////////////////////////
|
////////////////////////
|
||||||
@@ -386,7 +390,7 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
|
|||||||
if( fScore[p] > pNotes->m_iTopScore )
|
if( fScore[p] > pNotes->m_iTopScore )
|
||||||
{
|
{
|
||||||
pNotes->m_iTopScore = (int)fScore[p];
|
pNotes->m_iTopScore = (int)fScore[p];
|
||||||
m_bNewRecord[p] = true;
|
bNewRecord[p] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( grade[p] > pNotes->m_TopGrade )
|
if( grade[p] > pNotes->m_TopGrade )
|
||||||
@@ -590,7 +594,7 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Chris: If EZ2 wants to hide these things, place them off screen using theme metrics
|
// Chris: If EZ2 wants to hide these things, place them off screen using theme metrics
|
||||||
if( m_bNewRecord[p] )
|
if( bNewRecord[p] )
|
||||||
{
|
{
|
||||||
m_textNewRecord[p].LoadFromFont( THEME->GetPathTo("Fonts","header1") );
|
m_textNewRecord[p].LoadFromFont( THEME->GetPathTo("Fonts","header1") );
|
||||||
m_textNewRecord[p].SetXY( NEW_RECORD_X(p), NEW_RECORD_Y );
|
m_textNewRecord[p].SetXY( NEW_RECORD_X(p), NEW_RECORD_Y );
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ protected:
|
|||||||
Sprite m_sprScoreLabel;
|
Sprite m_sprScoreLabel;
|
||||||
ScoreDisplayNormal m_ScoreDisplay[NUM_PLAYERS];
|
ScoreDisplayNormal m_ScoreDisplay[NUM_PLAYERS];
|
||||||
|
|
||||||
bool m_bNewRecord[NUM_PLAYERS];
|
|
||||||
BitmapText m_textNewRecord[NUM_PLAYERS];
|
BitmapText m_textNewRecord[NUM_PLAYERS];
|
||||||
|
|
||||||
bool m_bTryExtraStage;
|
bool m_bTryExtraStage;
|
||||||
|
|||||||
@@ -880,7 +880,7 @@ void ScreenGameplay::Update( float fDeltaTime )
|
|||||||
// fPositionSeconds ahead
|
// fPositionSeconds ahead
|
||||||
if( GAMESTATE->m_SongOptions.m_AssistType == SongOptions::ASSIST_TICK )
|
if( GAMESTATE->m_SongOptions.m_AssistType == SongOptions::ASSIST_TICK )
|
||||||
{
|
{
|
||||||
fPositionSeconds += (SOUND->GetPlayLatency()+0.01f) * m_soundMusic.GetPlaybackRate(); // HACK: Add 0.02 seconds to account for the fact that the sound file has 0.01 seconds of silence at the beginning
|
fPositionSeconds += (SOUND->GetPlayLatency()+0.015f) * m_soundMusic.GetPlaybackRate(); // HACK: Add 0.015 seconds to account for the fact that the middle of the tick sounds occurs 0.015 seconds into playing.
|
||||||
GAMESTATE->m_pCurSong->GetBeatAndBPSFromElapsedTime( fPositionSeconds, fSongBeat, fBPS, bFreeze );
|
GAMESTATE->m_pCurSong->GetBeatAndBPSFromElapsedTime( fPositionSeconds, fSongBeat, fBPS, bFreeze );
|
||||||
|
|
||||||
int iRowNow = BeatToNoteRowNotRounded( fSongBeat );
|
int iRowNow = BeatToNoteRowNotRounded( fSongBeat );
|
||||||
@@ -951,6 +951,18 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ
|
|||||||
{
|
{
|
||||||
switch( DeviceI.button )
|
switch( DeviceI.button )
|
||||||
{
|
{
|
||||||
|
case DIK_F7:
|
||||||
|
if( GAMESTATE->m_SongOptions.m_AssistType == SongOptions::ASSIST_NONE )
|
||||||
|
GAMESTATE->m_SongOptions.m_AssistType = SongOptions::ASSIST_TICK;
|
||||||
|
else
|
||||||
|
GAMESTATE->m_SongOptions.m_AssistType = SongOptions::ASSIST_NONE;
|
||||||
|
m_textDebug.SetText( ssprintf( "Assist tick is %s.", (GAMESTATE->m_SongOptions.m_AssistType==SongOptions::ASSIST_NONE)?"OFF":"ON") );
|
||||||
|
m_textDebug.SetDiffuseColor( D3DXCOLOR(1,1,1,1) );
|
||||||
|
m_textDebug.StopTweening();
|
||||||
|
m_textDebug.BeginTweeningQueued( 3 ); // sleep
|
||||||
|
m_textDebug.BeginTweeningQueued( 0.5f ); // fade out
|
||||||
|
m_textDebug.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,0) );
|
||||||
|
break;
|
||||||
case DIK_F8:
|
case DIK_F8:
|
||||||
PREFSMAN->m_bAutoPlay = !PREFSMAN->m_bAutoPlay;
|
PREFSMAN->m_bAutoPlay = !PREFSMAN->m_bAutoPlay;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -9,12 +9,16 @@
|
|||||||
#define INSTALL 133
|
#define INSTALL 133
|
||||||
#define MANAGE 135
|
#define MANAGE 135
|
||||||
#define IDC_LIST_SONGS 1000
|
#define IDC_LIST_SONGS 1000
|
||||||
|
#define IDC_LIST 1000
|
||||||
#define IDC_BUTTON_PLAY 1001
|
#define IDC_BUTTON_PLAY 1001
|
||||||
#define IDC_BUTTON_EXPORT 1002
|
#define IDC_BUTTON_EXPORT 1002
|
||||||
|
#define IDC_BUTTON_EXPORT_AS_ONE 1002
|
||||||
#define IDC_BUTTON_BACK 1003
|
#define IDC_BUTTON_BACK 1003
|
||||||
|
#define IDC_BUTTON_EXPORT_AS_INDIVIDUAL 1003
|
||||||
#define IDC_EDIT_MESSAGE1 1005
|
#define IDC_EDIT_MESSAGE1 1005
|
||||||
#define IDC_EDIT_MESSAGE3 1006
|
#define IDC_EDIT_MESSAGE3 1006
|
||||||
#define IDC_EDIT_MESSAGE2 1007
|
#define IDC_EDIT_MESSAGE2 1007
|
||||||
|
#define IDC_TREE1 1008
|
||||||
|
|
||||||
// Next default values for new objects
|
// Next default values for new objects
|
||||||
//
|
//
|
||||||
@@ -22,7 +26,7 @@
|
|||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 137
|
#define _APS_NEXT_RESOURCE_VALUE 137
|
||||||
#define _APS_NEXT_COMMAND_VALUE 32771
|
#define _APS_NEXT_COMMAND_VALUE 32771
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1007
|
#define _APS_NEXT_CONTROL_VALUE 1009
|
||||||
#define _APS_NEXT_SYMED_VALUE 101
|
#define _APS_NEXT_SYMED_VALUE 101
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ Class2=CSmpackageDlg
|
|||||||
|
|
||||||
ResourceCount=3
|
ResourceCount=3
|
||||||
Resource1=IDR_MAINFRAME
|
Resource1=IDR_MAINFRAME
|
||||||
Resource2=IDD_INSTALL
|
Resource2=IDD_MANAGER
|
||||||
Class3=CSMPackageInstallDlg
|
Class3=CSMPackageInstallDlg
|
||||||
Resource3=IDD_MANAGER
|
Resource3=IDD_INSTALL
|
||||||
|
|
||||||
[CLS:CSmpackageApp]
|
[CLS:CSmpackageApp]
|
||||||
Type=0
|
Type=0
|
||||||
@@ -23,6 +23,8 @@ HeaderFile=smpackage.h
|
|||||||
ImplementationFile=smpackage.cpp
|
ImplementationFile=smpackage.cpp
|
||||||
Filter=N
|
Filter=N
|
||||||
LastObject=CSmpackageApp
|
LastObject=CSmpackageApp
|
||||||
|
BaseClass=CWinApp
|
||||||
|
VirtualFilter=AC
|
||||||
|
|
||||||
[CLS:CSmpackageDlg]
|
[CLS:CSmpackageDlg]
|
||||||
Type=0
|
Type=0
|
||||||
@@ -38,12 +40,13 @@ VirtualFilter=dWC
|
|||||||
[DLG:IDD_MANAGER]
|
[DLG:IDD_MANAGER]
|
||||||
Type=1
|
Type=1
|
||||||
Class=CSmpackageDlg
|
Class=CSmpackageDlg
|
||||||
ControlCount=5
|
ControlCount=6
|
||||||
Control1=IDOK,button,1342242817
|
Control1=IDOK,button,1342242817
|
||||||
Control2=IDC_LIST_SONGS,listbox,1352728835
|
Control2=IDC_LIST,listbox,1352728843
|
||||||
Control3=IDC_BUTTON_PLAY,button,1342242816
|
Control3=IDC_BUTTON_PLAY,button,1342242816
|
||||||
Control4=IDC_BUTTON_EXPORT,button,1476460544
|
Control4=IDC_BUTTON_EXPORT_AS_ONE,button,1476460544
|
||||||
Control5=IDC_STATIC,static,1342177294
|
Control5=IDC_STATIC,static,1342177294
|
||||||
|
Control6=IDC_BUTTON_EXPORT_AS_INDIVIDUAL,button,1476460544
|
||||||
|
|
||||||
[DLG:IDD_INSTALL]
|
[DLG:IDD_INSTALL]
|
||||||
Type=1
|
Type=1
|
||||||
|
|||||||
@@ -19,9 +19,7 @@ static char THIS_FILE[] = __FILE__;
|
|||||||
|
|
||||||
BEGIN_MESSAGE_MAP(CSmpackageApp, CWinApp)
|
BEGIN_MESSAGE_MAP(CSmpackageApp, CWinApp)
|
||||||
//{{AFX_MSG_MAP(CSmpackageApp)
|
//{{AFX_MSG_MAP(CSmpackageApp)
|
||||||
// NOTE - the ClassWizard will add and remove mapping macros here.
|
//}}AFX_MSG_MAP
|
||||||
// DO NOT EDIT what you see in these blocks of generated code!
|
|
||||||
//}}AFX_MSG
|
|
||||||
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
|
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
|
||||||
END_MESSAGE_MAP()
|
END_MESSAGE_MAP()
|
||||||
|
|
||||||
|
|||||||
@@ -34,8 +34,6 @@ public:
|
|||||||
// Implementation
|
// Implementation
|
||||||
|
|
||||||
//{{AFX_MSG(CSmpackageApp)
|
//{{AFX_MSG(CSmpackageApp)
|
||||||
// NOTE - the ClassWizard will add and remove member functions here.
|
|
||||||
// DO NOT EDIT what you see in these blocks of generated code !
|
|
||||||
//}}AFX_MSG
|
//}}AFX_MSG
|
||||||
DECLARE_MESSAGE_MAP()
|
DECLARE_MESSAGE_MAP()
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -80,12 +80,15 @@ EXSTYLE WS_EX_APPWINDOW
|
|||||||
CAPTION "Stepmania Package Manager"
|
CAPTION "Stepmania Package Manager"
|
||||||
FONT 8, "MS Sans Serif"
|
FONT 8, "MS Sans Serif"
|
||||||
BEGIN
|
BEGIN
|
||||||
DEFPUSHBUTTON "Close",IDOK,260,215,65,14
|
DEFPUSHBUTTON "Close",IDOK,259,215,65,14
|
||||||
LISTBOX IDC_LIST_SONGS,5,45,260,160,LBS_SORT |
|
LISTBOX IDC_LIST,5,45,247,160,LBS_SORT | LBS_MULTIPLESEL |
|
||||||
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
|
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
|
||||||
PUSHBUTTON "Play Stepmania",IDC_BUTTON_PLAY,5,215,70,15
|
PUSHBUTTON "Play Stepmania",IDC_BUTTON_PLAY,5,215,70,15
|
||||||
PUSHBUTTON "Export",IDC_BUTTON_EXPORT,275,75,50,15,WS_DISABLED
|
PUSHBUTTON "Export As One",IDC_BUTTON_EXPORT_AS_ONE,256,75,68,15,
|
||||||
CONTROL 135,IDC_STATIC,"Static",SS_BITMAP,0,0,295,30
|
WS_DISABLED
|
||||||
|
CONTROL 135,IDC_STATIC,"Static",SS_BITMAP,0,0,332,38
|
||||||
|
PUSHBUTTON "Export As Individual",IDC_BUTTON_EXPORT_AS_INDIVIDUAL,
|
||||||
|
256,108,68,15,WS_DISABLED
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_INSTALL DIALOG DISCARDABLE 0, 0, 332, 234
|
IDD_INSTALL DIALOG DISCARDABLE 0, 0, 332, 234
|
||||||
@@ -163,7 +166,7 @@ BEGIN
|
|||||||
IDD_MANAGER, DIALOG
|
IDD_MANAGER, DIALOG
|
||||||
BEGIN
|
BEGIN
|
||||||
LEFTMARGIN, 7
|
LEFTMARGIN, 7
|
||||||
RIGHTMARGIN, 325
|
RIGHTMARGIN, 324
|
||||||
TOPMARGIN, 7
|
TOPMARGIN, 7
|
||||||
BOTTOMMARGIN, 227
|
BOTTOMMARGIN, 227
|
||||||
END
|
END
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "smpackage.h"
|
#include "smpackage.h"
|
||||||
#include "smpackageDlg.h"
|
#include "smpackageDlg.h"
|
||||||
#include "../RageUtil.h"
|
#include "../RageUtil.h"
|
||||||
|
#include "ZipArchive\ZipArchive.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
@@ -30,8 +31,9 @@ void CSmpackageDlg::DoDataExchange(CDataExchange* pDX)
|
|||||||
{
|
{
|
||||||
CDialog::DoDataExchange(pDX);
|
CDialog::DoDataExchange(pDX);
|
||||||
//{{AFX_DATA_MAP(CSmpackageDlg)
|
//{{AFX_DATA_MAP(CSmpackageDlg)
|
||||||
DDX_Control(pDX, IDC_BUTTON_EXPORT, m_buttonExport);
|
DDX_Control(pDX, IDC_BUTTON_EXPORT_AS_ONE, m_buttonExportAsOne);
|
||||||
DDX_Control(pDX, IDC_LIST_SONGS, m_listBoxSongs);
|
DDX_Control(pDX, IDC_BUTTON_EXPORT_AS_INDIVIDUAL, m_buttonExportAsIndividual);
|
||||||
|
DDX_Control(pDX, IDC_LIST, m_listBox);
|
||||||
//}}AFX_DATA_MAP
|
//}}AFX_DATA_MAP
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,8 +41,9 @@ BEGIN_MESSAGE_MAP(CSmpackageDlg, CDialog)
|
|||||||
//{{AFX_MSG_MAP(CSmpackageDlg)
|
//{{AFX_MSG_MAP(CSmpackageDlg)
|
||||||
ON_WM_PAINT()
|
ON_WM_PAINT()
|
||||||
ON_WM_QUERYDRAGICON()
|
ON_WM_QUERYDRAGICON()
|
||||||
ON_LBN_SELCHANGE(IDC_LIST_SONGS, OnSelchangeListSongs)
|
ON_LBN_SELCHANGE(IDC_LIST, OnSelchangeList)
|
||||||
ON_BN_CLICKED(IDC_BUTTON_EXPORT, OnButtonExport)
|
ON_BN_CLICKED(IDC_BUTTON_EXPORT_AS_ONE, OnButtonExportAsOne)
|
||||||
|
ON_BN_CLICKED(IDC_BUTTON_EXPORT_AS_INDIVIDUAL, OnButtonExportAsIndividual)
|
||||||
ON_BN_CLICKED(IDC_BUTTON_PLAY, OnButtonPlay)
|
ON_BN_CLICKED(IDC_BUTTON_PLAY, OnButtonPlay)
|
||||||
//}}AFX_MSG_MAP
|
//}}AFX_MSG_MAP
|
||||||
END_MESSAGE_MAP()
|
END_MESSAGE_MAP()
|
||||||
@@ -61,22 +64,53 @@ BOOL CSmpackageDlg::OnInitDialog()
|
|||||||
// TODO: Add extra initialization here
|
// TODO: Add extra initialization here
|
||||||
//
|
//
|
||||||
|
|
||||||
// Find all song directories
|
//
|
||||||
CStringArray arrayGroupDirs;
|
// Add announcers, themes, BGAnimations, random movies, and visualizations
|
||||||
GetDirListing( "Songs\\*.*", arrayGroupDirs, true );
|
//
|
||||||
|
|
||||||
for( int i=0; i<arrayGroupDirs.GetSize(); i++ )
|
|
||||||
{
|
{
|
||||||
CString sGroupName = arrayGroupDirs[i];
|
CStringArray as1;
|
||||||
|
GetDirListing( "Announcers/*.*", as1, true, true );
|
||||||
|
GetDirListing( "Themes/*.*", as1, true, true );
|
||||||
|
GetDirListing( "BGAnimations/*.*", as1, true, true );
|
||||||
|
GetDirListing( "RandomMovies/*.avi", as1, false, true );
|
||||||
|
GetDirListing( "RandomMovies/*.mpg", as1, false, true );
|
||||||
|
GetDirListing( "RandomMovies/*.mpeg", as1, false, true );
|
||||||
|
GetDirListing( "Visualizations/*.avi", as1, false, true );
|
||||||
|
GetDirListing( "Visualizations/*.mpg", as1, false, true );
|
||||||
|
GetDirListing( "Visualizations/*.mpeg", as1, false, true );
|
||||||
|
for( int i=0; i<as1.GetSize(); i++ )
|
||||||
|
m_listBox.AddString( as1[i] );
|
||||||
|
}
|
||||||
|
|
||||||
CStringArray arraySongDirs;
|
m_listBox.AddString( "Courses\\" );
|
||||||
GetDirListing( "Songs\\" + sGroupName + "\\*.*", arraySongDirs, true );
|
|
||||||
|
|
||||||
for( int j=0; j<arraySongDirs.GetSize(); j++ )
|
//
|
||||||
|
// Add NoteSkins
|
||||||
|
//
|
||||||
{
|
{
|
||||||
CString sSongName = arraySongDirs[j];
|
CStringArray as1;
|
||||||
|
GetDirListing( "NoteSkins/*.*", as1, true, true );
|
||||||
|
for( int i=0; i<as1.GetSize(); i++ )
|
||||||
|
{
|
||||||
|
CStringArray as2;
|
||||||
|
GetDirListing( as1[i] + "\\*.*", as2, true, true );
|
||||||
|
for( int j=0; j<as2.GetSize(); j++ )
|
||||||
|
m_listBox.AddString( as2[j] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_listBoxSongs.AddString( sGroupName + "\\" + sSongName );
|
//
|
||||||
|
// Add Songs
|
||||||
|
//
|
||||||
|
{
|
||||||
|
CStringArray as1;
|
||||||
|
GetDirListing( "Songs/*.*", as1, true, true );
|
||||||
|
for( int i=0; i<as1.GetSize(); i++ )
|
||||||
|
{
|
||||||
|
CStringArray as2;
|
||||||
|
GetDirListing( as1[i] + "\\*.*", as2, true, true );
|
||||||
|
for( int j=0; j<as2.GetSize(); j++ )
|
||||||
|
m_listBox.AddString( as2[j] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,72 +153,102 @@ HCURSOR CSmpackageDlg::OnQueryDragIcon()
|
|||||||
return (HCURSOR) m_hIcon;
|
return (HCURSOR) m_hIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSmpackageDlg::OnSelchangeListSongs()
|
void CSmpackageDlg::OnSelchangeList()
|
||||||
{
|
|
||||||
// TODO: Add your control notification handler code here
|
|
||||||
int iCurSel = m_listBoxSongs.GetCurSel();
|
|
||||||
if( iCurSel == LB_ERR ) // no song is selected
|
|
||||||
{
|
|
||||||
m_buttonExport.EnableWindow( false );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_buttonExport.EnableWindow( true );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSmpackageDlg::OnButtonExport()
|
|
||||||
{
|
{
|
||||||
// TODO: Add your control notification handler code here
|
// TODO: Add your control notification handler code here
|
||||||
|
|
||||||
// Get the path to the selected song folder
|
if( m_listBox.GetSelCount() == LB_ERR ) // no song is selected
|
||||||
int iCurSel = m_listBoxSongs.GetCurSel();
|
{
|
||||||
CString sSongDir;
|
m_buttonExportAsOne.EnableWindow( false );
|
||||||
m_listBoxSongs.GetText( iCurSel, sSongDir );
|
m_buttonExportAsIndividual.EnableWindow( false );
|
||||||
sSongDir = "Songs\\" + sSongDir;
|
}
|
||||||
//MessageBox( ssprintf("sSongDir is '%s'", sSongDir), "", MB_OK );
|
else
|
||||||
|
{
|
||||||
|
m_buttonExportAsOne.EnableWindow( true );
|
||||||
|
m_buttonExportAsIndividual.EnableWindow( true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CString ReplaceInvalidFileNameChars( CString sOldFileName )
|
||||||
// Extract the group name and song name
|
{
|
||||||
CStringArray arrayPathBits;
|
CString sNewFileName = sOldFileName;
|
||||||
split( sSongDir, "\\", arrayPathBits );
|
|
||||||
CString sGroupName = arrayPathBits[1];
|
|
||||||
CString sSongName = arrayPathBits[2];
|
|
||||||
CString sGroupDir = "Songs\\" + sGroupName;
|
|
||||||
|
|
||||||
|
|
||||||
// Get path to desktop
|
|
||||||
CString sDesktopPath = getenv("USERPROFILE");
|
|
||||||
sDesktopPath += "\\Desktop\\";
|
|
||||||
//MessageBox( ssprintf("Desktop path is '%s'", sDesktopPath), "", MB_OK );
|
|
||||||
|
|
||||||
|
|
||||||
// Create a new zip file on the desktop
|
|
||||||
CString sZipFileName = sSongName + ".smzip";
|
|
||||||
const char charsToReplace[] = {
|
const char charsToReplace[] = {
|
||||||
' ', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
|
' ', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
|
||||||
'+', '=', '[', ']', '{', '}', '|', ':', '\"', '\\',
|
'+', '=', '[', ']', '{', '}', '|', ':', '\"', '\\',
|
||||||
'<', '>', ',', '?', '/'
|
'<', '>', ',', '?', '/'
|
||||||
};
|
};
|
||||||
for( int i=0; i<sizeof(charsToReplace); i++ )
|
for( int i=0; i<sizeof(charsToReplace); i++ )
|
||||||
sZipFileName.Replace( charsToReplace[i], '_' );
|
sNewFileName.Replace( charsToReplace[i], '_' );
|
||||||
|
return sNewFileName;
|
||||||
|
}
|
||||||
|
|
||||||
CString sZipFilePath = sDesktopPath + sZipFileName;
|
void GetFilePathsInDirectory( CString sDir, CStringArray& asPathToFilesOut )
|
||||||
//MessageBox( ssprintf("sZipFilePath is '%s'", sZipFilePath), "", MB_OK );
|
{
|
||||||
|
CStringArray asDirectoriesToExplore;
|
||||||
|
|
||||||
|
// HACK:
|
||||||
|
// Must use backslashes in the path, or else WinZip and WinRAR don't see the files.
|
||||||
|
// Not sure if this is ZipArchive's fault.
|
||||||
|
|
||||||
|
GetDirListing( sDir + "\\*.*", asPathToFilesOut, false, true );
|
||||||
|
GetDirListing( sDir + "\\*.*", asDirectoriesToExplore, true, true );
|
||||||
|
while( asDirectoriesToExplore.GetSize() > 0 )
|
||||||
|
{
|
||||||
|
GetDirListing( asDirectoriesToExplore[0] + "\\*.*", asPathToFilesOut, false, true );
|
||||||
|
GetDirListing( asDirectoriesToExplore[0] + "\\*.*", asDirectoriesToExplore, true, true );
|
||||||
|
asDirectoriesToExplore.RemoveAt( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ExportPackage( CString sPackageName, const CStringArray& asDirectoriesToExport )
|
||||||
|
{
|
||||||
|
CZipArchive zip;
|
||||||
|
|
||||||
|
const CString sDesktopPath = CString(getenv("USERPROFILE")) + "/Desktop/";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create the package zip file
|
||||||
|
//
|
||||||
|
const CString sPackagePath = sDesktopPath + sPackageName;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_zip.Open( sZipFilePath, CZipArchive::zipCreate );
|
zip.Open( sPackagePath, CZipArchive::zipCreate );
|
||||||
}
|
}
|
||||||
catch( CException* e )
|
catch( CException* e )
|
||||||
{
|
{
|
||||||
MessageBox( ssprintf("Error creating zip file '%s'", sDesktopPath), "", MB_OK );
|
AfxMessageBox( ssprintf("Error creating zip file '%s'", sPackagePath) );
|
||||||
m_zip.Close();
|
zip.Close();
|
||||||
e->Delete();
|
e->Delete();
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CStringArray arrayFiles;
|
//
|
||||||
|
// Add files to zip
|
||||||
|
//
|
||||||
|
for( int i=0; i<asDirectoriesToExport.GetSize(); i++ )
|
||||||
|
{
|
||||||
|
CStringArray asFilePaths;
|
||||||
|
GetFilePathsInDirectory( asDirectoriesToExport[i], asFilePaths );
|
||||||
|
|
||||||
|
for( int j=0; j<asFilePaths.GetSize(); j++ )
|
||||||
|
{
|
||||||
|
CString sFilePath = asFilePaths[j];
|
||||||
|
try
|
||||||
|
{
|
||||||
|
zip.AddNewFile( sFilePath, Z_BEST_COMPRESSION, true );
|
||||||
|
}
|
||||||
|
catch (CException* e)
|
||||||
|
{
|
||||||
|
AfxMessageBox( ssprintf("Error adding file '%s'.", sFilePath) );
|
||||||
|
zip.Close();
|
||||||
|
e->Delete();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CStringArray arrayFiles;
|
||||||
GetDirListing( sSongDir + "\\*.*", arrayFiles );
|
GetDirListing( sSongDir + "\\*.*", arrayFiles );
|
||||||
//m_zip.AddNewFile( sRelPathToSelectedSong, 0, true ); // add the directory
|
//m_zip.AddNewFile( sRelPathToSelectedSong, 0, true ); // add the directory
|
||||||
|
|
||||||
@@ -195,7 +259,7 @@ void CSmpackageDlg::OnButtonExport()
|
|||||||
for( i=0; i<arrayFiles.GetSize(); i++ )
|
for( i=0; i<arrayFiles.GetSize(); i++ )
|
||||||
{
|
{
|
||||||
CString sFileName = arrayFiles[i];
|
CString sFileName = arrayFiles[i];
|
||||||
CString sFilePath = sSongDir + "\\" + sFileName;
|
CString sFilePath = sSongDir + "/" + sFileName;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_zip.AddNewFile( sFilePath, 9, true );
|
m_zip.AddNewFile( sFilePath, 9, true );
|
||||||
@@ -208,15 +272,93 @@ void CSmpackageDlg::OnButtonExport()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
AfxMessageBox( ssprintf("Successfully exported '%s' to '%s' on your Desktop.", sSongDir, sZipFileName) );
|
zip.Close();
|
||||||
|
return true;
|
||||||
|
|
||||||
m_zip.Close();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CSmpackageDlg::OnButtonExportAsOne()
|
||||||
|
{
|
||||||
|
// TODO: Add your control notification handler code here
|
||||||
|
|
||||||
|
ASSERT( m_listBox.GetSelCount() != LB_ERR );
|
||||||
|
|
||||||
|
if( m_listBox.GetSelCount() == 1 )
|
||||||
|
{
|
||||||
|
OnButtonExportAsIndividual();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// Generate a package name
|
||||||
|
CString sPackageName;
|
||||||
|
int iNumNameTries = 0;
|
||||||
|
try_another_name:
|
||||||
|
iNumNameTries++;
|
||||||
|
sPackageName = ReplaceInvalidFileNameChars( ssprintf("New Package %d.smzip",iNumNameTries) );
|
||||||
|
CStringArray asFilesOnDesktop;
|
||||||
|
const CString sDesktopPath = CString(getenv("USERPROFILE")) + "\\Desktop";
|
||||||
|
GetDirListing( sDesktopPath + "\\*.*", asFilesOnDesktop );
|
||||||
|
for( i=0; i<asFilesOnDesktop.GetSize(); i++ )
|
||||||
|
if( stricmp(asFilesOnDesktop[i],sPackageName) == 0 )
|
||||||
|
goto try_another_name;
|
||||||
|
|
||||||
|
|
||||||
|
CStringArray asPathsToExport;
|
||||||
|
int iSelectedItems[200];
|
||||||
|
int iNumSelectedItems = m_listBox.GetSelItems( 200, iSelectedItems );
|
||||||
|
for( i=0; i<iNumSelectedItems; i++ )
|
||||||
|
{
|
||||||
|
CString sPath;
|
||||||
|
m_listBox.GetText( iSelectedItems[i], sPath );
|
||||||
|
asPathsToExport.Add( sPath );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ExportPackage( sPackageName, asPathsToExport ) )
|
||||||
|
AfxMessageBox( ssprintf("Successfully exported package '%s' to your Desktop.",sPackageName) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSmpackageDlg::OnButtonExportAsIndividual()
|
||||||
|
{
|
||||||
|
// TODO: Add your control notification handler code here
|
||||||
|
|
||||||
|
ASSERT( m_listBox.GetSelCount() != LB_ERR );
|
||||||
|
|
||||||
|
|
||||||
|
int iSelectedItems[200];
|
||||||
|
int iNumSelectedItems = m_listBox.GetSelItems( 200, iSelectedItems );
|
||||||
|
bool bAllSucceeded = true;
|
||||||
|
CStringArray asExportedPackages;
|
||||||
|
CStringArray asFailedPackages;
|
||||||
|
for( int i=0; i<iNumSelectedItems; i++ )
|
||||||
|
{
|
||||||
|
// Generate a package name for every path
|
||||||
|
CString sPath;
|
||||||
|
m_listBox.GetText( iSelectedItems[i], sPath );
|
||||||
|
|
||||||
|
CString sPackageName;
|
||||||
|
CStringArray asPathBits;
|
||||||
|
split( sPath, "/", asPathBits, true );
|
||||||
|
sPackageName = asPathBits[ asPathBits.GetSize()-1 ] + ".smzip";
|
||||||
|
sPackageName = ReplaceInvalidFileNameChars( sPackageName );
|
||||||
|
|
||||||
|
CStringArray asPathsToExport;
|
||||||
|
asPathsToExport.Add( sPath );
|
||||||
|
|
||||||
|
if( ExportPackage( sPackageName, asPathsToExport ) )
|
||||||
|
asExportedPackages.Add( sPackageName );
|
||||||
|
else
|
||||||
|
asFailedPackages.Add( sPackageName );
|
||||||
|
}
|
||||||
|
|
||||||
|
CString sMessage = ssprintf("Successfully exported the packages %s to your Desktop.", join(", ",asExportedPackages) );
|
||||||
|
if( asFailedPackages.GetSize() > 0 )
|
||||||
|
sMessage += ssprintf(" The packages %s failed to export.", join(", ",asFailedPackages) );
|
||||||
|
AfxMessageBox( sMessage );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void CSmpackageDlg::OnButtonPlay()
|
void CSmpackageDlg::OnButtonPlay()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,9 +12,6 @@
|
|||||||
// CSmpackageDlg dialog
|
// CSmpackageDlg dialog
|
||||||
|
|
||||||
|
|
||||||
#include "ZipArchive\ZipArchive.h"
|
|
||||||
|
|
||||||
|
|
||||||
class CSmpackageDlg : public CDialog
|
class CSmpackageDlg : public CDialog
|
||||||
{
|
{
|
||||||
// Construction
|
// Construction
|
||||||
@@ -24,8 +21,9 @@ public:
|
|||||||
// Dialog Data
|
// Dialog Data
|
||||||
//{{AFX_DATA(CSmpackageDlg)
|
//{{AFX_DATA(CSmpackageDlg)
|
||||||
enum { IDD = IDD_SMPACKAGE_DIALOG };
|
enum { IDD = IDD_SMPACKAGE_DIALOG };
|
||||||
CButton m_buttonExport;
|
CButton m_buttonExportAsOne;
|
||||||
CListBox m_listBoxSongs;
|
CButton m_buttonExportAsIndividual;
|
||||||
|
CListBox m_listBox;
|
||||||
//}}AFX_DATA
|
//}}AFX_DATA
|
||||||
|
|
||||||
// ClassWizard generated virtual function overrides
|
// ClassWizard generated virtual function overrides
|
||||||
@@ -37,7 +35,6 @@ public:
|
|||||||
// Implementation
|
// Implementation
|
||||||
protected:
|
protected:
|
||||||
HICON m_hIcon;
|
HICON m_hIcon;
|
||||||
CZipArchive m_zip;
|
|
||||||
|
|
||||||
|
|
||||||
// Generated message map functions
|
// Generated message map functions
|
||||||
@@ -45,8 +42,9 @@ protected:
|
|||||||
virtual BOOL OnInitDialog();
|
virtual BOOL OnInitDialog();
|
||||||
afx_msg void OnPaint();
|
afx_msg void OnPaint();
|
||||||
afx_msg HCURSOR OnQueryDragIcon();
|
afx_msg HCURSOR OnQueryDragIcon();
|
||||||
afx_msg void OnSelchangeListSongs();
|
afx_msg void OnSelchangeList();
|
||||||
afx_msg void OnButtonExport();
|
afx_msg void OnButtonExportAsOne();
|
||||||
|
afx_msg void OnButtonExportAsIndividual();
|
||||||
afx_msg void OnButtonPlay();
|
afx_msg void OnButtonPlay();
|
||||||
//}}AFX_MSG
|
//}}AFX_MSG
|
||||||
DECLARE_MESSAGE_MAP()
|
DECLARE_MESSAGE_MAP()
|
||||||
|
|||||||
Reference in New Issue
Block a user