📄 mtlprofile.h
字号:
#ifndef __MTLPROFILE_H__
#define __MTLPROFILE_H__
// MTL Version 0.03
// Copyright (C) 2000 MB<mb2@geocities.co.jp>
// All rights unreserved.
//
// This file is a part of Mb Template Library.
// The code and information is *NOT* provided "as-is" without
// warranty of any kind, either expressed or implied.
//
// Last updated: August 16, 2000
#pragma once
#ifndef __MTLMISC_H__
#error mtlctrlw.h requires mtlmisc.h to be included first
#endif
#include <functional>
#include <iterator>
#include <algorithm>
// #define _MTL_PROFILE_EXTRA_TRACE
namespace MTL
{
using ATL::CRegKey;
using ATL::CSimpleArray;
using WTL::CString;
using WTL::wtlTraceFlags;
using WTL::CStatusBarCtrl;
using WTL::CReBarCtrl;
using WTL::CToolBarCtrl;
////////////////////////////////////////////////////////////////////////////
// CIniSection
class CIniSection
{
public:
// Constructor/destructor
CIniSection();
~CIniSection();
// Attributes
public:
CString m_strFileName, m_strSectionName;
// Operations
public:
// for "Profile" concepts
LONG SetValue(DWORD dwValue, LPCTSTR lpszValueName);
LONG QueryValue(DWORD& dwValue, LPCTSTR lpszValueName);
LONG QueryValue(LPTSTR szValue, LPCTSTR lpszValueName, DWORD* pdwCount);
LONG SetValue(LPCTSTR lpszValue, LPCTSTR lpszValueName);
LONG DeleteValue(LPCTSTR lpszValueName);
// original
void Open(const CString& strFileName, const CString& strSectionName);
void Close();
// Implementation
protected:
enum { _nDefault = 0xABCD0123 };// magic number
BOOL _IsOpen()
{
if (!m_strFileName.IsEmpty() && !m_strSectionName.IsEmpty())
return TRUE;
else
return FALSE;
}
};
inline CIniSection::CIniSection()
{
}
inline CIniSection::~CIniSection()
{
}
inline void CIniSection::Close()
{
m_strFileName.Empty();
m_strSectionName.Empty();
}
inline void CIniSection::Open(const CString& strFileName, const CString& strSectionName)
{
ATLASSERT(!strFileName.IsEmpty());
ATLASSERT(!strSectionName.IsEmpty());
ATLASSERT(!_IsOpen());
m_strFileName = strFileName;
m_strSectionName = strSectionName;
}
inline LONG CIniSection::QueryValue(DWORD& dwValue, LPCTSTR lpszValueName)
{
ATLASSERT(_IsOpen());
UINT nValue = ::GetPrivateProfileInt(m_strSectionName, lpszValueName, _nDefault, m_strFileName);
if (nValue == _nDefault)
return ERROR_CANTREAD;
dwValue = nValue;
return ERROR_SUCCESS;
}
inline LONG CIniSection::QueryValue(LPTSTR szValue, LPCTSTR lpszValueName, DWORD* pdwCount)
{
ATLASSERT(pdwCount != NULL);
ATLASSERT(_IsOpen());
ATLASSERT(szValue != NULL);// Ini section can't determine dwCount.
DWORD dw = ::GetPrivateProfileString(m_strSectionName, lpszValueName,
_T(""), szValue, *pdwCount, m_strFileName);
if (dw == 0)
return ERROR_CANTREAD;
return ERROR_SUCCESS;
}
inline LONG CIniSection::SetValue(DWORD dwValue, LPCTSTR lpszValueName)
{
ATLASSERT(lpszValueName != NULL);// don't make section deleted
ATLASSERT(_IsOpen());
TCHAR szT[16];
::wsprintf(szT, _T("%d"), dwValue);
if (::WritePrivateProfileString(m_strSectionName, lpszValueName, szT, m_strFileName))
return ERROR_SUCCESS;
else
return ERROR_CANTWRITE;
}
inline LONG CIniSection::SetValue(LPCTSTR lpszValue, LPCTSTR lpszValueName)
{
ATLASSERT(lpszValue != NULL);
ATLASSERT(_IsOpen());
ATLASSERT(m_strFileName.GetLength() < 4095); // can't read in bigger
if (::WritePrivateProfileString(m_strSectionName, lpszValueName, lpszValue, m_strFileName))
return ERROR_SUCCESS;
else
return ERROR_CANTWRITE;
}
inline LONG CIniSection::DeleteValue(LPCTSTR lpszValueName)
{
if (::WritePrivateProfileString(m_strSectionName, lpszValueName, NULL, m_strFileName))
return ERROR_SUCCESS;
else
return ERROR_CANTWRITE;
}
inline bool MtlIniDeleteSection(const CString& strIniFileName, const CString& strSectionName)
{
return ::WritePrivateProfileString(strSectionName, NULL, NULL, strIniFileName) ? true : false;
}
inline bool MtlIniDeleteAllSection(const CString& strIniFileName, const CString& strSectionName)
{
return true;
}
/////////////////////////////////////////////////////////////////////////////
// CProfileBinary, an adaptor
template <class _Profile>
class CProfileBinary
{
public:
explicit CProfileBinary(_Profile& __x) : profile(&__x) { }
// Operations
LONG SetValue(LPBYTE pValue, LPCTSTR lpszValueName, UINT nBytes)
{
// convert to string and write out
LPTSTR lpsz = new TCHAR[nBytes*2+1];
for (UINT i = 0; i < nBytes; i++) {
lpsz[i*2] = (TCHAR)((pValue[i] & 0x0F) + 'A'); //low nibble
lpsz[i*2+1] = (TCHAR)(((pValue[i] >> 4) & 0x0F) + 'A'); //high nibble
}
lpsz[i*2] = 0;
LONG lRet = profile->SetValue(lpsz, lpszValueName);
delete[] lpsz;
return lRet;
}
LONG QueryValue(BYTE** ppValue, LPCTSTR lpszValueName, UINT* pBytes)
{
ATLASSERT(ppValue != NULL);
ATLASSERT(pBytes != NULL);
*ppValue = NULL;
*pBytes = 0;
TCHAR szT[4096];
DWORD dwCount = 4096;
LONG lRet = profile->QueryValue(szT, lpszValueName, &dwCount);
if (lRet != ERROR_SUCCESS)
return lRet;
ATLASSERT(::lstrlen(szT)%2 == 0);
int nLen = ::lstrlen(szT);
*pBytes = nLen/2;
*ppValue = new BYTE[*pBytes];
for (int i = 0; i < nLen; i += 2) {
(*ppValue)[i/2] = (BYTE)
(((szT[i+1] - 'A') << 4) + (szT[i] - 'A'));
}
return lRet;
}
protected:
_Profile* profile;
};
// Specialization for CRegKey
template <>
class CProfileBinary<CRegKey>
{
public:
explicit CProfileBinary(CRegKey& __x) : regkey(&__x) { }
// Operations
LONG SetValue(LPBYTE lpValue, LPCTSTR lpszValueName, UINT nBytes)
{
ATLASSERT(lpValue != NULL);
ATLASSERT(regkey->m_hKey != NULL);
return ::RegSetValueEx(regkey->m_hKey, lpszValueName, NULL, REG_BINARY,
lpValue, nBytes);
}
LONG QueryValue(BYTE** ppValue, LPCTSTR lpszValueName, UINT* pBytes)
{
ATLASSERT(regkey->m_hKey != NULL);
DWORD dwType, dwCount;
LONG lResult = ::RegQueryValueEx(regkey->m_hKey, (LPTSTR)lpszValueName, NULL, &dwType,
NULL, &dwCount);
*pBytes = dwCount;
if (lResult == ERROR_SUCCESS) {
ATLASSERT(dwType == REG_BINARY);
*ppValue = new BYTE[*pBytes];
lResult = ::RegQueryValueEx(regkey->m_hKey, (LPTSTR)lpszValueName, NULL, &dwType,
*ppValue, &dwCount);
}
if (lResult != ERROR_SUCCESS) {
delete [] *ppValue;
*ppValue = NULL;
}
return lResult;
}
protected:
CRegKey* regkey;
};
template <class _Profile>
inline CProfileBinary<_Profile> MtlProfileBinary(_Profile& __x)
{
return CProfileBinary<_Profile>(__x);
}
/////////////////////////////////////////////////////////////////////////////
// CWindowPlacement
class CWindowPlacement : public WINDOWPLACEMENT
{
public:
// Constructors
CWindowPlacement()
{
length = sizeof(WINDOWPLACEMENT);
// random filled
}
CWindowPlacement(const WINDOWPLACEMENT& srcWndpl)
{
*(WINDOWPLACEMENT*)this = srcWndpl;
}
// Profile Operations
template <class _Profile>
void WriteProfile(_Profile& __profile, const CString& strPrefix = _T("wp.")) const
{
MTLVERIFY(__profile.SetValue(flags, strPrefix + _T("flags")) == ERROR_SUCCESS);
MTLVERIFY(__profile.SetValue(showCmd, strPrefix + _T("showCmd")) == ERROR_SUCCESS);
MTLVERIFY(__profile.SetValue(ptMinPosition.x, strPrefix + _T("ptMinPosition.x")) == ERROR_SUCCESS);
MTLVERIFY(__profile.SetValue(ptMinPosition.y, strPrefix + _T("ptMinPosition.y")) == ERROR_SUCCESS);
MTLVERIFY(__profile.SetValue(ptMaxPosition.x, strPrefix + _T("ptMaxPosition.x")) == ERROR_SUCCESS);
MTLVERIFY(__profile.SetValue(ptMaxPosition.y, strPrefix + _T("ptMaxPosition.y")) == ERROR_SUCCESS);
MTLVERIFY(__profile.SetValue(rcNormalPosition.left, strPrefix + _T("rcNormalPosition.left")) == ERROR_SUCCESS);
MTLVERIFY(__profile.SetValue(rcNormalPosition.top, strPrefix + _T("rcNormalPosition.top")) == ERROR_SUCCESS);
MTLVERIFY(__profile.SetValue(rcNormalPosition.right, strPrefix + _T("rcNormalPosition.right")) == ERROR_SUCCESS);
MTLVERIFY(__profile.SetValue(rcNormalPosition.bottom, strPrefix + _T("rcNormalPosition.bottom")) == ERROR_SUCCESS);
}
template <class _Profile>
bool GetProfile(_Profile& __profile, const CString& strPrefix = _T("wp."))
{
DWORD dwFlags, dwShowCmd, dwMinX, dwMinY, dwMaxX, dwMaxY,
dwLeft, dwTop, dwRight, dwBottom;
if (__profile.QueryValue(dwFlags, strPrefix + _T("flags")) == ERROR_SUCCESS &&
__profile.QueryValue(dwShowCmd, strPrefix + _T("showCmd")) == ERROR_SUCCESS &&
__profile.QueryValue(dwMinX, strPrefix + _T("ptMinPosition.x")) == ERROR_SUCCESS &&
__profile.QueryValue(dwMinY, strPrefix + _T("ptMinPosition.y")) == ERROR_SUCCESS &&
__profile.QueryValue(dwMaxX, strPrefix + _T("ptMaxPosition.x")) == ERROR_SUCCESS &&
__profile.QueryValue(dwMaxY, strPrefix + _T("ptMaxPosition.y")) == ERROR_SUCCESS &&
__profile.QueryValue(dwLeft, strPrefix + _T("rcNormalPosition.left")) == ERROR_SUCCESS &&
__profile.QueryValue(dwTop, strPrefix + _T("rcNormalPosition.top")) == ERROR_SUCCESS &&
__profile.QueryValue(dwRight, strPrefix + _T("rcNormalPosition.right")) == ERROR_SUCCESS &&
__profile.QueryValue(dwBottom, strPrefix + _T("rcNormalPosition.bottom")) == ERROR_SUCCESS)
{
flags = dwFlags;
showCmd = dwShowCmd;
ptMinPosition.x = dwMinX;
ptMinPosition.y = dwMinY;
ptMaxPosition.x = dwMaxX;
ptMaxPosition.y = dwMaxY;
rcNormalPosition.left = dwLeft;
rcNormalPosition.top = dwTop;
rcNormalPosition.right = dwRight;
rcNormalPosition.bottom = dwBottom;
return true;
}
return false;
}
// Additional Operations
void operator=(const WINDOWPLACEMENT& srcWndpl)
{
*(WINDOWPLACEMENT*)this = srcWndpl;
}
// Helper Operations
bool IsInsideScreen() const
{
#ifndef SM_CMONITORS
#define SM_XVIRTUALSCREEN 76
#define SM_YVIRTUALSCREEN 77
#define SM_CXVIRTUALSCREEN 78
#define SM_CYVIRTUALSCREEN 79
#define SM_CMONITORS 80
#endif
// I separate the code with multi or not, so I guess no need to install multimon.h's stub
int nMonitorCount = ::GetSystemMetrics(SM_CMONITORS);// if win95, it will fail and return 0.
if (nMonitorCount > 0) {// multi monitor
int left = ::GetSystemMetrics(SM_XVIRTUALSCREEN);
int top = ::GetSystemMetrics(SM_YVIRTUALSCREEN);
CRect rcMonitor(left, top, left + ::GetSystemMetrics(SM_CXVIRTUALSCREEN), top + ::GetSystemMetrics(SM_CYVIRTUALSCREEN));
if (MtlIsCrossRect(rcMonitor, rcNormalPosition))
return true;
else
return false;
}
else {
CRect rcScreen(0, 0, ::GetSystemMetrics(SM_CXSCREEN), ::GetSystemMetrics(SM_CYSCREEN));
if (MtlIsCrossRect(rcScreen, rcNormalPosition))
return true;
else
return false;
}
}
// Binary Profile Operations
template <class _ProfileBinary>
bool WriteProfileBinary(_ProfileBinary& __profile, const CString& strValueName = _T("WindowPlacement")) const
{
LONG lRet = __profile.SetValue((LPBYTE)this, strValueName, sizeof(WINDOWPLACEMENT));
if (lRet == ERROR_SUCCESS)
return true;
else
return false;
}
template <class _ProfileBinary>
bool GetProfileBinary(_ProfileBinary& __profile, const CString& strValueName = _T("WindowPlacement"))
{
LPBYTE pData; UINT nBytes;
LONG lRet = __profile.QueryValue(&pData, strValueName, &nBytes);
if (lRet != ERROR_SUCCESS)
return false;
::memcpy(static_cast<WINDOWPLACEMENT*>(this), pData, nBytes);
delete [] pData;
return true;
}
};
/////////////////////////////////////////////////////////////////////////////
// CLogFont
static const LOGFONT _lfDefault = { 0, 0, 0, 0, 0, FALSE, FALSE, FALSE, DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, _T("") };
class CLogFont : public LOGFONT
{// Fixed by DOGSTORE for serialization of 'lfCharSet', Thanks
public:
// Constructor
CLogFont()
{
// random filled
}
CLogFont(const LOGFONT& srcLogFont)
{
*(LOGFONT*)this = srcLogFont;
}
void InitDefault()
{
*(LOGFONT*)this = _lfDefault;
}
// Profile methods
template <class _Profile>
void WriteProfile(_Profile& __profile, HDC hDC = NULL, const CString& strPrefix = _T("lf.")) const
{
MTLVERIFY(__profile.SetValue(lfFaceName, strPrefix + _T("lfFaceName")) == ERROR_SUCCESS);
MTLVERIFY(__profile.SetValue(GetPointSizeFromHeight(lfHeight, hDC), strPrefix + _T("lfPointSize")) == ERROR_SUCCESS);
MTLVERIFY(__profile.SetValue(lfWeight, strPrefix + _T("lfWeight")) == ERROR_SUCCESS);
MTLVERIFY(__profile.SetValue(lfItalic, strPrefix + _T("lfItalic")) == ERROR_SUCCESS);
MTLVERIFY(__profile.SetValue(lfUnderline, strPrefix + _T("lfUnderLine")) == ERROR_SUCCESS);
MTLVERIFY(__profile.SetValue(lfStrikeOut, strPrefix + _T("lfStrikeOut")) == ERROR_SUCCESS);
MTLVERIFY(__profile.SetValue(lfCharSet, strPrefix + _T("lfCharSet")) == ERROR_SUCCESS);
}
template <class _Profile>
bool GetProfile(_Profile& __profile, HDC hDC = NULL, const CString& strPrefix = _T("lf."))
{
DWORD dwFaceSize = LF_FACESIZE, dwPointSize, dwWeight, dwItalic, dwUnderline, dwStrikeOut, dwCharSet;
if (__profile.QueryValue(lfFaceName, strPrefix + _T("lfFaceName"), &dwFaceSize) == ERROR_SUCCESS &&
__profile.QueryValue(dwPointSize, strPrefix + _T("lfPointSize")) == ERROR_SUCCESS &&
__profile.QueryValue(dwWeight, strPrefix + _T("lfWeight")) == ERROR_SUCCESS &&
__profile.QueryValue(dwItalic, strPrefix + _T("lfItalic")) == ERROR_SUCCESS &&
__profile.QueryValue(dwUnderline, strPrefix + _T("lfUnderLine")) == ERROR_SUCCESS &&
__profile.QueryValue(dwStrikeOut, strPrefix + _T("lfStrikeOut")) == ERROR_SUCCESS &&
__profile.QueryValue(dwCharSet, strPrefix + _T("lfCharSet")) == ERROR_SUCCESS)
{
lfHeight = GetHeightFromPointSize(dwPointSize, hDC);
lfWeight = dwWeight;
lfItalic = dwItalic;
lfUnderline = dwUnderline;
lfStrikeOut = dwStrikeOut;
lfCharSet = dwCharSet;
return true;
}
return false;
}
// Additional Operations
void operator=(const LOGFONT& srcLogFont)
{
*(LOGFONT*)this = srcLogFont;
}
bool operator==(const LOGFONT& lf) const
{
return (lfHeight == lf.lfHeight &&
lfWidth == lf.lfWidth &&
lfEscapement == lf.lfEscapement &&
lfOrientation == lf.lfOrientation &&
lfWeight == lf.lfWeight &&
lfItalic == lf.lfItalic &&
lfUnderline == lf.lfUnderline &&
lfStrikeOut == lf.lfStrikeOut &&
lfCharSet == lf.lfCharSet &&
lfOutPrecision == lf.lfOutPrecision &&
lfClipPrecision == lf.lfClipPrecision &&
lfQuality == lf.lfQuality &&
lfPitchAndFamily == lf.lfPitchAndFamily &&
::lstrcmp(lfFaceName, lf.lfFaceName) == 0);
}
bool operator!=(const LOGFONT& lf) const
{
return !(*this == lf);
}
// Helper Operations
static LONG GetHeightFromPointSize(LONG nPointSize, HDC hDC = NULL)
{// cf.WTL::CFont::CreatePointFontIndirect
HDC hDC1 = (hDC != NULL) ? hDC : (::GetDC(NULL));
// convert nPointSize to logical units based on hDC
POINT pt;
pt.y = ::GetDeviceCaps(hDC1, LOGPIXELSY) * nPointSize;
pt.y /= 72; // 72 points/inch, 10 decipoints/point
::DPtoLP(hDC1, &pt, 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -