393 lines
10 KiB
C
393 lines
10 KiB
C
|
// Win32++ Version 7.2
|
||
|
// Released: 5th AUgust 2011
|
||
|
//
|
||
|
// David Nash
|
||
|
// email: dnash@bigpond.net.au
|
||
|
// url: https://sourceforge.net/projects/win32-framework
|
||
|
//
|
||
|
//
|
||
|
// Copyright (c) 2005-2011 David Nash
|
||
|
//
|
||
|
// Permission is hereby granted, free of charge, to
|
||
|
// any person obtaining a copy of this software and
|
||
|
// associated documentation files (the "Software"),
|
||
|
// to deal in the Software without restriction, including
|
||
|
// without limitation the rights to use, copy, modify,
|
||
|
// merge, publish, distribute, sublicense, and/or sell
|
||
|
// copies of the Software, and to permit persons to whom
|
||
|
// the Software is furnished to do so, subject to the
|
||
|
// following conditions:
|
||
|
//
|
||
|
// The above copyright notice and this permission notice
|
||
|
// shall be included in all copies or substantial portions
|
||
|
// of the Software.
|
||
|
//
|
||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||
|
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||
|
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||
|
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||
|
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||
|
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||
|
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||
|
// OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////
|
||
|
|
||
|
|
||
|
#ifndef _WIN32XX_FILE_H_
|
||
|
#define _WIN32XX_FILE_H_
|
||
|
|
||
|
|
||
|
#include "wincore.h"
|
||
|
|
||
|
namespace Win32xx
|
||
|
{
|
||
|
|
||
|
class CFile
|
||
|
{
|
||
|
public:
|
||
|
CFile();
|
||
|
CFile(HANDLE hFile);
|
||
|
CFile(LPCTSTR pszFileName, UINT nOpenFlags);
|
||
|
~CFile();
|
||
|
operator HANDLE() const;
|
||
|
|
||
|
BOOL Close();
|
||
|
BOOL Flush();
|
||
|
HANDLE GetHandle() const;
|
||
|
ULONGLONG GetLength() const;
|
||
|
const CString& GetFileName() const;
|
||
|
const CString& GetFilePath() const;
|
||
|
const CString& GetFileTitle() const;
|
||
|
ULONGLONG GetPosition() const;
|
||
|
BOOL LockRange(ULONGLONG Pos, ULONGLONG Count);
|
||
|
BOOL Open(LPCTSTR pszFileName, UINT nOpenFlags);
|
||
|
CString OpenFileDialog(LPCTSTR pszFilePathName = NULL,
|
||
|
DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR pszFilter = NULL,
|
||
|
CWnd* pOwnerWnd = NULL);
|
||
|
UINT Read(void* pBuf, UINT nCount);
|
||
|
static BOOL Remove(LPCTSTR pszFileName);
|
||
|
static BOOL Rename(LPCTSTR pszOldName, LPCTSTR pszNewName);
|
||
|
CString SaveFileDialog(LPCTSTR pszFilePathName = NULL,
|
||
|
DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR pszFilter = NULL,
|
||
|
LPCTSTR pszDefExt = NULL, CWnd* pOwnerWnd = NULL);
|
||
|
ULONGLONG Seek(LONGLONG lOff, UINT nFrom);
|
||
|
void SeekToBegin();
|
||
|
ULONGLONG SeekToEnd();
|
||
|
void SetFilePath(LPCTSTR pszNewName);
|
||
|
BOOL SetLength(ULONGLONG NewLen);
|
||
|
BOOL UnlockRange(ULONGLONG Pos, ULONGLONG Count);
|
||
|
BOOL Write(const void* pBuf, UINT nCount);
|
||
|
|
||
|
private:
|
||
|
CFile(const CFile&); // Disable copy construction
|
||
|
CFile& operator = (const CFile&); // Disable assignment operator
|
||
|
CString m_FileName;
|
||
|
CString m_FilePath;
|
||
|
CString m_FileTitle;
|
||
|
HANDLE m_hFile;
|
||
|
};
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
namespace Win32xx
|
||
|
{
|
||
|
inline CFile::CFile() : m_hFile(0)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
inline CFile::CFile(HANDLE hFile) : m_hFile(hFile)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
inline CFile::CFile(LPCTSTR pszFileName, UINT nOpenFlags) : m_hFile(0)
|
||
|
{
|
||
|
assert(pszFileName);
|
||
|
Open(pszFileName, nOpenFlags);
|
||
|
assert(m_hFile);
|
||
|
}
|
||
|
|
||
|
inline CFile::~CFile()
|
||
|
{
|
||
|
Close();
|
||
|
}
|
||
|
|
||
|
inline CFile::operator HANDLE() const
|
||
|
{
|
||
|
return m_hFile;
|
||
|
}
|
||
|
|
||
|
inline BOOL CFile::Close()
|
||
|
// Closes the file associated with this object. Closed file can no longer be read or written to.
|
||
|
{
|
||
|
BOOL bResult = TRUE;
|
||
|
if (m_hFile)
|
||
|
bResult = CloseHandle(m_hFile);
|
||
|
|
||
|
m_hFile = 0;
|
||
|
return bResult;
|
||
|
}
|
||
|
|
||
|
inline BOOL CFile::Flush()
|
||
|
// Causes any remaining data in the file buffer to be written to the file.
|
||
|
{
|
||
|
assert(m_hFile);
|
||
|
return FlushFileBuffers(m_hFile);
|
||
|
}
|
||
|
|
||
|
inline HANDLE CFile::GetHandle() const
|
||
|
{
|
||
|
return m_hFile;
|
||
|
}
|
||
|
|
||
|
inline ULONGLONG CFile::GetLength( ) const
|
||
|
// Returns the length of the file in bytes.
|
||
|
{
|
||
|
assert(m_hFile);
|
||
|
|
||
|
LONG High = 0;
|
||
|
DWORD LowPos = SetFilePointer(m_hFile, 0, &High, FILE_END);
|
||
|
|
||
|
ULONGLONG Result = ((ULONGLONG)High << 32) + LowPos;
|
||
|
return Result;
|
||
|
}
|
||
|
|
||
|
inline const CString& CFile::GetFileName() const
|
||
|
// Returns the filename of the file associated with this object.
|
||
|
{
|
||
|
return (const CString&)m_FileName;
|
||
|
}
|
||
|
|
||
|
inline const CString& CFile::GetFilePath() const
|
||
|
// Returns the full filename including the directory of the file associated with this object.
|
||
|
{
|
||
|
return (const CString&)m_FilePath;
|
||
|
}
|
||
|
|
||
|
inline const CString& CFile::GetFileTitle() const
|
||
|
// Returns the filename of the file associated with this object, excluding the path and the file extension
|
||
|
{
|
||
|
return (const CString&)m_FileTitle;
|
||
|
}
|
||
|
|
||
|
inline ULONGLONG CFile::GetPosition() const
|
||
|
// Returns the current value of the file pointer, which can be used in subsequent calls to Seek.
|
||
|
{
|
||
|
assert(m_hFile);
|
||
|
LONG High = 0;
|
||
|
DWORD LowPos = SetFilePointer(m_hFile, 0, &High, FILE_CURRENT);
|
||
|
|
||
|
ULONGLONG Result = ((ULONGLONG)High << 32) + LowPos;
|
||
|
return Result;
|
||
|
}
|
||
|
|
||
|
inline BOOL CFile::LockRange(ULONGLONG Pos, ULONGLONG Count)
|
||
|
// Locks a range of bytes in and open file.
|
||
|
{
|
||
|
assert(m_hFile);
|
||
|
|
||
|
DWORD dwPosHigh = (DWORD)(Pos >> 32);
|
||
|
DWORD dwPosLow = (DWORD)(Pos & 0xFFFFFFFF);
|
||
|
DWORD dwCountHigh = (DWORD)(Count >> 32);
|
||
|
DWORD dwCountLow = (DWORD)(Count & 0xFFFFFFFF);
|
||
|
|
||
|
return ::LockFile(m_hFile, dwPosLow, dwPosHigh, dwCountLow, dwCountHigh);
|
||
|
}
|
||
|
|
||
|
inline BOOL CFile::Open(LPCTSTR pszFileName, UINT nOpenFlags)
|
||
|
// Prepares a file to be written to or read from.
|
||
|
{
|
||
|
if (m_hFile) Close();
|
||
|
|
||
|
m_hFile = ::CreateFile(pszFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, nOpenFlags, FILE_ATTRIBUTE_NORMAL, NULL);
|
||
|
|
||
|
if (INVALID_HANDLE_VALUE == m_hFile)
|
||
|
{
|
||
|
TRACE(_T("Failed\n"));
|
||
|
m_hFile = 0;
|
||
|
}
|
||
|
|
||
|
if (m_hFile)
|
||
|
{
|
||
|
SetFilePath(pszFileName);
|
||
|
}
|
||
|
|
||
|
return (m_hFile != 0);
|
||
|
}
|
||
|
|
||
|
inline CString CFile::OpenFileDialog(LPCTSTR pszFilePathName, DWORD dwFlags, LPCTSTR pszFilter, CWnd* pOwnerWnd)
|
||
|
// Displays the file open dialog.
|
||
|
// Returns a CString containing either the selected file name or an empty CString.
|
||
|
{
|
||
|
CString str;
|
||
|
if (pszFilePathName)
|
||
|
str = pszFilePathName;
|
||
|
|
||
|
OPENFILENAME ofn = {0};
|
||
|
ofn.lStructSize = sizeof(OPENFILENAME);
|
||
|
|
||
|
#if defined OPENFILENAME_SIZE_VERSION_400
|
||
|
if (GetWinVersion() < 2500)
|
||
|
ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
|
||
|
#endif
|
||
|
|
||
|
ofn.hwndOwner = pOwnerWnd? pOwnerWnd->GetHwnd() : NULL;
|
||
|
ofn.hInstance = GetApp()->GetInstanceHandle();
|
||
|
ofn.lpstrFilter = pszFilter;
|
||
|
ofn.lpstrTitle = _T("Open File");
|
||
|
ofn.Flags = dwFlags;
|
||
|
ofn.nMaxFile = _MAX_PATH;
|
||
|
|
||
|
ofn.lpstrFile = (LPTSTR)str.GetBuffer(_MAX_PATH);
|
||
|
::GetOpenFileName(&ofn);
|
||
|
str.ReleaseBuffer();
|
||
|
|
||
|
return str;
|
||
|
}
|
||
|
|
||
|
inline UINT CFile::Read(void* pBuf, UINT nCount)
|
||
|
// Reads from the file, storing the contents in the specified buffer.
|
||
|
{
|
||
|
assert(m_hFile);
|
||
|
DWORD dwRead = 0;
|
||
|
|
||
|
if (!::ReadFile(m_hFile, pBuf, nCount, &dwRead, NULL))
|
||
|
dwRead = 0;
|
||
|
|
||
|
return dwRead;
|
||
|
}
|
||
|
|
||
|
inline BOOL CFile::Rename(LPCTSTR pszOldName, LPCTSTR pszNewName)
|
||
|
// Renames the specified file.
|
||
|
{
|
||
|
return ::MoveFile(pszOldName, pszNewName);
|
||
|
}
|
||
|
|
||
|
inline BOOL CFile::Remove(LPCTSTR pszFileName)
|
||
|
// Deletes the specified file.
|
||
|
{
|
||
|
return ::DeleteFile(pszFileName);
|
||
|
}
|
||
|
|
||
|
inline CString CFile::SaveFileDialog(LPCTSTR pszFilePathName, DWORD dwFlags, LPCTSTR pszFilter, LPCTSTR pszDefExt, CWnd* pOwnerWnd)
|
||
|
// Displays the SaveFileDialog.
|
||
|
// Returns a CString containing either the selected file name or an empty CString
|
||
|
{
|
||
|
CString str;
|
||
|
if (pszFilePathName)
|
||
|
str = pszFilePathName;
|
||
|
|
||
|
OPENFILENAME ofn = {0};
|
||
|
ofn.lStructSize = sizeof(OPENFILENAME);
|
||
|
|
||
|
#if defined OPENFILENAME_SIZE_VERSION_400
|
||
|
if (GetWinVersion() < 2500)
|
||
|
ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
|
||
|
#endif
|
||
|
|
||
|
ofn.hwndOwner = pOwnerWnd? pOwnerWnd->GetHwnd() : NULL;
|
||
|
ofn.hInstance = GetApp()->GetInstanceHandle();
|
||
|
ofn.lpstrFilter = pszFilter;
|
||
|
ofn.lpstrFile = (LPTSTR)pszFilePathName;
|
||
|
ofn.lpstrFileTitle = (LPTSTR)pszFilePathName;
|
||
|
ofn.lpstrDefExt = pszDefExt;
|
||
|
ofn.nMaxFile = lstrlen(pszFilePathName);
|
||
|
ofn.lpstrTitle = _T("Save File");
|
||
|
ofn.Flags = dwFlags;
|
||
|
ofn.nMaxFile = _MAX_PATH;
|
||
|
ofn.lpstrFile = (LPTSTR)str.GetBuffer(_MAX_PATH);
|
||
|
::GetSaveFileName(&ofn);
|
||
|
str.ReleaseBuffer();
|
||
|
|
||
|
return str;
|
||
|
}
|
||
|
|
||
|
inline ULONGLONG CFile::Seek(LONGLONG lOff, UINT nFrom)
|
||
|
// Positions the current file pointer.
|
||
|
// Permitted values for nFrom are: FILE_BEGIN, FILE_CURRENT, or FILE_END.
|
||
|
{
|
||
|
assert(m_hFile);
|
||
|
assert(nFrom == FILE_BEGIN || nFrom == FILE_CURRENT || nFrom == FILE_END);
|
||
|
|
||
|
LONG High = LONG(lOff >> 32);
|
||
|
LONG Low = (LONG)(lOff & 0xFFFFFFFF);
|
||
|
|
||
|
DWORD LowPos = SetFilePointer(m_hFile, Low, &High, nFrom);
|
||
|
|
||
|
ULONGLONG Result = ((ULONGLONG)High << 32) + LowPos;
|
||
|
return Result;
|
||
|
}
|
||
|
|
||
|
inline void CFile::SeekToBegin()
|
||
|
// Sets the current file pointer to the beginning of the file.
|
||
|
{
|
||
|
assert(m_hFile);
|
||
|
Seek(0, FILE_BEGIN);
|
||
|
}
|
||
|
|
||
|
inline ULONGLONG CFile::SeekToEnd()
|
||
|
// Sets the current file pointer to the end of the file.
|
||
|
{
|
||
|
assert(m_hFile);
|
||
|
return Seek(0, FILE_END);
|
||
|
}
|
||
|
|
||
|
inline void CFile::SetFilePath(LPCTSTR pszFileName)
|
||
|
// Specifies the full file name, including its path
|
||
|
{
|
||
|
TCHAR* pFileName = NULL;
|
||
|
int nBuffSize = ::GetFullPathName(pszFileName, 0, 0, 0);
|
||
|
if (nBuffSize > 0)
|
||
|
{
|
||
|
TCHAR* pBuff = m_FilePath.GetBuffer(nBuffSize);
|
||
|
::GetFullPathName(pszFileName, nBuffSize, pBuff, &pFileName);
|
||
|
m_FilePath.ReleaseBuffer();
|
||
|
m_FileName = pFileName;
|
||
|
int nPos = m_FileName.ReverseFind(_T("."));
|
||
|
if (nPos >= 0)
|
||
|
m_FileTitle = m_FileName.Left(nPos);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
inline BOOL CFile::SetLength(ULONGLONG NewLen)
|
||
|
// Changes the length of the file to the specified value.
|
||
|
{
|
||
|
assert(m_hFile);
|
||
|
|
||
|
Seek(NewLen, FILE_BEGIN);
|
||
|
return ::SetEndOfFile(m_hFile);
|
||
|
}
|
||
|
|
||
|
inline BOOL CFile::UnlockRange(ULONGLONG Pos, ULONGLONG Count)
|
||
|
// Unlocks a range of bytes in an open file.
|
||
|
{
|
||
|
assert(m_hFile);
|
||
|
|
||
|
DWORD dwPosHigh = (DWORD)(Pos >> 32);
|
||
|
DWORD dwPosLow = (DWORD)(Pos & 0xFFFFFFFF);
|
||
|
DWORD dwCountHigh = (DWORD)(Count >> 32);
|
||
|
DWORD dwCountLow = (DWORD)(Count & 0xFFFFFFFF);
|
||
|
|
||
|
return ::UnlockFile(m_hFile, dwPosLow, dwPosHigh, dwCountLow, dwCountHigh);
|
||
|
}
|
||
|
|
||
|
inline BOOL CFile::Write(const void* pBuf, UINT nCount)
|
||
|
// Writes the specified buffer to the file.
|
||
|
{
|
||
|
assert(m_hFile);
|
||
|
DWORD dwWritten = 0;
|
||
|
BOOL bResult = ::WriteFile(m_hFile, pBuf, nCount, &dwWritten, NULL);
|
||
|
if (dwWritten != nCount)
|
||
|
bResult = FALSE;
|
||
|
|
||
|
return bResult;
|
||
|
}
|
||
|
|
||
|
|
||
|
} // namespace Win32xx
|
||
|
|
||
|
#endif
|