github publish

This commit is contained in:
Ondrej Novak 2025-01-24 18:27:22 +01:00
commit 506e23bf32
542 changed files with 120675 additions and 0 deletions

View file

@ -0,0 +1,93 @@
#include "stdafx.h"
#include ".\ddlfile.h"
DDLFile::DDLFile(void)
{
_hFile=0;
}
DDLFile::~DDLFile(void)
{
if (_hFile!=0) CloseHandle(_hFile);
}
bool DDLFile::OpenDDLFile(WString filename)
{
_hFile=CreateFile(filename,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,
OPEN_EXISTING,FILE_FLAG_RANDOM_ACCESS,NULL);
if (_hFile==INVALID_HANDLE_VALUE)
{
_hFile=0;
return false;
}
return true;
}
bool DDLFile::ReadFile(void *data, size_t sz)
{
DWORD readed=0;
if (::ReadFile(_hFile,data,sz,&readed,NULL)==FALSE) return false;
if (readed!=sz) return false;
return true;
}
bool DDLFile::EnumFiles(IDDLFileEnumerator &enmClass)
{
unsigned long firstGroup;
unsigned long groupEndOffset;
unsigned long endGroups;
int i;
int ngroups;
SetFilePointer(_hFile,0,0,FILE_BEGIN);
if (ReadFile(&firstGroup,sizeof(firstGroup))==false) return false;
if (ReadFile(&groupEndOffset,sizeof(firstGroup))==false) return false;
unsigned long *group=(unsigned long *)alloca(groupEndOffset);
group[0]=firstGroup;
group[1]=groupEndOffset;
ngroups=groupEndOffset/8;
if (groupEndOffset!=8 && ReadFile(group+2,groupEndOffset-8)==false) return false;
SetFilePointer(_hFile,12,0,FILE_CURRENT);
if (ReadFile(&endGroups,sizeof(endGroups))==false) return false;
for (i=0;i<ngroups && group[i*2+1]<endGroups;i++);
ngroups=i;
WString fname;
for (i=0;i<ngroups;i++)
{
unsigned long endGroup=(i+1)<ngroups?group[i*2+3]:endGroups;
SetFilePointer(_hFile,group[i*2+1],0,FILE_BEGIN);
unsigned long pos=group[i*2+1];
while (pos<endGroup)
{
char buff[13];
unsigned long offset;
if (ReadFile(buff,12)==false) return false;
if (ReadFile(&offset,4)==false) return false;
buff[12]=0;
fname.SetUTF8(buff);
enmClass.File(fname,group[i*2],offset);
pos+=12+4;
}
}
return true;
}
unsigned long DDLFile::GetFileSize(unsigned long offset)
{
unsigned long sz=0;
SetFilePointer(_hFile,offset,0,FILE_BEGIN);
ReadFile(&sz,4);
return sz;
}
DDLData DDLFile::ExtractFile(unsigned long offset)
{
SetFilePointer(_hFile,offset,0,FILE_BEGIN);
DDLData data;
if (ReadFile(&data.sz,4)==false) return DDLData();
data.data=malloc(data.sz);
if (ReadFile(data.data,data.sz)==false) return DDLData();
return data;
}

View file

@ -0,0 +1,45 @@
#pragma once
#include "WString.h"
class IDDLFileEnumerator
{
public:
virtual bool File(WString name, int group, unsigned long offset)=0;
};
struct DDLData
{
void *data;
size_t sz;
DDLData():data(0),sz(0) {}
~DDLData() {free(data);}
DDLData(const DDLData &other):data(other.data),sz(other.sz)
{
DDLData &dother=const_cast<DDLData &>(other);
dother.data=0;dother.sz=0;
}
DDLData& operator =(const DDLData &other)
{
DDLData &dother=const_cast<DDLData &>(other);
data=other.data;sz=other.sz;
dother.data=0;dother.sz=0;
return *this;
}
};
class DDLFile
{
HANDLE _hFile;
bool ReadFile(void *data, size_t sz);
public:
DDLFile(void);
~DDLFile(void);
bool OpenDDLFile(WString filename);
bool EnumFiles(IDDLFileEnumerator &enmClass);
DDLData ExtractFile(unsigned long offset);
unsigned long GetFileSize(unsigned long offset);
};

View file

@ -0,0 +1,67 @@
// DDLReader.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "DDLReader.h"
#include "DDLReaderDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDDLReaderApp
BEGIN_MESSAGE_MAP(CDDLReaderApp, CWinApp)
//{{AFX_MSG_MAP(CDDLReaderApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDDLReaderApp construction
CDDLReaderApp::CDDLReaderApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CDDLReaderApp object
CDDLReaderApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CDDLReaderApp initialization
BOOL CDDLReaderApp::InitInstance()
{
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
CDDLReaderDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}

View file

@ -0,0 +1,49 @@
// DDLReader.h : main header file for the DDLREADER application
//
#if !defined(AFX_DDLREADER_H__9FE8F7F8_112D_4735_A4BA_5141A991D609__INCLUDED_)
#define AFX_DDLREADER_H__9FE8F7F8_112D_4735_A4BA_5141A991D609__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
#include "resource.h" // main symbols
/////////////////////////////////////////////////////////////////////////////
// CDDLReaderApp:
// See DDLReader.cpp for the implementation of this class
//
class CDDLReaderApp : public CWinApp
{
public:
CDDLReaderApp();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDDLReaderApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
//{{AFX_MSG(CDDLReaderApp)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_DDLREADER_H__9FE8F7F8_112D_4735_A4BA_5141A991D609__INCLUDED_)

View file

@ -0,0 +1,278 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Czech resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CSY)
#ifdef _WIN32
LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
#pragma code_page(1250)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
"#define _AFX_NO_OLE_RESOURCES\r\n"
"#define _AFX_NO_TRACKER_RESOURCES\r\n"
"#define _AFX_NO_PROPERTY_RESOURCES\r\n"
"\r\n"
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
"#ifdef _WIN32\r\n"
"LANGUAGE 9, 1\r\n"
"#pragma code_page(1252)\r\n"
"#endif //_WIN32\r\n"
"#include ""res\\DDLReader.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
"#include ""afxres.rc"" // Standard components\r\n"
"#endif\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_MAINFRAME ICON "res\\DDLReader.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_EXPORTING DIALOGEX 0, 0, 186, 82
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE |
WS_CAPTION | WS_SYSMENU
CAPTION "Exporting"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER | 0x1,7,39,
172,14
CTEXT "Exporting",IDC_STATIC,7,7,172,8
CTEXT "Static",IDC_NAME,7,23,172,8
PUSHBUTTON "Stop",IDC_BUTTON1,68,61,50,14
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_EXPORTING, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 179
TOPMARGIN, 7
BOTTOMMARGIN, 75
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_ABOUTBOX "&About DDLReader..."
IDS_FILEOPENFAILED "Failed to open DDL"
IDC_HEADGROUP "Group"
IDC_HEADFNAME "Filename"
IDC_HEADSIZE "Size"
IDC_HEADOFFSET "Offset"
IDS_DDLFILTER "DDLFiles|*.ddl|All Files|*.*||"
IDC_GROUP_GRAPHICS "Graphics"
IDC_GROUP_SOUNDS "Sounds"
IDC_GROUP_FONTS "Fonts"
IDC_GROUP_BASIC "Basic graphics"
END
STRINGTABLE
BEGIN
IDC_GROUP_ITEMS "Item graphics"
IDC_GROUP_MONSTERS "Monster graphics"
IDC_GROUP_DIALOGS "Dialog graphics"
IDC_GROUP_UNSPECIFIED "Unspecified"
IDC_GROUP_UNKNOWN "Unknown (%d)"
IDS_UNABLETOCREATEFILE "Unable to create target file: \r\n%1"
IDS_UNABLETOEXTACTDATA "Unable to extract data. General reading error"
END
#endif // Czech resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_ABOUTBOX DIALOG 0, 0, 235, 55
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About DDLReader"
FONT 8, "MS Sans Serif"
BEGIN
ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20
LTEXT "DDLReader Version 1.0",IDC_STATIC,40,10,119,8,
SS_NOPREFIX
LTEXT "Copyright (C) 2005",IDC_STATIC,40,25,119,8
DEFPUSHBUTTON "OK",IDOK,178,7,50,14,WS_GROUP
END
IDD_DDLREADER_DIALOG DIALOGEX 0, 0, 364, 262
STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE | WS_CAPTION |
WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_APPWINDOW
CAPTION "DDLReader"
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
CONTROL "List2",IDC_FILELIST,"SysListView32",LVS_REPORT |
LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,0,14,363,219
LTEXT "Export to folder:",IDC_POPISEK,0,235,50,8
EDITTEXT IDC_FOLDER,0,248,263,14,ES_AUTOHSCROLL
PUSHBUTTON "Browse",IDC_BROWSE,268,248,34,14
PUSHBUTTON "Export",IDC_EXPORT,306,248,58,14
EDITTEXT IDC_DDLFILE,0,0,313,12,ES_AUTOHSCROLL
PUSHBUTTON "Browse DDL",IDC_DDLBROWSE,314,0,50,12
END
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904B0"
BEGIN
VALUE "FileDescription", "DDLReader MFC Application"
VALUE "FileVersion", "1, 0, 0, 1"
VALUE "InternalName", "DDLReader"
VALUE "LegalCopyright", "Copyright (C) 2005"
VALUE "OriginalFilename", "DDLReader.EXE"
VALUE "ProductName", "DDLReader Application"
VALUE "ProductVersion", "1, 0, 0, 1"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_ABOUTBOX, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 228
TOPMARGIN, 7
BOTTOMMARGIN, 48
END
IDD_DDLREADER_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 357
TOPMARGIN, 7
BOTTOMMARGIN, 255
END
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE 9, 1
#pragma code_page(1252)
#endif //_WIN32
#include "res\DDLReader.rc2" // non-Microsoft Visual C++ edited resources
#include "afxres.rc" // Standard components
#endif
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View file

@ -0,0 +1,34 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DDLReader", "DDLReader.vcproj", "{A5326507-3420-4D03-B9EB-5583790B412B}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SourceCodeControl) = preSolution
SccNumberOfProjects = 2
SccProjectName0 = \u0022$/Skeldal/DDLReader\u0022,\u0020NJEAAAAA
SccLocalPath0 = ..\\..\\..
SccProvider0 = MSSCCI:Microsoft\u0020Visual\u0020SourceSafe
CanCheckoutShared = false
SccProjectFilePathRelativizedFromConnection0 = Projects\\Skeldal\\DDLReader\\
SolutionUniqueID = {A1A5598F-1F71-475C-8CAA-699B487DC20F}
SccProjectUniqueName1 = DDLReader.vcproj
SccLocalPath1 = ..\\..\\..
CanCheckoutShared = false
SccProjectFilePathRelativizedFromConnection1 = Projects\\Skeldal\\DDLReader\\
EndGlobalSection
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{A5326507-3420-4D03-B9EB-5583790B412B}.Debug.ActiveCfg = Debug|Win32
{A5326507-3420-4D03-B9EB-5583790B412B}.Debug.Build.0 = Debug|Win32
{A5326507-3420-4D03-B9EB-5583790B412B}.Release.ActiveCfg = Release|Win32
{A5326507-3420-4D03-B9EB-5583790B412B}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,291 @@
<?xml version="1.0" encoding="windows-1250"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="DDLReader"
ProjectGUID="{A5326507-3420-4D03-B9EB-5583790B412B}"
SccProjectName="&quot;$/Skeldal/DDLReader&quot;, NJEAAAAA"
SccAuxPath=""
SccLocalPath="..\..\.."
SccProvider="MSSCCI:Microsoft Visual SourceSafe"
Keyword="MFCProj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
UseOfMFC="2"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="1">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
StringPooling="TRUE"
RuntimeLibrary="2"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="3"
PrecompiledHeaderThrough="stdafx.h"
PrecompiledHeaderFile=".\Release/DDLReader.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Release/DDLReader.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ProgramDatabaseFile=".\Release/DDLReader.pdb"
SubSystem="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\Release/DDLReader.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1029"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
UseOfMFC="2"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="1">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="3"
PrecompiledHeaderThrough="stdafx.h"
PrecompiledHeaderFile=".\Debug/DDLReader.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Debug/DDLReader.exe"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug/DDLReader.pdb"
SubSystem="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\Debug/DDLReader.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1029"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath=".\DDLFile.cpp">
</File>
<File
RelativePath=".\DDLReader.cpp">
</File>
<File
RelativePath=".\DDLReader.rc">
</File>
<File
RelativePath=".\DDLReaderDlg.cpp">
</File>
<File
RelativePath=".\DlgProgress.cpp">
</File>
<File
RelativePath=".\StdAfx.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"/>
</FileConfiguration>
</File>
<File
RelativePath=".\WPathname.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
<File
RelativePath=".\WString.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
<File
RelativePath=".\WStringMemory.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
<File
RelativePath=".\WStringProxy.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
RelativePath=".\DDLFile.h">
</File>
<File
RelativePath=".\DDLReader.h">
</File>
<File
RelativePath=".\DDLReaderDlg.h">
</File>
<File
RelativePath=".\DlgProgress.h">
</File>
<File
RelativePath=".\IWStringEffect.h">
</File>
<File
RelativePath=".\resource.h">
</File>
<File
RelativePath=".\StdAfx.h">
</File>
<File
RelativePath=".\WPathname.h">
</File>
<File
RelativePath=".\WString.h">
</File>
<File
RelativePath=".\WStringMemory.h">
</File>
<File
RelativePath=".\WStringProxy.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
<File
RelativePath=".\res\DDLReader.ico">
</File>
</Filter>
</Files>
<Globals>
<Global
Name="RESOURCE_FILE"
Value="DDLReader.rc"/>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,533 @@
// DDLReaderDlg.cpp : implementation file
//
#include "stdafx.h"
#include "DDLReader.h"
#include "DDLReaderDlg.h"
#include ".\ddlreaderdlg.h"
#include "WPathname.h"
#include "DlgProgress.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDDLReaderDlg dialog
CDDLReaderDlg::CDDLReaderDlg(CWnd* pParent /*=NULL*/)
: CDialog(CDDLReaderDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CDDLReaderDlg)
vFolder = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
CDDLReaderDlg::~CDDLReaderDlg()
{
if (!_lastTemp.IsNull()) DeleteFile(_lastTemp);
}
void CDDLReaderDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDDLReaderDlg)
DDX_Control(pDX, IDC_FOLDER, wFolder);
DDX_Control(pDX, IDC_FILELIST, wFileList);
DDX_Control(pDX, IDC_BROWSE, wBrowse);
DDX_Control(pDX, IDC_EXPORT, wExport);
DDX_Text(pDX, IDC_FOLDER, vFolder);
DDX_Control(pDX, IDC_POPISEK, wPopisek);
//}}AFX_DATA_MAP
DDX_Control(pDX, IDC_DDLFILE, wDDLFile);
DDX_Control(pDX, IDC_DDLBROWSE, wDDLBrowse);
}
BEGIN_MESSAGE_MAP(CDDLReaderDlg, CDialog)
//{{AFX_MSG_MAP(CDDLReaderDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_WM_SIZE()
ON_WM_GETMINMAXINFO()
ON_EN_KILLFOCUS(IDC_DDLFILE, OnEnKillfocusDdlfile)
ON_BN_CLICKED(IDC_DDLBROWSE, OnBnClickedDdlbrowse)
ON_NOTIFY(LVN_COLUMNCLICK, IDC_FILELIST, OnLvnColumnclickFilelist)
ON_BN_CLICKED(IDC_BROWSE, OnBnClickedBrowse)
ON_BN_CLICKED(IDC_EXPORT, OnBnClickedExport)
ON_NOTIFY(NM_DBLCLK, IDC_FILELIST, OnNMDblclkFilelist)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDDLReaderDlg message handlers
BOOL CDDLReaderDlg::OnInitDialog()
{
CRect rc;
GetClientRect(&rc);
_dlgSize=rc.Size();
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
CString header;
header.LoadString(IDC_HEADGROUP);
wFileList.InsertColumn(0,header,LVCFMT_CENTER,100,0);
header.LoadString(IDC_HEADFNAME);
wFileList.InsertColumn(1,header,LVCFMT_LEFT,140,1);
header.LoadString(IDC_HEADSIZE);
wFileList.InsertColumn(2,header,LVCFMT_RIGHT,80,2);
header.LoadString(IDC_HEADOFFSET);
wFileList.InsertColumn(3,header,LVCFMT_RIGHT,80,3);
ListView_SetExtendedListViewStyleEx(wFileList,LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_HEADERDRAGDROP,LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_HEADERDRAGDROP);
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
void CDDLReaderDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CDDLReaderDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CDDLReaderDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void MoveWindowRel(HDWP &hdwp, CWnd &wnd, int xr,int yr, int xs, int ys)
{
CRect rc;
wnd.GetWindowRect(&rc);
wnd.GetParent()->ScreenToClient(&rc);
rc.left+=xr;
rc.top+=yr;
rc.bottom+=yr+ys;
rc.right+=xr+xs;
hdwp=DeferWindowPos(hdwp,wnd,NULL,rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top,SWP_NOZORDER);
}
void CDDLReaderDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
if (nType!=SIZE_MINIMIZED)
{
if (wFileList.GetSafeHwnd()!=0)
{
HDWP dwp=BeginDeferWindowPos(10);
int difx=cx-_dlgSize.cx;
int dify=cy-_dlgSize.cy;
MoveWindowRel(dwp,wFileList,0,0,difx,dify);
MoveWindowRel(dwp,wPopisek,0,dify,0,0);
MoveWindowRel(dwp,wFolder,0,dify,difx,0);
MoveWindowRel(dwp,wExport,difx,dify,0,0);
MoveWindowRel(dwp,wBrowse,difx,dify,0,0);
MoveWindowRel(dwp,wDDLFile,0,0,difx,0);
MoveWindowRel(dwp,wDDLBrowse,difx,0,0,0);
EndDeferWindowPos(dwp);
}
_dlgSize.cx=cx;
_dlgSize.cy=cy;
}
}
void CDDLReaderDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
{
CDialog::OnGetMinMaxInfo(lpMMI);
lpMMI->ptMinTrackSize.x=200;
lpMMI->ptMinTrackSize.y=150;
}
void CDDLReaderDlg::OnEnKillfocusDdlfile()
{
CString name;
wDDLFile.GetWindowText(name);
if (_ddlfile.OpenDDLFile(WString(name.GetString()))==false)
AfxMessageBox(IDS_FILEOPENFAILED);
UpdateList();
}
static CString GetGroupName(int group)
{
int id;
switch (group)
{
case 1: id= IDC_GROUP_GRAPHICS;break;
case 2: id= IDC_GROUP_SOUNDS;break;
case 3: id= IDC_GROUP_FONTS;break;
case 7: id= IDC_GROUP_BASIC;break;
case 8: id= IDC_GROUP_ITEMS;break;
case 9: id= IDC_GROUP_MONSTERS;break;
case 11: id= IDC_GROUP_DIALOGS;break;
case 0: id=IDC_GROUP_UNSPECIFIED;break;
default: id=IDC_GROUP_UNKNOWN;break;
}
CString res;
res.Format(id,group);
return res;
}
bool CDDLReaderDlg::File(WString name, int group, unsigned long offset)
{
LVITEM item;
CString grpname=GetGroupName(group);
wchar_t buff[40];
item.iItem=wFileList.GetItemCount();
item.iSubItem=0;
item.mask=LVIF_GROUPID|LVIF_TEXT;
item.iGroupId=group;
item.pszText=grpname.LockBuffer();
int ipos=wFileList.InsertItem(&item);
wFileList.SetItemText(ipos,1,name);
wFileList.SetItemText(ipos,3,_ui64tow(offset,buff,10));
grpname.UnlockBuffer();
return true;
}
void CDDLReaderDlg::UpdateList(void)
{
CString tmp;
wFileList.DeleteAllItems();
_ddlfile.EnumFiles(*this);
for (int i=0,cnt=wFileList.GetItemCount();i<cnt;i++)
{
unsigned long offset;
tmp=wFileList.GetItemText(i,3);
offset=_wtoi(tmp);
unsigned long size=_ddlfile.GetFileSize(offset);
if (size<1024)
tmp.Format(_T("%d B"),size);
else
tmp.Format(_T("%d KB"),(size+512)/1024);
wFileList.SetItemText(i,2,tmp);
}
}
void CDDLReaderDlg::OnBnClickedDdlbrowse()
{
CString fname;
wDDLFile.GetWindowText(fname);
CString ddlfilter;
ddlfilter.LoadString(IDS_DDLFILTER);
CFileDialog fdlg(TRUE,_T("DDL"),fname,OFN_HIDEREADONLY|OFN_FILEMUSTEXIST,ddlfilter);
if (fdlg.DoModal()==IDOK)
{
wDDLFile.SetWindowText(fdlg.GetPathName());
OnEnKillfocusDdlfile();
}
}
struct SortInfo
{
int index;
CListCtrl *list;
CString left;
CString right;
DDLFile *_ddlfile;
};
static int CALLBACK SortItemsInFileList(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
SortInfo &sinfo=*(SortInfo *)lParamSort;
int res;
if (sinfo.index!=2)
{
sinfo.left=sinfo.list->GetItemText(lParam1,sinfo.index);
sinfo.right=sinfo.list->GetItemText(lParam2,sinfo.index);
switch (sinfo.index)
{
case 0:
case 1: res=wcsicmp(sinfo.left,sinfo.right);break;
case 3: {
int l=_wtoi(sinfo.left);
int r=_wtoi(sinfo.right);
res=(l>r)-(l<r);
}
}
}
else
{
sinfo.left=sinfo.list->GetItemText(lParam1,3);
sinfo.right=sinfo.list->GetItemText(lParam2,3);
unsigned long l=_wtoi(sinfo.left);
unsigned long r=_wtoi(sinfo.right);
l=sinfo._ddlfile->GetFileSize(l);
r=sinfo._ddlfile->GetFileSize(r);
res=(l>r)-(l<r);
}
if (res==0) res=(lParam1>lParam2)-(lParam1<lParam2);
return res;
}
void CDDLReaderDlg::OnLvnColumnclickFilelist(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
for (int i=0,cnt=wFileList.GetItemCount();i<cnt;i++)
wFileList.SetItemData(i,i);
SortInfo sinfo;
sinfo.index=pNMLV->iSubItem;
sinfo.list=&wFileList;
sinfo._ddlfile=&_ddlfile;
wFileList.SortItems(SortItemsInFileList,(LPARAM)&sinfo);
*pResult = 0;
}
static int WINAPI PosBrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam,LPARAM lpData)
{
const wchar_t *curpath=(const wchar_t *)lpData;
if (uMsg == BFFM_INITIALIZED)
{
if (curpath && curpath[0])
{
::SendMessage(hwnd,BFFM_SETSELECTION,TRUE,(LPARAM)((LPCSTR)curpath));
::SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)((LPCSTR)curpath));
}
}
else if (uMsg == BFFM_SELCHANGED)
{
wchar_t buff[_MAX_PATH];
if (SHGetPathFromIDList((LPITEMIDLIST)lParam,buff))
{
::SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)buff);
}
}
return 0;
};
static bool PathBrowser(HWND hWnd, wchar_t *path /* MAX_PATH size */)
{
BROWSEINFO brw;
memset(&brw,0,sizeof(brw));
brw.hwndOwner=hWnd;
brw.pidlRoot=NULL;
brw.pszDisplayName=path;
brw.lParam=(LPARAM)path;
brw.ulFlags= BIF_RETURNONLYFSDIRS |BIF_STATUSTEXT|BIF_USENEWUI ;
brw.lpfn = (BFFCALLBACK)(PosBrowseCallbackProc);
LPITEMIDLIST il=SHBrowseForFolder( &brw );
if (il==NULL) return false;
SHGetPathFromIDList(il,path);
IMalloc *shmalloc;
SHGetMalloc(&shmalloc);
shmalloc->Free(il);
if (path[0]==0) return false;
return true;
}
void CDDLReaderDlg::OnBnClickedBrowse()
{
wchar_t path[MAX_PATH];
wFolder.GetWindowText(path,MAX_PATH);
if (PathBrowser(*this,path))
{
wFolder.SetWindowText(path);
}
}
void CDDLReaderDlg::OnBnClickedExport()
{
wchar_t path[MAX_PATH];
wFolder.GetWindowText(path,MAX_PATH);
if (path[0]==0) OnBnClickedBrowse();
wFolder.GetWindowText(path,MAX_PATH);
if (path[0]==0) return;
WPathname fpath;
fpath.SetDirectory(path);
POSITION pos=wFileList.GetFirstSelectedItemPosition();
int max=wFileList.GetSelectedCount();
int cur=0;
DlgProgress pb;
if (max) {pb.Create(IDD_EXPORTING);pb.CenterWindow(this);EnableWindow(FALSE);}
while (pos)
{
MSG msg;
pb.wProgress.SetRange(0,max);
pb.wProgress.SetPos(++cur);
int i=wFileList.GetNextSelectedItem(pos);
CString fname;
unsigned long offset;
fname=wFileList.GetItemText(i,1);
offset=(unsigned long)_wtoi64(wFileList.GetItemText(i,3));
pb.wDesc.SetWindowText(fname);
if (PeekMessage(&msg,0,0,0,PM_NOREMOVE)==TRUE) AfxPumpMessage();
if (pb.stop) break;
DDLData data=_ddlfile.ExtractFile(offset);
if (data.data!=NULL)
{
fpath.SetFilename(fname);
HANDLE hFile=CreateFile(fpath,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);
while (hFile==INVALID_HANDLE_VALUE)
{
CString msg;
AfxFormatString1(msg,IDS_UNABLETOCREATEFILE,fpath);
int retry=AfxMessageBox(msg,MB_ABORTRETRYIGNORE);
if (retry==IDABORT) {EnableWindow(TRUE);return;}
if (retry==IDIGNORE) break;
hFile=CreateFile(fpath,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);
}
if (hFile!=INVALID_HANDLE_VALUE)
{
DWORD written;
WriteFile(hFile,data.data,data.sz,&written,NULL);
CloseHandle(hFile);
}
}
else
{
CString msg;
AfxFormatString1(msg,IDS_UNABLETOEXTACTDATA,fpath);
AfxMessageBox(msg,MB_OK|MB_ICONSTOP);
}
}
EnableWindow(TRUE);
}
WPathname CDDLReaderDlg::CreateTemp(int index)
{
if (!_lastTemp.IsNull()) DeleteFile(_lastTemp);
CString fname;
unsigned long offset;
fname=wFileList.GetItemText(index,1);
offset=(unsigned long)_wtoi64(wFileList.GetItemText(index,3));
_lastTemp.SetTempDirectory();
_lastTemp.SetFileTitle(WSC("SkeldalDDLReader"));
_lastTemp.SetExtension(WSC(".")+WString(fname));
DDLData data=_ddlfile.ExtractFile(offset);
if (data.data)
{
HANDLE hFile=CreateFile(_lastTemp,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);
DWORD written;
WriteFile(hFile,data.data,data.sz,&written,NULL);
CloseHandle(hFile);
}
return _lastTemp;
}
void CDDLReaderDlg::OnNMDblclkFilelist(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: Add your control notification handler code here
*pResult = 0;
int index=wFileList.GetNextItem(-1,LVNI_FOCUSED);
WPathname pth=CreateTemp(index);
ShellExecute(*this,0,pth,0,0,SW_NORMAL);
}

View file

@ -0,0 +1,76 @@
// DDLReaderDlg.h : header file
//
#include "t:\h\atlmfc\include\afxwin.h"
#include "ddlfile.h"
#include "WPathname.h"
#if !defined(AFX_DDLREADERDLG_H__E765355F_0112_4B3E_90CE_111E28FE8EC6__INCLUDED_)
#define AFX_DDLREADERDLG_H__E765355F_0112_4B3E_90CE_111E28FE8EC6__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
/////////////////////////////////////////////////////////////////////////////
// CDDLReaderDlg dialog
class CDDLReaderDlg : public CDialog, public IDDLFileEnumerator
{
// Construction
CSize _dlgSize;
WPathname _lastTemp;
public:
CDDLReaderDlg(CWnd* pParent = NULL); // standard constructor
~CDDLReaderDlg();
// Dialog Data
//{{AFX_DATA(CDDLReaderDlg)
enum { IDD = IDD_DDLREADER_DIALOG };
CEdit wFolder;
CListCtrl wFileList;
CButton wBrowse;
CButton wExport;
CString vFolder;
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDDLReaderDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CDDLReaderDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnSize(UINT nType, int cx, int cy);
CStatic wPopisek;
CEdit wDDLFile;
CButton wDDLBrowse;
afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI);
DDLFile _ddlfile;
afx_msg void OnEnKillfocusDdlfile();
void UpdateList(void);
virtual bool File(WString name, int group, unsigned long offset);
afx_msg void OnBnClickedDdlbrowse();
afx_msg void OnLvnColumnclickFilelist(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnBnClickedBrowse();
afx_msg void OnBnClickedExport();
afx_msg void OnNMDblclkFilelist(NMHDR *pNMHDR, LRESULT *pResult);
WPathname CreateTemp(int index);
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_DDLREADERDLG_H__E765355F_0112_4B3E_90CE_111E28FE8EC6__INCLUDED_)

View file

@ -0,0 +1,41 @@
// DlgProgress.cpp : implementation file
//
#include "stdafx.h"
#include "DDLReader.h"
#include "DlgProgress.h"
#include ".\dlgprogress.h"
// DlgProgress dialog
IMPLEMENT_DYNAMIC(DlgProgress, CDialog)
DlgProgress::DlgProgress(CWnd* pParent /*=NULL*/)
: CDialog(DlgProgress::IDD, pParent)
{
stop=false;
}
DlgProgress::~DlgProgress()
{
}
void DlgProgress::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_PROGRESS, wProgress);
DDX_Control(pDX, IDC_NAME, wDesc);
}
BEGIN_MESSAGE_MAP(DlgProgress, CDialog)
ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
END_MESSAGE_MAP()
// DlgProgress message handlers
void DlgProgress::OnBnClickedButton1()
{
stop=true;
}

View file

@ -0,0 +1,28 @@
#pragma once
#include "t:\h\atlmfc\include\afxcmn.h"
#include "t:\h\atlmfc\include\afxwin.h"
// DlgProgress dialog
class DlgProgress : public CDialog
{
DECLARE_DYNAMIC(DlgProgress)
public:
DlgProgress(CWnd* pParent = NULL); // standard constructor
virtual ~DlgProgress();
// Dialog Data
enum { IDD = IDD_EXPORTING };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
public:
CProgressCtrl wProgress;
CStatic wDesc;
afx_msg void OnBnClickedButton1();
bool stop;
};

View file

@ -0,0 +1,36 @@
#if !defined(AFX_IWSTRINGEFFECT_H__863ADE82_7789_4E54_BE7D_B8F0740FD81B__INCLUDED_)
#define AFX_IWSTRINGEFFECT_H__863ADE82_7789_4E54_BE7D_B8F0740FD81B__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <wchar.h>
class IWStringEffect
{
public:
///function returns extra size that effect needs
/**
@param curSize size of string that enters to the effect
@return count of extra characters needs to effects;
*/
virtual unsigned long GetEffectExtraSize(unsigned long curSize) {return 0;}
///function renders begin of string.
/** Function returns number of characters rendered, and must be <= then size returned by GetEffectExtraSize()
@param renderPtr pointer to render buffer
@param curSize size of string that enters to the effect
@return number of characters rendered. Entered string will be rendered behind.
*/
virtual unsigned long PreRenderString(wchar_t *renderPtr,unsigned long curSize) {return 0;}
///function renders effect.
/**
@param renderPtr pointer to begin of render buffer.
@param rendered number of characters rendered by previous effect. Value doesn't point to the end
of buffer, function must add result of PreRenderString */
virtual void RenderString(wchar_t *renderPtr, unsigned long rendered)=0;
};
#endif

View file

@ -0,0 +1,8 @@
// stdafx.cpp : source file that includes just the standard includes
// DDLReader.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"

View file

@ -0,0 +1,27 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__C5BDACC6_729E_4CA2_B27E_A1F209FB32A7__INCLUDED_)
#define AFX_STDAFX_H__C5BDACC6_729E_4CA2_B27E_A1F209FB32A7__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
#include "wstring.h"
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__C5BDACC6_729E_4CA2_B27E_A1F209FB32A7__INCLUDED_)

View file

@ -0,0 +1,408 @@
// WPathname.cpp: implementation of the WPathname class.
//
//////////////////////////////////////////////////////////////////////
#include "WPathname.h"
#include <windows.h>
#include <shlobj.h>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
WPathname::WPathname(const wchar_t *name /*=NULL*/)
{
if (name) SetPathname(name);
}
WPathname::WPathname(const WString &name)
{
SetPathname(name);
}
WPathname::WPathname(const wchar_t *relpath, const WPathname &abspath)
{
_fullpath=WString(relpath);
int chr=_fullpath.FindLast('\\');
if (chr!=-1)
{
_path=_fullpath.Left(chr+1);
_filetitle=_fullpath.Right(chr+1);
}
else
{
_filetitle=_fullpath;
}
chr=_filetitle.FindLast('.');
if (chr!=-1)
{
_extension=_filetitle.Right(chr);
_filetitle=_filetitle.Left(chr);
}
RelativeToFull(abspath);
}
WPathname::WPathname(const WPathname &other)
{
_fullpath=other._fullpath;
_path=other._path;
_filetitle=other._filetitle;
_extension=other._extension;
}
void WPathname::SetDrive(wchar_t dr)
{
if (HasDrive())
{
if (dr==0) _path=_path.Right(2);
else _path[0]=dr;
}
else if (dr!=0)
{
int np=IsNetworkPath();
wchar_t buff[2];
buff[0]=dr;
buff[1]=':';
buff[2]=0;
if (np)
_path=WString(buff)+_path.Right(np);
else
_path=WString(buff)+_path;
}
RebuildPath();
}
void WPathname::SetDirectory(const wchar_t *dir)
{
bool copydrv; //directory doesn't contain drive, need copy from original
bool addslash; //directory doesn't ending by backslash, need add it
int len=wcslen(dir);
copydrv=HasDrive(dir) || !HasDrive(); //copy original drive, if exists and directory doesn't contaion drive
if (wcsncmp(dir,L"\\\\",2)==0) copydrv=true; //network path, don't copy drive
addslash=len && dir[len-1]!='\\'; //add slash
if (copydrv)
_path=WString(dir);
else
_path=_path.Left(2)+WString(dir);
if (addslash)
_path+=WSC("\\");
RebuildPath();
}
void WPathname::SetFilename(const wchar_t *filename)
{
WString wfilename=WString(filename);
int dot=wfilename.FindLast('.');
if (dot==-1)
{
_filetitle=wfilename;
_extension=0;
}
else
{
_filetitle=wfilename.Left(dot);
_extension=wfilename.Right(dot);
}
RebuildPath();
}
void WPathname::SetExtension(const wchar_t *ext)
{
_extension=WString(ext);
RebuildPath();
}
void WPathname::SetFileTitle(const wchar_t *title)
{
_filetitle=WString(title);
RebuildPath();
}
void WPathname::SetPathname(const wchar_t *pathname)
{
SetPathname(WString(pathname));
}
void WPathname::SetPathname(const WString &pathname)
{
if (pathname.GetLength()==0) SetNull();
else
{
wchar_t *part;
DWORD needsz=GetFullPathNameW(pathname,0,NULL,&part);
wchar_t *fpth=(wchar_t *)alloca(needsz*sizeof(*fpth));
GetFullPathNameW(pathname,needsz,fpth,&part);
part=wcsrchr(fpth,'\\');
if (part) part++;else part=NULL;
if (part)
{
SetFilename(part);
*part=0;
}
else
SetFilename(WString());
SetDirectory(fpth);
}
}
const wchar_t *WPathname::GetNameFromPath(const wchar_t *path)
{
const wchar_t *c=wcsrchr(path,'\\');
if (c!=NULL) c++;else return path;
return c;
}
const wchar_t *WPathname::GetExtensionFromPath(const wchar_t *path)
{
const wchar_t *fname=GetNameFromPath(path);
const wchar_t *c=wcsrchr(fname,'.');
if (c==NULL) c=wcsrchr(path,0);
return c;
}
void WPathname::RebuildPath()
{
_fullpath=_path+_filetitle+_extension;
}
bool WPathname::GetDirectoryWithDriveWLBS(wchar_t *buff, size_t size) const
{
size_t psize=wcslen(GetDirectoryWithDrive());
if (psize>size) return false;
if (psize==0) {buff[0]=0;return true;}
wcsncpy(buff,GetDirectoryWithDrive(),psize-1);
buff[psize-1]=0;
return true;
}
WString WPathname::GetDirectoryWithDriveWLBS() const
{
if (_path.GetLength()) return _path.Left(_path.GetLength()-1);
return WString();
}
bool WPathname::IsPathValid() const
{
if (IsNull()) return false;
wchar_t *invalidChars=L"/*?\"<>|";
const wchar_t *path=GetFullPath();
if (*path==0) return false;
while (*path)
{
if (wcschr(invalidChars,*path)!=NULL) return false;
path++;
}
return true;
}
bool WPathname::SetTempDirectory()
{
wchar_t buff[1];
DWORD size=GetTempPathW(1,buff);
if (size==0) return false;
WString pth;
wchar_t *p=pth.CreateBuffer(size);
if (GetTempPathW(size,p)==0) return false;
pth.UnlockBuffer();
_path=pth;
return true;
}
bool WPathname::SetDirectorySpecial(int nSpecCode)
{
wchar_t buff[MAX_PATH];
if (SHGetSpecialFolderPathW(GetForegroundWindow(),buff,nSpecCode,FALSE)!=NOERROR) return false;
SetDirectory(buff);
return true;
}
bool WPathname::SetTempFile(const wchar_t *prefix, unsigned int unique)
{
wchar_t tempname[MAX_PATH];
if (GetTempFileNameW(GetDirectoryWithDrive(),prefix,unique,tempname)==0) return false;
this->SetPathname(tempname);
return true;
}
WPathname WPathname::GetExePath()
{
wchar_t buff[MAX_PATH*4];
GetModuleFileNameW(NULL,buff,sizeof(buff));
return WPathname(buff);
}
const wchar_t *WPathname::FullToRelativeProjectRoot(const wchar_t *full, const wchar_t *projectRoot)
{
const wchar_t *a=full,*b=projectRoot;
while (*a && towlower(*a)==towlower(*b)) {a++;b++;};
if (*b) return full;
return a;
}
bool WPathname::FullToRelative(const WPathname &relativeto)
{
if (relativeto.IsNull() || IsNull()) return false;
bool h1=HasDrive();
bool h2=relativeto.HasDrive();
if (h1!=h2) return false; //rozdilny zpusob adresace - nelze vytvorit relatvni cestu
if (h1==true && h2==true && towupper(GetDrive())!=towupper(relativeto.GetDrive()))
return false; //ruzne disky, nelze vytvorit relativni cestu
if (wcsncmp(_path,L"\\\\",2)==0) //sitova cesta
{
int slsh=0; //citac lomitek
const wchar_t *a=_path;
const wchar_t *b=relativeto._path;
while (towupper(*a)==towupper(*b) && *a && slsh<3) //zacatek sitove cesty musi byt stejny
{
if (*a=='\\') slsh++;
a++;b++;
}
if (slsh!=3) return false; //pokud neni stejny, nelze vytvorit relativni cestu
}
int sublevel=0;
const wchar_t *ps1=_path;
const wchar_t *ps2=relativeto._path;
if (h1) {ps1+=2;ps2+=2;}
const wchar_t *sls=ps2;
while (towupper(*ps1)==towupper(*ps2) && *ps1)
{
if (*ps2=='\\') sls=ps2+1;
ps1++;ps2++;
}
ps1-=ps2-sls;
if (sls)
{
while (sls=wcschr(sls,'\\'))
{
sls++;
sublevel++;
}
}
wchar_t *buff=(wchar_t *)alloca((sublevel*3+wcslen(ps1)+1)*sizeof(*buff));
wchar_t *pos=buff;
for (int i=0;i<sublevel;i++)
{wcscpy(pos,L"..\\");pos+=3;}
wcscpy(pos,ps1);
SetDrive(0);
SetDirectory(buff);
return true;
}
bool WPathname::RelativeToFull(const WPathname &ref)
{
if (ref.IsNull() || IsNull()) return false;
const wchar_t *beg;
if (HasDrive())
if (towupper(GetDrive())!=towupper(ref.GetDrive())) return false;
else beg=_path+2;
else beg=_path;
const wchar_t *end=wcschr(ref._path,0);
if (beg[0]=='\\')
{
int np;
if (ref.HasDrive()) end=ref._path+2;
else if (np=ref.IsNetworkPath()) end=ref._path+np;
else end=ref._path;
}
else while (wcsncmp(beg,L"..\\",3)==0 || wcsncmp(beg,L".\\",2)==0)
{
if (beg[1]=='.')
{
if (end>ref._path.GetString())
{
end--;
while (end>ref._path.GetString() && end[-1]!='\\') end--;
}
beg+=3;
}
else
beg+=2;
}
int partln=end-ref._path;
wchar_t *buff=(wchar_t *)alloca((partln+wcslen(beg)+1)*sizeof(*buff));
wcsncpy(buff,ref._path,partln);
wcscpy(buff+partln,beg);
SetDrive(0);
SetDirectory(buff);
return true;
}
int WPathname::IsNetworkPath() const
{
if (wcsncmp(_path,L"\\\\",2)==0) //sitova cesta
{
const wchar_t *p=_path+2;
const wchar_t *c=wcschr(p,'\\');
if (c) return c-_path;
}
return 0;
}
void WPathname::SetServerName(const wchar_t *server)
{
if (HasDrive()) SetDrive(0);
else
{
int np=IsNetworkPath();
_path=_path.Right(np);
}
_path=WSC("\\\\")+WString(server)+WSC("\\");
RebuildPath();
}
void WPathname::SetNull()
{
_fullpath=_path=_filetitle=_extension=0;
}
bool WPathname::GetPartFromPath(const wchar_t *path, int partnum, wchar_t *buff, int bufsize, int mode)
{
const wchar_t *scan=path;
while (*scan=='\\') scan++;
while (partnum && *scan)
{
while (*scan!='\\' && *scan) scan++;
while (*scan=='\\') scan++;
partnum--;
}
if (*scan==0)
{
buff[0]=0;
return false;
}
int pt=0;
if (mode==-1)
{
pt=scan-path;
if (pt>bufsize)
{
buff[0]=0;
return true;
}
else
memcpy(buff,path,pt);
}
bool nlast=false;
while (*scan && (mode==1 || !nlast) && pt<bufsize)
{
buff[pt]=*scan;
pt++;
scan++;
if (*scan=='\\') nlast=true;
}
if (pt==bufsize)
{
buff[0]=0;
return true;
}
buff[pt]=0;
return nlast;
}

View file

@ -0,0 +1,400 @@
// WPathname.h: interface for the WPathname class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_WPathname_H__158F59D5_B422_4FA6_86AC_10B5EC48C81B__INCLUDED_)
#define AFX_WPathname_H__158F59D5_B422_4FA6_86AC_10B5EC48C81B__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "WString.h"
#ifndef ASSERT
#ifdef _DEBUG
#define ASSERT(x) assert(x)
#else
#define ASSERT(x)
#endif
#endif
#define WPathnameCompare(op) bool operator op (const WPathname &other) const \
{if (IsNull() || other.IsNull()) return false;else return wcsicmp(_fullpath,other._fullpath) op 0;}\
bool operator op (const wchar_t *other) const \
{ASSERT(!other || other[0]!=0);\
if (IsNull() || other==NULL) return false;else return wcsicmp(_fullpath,other) op 0;}
/** class WPathname simplifying manipulation with WPathnames, filenames, general paths, and
also supports convert from absolute path to relative respectively */
class WPathname
{
///object value and data
/**The implementation of WPathname creates only one buffer for all variables. It can
increase speed by effective memory use. Strings are stored one after another separated
by zero byte. Evry time any string changed, implementation recalculate buffer usage, and
decide, whether it should resize buffer or not.
_fullpath also points to string contain full path with filename,
it is dominant value of the class
*/
WString _fullpath;
WString _path; ///<current path with drive
WString _filetitle; ///<file title without extension
WString _extension; ///<file extension
public:
///Construct WPathname class.
/** If name is not provided, current path is used, and as filename, WPathname suppl wildcards
*.* . That is useful, for searching in directory.<br>
If name is provided, WPathname will expand it into full name with drive and folder name.
@param name optional argument to inicialize object
*/
WPathname(const wchar_t *name=NULL);
WPathname(const WString &name);
///Construct WPathname class
/**
@param relpath Relative path or uncomplette path or single filename with extension.
WPathname will expand this WPathname into full using absolute path provided by the second
argument.
@param abspath Absolute path used as reference to folder - the origin of relative path
provided in the first argument.
*/
WPathname(const wchar_t *relpath, const WPathname &abspath);
///Construct WPathname as copy of another WPathname
WPathname(const WPathname &other);
///Function returns the current drive letter.
/** Before usage, ensure, that current WPathname contain drive.
In network path drive letter is missing.
In this case, result is undefined. To ensure, use HasDrive function
@return the drive letter of current path.
*/
wchar_t GetDrive() const
{
if (IsNull()) return 0;
return _path[0];
}
///Static function determines, if argument contain a drive information.
/**
@param dir directory to inspect
@return true, if directory contain drive.<p>
This function is independed, it don't need any WPathname variable declared.
*/
static bool HasDrive(const wchar_t *dir)
{return (dir[0]>='A' && dir[0]<='Z' || dir[0]>='a' && dir[0]<='z') && dir[1]==':';}
///Function determines, if current WPathname contain a drive information
/**
@return true, if current WPathname contain a drive information
*/
bool HasDrive() const
{
if (IsNull()) return false;
return HasDrive(_path);
}
///Function returns current folder name
/**
if current folder name contain drive, only folder name is returned (without drive).
In other cases (relative or network drives) returns full path.
@return folder name or full path. Pointer is valid until any first change in object.
Do not invoke release function at pointer!
*/
const wchar_t *GetDirectory() const
{
if (HasDrive()) return _path.GetString()+3;
else return _path.GetString()+IsNetworkPath();
}
const wchar_t *GetDirectoryWithDrive() const
{
return _path;
}
///Function returns current filename with extension
/**
@return current filename with extension. Pointer is valid until any first change in object.
Do not invoke release function at pointer!
*/
const wchar_t *GetFilename() const
{
if (IsNull()) return NULL;
const wchar_t *blk=wcsrchr(_fullpath,'\\');
if (blk) blk=blk+1;else blk=_fullpath;
return blk;
}
///Function returns current extension (with starting dot)
/**
@return current extension. Pointer is valid until any first change in object.
Do not invoke release function at pointer!
*/
const wchar_t *GetExtension() const
{return _extension;}
///Function returns current filename without extension (without dot)
/**
@return current filename without extension (without dot). Pointer is valid until any first change in object.
Do not invoke release function at pointer!
*/
const wchar_t *GetTitle() const
{return _filetitle;}
///Function changes current drive.
/**If object contain WPathname with drive, then current drive is changed and function returns.
If object contain network path, then computer name is changed to the drive name.
If object contain relative path, then whole path is replaced by path on root on drive.
@param dr new drive letter. This parameter can be set to zero. It means, that current
driver is deleted, and path is converted to relative path from root. Note: Zero c
cannot be used with network paths and relative paths, and finnaly has no effect to the object
*/
void SetDrive(wchar_t dr);
///Sets new directory for object
/** if object contain a drive letter and argument dir doesn't, then current drive is remain
and only directory part is replaced. If current path is network path or relative path,
then whole path is replaced by new one.
If argument dir contain drive letter, then whole path is replaced too.
@param dir contain new WPathname. Backslash should be the last wchar_tacter in string
*/
void SetDirectory(const wchar_t *dir);
///Sets new filename for object.
/**
If filename contain dot, function assumes, that filename is provided with extension.
Otherwise, current extension remains untouched.
@param filename new filename for object
*/
void SetFilename(const wchar_t *filename);
///Sets new extension for object.
/**
If ext doesn't starting with dot, function adds it.
@param ext new extension for object
*/
void SetExtension(const wchar_t *ext);
///Sets new file title
/** Function changes file title, extension remains untouched.
if title contains extension (dot inside its name), this extension doesn't change
current extension. For example, if current extension is ".cpp" and filetitle contain
"source.h", then result is "source.h.cpp"
@param title a new title for object.
*/
void SetFileTitle(const wchar_t *title);
///Function returns full WPathname.
/**
@return current WPathname. Pointer is valid until any first change in object.
Do not invoke release function at pointer!
*/
const wchar_t *GetFullPath() const
{return _fullpath;}
///Sets WPathname
/** Function has same effect as constructor. But it can be used
anytime during object lifetime. It simply replaces current WPathname with newer. WPathname
in argument is expanded to full WPathname, current directory is used as reference.
@param WPathname new WPathname
*/
void SetPathname(const wchar_t *pathname);
void SetPathname(const WString &pathname);
WPathname& operator=(const wchar_t *other)
{SetPathname(other);return *this;}
WPathname& operator=(const WString &other)
{SetPathname(other);return *this;}
WPathname& operator=(const WPathname& other)
{
_fullpath=other._fullpath;
_path=other._path;
_filetitle=other._filetitle;
_extension=other._extension;
return *this;
}
///converts object to string
operator const wchar_t *() const
{return GetFullPath();}
///Static function to help getting filename from WPathname
/** Function finds last backslash / and return pointer to first wchar_tacter after it.
Pointer stays valid until original path is destroyed or until original path is changed
@param path WPathname to inspect as string
@return pointer to filename
*/
static const wchar_t *GetNameFromPath(const wchar_t *path);
///Static function to help getting extension from WPathname
/** Function finds last dot '.' in filename return pointer to it (extension with dot).
Pointer stays valid until original path is destroyed or until original path is changed
@param path WPathname to inspect as string
@return pointer to extension
*/
static const wchar_t *GetExtensionFromPath(const wchar_t *path);
///Function sets server name for network path
/** If current path is network path, then changes server name to newer. Otherwise
it remove drive letter, and insert server name before remain path
@param server server name without slashes
*/
void SetServerName(const wchar_t *server);
///Function inspects current path and returns, whether contain server name
/**@return zero, if current path is not valid network path. Nonzero if path contain
server name. Then value returned count wchar_tacters containing server name with precedent
slashes.
*/
int IsNetworkPath() const;
///Function converts current relative path into absolute path
/**
If current path is not relative, function do nothing.
@param ref reference to path, against which path is relative.
@return true if path has been converted, or false, if conversion is impossible
*/
bool RelativeToFull(const WPathname &ref);
///Function converts current absolute path into relative path
/**
If current path is not relative, function do nothing. Both paths must be on the same
drive or network computer.
@param ref reference to path, against which path should be relative.
@return true if path has been converted, or false, if conversion is impossible
*/
bool FullToRelative(const WPathname &relativeto);
WPathname& operator+=(const wchar_t *relativePath)
{*this=WPathname(relativePath,*this);return *this;}
WPathname operator+(const wchar_t *relativePath)
{WPathname out(relativePath,*this);return out;}
bool IsNull() const {return _fullpath.GetLength()==0;}
void SetNull();
WPathnameCompare(<)
WPathnameCompare(>)
WPathnameCompare(==)
WPathnameCompare(>=)
WPathnameCompare(<=)
WPathnameCompare(!=)
///Function gets part of WPathname
/**
@param path subject of examine
@param partnum zero-base index of part of WPathname. Index 0 mostly contain drive or server, in case of
relative path, there is the name of the first folder or dots.
@param buff buffer for store result
@param bufsize count wchar_tacters in buffer;
@param mode mode=0, gets only name of part.
mode=1, get current part and remain parts of path.
mode=-1, gets all parts till current
@return Function returns true, if it was succesful, and it was not last part. Function returns
false, if it was succesful, and it was last part. Function returns false and sets buffer empty,
if an error occured. Function returns true and sets buffer empty, if buffer is too small to hold data
*/
static bool GetPartFromPath(const wchar_t *path, int partnum, wchar_t *buff, int bufsize, int mode=0);
///Function gets part of object
/**
@param partnum zero-base index of part of WPathname. Index 0 mostly contain drive or server, in case of
relative path, there is the name of the first folder or dots.
@param buff buffer for store result
@param bufsize count wchar_tacters in buffer;
@param mode mode=0, gets only name of part.
mode=1, get current part and remain parts of path.
mode=-1, gets all parts till current
@return Function returns true, if it was succesful, and it was not last part. Function returns
false, if it was succesful, and it was last part. Function returns false and sets buffer empty,
if an error occured. Function returns true and sets buffer empty, if buffer is too small to hold data
*/
bool GetPart(int partnum, wchar_t *buff, int bufsize,int mode=0) const
{
return GetPartFromPath(this->_fullpath,partnum,buff,bufsize,mode);
}
/// Get Directory With Drive Without Last Back Slash
/** Retrieves into buffer directory with drive and removes last backslash
@param buff buffer that retrieves path
@param size size of buffer
@return true, if success, failed if buffer is too small*/
bool GetDirectoryWithDriveWLBS(wchar_t *buff, size_t size) const;
WString GetDirectoryWithDriveWLBS() const;
/// function checks, if path is valid and returns true, if does.
bool IsPathValid() const;
/// Sets special directory.
/**
@param bSpecCode this value may be operation-system
depend. Windows implementation using CSIDL_XXXX constants, which is described in SHGetSpecialFolderLocation function
description
@return true, if function were successful
*/
bool SetDirectorySpecial(int nSpecCode);
///Sets temporaly directory.
bool SetTempDirectory();
///Guess temporaly file name
/**
@param prefix prefix string for name
@param unique if unique is non-zero, it is used for new temporaly file. If unique is zero, function guess own unique
value.
@return true if function were successful
*/
bool SetTempFile(const wchar_t *prefix=L"tmp", unsigned int unique=NULL);
///Returns path of current executable.
/**It useful, when accessing folder, from when current module has been executed */
static WPathname GetExePath();
///Solves most used conversion from fullpath to path relative to project root
/**
@param full full WPathname with drive
@param projectRoot project root path
@return function returns pointer to full path, where starts relative part. If
fullpath doesn't contain project root path, it returns pointer to full.
@example FullToProjectRoot("x:\\project\\data\\example.txt","x:\\project"); //result is "data\\example.txt"
*/
static const wchar_t *FullToRelativeProjectRoot(const wchar_t *full, const wchar_t *projectRoot);
protected:
///Function only rebuild _fullpath string.
/** It doesn't check space for string! This function is used, when length of path is excepted
the same or smaller, then current.
*/
void RebuildPath();
};
#endif // !defined(AFX_WPathname_H__158F59D5_B422_4FA6_86AC_10B5EC48C81B__INCLUDED_)

View file

@ -0,0 +1,193 @@
// WString.cpp: implementation of the WString class.
//
//////////////////////////////////////////////////////////////////////
#include "WString.h"
#include <windows.h>
#include <stdio.h>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
WString::WString(const char *sbstring, unsigned int codePage)
{
if (sbstring==NULL || *sbstring==0)
{
_ref=NULL;
}
else
{
size_t reqBuff=MultiByteToWideChar(codePage,0,sbstring,-1,NULL,0);
_ref=WStringMemory::AllocString(NULL,reqBuff);
_ref->AddRef();
wchar_t *str=const_cast<wchar_t *>(_ref->GetStringFromMemBlock());
MultiByteToWideChar(codePage,0,sbstring,-1,str,reqBuff);
}
}
int WString::FormatV(wchar_t *format, va_list lst)
{
size_t curSize=4096;
int written;
do
{
_ref=WStringMemory::AllocString(NULL,curSize);
wchar_t *str=const_cast<wchar_t *>(_ref->GetStringFromMemBlock());
written=_vsnwprintf(str,curSize,format,lst);
if (written<0)
{
curSize*=2;
WStringMemory::FreeProxy(_ref);
}
}
while (written<-1);
_ref->RecalcLength();
_ref->AddRef();
return written;
}
int WString::Format(wchar_t *format, ...)
{
va_list valst;
va_start(valst,format);
return FormatV(format,valst);
}
int WString::ScanStringV(const wchar_t *format, va_list lst) const
{
unsigned long *ptr=(unsigned long *)lst;
return swscanf(GetString(),format,ptr[0],ptr[1],ptr[2],ptr[3],ptr[4],ptr[5],ptr[6],ptr[7],ptr[8],ptr[9],
ptr[10],ptr[11],ptr[12],ptr[13],ptr[14],ptr[15],ptr[16],ptr[17],ptr[18],ptr[19]);
}
int WString::ScanString(const wchar_t *format, ...) const
{
va_list valst;
va_start(valst,format);
return ScanStringV(format,valst);
}
bool WString::ReplaceOnce(const WString &findWhat,const WString &replaceWith)
{
int pos=Find(findWhat);
if (pos==-1) return false;
(*this)=Left(pos)+replaceWith+Right(pos+replaceWith.GetLength());
return true;
}
bool WString::ReplaceAll(const WString &findWhat,const WString &replaceWith)
{
WString process=*this;
WString result;
int pos;
bool processed=false;
while ((pos=process.Find(findWhat))!=-1)
{
result=result+process.Left(pos)+replaceWith;
process=process.Right(pos+findWhat.GetLength());
processed=true;
}
*this=result+process;
return processed;
}
WString WString::TrimLeft() const
{
return TrimLeft(L" \r\n\t");
}
WString WString::TrimRight() const
{
return TrimRight(L" \r\n\t");
}
WString WString::TrimLeft(wchar_t *trimChars) const
{
const wchar_t *proStr=GetString();
int p=0;
while (proStr[p] && wcschr(trimChars,proStr[p]!=NULL)) p++;
return Right(p);
}
WString WString::TrimRight(wchar_t *trimChars) const
{
const wchar_t *proStr=GetString();
int p=GetLength()-1;
while (p>=0 && wcschr(trimChars,proStr[p]!=NULL)) p--;
return Left(p+1);
}
WString WString::Upper() const
{
return WString(WStringMemory::AllocProxy(WStringProxy(_ref,WStringProxy::EfUpper)));
}
WString WString::Lower() const
{
return WString(WStringMemory::AllocProxy(WStringProxy(_ref,WStringProxy::EfLower)));
}
WString WString::Reverse() const
{
return WString(WStringMemory::AllocProxy(WStringProxy(_ref,WStringProxy::EfReverse)));
}
WString WString::Effect(IWStringEffect *effect) const
{
return WString(WStringMemory::AllocProxy(WStringProxy(_ref,effect)));
}
void WString::SetUTF7(const char *utf7)
{
*this=WString(utf7,CP_UTF7);
}
void WString::SetUTF8(const char *utf8)
{
*this=WString(utf8,CP_UTF8);
}
const char *WString::AsSBString(unsigned int codePage, WString &holder)
{
const wchar_t *str=GetString();
size_t reqsize=WideCharToMultiByte(codePage,0,str,-1,NULL,0,NULL,NULL);
WStringProxy *holderProxy=WStringMemory::AllocString(NULL,reqsize/2); //reqsize/2+(2 bytes)
char *mbstr=reinterpret_cast<char *>(const_cast<wchar_t *>(holderProxy->GetStringFromMemBlock()));
WideCharToMultiByte(codePage,0,str,-1,mbstr,reqsize,NULL,NULL);
holder=WString(holderProxy);
return mbstr;
}
const char *WString::AsUTF7(WString &holder)
{
return AsSBString(CP_UTF7,holder);
}
const char *WString::AsUTF8(WString &holder)
{
return AsSBString(CP_UTF8,holder);
}
void WString::ReadFromStream(size_t (*streamReader)(wchar_t *buffer, size_t bufferLen, void *context),void *context)
{
_ref->Release();
_ref=NULL;
wchar_t buff[256];
size_t rd;
while ((rd=streamReader(buff,sizeof(buff)/sizeof(wchar_t),context))!=0)
{
*this=*this+WString(buff,rd);
}
}
const WString WStringConst(const wchar_t *text)
{
return WString(WStringMemory::AllocProxy(WStringProxy(text)));
}

View file

@ -0,0 +1,496 @@
// WString.h: interface for the WString class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_WSTRING_H__481164FB_3BB7_4824_B0E3_8B371F0AAF3A__INCLUDED_)
#define AFX_WSTRING_H__481164FB_3BB7_4824_B0E3_8B371F0AAF3A__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "WStringProxy.h"
#include <stdlib.h>
class WString
{
mutable WStringProxy *_ref;
public:
///constructs empty string
WString():_ref(0) {}
///constructs string.
explicit WString(const wchar_t *string):_ref(string==NULL?NULL:WStringMemory::AllocString(string,0)) {_ref->AddRef();};
///constructs string from wide-char array with specified length
WString(const wchar_t *string, size_t sz):_ref(WStringMemory::AllocString(string,sz)) {_ref->AddRef();};
///copy constructor
/**constructor doesn't copy the string, only reference.
String is shared until it is changed
*/
WString(const WString &other):_ref(other._ref) {_ref->AddRef();}
///constructs string from multi-byte string. codePage specified code page of string
WString(const char *sbstring, unsigned int codePage);
///constructs string from string-proxy. Used internally with WStringMemory::AllocXXX functions
WString(WStringProxy *proxy):_ref(proxy) {_ref->AddRef();}
///assignment operator
/** assignment operator doesn't copy the string only reference.
String is shared until it is changed */
WString &operator=(const WString &other)
{other._ref->AddRef();_ref->Release();_ref=other._ref;return *this;}
///Destructor - releases reference
~WString() {_ref->Release();}
///function converts instance of WString to wchar_t pointer
/**
Function will perform RenderString, if it is needed.
*/
const wchar_t *GetString() const
{
if (_ref==NULL) return L"";
WStringProxy *str=_ref->RenderString();
if (_ref!=str)
{
str->AddRef();_ref->Release();_ref=str;
}
return _ref->GetStringFromMemBlock();
}
///operator can convert WString to wchar_t pointer anytime
operator const wchar_t *() const {return GetString();}
///function returns count of characters in string
/** function doesn't need to render string, so it can be called anytime
without loosing the benefit of "pseudo-strings" boosting */
size_t GetLength() const
{
if (_ref) return _ref->GetLength();
else return 0;
}
///function creates string as sum of this and another string
/** function creates "pseudo-string" that represents sum of two string.
pseudo-string is rendered to "real-string" automatically, when it is needed */
WString operator+(const WString other) const
{
if (_ref==NULL) return other;
if (other._ref==NULL) return *this;
return WString(WStringMemory::AllocProxy(WStringProxy(_ref,other._ref)));
}
WString &operator+=(const WString other)
{
*this=*this+other;
return *this;
}
///function creates string as substring of another string
/** function creates "pseudo-string" that represents substring of anothers string.
Pseudo-string is rendered to "real-string" automatically, when it is needed */
WString Mid(size_t begin, size_t len) const
{
if (begin==0) return Left(len);
if (_ref==NULL || begin>GetLength()) return WString();
if (begin+len>GetLength()) return Right(begin);
return WString(WStringMemory::AllocProxy(WStringProxy(_ref,begin,len)));
}
WString Left(size_t len) const
{
if (_ref==NULL) return WString();
if (len>=GetLength()) return *this;
return WString(WStringMemory::AllocProxy(WStringProxy(_ref,0,len)));
}
WString Right(size_t begin) const
{
if (_ref==NULL || begin>GetLength()) return WString();
if (begin==0) return *this;
return WString(WStringMemory::AllocProxy(WStringProxy(_ref,begin,GetLength()-begin)));
}
WString RightR(size_t count) const
{
if (_ref==NULL || count==0) return WString();
if (count>=GetLength()) return *this;
return WString(WStringMemory::AllocProxy(WStringProxy(_ref,GetLength()-count,count)));
}
WString Delete(size_t begin, size_t count) const
{
if (_ref==NULL) return WString();
if (begin==0) return Right(count);
if (begin+count>=GetLength()) return Left(begin);
return WString(WStringMemory::AllocProxy(WStringProxy(Left(begin)._ref,Right(begin+count)._ref)));
}
WString Insert(const WString &what, size_t index) const
{
if (_ref==NULL) return what;
if (index==0) return what+*this;
if (index>=GetLength()) return *this+what;
return Left(index)+what+Right(index);
}
/// function allows to access any char in string
wchar_t operator[](int index) const
{
assert(index<=(int)GetLength() && index>=0);
return GetString()[index];
}
/// functions allows lock string for accesing it directly.
/** Function returns pointer to buffer which holds string.
Buffer size is equal to string length plus terminating zero.
Application can modify content of buffer.
If string is shared with another WString object, LockBuffer
creates copy of string
Do not forger to call UnlockBuffer, when you finish modifiing the content
*/
wchar_t *LockBuffer()
{
if (_ref==NULL) return NULL;
GetString();
WStringMemory::LockProxy(_ref);
if (_ref->IsShared())
{
WStringMemory::UnlockProxy(_ref);
_ref->Release();
_ref=WStringMemory::AllocString(_ref->GetStringFromMemBlock(),0);
_ref->AddRef();
WStringMemory::LockProxy(_ref);
}
return const_cast<wchar_t *>(_ref->GetStringFromMemBlock());
}
/// Function creates buffer for string and returns its address
/** Application can use buffer in functions, that cannot work with
WString objects. Size of buffer is specified by sz value, and it is in characters.
Application must call UnlockBuffer after writes all data into buffer.
NOTE: Prevoius content of string is lost.
NOTE: sz specifies buffer size without terminating zero character
*/
wchar_t *CreateBuffer(size_t sz)
{
_ref->Release();
_ref=WStringMemory::AllocString(NULL,sz);
_ref->AddRef();
WStringMemory::LockProxy(_ref);
return const_cast<wchar_t *>(_ref->GetStringFromMemBlock());
}
/// Function creates buffer, and copies string into it.
/** Parameter sz specifies size of new buffer in characters
When sz is smaller then size of string, string is truncated
When sz is larger then size of string, string is copied unchanged,
but extra characters can be appended.
NOTE: sz specifies buffer size without terminating zero character
*/
wchar_t *CreateBufferCopy(size_t sz)
{
WString save=*this;
wchar_t *wbuff=CreateBuffer(sz);
int minsz=__min(sz,save.GetLength());
wcsncpy(wbuff,save.GetString(),minsz);
return wbuff;
}
/// Function unlocks internal buffer
/** parameter sz specifies final lenght of string in buffer. Default
value -1 forces function calc size by own
*/
void UnlockBuffer(int sz=-1)
{
if (_ref==NULL) return;
wchar_t *wbuff=const_cast<wchar_t *>(_ref->GetStringFromMemBlock());
if (sz<0) sz=wcslen(wbuff);
else wbuff[sz]=0;
if (sz!=(signed)_ref->GetLength())
{
_ref->RecalcLength();
WStringMemory::UnlockProxy(_ref);
}
}
class WStringAtCharHelper
{
WString &_str;
size_t _index;
public:
WStringAtCharHelper(WString &str,size_t index):_str(str),_index(index) {}
WString &operator=(wchar_t z)
{
wchar_t *buff=_str.LockBuffer();
assert(buff && _index<_str.GetLength());
buff[_index]=z;
_str.UnlockBuffer();
return _str;
}
operator wchar_t()
{
assert(_index<_str.GetLength());
return ((const wchar_t *)_str)[_index];
}
};
/// Function will return helper object, which can access single character in string
/**
Using array operator is slower than accessing characters by LockBuffer function
*/
WStringAtCharHelper operator[](int index)
{
return WStringAtCharHelper(*this,index);
}
int Find(wchar_t z,size_t from=0) const
{
if (from>=GetLength()) return -1;
const wchar_t *res=wcschr(GetString()+from,z);
if (res) return res-GetString();
else return -1;
}
int FindLast(wchar_t z) const
{
const wchar_t *res=wcsrchr(GetString(),z);
if (res) return res-GetString();
else return -1;
}
int Find(const wchar_t *z,size_t from=0) const
{
if (z==NULL) return -1;
if (from>=GetLength()) return -1;
const wchar_t *res=wcsstr(GetString()+from,z);
if (res) return res-GetString();
else return -1;
}
int FormatV(wchar_t *format, va_list lst);
int Format(wchar_t *format, ...);
///Scans string for format
/** function is limited, item count is limited up to 20 items */
int ScanStringV(const wchar_t *format, va_list lst) const;
///Scans string for format
/** function is limited, item count is limited up to 20 items */
int ScanString(const wchar_t *format, ...) const;
bool ReplaceOnce(const WString &findWhat,const WString &replaceWith);
bool ReplaceAll(const WString &findWhat,const WString &replaceWith);
WString TrimLeft() const;
WString TrimRight() const;
WString TrimLeft(wchar_t *trimChars) const;
WString TrimRight(wchar_t *trimChars) const;
///Function splits string into two
/** Left part of string is returned.
Right part of string is leaved in object
@param splitPos split position.
@return if splitPos==0, function returns empty string. if splitPos>=length, function
moves string from object to result*/
WString Split(size_t splitPos)
{
WString result=Left(splitPos);
*this=Right(splitPos);
return result;
}
bool IsEmpty() const {return _ref==NULL;}
void Empty() const {_ref->Release();_ref=NULL;}
int Compare(const wchar_t *other) const
{
return wcscmp(*this,other);
}
bool operator>(const WString &other) const {return Compare(other)>0;}
bool operator<(const WString &other) const {return Compare(other)<0;}
bool operator>=(const WString &other) const {return Compare(other)>=0;}
bool operator<=(const WString &other) const {return Compare(other)<=0;}
bool operator!=(const WString &other) const {return Compare(other)<=0;}
bool operator==(const WString &other) const {return Compare(other)<=0;}
WString Upper() const;
WString Lower() const;
WString Reverse() const;
///Applies user effect on string
/** pointer should be static allocated object, or must be valid during lifetime of resulting string */
WString Effect(IWStringEffect *effect) const;
void SetUTF7(const char *utf7);
void SetUTF8(const char *utf8);
///Function converts string to SingleByte string
/**
@param codePage Platform depends code page of result
@param holder Object that holds result. Result pointer is valid during lifetime of holder. Once holder
released, pointer is invalidated. You can get resulting pointer anytime from holder reintepreting
wchar_t to char
@result pointer to string
*/
const char *AsSBString(unsigned int codePage, WString &holder);
///Returns multibyte string in UTF7 codepage
/**See AsSBString description*/
const char *AsUTF7(WString &holder);
///Returns multibyte string in UTF7 codepage
/**See AsSBString description*/
const char *AsUTF8(WString &holder);
///Function reads string from stream
/**
Function calls streamReader repeatly until function returns zero. In each call, streamReader returns
number of characters, that has been readed.
@param sreamReader pointer to function which provides reading from a stream
@param context user defined context pointer (most in cases, pointer to stream is passed)
@param buffer space allocated for data readed from stream
@param bufferLen maximum count of characters can be written to buffer
@return streamReader returns number of characters, that has been written to buffer. Function must return zero
to stop reading
*/
void ReadFromStream(size_t (*streamReader)(wchar_t *buffer, size_t bufferLen, void *context),void *context);
WString operator() (int from) const {return from<0?RightR(-from):Right(from);}
WString operator() (int from, int to) const
{
if (from>=0)
return to<0?Mid(from,-to):Mid(from,to-from);
else
return to<0?Mid(GetLength()+from,-to):Mid(GetLength()+from,GetLength()-from-to);
}
///Enables global string sharing.
/** Function Share allows share strings that contains same text. It can reduce memory
usage. Function is useful when there is many objects that contains string with same text.
Basically, two strings is shared, if one string is created as copy of another string. Strings
is sharing they content, until one of them is modified.
Calling Share function, string is registered for global sharing. If string with same content is already
registered, then content of current string is released, and string is shared.
To successfully share two strings, both strings must call Share() function. Sharing is provided until one
of strings is modified. After modifications are done, Share function of modified string must be called again.
Remember: Global sharing can reduce amount of memory, if there are multiple strings that containging
the same content. But sharing of each unique string takes small piece of memory to store sharing
informations.
To share string automatically, use WSharedString class
WSC strings cannot be shared!
*/
void Share() const
{
WStringProxy *curref=_ref;
GetString();
_ref=WStringMemory::ShareString(curref);
_ref->AddRef();
curref->Release();
}
///Disables global string sharing
/** Function unregisters string from global sharing database. If string is shared, function doesn't break
it. But all strings that currently sharing content will not be shared with newly created strings.
*/
void Unshare()
{
WStringMemory::UnshareString(_ref);
}
};
///Function will create constant WString
/** function will not copy content of string. Only creates reference to string
Using WStringConst is faster for strings in code
@exmple result=a+WStringConst(L"text")+b;
*/
const WString WStringConst(const wchar_t *text);
///Macro to easy convert incode string to WString
/**
function also marks text wide.
@example WString text=WSC("Hello world");
*/
#define WSC(x) WStringConst(L##x)
///Macro to easy convert any wchar_t buffer to constant WString
/**
IMPORTANT NOTE!: Buffer must exists until string is rendered.
If you are using WSCB in function, don't forget call GetString before function exits
If you are excepting additional string operations outside function, using standard
WString conversion can be more effecient.
*/
#define WSCB(x) WStringConst(x)
class WSharedString: public WString
{
public:
WSharedString() {}
///constructs string.
explicit WSharedString(const wchar_t *string):WString(string) {Share();}
///constructs string from wide-char array with specified length
WSharedString(const wchar_t *string, size_t sz):WString(string,sz) {Share();};
///copy constructor
/**constructor doesn't copy the string, only reference.
String is shared until it is changed
*/
WSharedString(const WSharedString &other):WString(other) {}
WSharedString(const WString &other):WString(other) {Share();}
///constructs string from multi-byte string. codePage specified code page of string
WSharedString(const char *sbstring, unsigned int codePage):WString(sbstring,codePage) {Share();}
///assignment operator
/** assignment operator doesn't copy the string only reference.
String is shared until it is changed */
WSharedString &operator=(const WString &other)
{WString::operator =(other);Share();return *this;}
const wchar_t *GetString() const
{
const wchar_t *res=WString::GetString();
Share();
return res;
}
operator const wchar_t *() const {return GetString();}
wchar_t operator[](int index) const
{
assert(index<=(int)GetLength() && index>=0);
return GetString()[index];
}
void UnlockBuffer(int sz=-1)
{
WString::UnlockBuffer(sz);
Share();
}
};
#endif // !defined(AFX_WSTRING_H__481164FB_3BB7_4824_B0E3_8B371F0AAF3A__INCLUDED_)

View file

@ -0,0 +1,397 @@
// WStringMemorySingleThread.cpp: implementation of the WStringMemory class.
//
//////////////////////////////////////////////////////////////////////
#include <malloc.h>
#include <windows.h>
#include "WStringMemory.h"
#include "WStringProxy.h"
#include <assert.h>
#include <stdio.h>
#include <projects/btree/btree.h>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#ifdef _MT //multithreading
#define WSTRING_MT
#endif
#ifdef WSTRING_MT //multithreading
struct WStringMTLock
{
WStringProxy *_lockProxy;
LONG _recursionCount;
DWORD _owner;
HANDLE _event;
WStringMTLock(WStringProxy *x):_lockProxy(x) {}
WStringMTLock():_lockProxy(NULL) {}
bool operator==(const WStringMTLock &other) const {return _lockProxy==other._lockProxy;}
bool operator!=(const WStringMTLock &other) const {return _lockProxy!=other._lockProxy;}
bool operator>=(const WStringMTLock &other) const {return _lockProxy>=other._lockProxy;}
bool operator<=(const WStringMTLock &other) const {return _lockProxy<=other._lockProxy;}
bool operator>(const WStringMTLock &other) const {return _lockProxy>other._lockProxy;}
bool operator<(const WStringMTLock &other) const {return _lockProxy<other._lockProxy;}
int operator=(int zero) {_lockProxy=NULL;return zero;}
};
static CRITICAL_SECTION GLocker={{0},-1,0,0,0,0};
static HANDLE GLockProxy=NULL; //event object to notify waiters that somebody unlocks;
static BTree<WStringMTLock> *GLockDB=NULL; //Lock proxy database
static void exitMT()
{
DeleteCriticalSection(&GLocker);
}
static void OnStartup()
{
InitializeCriticalSection(&GLocker);
atexit(exitMT);
}
#define ON_STARTUP_PRIORITY_NORMAL OnStartup
#include <Es/Common/Startup.hpp>
#endif
#define WS_MAXFREELISTS 32
#define WS_FREELISTSTEP 32
#define WS_TOTALMAXFREEKBYTES 256
#define WS_MAXIMUMFASTALLOC (WS_MAXFREELISTS*WS_FREELISTSTEP)
#define WS_MAXFREEBYTES PerSlotMaxAlloc
static size_t PerSlotMaxAlloc=(WS_TOTALMAXFREEKBYTES*1024/WS_MAXFREELISTS);
static WStringProxy *FreeList=NULL;
static void **StringFreeList[WS_MAXFREELISTS];
static size_t StringFreeBytes[WS_MAXFREELISTS];
static bool InitManager=true;
static void InitManagerPointers()
{
memset(StringFreeList,0,sizeof(StringFreeList));
memset(StringFreeBytes,0,sizeof(StringFreeBytes));
InitManager=false;
}
static void *AllocStringBlock(size_t sz)
{
if (InitManager) InitManagerPointers();
if (sz>WS_MAXIMUMFASTALLOC) return malloc(sz);
int pos=(sz+WS_FREELISTSTEP-1)/WS_FREELISTSTEP;
void **nxt=StringFreeList[pos];
if (nxt==0)
{
printf("malloc %d\n",pos*WS_FREELISTSTEP);
return malloc(pos*WS_FREELISTSTEP);
}
printf("fast_alloc %d\n",pos*WS_FREELISTSTEP);
StringFreeList[pos]=(void **)(*nxt);
StringFreeBytes[pos]-=_msize(nxt);
return nxt;
}
static void DeallocStringBlock(void *ptr)
{
size_t sz=_msize(ptr);
if (sz>WS_MAXIMUMFASTALLOC) {free(ptr);return;}
int pos=(sz+WS_FREELISTSTEP-1)/WS_FREELISTSTEP;
if (sz+StringFreeBytes[pos]>WS_MAXFREEBYTES)
{
printf("free %d\n",sz);
free(ptr);return;
}
void **proxy=(void **)ptr;
*proxy=(void *)StringFreeList[pos];
StringFreeList[pos]=proxy;
StringFreeBytes[pos]+=sz;
printf("fast_free %d\n",sz);
}
static inline void *operator new(size_t alloc,size_t sz)
{
return AllocStringBlock(sz+alloc);
}
static inline void operator delete(void *p,size_t alloc)
{
DeallocStringBlock(p);
}
static inline void *operator new(size_t sz,void *ptr)
{
return ptr;
}
static inline void operator delete(void *ptr,void *p)
{
}
WStringProxy * WStringMemory::AllocString(const wchar_t *text, size_t size)
{
#ifdef WSTRING_MT
EnterCriticalSection(&GLocker);
#endif
assert(size!=0 || text!=0);
if (size==0) size=wcslen(text);
WStringProxy *proxy=new((size+1)*sizeof(wchar_t)) WStringProxy(size,0,0);
wchar_t *alloctext=const_cast<wchar_t *>(proxy->GetStringFromMemBlock());
if (text) wcsncpy(alloctext,text,size);
alloctext[size]=0;
if (proxy->_redirect==0)
{
proxy->_redirect=alloctext;
proxy->_blockData2=1;
}
#ifdef WSTRING_MT
LeaveCriticalSection(&GLocker);
#endif
return proxy;
}
WStringProxy * WStringMemory::AllocProxy(const WStringProxy &templateProxy)
{
WStringProxy * res;
#ifdef WSTRING_MT
EnterCriticalSection(&GLocker);
#endif
if (FreeList==NULL) res=new WStringProxy(templateProxy);
else
{
WStringProxy *alloc=FreeList;
FreeList=alloc->_baseString;
res=new((void *)alloc) WStringProxy(templateProxy);
}
#ifdef WSTRING_MT
LeaveCriticalSection(&GLocker);
#endif
return res;
}
void WStringMemory::FreeProxy(WStringProxy *proxy)
{
#ifdef WSTRING_MT
EnterCriticalSection(&GLocker);
#endif
if (proxy->_operation==proxy->OpMemBlck && !(proxy->_blockData2==0 && proxy->_redirect!=NULL))
{
if (proxy->_blockData2==2) UnshareString(proxy);
DeallocStringBlock(proxy);
}
else
{
proxy->~WStringProxy();
proxy->_baseString=FreeList;
FreeList=proxy;
}
#ifdef WSTRING_MT
LeaveCriticalSection(&GLocker);
#endif
}
#ifdef WSTRING_MT
void WStringMemory::LockProxy( WStringProxy *proxy)
{
nextTry:
EnterCriticalSection(&GLocker);
WStringMTLock srch(proxy),*found;
if (GLockDB==NULL) GLockDB=new BTree<WStringMTLock>(16);
found=GLockDB->Find(srch);
if (found==NULL)
{
srch._event=NULL;
srch._owner=GetCurrentThreadId();
srch._recursionCount=1;
GLockDB->Add(srch);
}
else
{
if (found->_owner!=GetCurrentThreadId())
{
HANDLE w=found->_event;
if (w==0) {w=found->_event=CreateEvent(NULL,TRUE,FALSE,NULL);}
LeaveCriticalSection(&GLocker); //leave section
WaitForSingleObject(w,INFINITE);
goto nextTry;
}
else
{
found->_recursionCount++;
}
}
LeaveCriticalSection(&GLocker); //leave section
}
void WStringMemory::UnlockProxy( WStringProxy *proxy)
{
EnterCriticalSection(&GLocker);
WStringMTLock srch(proxy),*found;
found=GLockDB->Find(srch);
if (found)
{
if (--found->_recursionCount==0)
{
if (found->_event!=NULL)
{
SetEvent(found->_event);
CloseHandle(found->_event);
}
GLockDB->Remove(*found);
}
}
LeaveCriticalSection(&GLocker);
}
void WStringMemory::AddRefProxy(WStringProxy *proxy)
{
InterlockedIncrement(reinterpret_cast<LONG *>(&proxy->_refCount));
}
bool WStringMemory::ReleaseRefProxy(WStringProxy *proxy)
{
LONG res=InterlockedDecrement(reinterpret_cast<LONG *>(&proxy->_refCount));
if (res<0) res=InterlockedIncrement(reinterpret_cast<LONG *>(&proxy->_refCount));
return res==0;
}
#else
void WStringMemory::LockProxy( WStringProxy *proxy)
{
//not needed in single thread environment
}
void WStringMemory::UnlockProxy( WStringProxy *proxy)
{
//not needed in single thread environment
}
void WStringMemory::AddRefProxy(WStringProxy *proxy)
{
//no special handling in single thread environment
++proxy->_refCount;
}
bool WStringMemory::ReleaseRefProxy(WStringProxy *proxy)
{
//no special handling in single thread environment
if (proxy->_refCount) --proxy->_refCount;
return proxy->_refCount==0;
}
#endif
void WStringMemory::FreeExtra()
{
#ifdef WSTRING_MT
EnterCriticalSection(&GLocker);
#endif
while (FreeList)
{
void *proxy=FreeList;
FreeList=FreeList->_baseString;
free(proxy);
}
for (int i=0;i<WS_MAXFREELISTS;i++)
{
while (StringFreeList[i])
{
void **proxy=StringFreeList[i];
StringFreeList[i]=(void **)(*proxy);
free(proxy);
}
StringFreeBytes[i]=0;
}
#ifdef WSTRING_MT
LeaveCriticalSection(&GLocker);
#endif
}
size_t WStringMemory::GetStatistics(size_t *details)
{
#ifdef WSTRING_MT
EnterCriticalSection(&GLocker);
#endif
size_t sum=0;
for (int i=0;i<WS_MAXFREELISTS;i++)
{
sum+=StringFreeBytes[i];
if (details) details[i]=StringFreeBytes[i];
}
#ifdef WSTRING_MT
LeaveCriticalSection(&GLocker);
#endif
return sum;
}
struct ShareDBItem
{
WStringProxy *_str;
ShareDBItem(WStringProxy *str=NULL):_str(str) {}
int Compare(const ShareDBItem& other) const
{
if (_str==NULL) return other._str!=NULL?1:0;
if (other._str==NULL) return -1;
return wcscmp(_str->_redirect,other._str->_redirect);
}
bool operator==(const ShareDBItem& other) const {return Compare(other)==0;}
bool operator>=(const ShareDBItem& other) const {return Compare(other)>=0;}
bool operator<=(const ShareDBItem& other) const {return Compare(other)<=0;}
bool operator!=(const ShareDBItem& other) const {return Compare(other)!=0;}
bool operator>(const ShareDBItem& other) const {return Compare(other)>0;}
bool operator<(const ShareDBItem& other) const {return Compare(other)<0;}
};
static BTree<ShareDBItem> *GDB=NULL;
WStringProxy *WStringMemory::ShareString(WStringProxy *proxy)
{
if (proxy->_operation!=WStringProxy::OpMemBlck || proxy->_blockData2==0 || proxy->_blockData2==2) return proxy;
#ifdef WSTRING_MT
EnterCriticalSection(&GLocker);
#endif
if (GDB==NULL) GDB=new BTree<ShareDBItem>;
proxy->_blockData2=2; //block is subject of sharing
proxy->_redirect=proxy->GetStringFromMemBlock(); //setup pointer to string
ShareDBItem *found=GDB->Find(ShareDBItem(proxy));
if (found) {proxy->_blockData2=1;proxy=found->_str;}
else GDB->Add(ShareDBItem(proxy));
#ifdef WSTRING_MT
LeaveCriticalSection(&GLocker);
#endif
return proxy;
}
void WStringMemory::UnshareString(WStringProxy *proxy)
{
if (proxy->_operation!=WStringProxy::OpMemBlck || proxy->_blockData2!=2) return;
if (GDB==NULL) return;
#ifdef WSTRING_MT
EnterCriticalSection(&GLocker);
#endif
GDB->Remove(ShareDBItem(proxy));
proxy->_blockData2=1;
#ifdef WSTRING_MT
LeaveCriticalSection(&GLocker);
#endif
}

View file

@ -0,0 +1,61 @@
// WStringMemory.h: interface for the WStringMemory class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_WSTRINGMEMORY_H__79693029_4788_4099_9A97_92AF310A7AD5__INCLUDED_)
#define AFX_WSTRINGMEMORY_H__79693029_4788_4099_9A97_92AF310A7AD5__INCLUDED_
#include <WCHAR.H>
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class WStringProxy;
class WStringMemory
{
public:
static WStringProxy * AllocString(const wchar_t *text, size_t size);
static WStringProxy * AllocProxy(const WStringProxy &templateProxy);
static void FreeProxy(WStringProxy *proxy);
static void LockProxy(WStringProxy *proxy);
static void UnlockProxy(WStringProxy *proxy);
//Releases extra memory leaved for future fast allocations
static void FreeExtra();
//Support addref for proxy - Single- or Multi- thread support
static void AddRefProxy(WStringProxy *proxy);
//Support addref for proxy - Single- or Multi- thread support
//returns true, when counter reached zero
static bool ReleaseRefProxy(WStringProxy *proxy);
///Gets statistics about memory manager
/**
@param details optional pointer to 32 size_t items. Array will be filled
with sizes of each string fastalloc group.
@return function returns total bytes allocated for string fast allocation.
(This number should be below 256KB)
*/
static size_t GetStatistics(size_t *details=NULL);
///Function allows sharing the strings
/** This function is called by WString::Share function
Function mark proxy shared. If string is same as shared,
it returns pointer to proxy with proxy of string that contains
the same text.
Read description of WString::Share for more informations
*/
static WStringProxy *ShareString(WStringProxy *proxy);
///Function disables sharing of the string
static void UnshareString(WStringProxy *proxy);
};
#endif // !defined(AFX_WSTRINGMEMORY_H__79693029_4788_4099_9A97_92AF310A7AD5__INCLUDED_)

View file

@ -0,0 +1,185 @@
// WStringProxy.cpp: implementation of the WStringProxy class.
//
//////////////////////////////////////////////////////////////////////
#include "WStringProxy.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
/** Funkce vytvoøí transitivní uzávìr.
to znamená, že zruší všechny zøetìzené redirecty.
*/
WStringProxy *WStringProxy::TransitivniUzaver()
{
if (_operation==OpSubstr && _offset==0 && _stringSize==_baseString->GetLength())
{
WStringProxy *next=_baseString->TransitivniUzaver();
if (next==NULL) return this;
next->AddRef();
_baseString->Release();
_baseString=next;
return next;
}
return NULL;
}
/** Main render procedure
It creates allocates buffer proxy and renders tree into it
Then turns self into redirect proxy a redirect self into newly created string
Rerurns pointer to newly created proxy
*/
WStringProxy *WStringProxy::RenderString()
{
if (_operation==OpMemBlck) return this;
WStringProxy *pp=TransitivniUzaver();
if (pp!=NULL) return pp->_baseString->RenderString();
WStringProxy *newProxy=WStringMemory::AllocString(NULL,_stringSize);
wchar_t *renderPtr=const_cast<wchar_t *>(newProxy->GetStringFromMemBlock());
RenderStringToBuffer(renderPtr);
newProxy->AddRef();
this->~WStringProxy();
_operation=OpSubstr;
_offset=0;
_baseString=newProxy;
return newProxy;
}
/** Function renders simple effect into buffer
Function needs buffer with nul terminated string
*/
void WStringProxy::RenderSimpleEffect(wchar_t *renderPtr)
{
assert(_operation==OpEffect);
switch (_effect)
{
case EfLower: wcslwr(renderPtr);break;
case EfUpper: wcsupr(renderPtr);break;
case EfReverse: wcsrev(renderPtr);break;
}
}
/** Light phase of rendering. Used to render string that is not
created from substring. This part is optimized for concat and user effects
When substring must be rendered, function call RenderStringToBufferSubstr to
render substring.
*/
void WStringProxy::RenderStringToBuffer(wchar_t *renderPtr)
{
WStringMemory::LockProxy(this);
switch (_operation)
{
case OpConcat:
_baseString->RenderStringToBuffer(renderPtr);
_secondString->RenderStringToBuffer(renderPtr+_baseString->GetLength());
break;
case OpSubstr:
{
_baseString->RenderStringToBufferSubstr(renderPtr,_offset,GetLength());
}
break;
case OpMemBlck:
{
const wchar_t *str=GetStringFromMemBlock();
wcsncpy(renderPtr,str,_stringSize);
}
break;
case OpEffect:
{
unsigned long offset=0;
renderPtr[_stringSize]=0; //we can append zero, because right side of string is not yet rendered
//if this is end of string, one extra character for zero is also allocated.
//efect functions can rely on it.
if (_blockData2>=256) offset=_userEffect->PreRenderString(renderPtr,_baseString->GetLength()); //call prerender to prepare begin of buffer
_baseString->RenderStringToBuffer(renderPtr+offset); //render string to rest of buffer
if (_blockData2>=256) _userEffect->RenderString(renderPtr,_baseString->GetLength()); //apply effect to buffer
else RenderSimpleEffect(renderPtr);
}
break;
};
WStringMemory::UnlockProxy(this);
}
/**
Deep phase of rendering. Function can render substrings, or render substring of two
concated strings. Function can also perform partial effect on string. Function cannot
handle partial user effect, so this effects are converted to things strings.
*/
void WStringProxy::RenderStringToBufferSubstr(wchar_t *renderPtr, size_t offset, size_t size)
{
WStringMemory::LockProxy(this);
switch (_operation)
{
case OpConcat:
{
//process substring of concat
//count characters in buffer
size_t rendered;
//when string starts in left string
if (_baseString->GetLength()>offset)
{
//calculate total characters that may be rendered
rendered=_baseString->GetLength()-offset;
//but limit it to request size
if (rendered>size) rendered=size;
//render substring into buffer
_baseString->RenderStringToBufferSubstr(renderPtr,offset,rendered);
}
else
//no character has been rendered
rendered=0;
//there is still characters remained to render. We will take it from second string
if (size-rendered>0)
{
if (offset>_baseString->GetLength()) offset-=_baseString->GetLength();
else offset=0;
_secondString->RenderStringToBufferSubstr(renderPtr+rendered,offset,size-rendered);
}
}
break;
case OpSubstr:
{ //rendering substrings is very easy
offset+=_offset; //add offset of substring
assert(offset+size<=GetLength()); //check length
//render substring
this->RenderStringToBufferSubstr(renderPtr,offset,size);
}
break;
case OpMemBlck:
{
//rendering from memory, final stop in recursion
//Get pointer string
const wchar_t *str=GetStringFromMemBlock();
//copy substring from string into render buffer
wcsncpy(renderPtr,str+offset,size);
}
break;
case OpEffect:
if (_blockData2>=256) //interface cannot handle partial rendering
{
RenderString(); //convert proxy to simple redirect and render it
RenderStringToBufferSubstr(renderPtr,offset,size); //now we are able to cut out part
}
else
{
//all standard effects maps string 1:1
//first get content of substring into buffer
_baseString->RenderStringToBufferSubstr(renderPtr,offset,size);
//we can append zero, because right side of string is not yet rendered
renderPtr[size]=0;
//process effect on target
RenderSimpleEffect(renderPtr);
}
break;
};
WStringMemory::UnlockProxy(this);
}

View file

@ -0,0 +1,232 @@
// WStringProxy.h: interface for the WStringProxy class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_WSTRINGPROXY_H__863ADE82_7789_4E54_BE7D_B8F0740FD81B__INCLUDED_)
#define AFX_WSTRINGPROXY_H__863ADE82_7789_4E54_BE7D_B8F0740FD81B__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "WStringMemory.h"
#include "IWStringEffect.h"
#include <WCHAR.H>
#include <string.h>
#include <assert.h>
#include <malloc.h>
/*
List of proxy types
Memory_Proxy _operation=OpMemBlck
_blockData==0 and _blockData2==0
or
_blockData!=0 and _blockData2!=0
(_redirect - debug pointer)
(_blockData - 1)
Proxy_Const _operation=OpMemBlck
_redirect - pointer to string
_blockData2=0
Proxy_Shared _operation=OpMemBlck
_redirect - pointer to string
_blockData2=2;
Proxy_Immediate _operation=OpMemBlck
_blockData>0xFFFF
_blockData2>0xFFFF
both parameters are used by immediate memory manager
Proxy_Concat _operation=OpConcat
_baseString and _secondString is valid
Proxy_Link _operation=OpSubstr
_baseString is valid
_stringSize==_baseString->_stringSize
_offset==0;
NOTE: Can be used without rendering
Proxy_RightSub _operation=OpSubstr
_baseString is valid
_offset<=_baseString->_stringSize
_stringSize==_baseString->_stringSize-_offset
NOTE: Can be used without rendering
Proxy_SubString _operation=OpSubstr
_baseString is valid
_offset<=_baseString->_stringSize
_stringSize<=_baseString->_stringSize-_offset
Proxy_Effect _operation=OpEffect
_baseString is valid
_stringSize=_baseString->_stringSize
_effect defining effect code < 0xFFFF
Proxy_UserEffect _operation=OpEffect
_baseString is valid
_stringSize=_baseString->_stringSize
_effect>0xFFFF
_userEffect defining pointer to effect interface
*/
class WStringProxy
{
public:
enum Operation
{
OpConcat=0, //proxy contains two links to concat it
OpSubstr=1, //proxy contains link to another proxy and specified substring
OpMemBlck=-2, //proxy contains informations about following string
OpEffect=-1, //proxy describing some efect with string
};
enum Effect
{
EfLower, //effect lower case
EfUpper, //effect upper case
EfReverse, //effect reverse string
};
public:
unsigned long _refCount; //reference count
unsigned long _stringSize:30; //string size in characters (maximum size 1073741823 characters ~ 2147483646 bytes)
Operation _operation:2; //operation with string or proxy type
union
{
WStringProxy *_baseString; //pointer to next proxy referenced by this proxy
unsigned long _blockData; //user defined block data for OpMemBlock proxy type
const wchar_t *_redirect; //used for OpMemBlock, when _blockData2 is zero.
};
union
{
WStringProxy *_secondString; //pointer to second string for OpConcat
unsigned long _offset; //offset of substring for OpSubstr
Effect _effect; //effect selector for OpEffect
IWStringEffect *_userEffect; //user effect defined by IWStringEffect interface (valid when _effect is invalid)
unsigned long _blockData2; //user defined block data for OpMemBlock proxy type - exception: if this value is zero, member _redirect is valid
};
void RenderStringToBuffer(wchar_t *renderPtr);
void RenderStringToBufferSubstr(wchar_t *renderPtr, size_t offset, size_t size);
WStringProxy *TransitivniUzaver();
void RenderSimpleEffect(wchar_t *renderPtr);
public:
WStringProxy():_refCount(0),_operation(OpSubstr),_stringSize(0),_baseString(0),_secondString(0) {} //inicializes empty string proxy
WStringProxy(WStringProxy *other):
_refCount(0),
_stringSize(other->GetLength()),
_baseString(other),
_operation(OpSubstr),
_offset(0)
{_baseString->AddRef();}
WStringProxy(WStringProxy *other, unsigned long offset, unsigned long size):
_refCount(0),
_stringSize(size),
_baseString(other),
_operation(OpSubstr),
_offset(offset)
{_baseString->AddRef();}
WStringProxy(WStringProxy *a, WStringProxy *b):
_refCount(0),
_stringSize(a->GetLength()+b->GetLength()),
_baseString(a),
_operation(OpConcat),
_secondString(b)
{_baseString->AddRef();_secondString->AddRef();}
WStringProxy(WStringProxy *a, Effect effect):
_refCount(0),
_stringSize(a->GetLength()),
_baseString(a),
_operation(OpEffect),
_effect(effect)
{_baseString->AddRef();}
WStringProxy(WStringProxy *a, IWStringEffect *userEffect):
_refCount(0),
_stringSize(a->GetLength()+userEffect->GetEffectExtraSize(a->GetLength())),
_baseString(a),
_operation(OpEffect),
_userEffect(userEffect)
{_baseString->AddRef();}
WStringProxy(unsigned long size, unsigned long user1, unsigned long user2):
_refCount(0),
_stringSize(size),
_operation(OpMemBlck),
_blockData(user1),
_blockData2(user2)
{}
WStringProxy(const wchar_t *imText):
_refCount(0),
_stringSize(wcslen(imText)),
_redirect(imText),
_blockData2(0),
_operation(OpMemBlck)
{}
WStringProxy(const WStringProxy &other)
{
memcpy(this,&other,sizeof(*this));
if (_operation!=OpMemBlck) _baseString->AddRef();
if (_operation==OpConcat) _secondString->AddRef();
}
WStringProxy& operator=(const WStringProxy &other)
{
WStringProxy::~WStringProxy(); //call destructor to destruct current proxy
memcpy(this,&other,sizeof(*this)); //construct new proxy from template
if (_operation!=OpMemBlck) _baseString->AddRef();
if (_operation==OpConcat) _secondString->AddRef();
}
WStringProxy *RenderString();
~WStringProxy()
{
if (_operation!=OpMemBlck) _baseString->Release();
if (_operation==OpConcat) _secondString->Release();
}
unsigned long GetLength() {return _stringSize;}
void AddRef() {if (this) WStringMemory::AddRefProxy(this);}
void Release() {if (this) if (WStringMemory::ReleaseRefProxy(this)) WStringMemory::FreeProxy(this);}
const wchar_t *GetString()
{
if (_operation==OpMemBlck) return (const wchar_t *)(this+1);
WStringProxy *p=RenderString();
(*this)=*p;
return (const wchar_t *)(p+1);
}
const wchar_t *GetStringFromMemBlock()
{
assert(_operation==OpMemBlck);
if (_blockData2==0 && _redirect!=NULL) return _redirect;
else return (const wchar_t *)(this+1);
}
bool IsShared() {return _refCount>1;}
void RecalcLength()
{
const wchar_t *str=GetStringFromMemBlock();
_stringSize=wcslen(str);
}
};
#endif // !defined(AFX_WSTRINGPROXY_H__863ADE82_7789_4E54_BE7D_B8F0740FD81B__INCLUDED_)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,49 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by DDLReader.rc
//
#define IDM_ABOUTBOX 0x0010
#define IDD_ABOUTBOX 100
#define IDS_ABOUTBOX 101
#define IDD_DDLREADER_DIALOG 102
#define IDS_FILEOPENFAILED 102
#define IDC_HEADGROUP 103
#define IDC_HEADFNAME 104
#define IDC_HEADSIZE 105
#define IDC_HEADOFFSET 106
#define IDS_DDLFILTER 107
#define IDC_GROUP_GRAPHICS 108
#define IDC_GROUP_SOUNDS 109
#define IDC_GROUP_FONTS 110
#define IDC_GROUP_BASIC 111
#define IDC_GROUP_ITEMS 112
#define IDC_GROUP_MONSTERS 113
#define IDC_GROUP_DIALOGS 114
#define IDC_GROUP_UNSPECIFIED 115
#define IDC_GROUP_UNKNOWN 116
#define IDS_UNABLETOCREATEFILE 117
#define IDS_UNABLETOEXTACTDATA 118
#define IDR_MAINFRAME 128
#define IDD_PROGRESS 129
#define IDD_EXPORTING 129
#define IDC_FILELIST 1001
#define IDC_FOLDER 1002
#define IDC_BROWSE 1003
#define IDC_EXPORT 1004
#define IDC_POPISEK 1005
#define IDC_DDLFILE 1006
#define IDC_DDLBROWSE 1007
#define IDC_PROGRESS 1008
#define IDC_NAME 1009
#define IDC_BUTTON1 1010
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 130
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1011
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif