/*==LICENSE==* CyanWorlds.com Engine - MMOG client, server and tools Copyright (C) 2011 Cyan Worlds, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . You can contact Cyan Worlds, Inc. by email legal@cyan.com or by snail mail at: Cyan Worlds, Inc. 14617 N Newport Hwy Mead, WA 99021 *==LICENSE==*/ #include "hsTypes.h" #include "hsTemplates.h" #include #include "afxres.h" #include "res/resource.h" #include #include #include #include "plResTreeView.h" #include "../plResMgr/plResManager.h" #include "../plResMgr/plResMgrSettings.h" #include "plWinRegistryTools.h" #include "../plFile/hsFiles.h" #define IDC_REGTREEVIEW 1000 extern HINSTANCE gInstance; extern char *gCommandLine; HWND gTreeView; HWND gInfoDlg; class plWaitCursor { HCURSOR fOrig; public: plWaitCursor() { fOrig = ::SetCursor( ::LoadCursor( nil, IDC_WAIT ) ); } ~plWaitCursor() { ::SetCursor( fOrig ); } }; void SetWindowTitle( HWND hWnd, char *path ) { char fun[ MAX_PATH + 50 ]; sprintf( fun, "plResBrowser%s%s", path != nil ? " - " : "", path != nil ? path : "" ); SetWindowText( hWnd, fun ); } BOOL CALLBACK AboutDialogProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { if( msg == WM_COMMAND ) EndDialog( hWnd, 0 ); return 0; } LRESULT CALLBACK HandleCommand( HWND hWnd, WPARAM wParam, LPARAM lParam ) { OPENFILENAME openInfo; char fileName[ MAX_PATH ]; char path[ MAX_PATH ]; static bool filter = true; switch( LOWORD( wParam ) ) { case ID_FILE_EXIT: PostQuitMessage( 0 ); break; case ID_FILE_OPENDIRECTORY: BROWSEINFO bInfo; LPITEMIDLIST itemList; LPMALLOC shMalloc; memset( &bInfo, 0, sizeof( bInfo ) ); bInfo.hwndOwner = hWnd; bInfo.pidlRoot = NULL; bInfo.pszDisplayName = path; bInfo.lpszTitle = "Select a Plasma 2 Data Directory:"; bInfo.ulFlags = BIF_EDITBOX; itemList = SHBrowseForFolder( &bInfo ); if( itemList != NULL ) { plWaitCursor myWaitCursor; SHGetPathFromIDList( itemList, path ); SHGetMalloc( &shMalloc ); shMalloc->Free( itemList ); shMalloc->Release(); hsgResMgr::Reset(); plResTreeView::ClearTreeView( gTreeView ); // Load that source plResManager *mgr = (plResManager *)hsgResMgr::ResMgr(); hsFolderIterator pathIterator(path); while (pathIterator.NextFileSuffix(".prp")) { char fileName[kFolderIterator_MaxPath]; pathIterator.GetPathAndName(fileName); mgr->AddSinglePage(fileName); } plResTreeView::FillTreeViewFromRegistry( gTreeView ); SetWindowTitle( hWnd, path ); } break; case ID_FILE_OPEN: fileName[ 0 ] = 0; memset( &openInfo, 0, sizeof( OPENFILENAME ) ); openInfo.hInstance = gInstance; openInfo.hwndOwner = hWnd; openInfo.lStructSize = sizeof( OPENFILENAME ); openInfo.lpstrFile = fileName; openInfo.nMaxFile = sizeof( fileName ); openInfo.lpstrFilter = "Plasma 2 Pack Files\0*.prp\0All Files\0*.*\0"; openInfo.lpstrTitle = "Choose a file to browse:"; openInfo.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST; if( GetOpenFileName( &openInfo ) ) { plWaitCursor myWaitCursor; hsgResMgr::Reset(); plResTreeView::ClearTreeView( gTreeView ); // Load that source plResManager *mgr = (plResManager *)hsgResMgr::ResMgr(); mgr->AddSinglePage(fileName); plResTreeView::FillTreeViewFromRegistry( gTreeView ); SetWindowTitle( hWnd, fileName ); } break; case ID_FILE_ABOUT: DialogBox( gInstance, MAKEINTRESOURCE( IDD_ABOUT ), hWnd, AboutDialogProc ); break; case ID_FILE_FINDOBJECT: plResTreeView::FindObject( gTreeView ); break; case ID_FILE_FINDNEXT: plResTreeView::FindNextObject( gTreeView ); break; case ID_FILE_VERIFYPAGE: plResTreeView::VerifyCurrentPage( gTreeView ); break; case IDC_SHOWASHEX: plResTreeView::UpdateInfoDlg( gTreeView ); break; case ID_FILE_ONLYLOAD: filter = !filter; plResTreeView::FilterLoadables( filter, gTreeView ); { HMENU menu = ::GetMenu( hWnd ); menu = ::GetSubMenu( menu, 0 ); ::CheckMenuItem( menu, ID_FILE_ONLYLOAD, MF_BYCOMMAND | ( filter ? MF_CHECKED : MF_UNCHECKED ) ); } break; case ID_FILE_SAVESELECTED: plResTreeView::SaveSelectedObject(gTreeView); break; default: return DefWindowProc( hWnd, WM_COMMAND, wParam, lParam ); } return 0; } void SizeControls( HWND parent ) { RECT clientRect, infoRect; GetClientRect( parent, &clientRect ); GetClientRect( gInfoDlg, &infoRect ); SetWindowPos( gTreeView, NULL, 0, 0, clientRect.right - infoRect.right - 4, clientRect.bottom, 0 ); OffsetRect( &infoRect, clientRect.right - infoRect.right, ( clientRect.bottom >> 1 ) - ( infoRect.bottom >> 1 ) ); SetWindowPos( gInfoDlg, NULL, infoRect.left, infoRect.top, 0, 0, SWP_NOSIZE ); } void InitWindowControls( HWND hWnd ) { RECT clientRect; GetClientRect( hWnd, &clientRect ); gTreeView = CreateWindowEx( WS_EX_CLIENTEDGE, WC_TREEVIEW, "Tree View", WS_VISIBLE | WS_CHILD | WS_BORDER | TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_SHOWSELALWAYS, 0, 0, 0, 0, hWnd, (HMENU)IDC_REGTREEVIEW, gInstance, NULL ); gInfoDlg = CreateDialog( gInstance, MAKEINTRESOURCE( IDD_INFODLG ), hWnd, plResTreeView::InfoDlgProc ); SizeControls( hWnd ); } static bool sFileTypesRegistered = false; void RegisterFileTypes( HWND mainWnd ) { if( sFileTypesRegistered ) return; // Make sure our file types are created char path[ MAX_PATH ]; if( ::GetModuleFileName( nil, path, sizeof( path ) ) == 0 ) return; //plWinRegistryTools::AssociateFileType( "PlasmaIdxFile", "Plasma 2 Index File", path, 1 ); //plWinRegistryTools::AssociateFileType( "PlasmaDatFile", "Plasma 2 Data File", path, 2 ); //plWinRegistryTools::AssociateFileType( "PlasmaPatchFile", "Plasma 2 Patch File", path, 3 ); plWinRegistryTools::AssociateFileType( "PlasmaPackFile", "Plasma 2 Packfile", path, 4 ); // Check our file extensions char prpAssoc[ 512 ]; hsBool needToRegister = true; if( plWinRegistryTools::GetCurrentFileExtensionAssociation( ".prp", prpAssoc, sizeof( prpAssoc ) ) ) { if( strcmp( prpAssoc, "PlasmaPackFile" ) == 0 ) needToRegister = false; } if( needToRegister ) { if( MessageBox( nil, "The Plasma 2 packed data file extension .prp is not currently associated with " "plResBrowser. Would you like to associate it now?", "plResBrowser File Type Association", MB_YESNO | MB_ICONQUESTION) == IDYES ) { // Associate 'em plWinRegistryTools::AssociateFileExtension( ".prp", "PlasmaPackFile" ); } } sFileTypesRegistered = true; } LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) { switch( message ) { case WM_CREATE: InitCommonControls(); InitWindowControls( hWnd ); RegisterFileTypes( hWnd ); plResMgrSettings::Get().SetLoadPagesOnInit(false); { plResTreeView::FilterLoadables( true, gTreeView ); HMENU menu = ::GetMenu( hWnd ); menu = ::GetSubMenu( menu, 0 ); ::CheckMenuItem( menu, ID_FILE_ONLYLOAD, MF_BYCOMMAND | MF_CHECKED ); } if( gCommandLine != nil ) { plWaitCursor myWaitCursor; char path[ MAX_PATH ]; if( gCommandLine[ 0 ] == '"' ) { strcpy( path, gCommandLine + 1 ); char *c = strchr( path, '"' ); if( c != nil ) *c = 0; } else strcpy( path, gCommandLine ); if( stricmp( PathFindExtension( path ), ".prp" ) == 0 ) { hsgResMgr::Reset(); plResTreeView::ClearTreeView( gTreeView ); plResManager *mgr = (plResManager *)hsgResMgr::ResMgr(); mgr->AddSinglePage(path); plResTreeView::FillTreeViewFromRegistry( gTreeView ); SetWindowTitle( hWnd, path ); } } break; case WM_CLOSE: DestroyWindow( hWnd ); break; case WM_DESTROY: plResTreeView::ClearTreeView( gTreeView ); PostQuitMessage(0); break; case WM_SIZING: case WM_SIZE: SizeControls( hWnd ); break; case WM_NOTIFY: if( wParam == IDC_REGTREEVIEW ) { NMHDR *hdr = (NMHDR *)lParam; if( hdr->code == TVN_SELCHANGED ) { plResTreeView::UpdateInfoDlg( gTreeView ); //NMTREEVIEW *tv = (NMTREEVIEW *)hdr; } else if( hdr->code == NM_DBLCLK ) { plResTreeView::SelectionDblClicked( gTreeView ); } } break; case WM_DROPFILES: { int i, j, fileCount = DragQueryFile( (HDROP)wParam, -1, nil, nil ); char path[ MAX_PATH ]; plWaitCursor myWaitCursor; hsgResMgr::Reset(); plResTreeView::ClearTreeView( gTreeView ); plResManager *mgr = (plResManager *)hsgResMgr::ResMgr(); if( fileCount == 1 && DragQueryFile( (HDROP)wParam, 0, path, sizeof( path ) ) > 0 && ( (char *)PathFindExtension( path ) )[ 0 ] == 0 ) { // Must be a directory hsFolderIterator pathIterator(path); while (pathIterator.NextFileSuffix(".prp")) { char fileName[kFolderIterator_MaxPath]; pathIterator.GetPathAndName(fileName); mgr->AddSinglePage(fileName); } } else { hsTArray filesAdded; filesAdded.Reset(); for( i = 0; i < fileCount; i++ ) { if( DragQueryFile( (HDROP)wParam, i, path, sizeof( path ) ) > 0 ) { // Check for duplicates for( j = 0; j < filesAdded.GetCount(); j++ ) { if( stricmp( filesAdded[ j ], path ) == 0 ) break; } if( j < filesAdded.GetCount() ) continue; if( stricmp( PathFindExtension( path ), ".prp" ) == 0 ) { mgr->AddSinglePage(path); filesAdded.Append( hsStrcpy( path ) ); } } } for( j = 0; j < filesAdded.GetCount(); j++ ) delete [] filesAdded[ j ]; } plResTreeView::FillTreeViewFromRegistry( gTreeView ); PathRemoveFileSpec( path ); SetWindowTitle( hWnd, path ); } break; case WM_COMMAND: return HandleCommand( hWnd, wParam, lParam ); } return DefWindowProc( hWnd, message, wParam, lParam ); }