#pragma once
#ifndef NULL
#define NULL 0
#endif
namespace RangeHelper
{
template <class T>
class CAutoDeletePtr {
//自动删除指针
public:
CAutoDeletePtr() : m_ptr(NULL) {
}
CAutoDeletePtr(T* ptr) {
m_ptr = ptr;
}
~CAutoDeletePtr() {
Free();
}
void Free() {
if (!m_ptr) return;
delete []m_ptr;
m_ptr = NULL;
}
bool Allocate(size_t nElements) {
Free();
m_ptr = new T[nElements];
if (!m_ptr) return false;
return true;
}
void Attach(T* p) {
ASSERT(p != NULL);
m_ptr = p;
}
T* Detach() {
T* p;
p = m_p;
m_p = NULL;
return( p );
}
T operator[](int i) const
{
ASSERT((i>=0) && AfxIsValidAddress(m_ptr, sizeof(T)*i));
return m_ptr[i];
}
T& operator[](int i)
{
ASSERT((i>=0) && AfxIsValidAddress(m_ptr, sizeof(T)*i));
return m_ptr[i];
}
CAutoDeletePtr<T>& operator=(const T* ptr)
{
if ((m_ptr != NULL) && (m_ptr != ptr))
{
if (m_ptr != NULL)
{
delete []m_ptr;
m_ptr = NULL;
}
}
m_ptr = const_cast<T*>(ptr);
return *this;
}
operator T*() const
{
return m_ptr;
}
private:
T *m_ptr;
};
template <class T>
class CAutoReleaseVM
//自释放虚拟内存
{
public:
CAutoReleaseVM() :m_ptr(NULL), m_nCnt(0) {
}
CAutoReleaseVM(T* vmData, ULONG nCnt) {
ASSERT(vmData);
ASSERT(nCnt>0);
m_ptr = vmData;
m_nCnt = nCnt;
}
CAutoReleaseVM(ULONG nElementCnt, DWORD flAllocationType=MEM_COMMIT, DWORD flProtect=PAGE_READWRITE) : m_ptr(NULL) {
AllocateVM(nElementCnt, flAllocationType, flProtect);
}
~CAutoReleaseVM()
{
FreeVM();
}
void FreeVM()
{
if (m_ptr) {
VirtualFree(m_ptr, 0, MEM_RELEASE);
m_nCnt = 0;
m_ptr = NULL;
}
}
BOOL AllocateVM(ULONG nElementCnt, DWORD flAllocationType=MEM_COMMIT, DWORD flProtect=PAGE_READWRITE)
{
FreeVM();
m_ptr = (T*)VirtualAlloc(NULL, nElementCnt*sizeof(T), flAllocationType, flProtect);
m_nCnt = nElementCnt;
return (m_ptr!=NULL);
}
BOOL ReAllocateVM(ULONG nElementCnt, BOOL bCopyOld=TRUE, DWORD flAllocationType=MEM_COMMIT, DWORD flProtect=PAGE_READWRITE)
{
if (!bCopyOld)
return AllocateVM(nElementCnt, flAllocationType, flProtect);
T *tmp = (T*)VirtualAlloc(NULL, nElementCnt*sizeof(T), flAllocationType, flProtect);
if (!tmp)
return FALSE;
memmove(tmp, m_ptr, min(nElementCnt, m_nCnt)*sizeof(T));
m_ptr = tmp;
m_nCnt= nElementCnt;
return TRUE;
}
BOOL IsOK() {
return (m_ptr!=NULL);
}
size_t GetDataBytes() {
size_t nDataBytes = 0;
if (IsOK()) {
nDataBytes = GetTypeSize()*m_nCnt;
}
return nDataBytes;
}
size_t GetTypeSize() {
return sizeof(T);
}
ULONG GetDataCount() {
ULONG nDataCount = 0;
if (IsOK()) {
nDataCount = m_nCnt;
}
return nDataCount;
}
T operator[](size_t i) const
{
ASSERT((i>=0) && m_ptr && AfxIsValidAddress(m_ptr, sizeof(T)*i));
return m_ptr[i];
}
T& operator[](size_t i)
{
ASSERT((i>=0) && m_ptr && AfxIsValidAddress(m_ptr, sizeof(T)*i));
return m_ptr[i];
}
operator T*() const
{
return m_ptr;
}
private:
T* m_ptr;
size_t m_nCnt;
};
class CAutoCloseHandle
//自动关闭句柄类
{
public:
CAutoCloseHandle(HANDLE* handle=NULL) : m_handle(handle)
{
}
CAutoCloseHandle& operator=(HANDLE* rh)
{
if (m_handle) {
CloseHandle(m_handle);
m_handle = NULL;
}
m_handle = rh;
return *this;
}
~CAutoCloseHandle()
{
CloseHandle(*m_handle);
}
private:
HANDLE *m_handle;
};
template <class T>
class CAutoDeleteArray : public CArray<T*, T*>
{
public:
~CAutoDeleteArray() {
RemoveAll();
}
void RemoveAt(INT_PTR nIndex, INT_PTR nCount = 1)
{
ASSERT(nCount>0);
for (INT_PTR i=nIndex; i!=min(nIndex+nCount, GetCount()); ++i)
{
T *pItem = GetAt(i);
delete pItem;
}
CArray::RemoveAt(nIndex, nCount);
}
void RemoveAll()
{
for (INT_PTR i=0; i!=GetCount(); ++i)
{
T *pItem = GetAt(i);
delete pItem;
}
CArray::RemoveAll();
}
};
/*
//CRangeFxnHelper使用示例
class A
{
public:
void func1(){
cout << 1 << endl;
}
void func2(){
cout << 2 << endl;
}
void test() {
CRangeFxnHelper<A> a(this, &A::func1, &A::func2);
}
};
*/
template <class T>
class CRangeFxnHelper
//局部函数调用
{
typedef void(T::* MemFxnPtr)(void); //成员函数
public:
CRangeFxnHelper(T* pClassName,
MemFxnPtr lpfxnEnter,
MemFxnPtr lpfxnLeave = NULL) : m_pClassName(pClassName),
m_lpfxnLeave(lpfxnLeave)
{
ASSERT(pClassName != NULL);
ASSERT(lpfxnEnter != NULL);
(m_pClassName->*lpfxnEnter)();
}
~CRangeFxnHelper()
{
if (m_lpfxnLeave != NULL)
(m_pClassName->*m_lpfxnLeave)();
}
private:
T *m_pClassName;
MemFxnPtr m_lpfxnLeave;
};
template <class T>
class CAutoRevertBOOL
//自动反置布尔变量
{
public:
CAutoRevertBOOL(T *pObjBool, T initVal) : m_pObjBool(pObjBool),
m_InitVal(initVal)
{
ASSERT(pObjBool != NULL);
*pObjBool = initVal;
}
~CAutoRevertBOOL()
{
*m_pObjBool = !m_InitVal;
}
private:
T *m_pObjBool;
T m_InitVal;
};
class CAutoDisableEnableChildCtls
{
public:
CAutoDisableEnableChildCtls(HWND hwndParent, UINT nFirstExcludeChildCtrlID=-1, ...)
: m_hwndParent(hwndParent), m_bDisabled(FALSE)
{
AddExcludeCtrlIDs(nFirstExcludeChildCtrlID);
}
~CAutoDisableEnableChildCtls()
{
if (m_bDisabled)
SwitchStatus();
}
void SwitchStatus()
{
struct stEnumChild
{
BOOL *pChangeStatus ;//改变状态
CArray<UINT, UINT> *pArrayExcludeID ;//无须进行状态改变的列表
CArray<HWND, HWND> *pStatusChangedWND ;//已经改变的窗口
};
class CEnumChildHelper
{
public:
static BOOL __stdcall EnumChildProc(HWND hwnd, LPARAM lParam)
{
stEnumChild *pParam = (stEnumChild *)lParam;
LONG lStyle = GetWindowLong(hwnd, GWL_STYLE);
BOOL bDisable = *(pParam->pChangeStatus);
CArray<UINT, UINT> &arr = *(pParam->pArrayExcludeID);
CArray<HWND, HWND> &aChanged = *(pParam->pStatusChangedWND);
for (int i=0; i!=arr.GetCount(); ++i)
{
if (GetDlgCtrlID(hwnd) == arr[i]) return TRUE;
}
TCHAR szClsName[512] = {_T('\0')};
GetClassName(hwnd, szClsName, 512);
if (!_tcscmp(szClsName, _T("Internet Explorer_Server")))//不处理Web浏览器
return TRUE;
if (!_tcscmp(szClsName, _T("Static"))) //静态文本
return TRUE;
if (bDisable)
{
if ((lStyle&WS_DISABLED) != WS_DISABLED) {
lStyle |= WS_DISABLED;
aChanged.Add(hwnd);
}
} else {
if ((lStyle&WS_DISABLED) == WS_DISABLED) {
int i = 0;
for (; i!=aChanged.GetCount(); ++i)
{
if (hwnd == aChanged[i])
break;
}
if (i == aChanged.GetCount()) {
//未在已处理过的控件列表中
return TRUE;
}
aChanged.RemoveAt(i);
lStyle &= ~WS_DISABLED;
}
}
SetWindowLong(hwnd, GWL_STYLE, lStyle);
::InvalidateRect(hwnd, NULL, TRUE);
return TRUE;
}
};
stEnumChild param;
param.pChangeStatus = &m_bDisabled;
param.pArrayExcludeID = &m_aExcludeIDs;
param.pStatusChangedWND = &m_aStatusChangedChild;
m_bDisabled = !m_bDisabled;
EnumChildWindows(m_hwndParent, CEnumChildHelper::EnumChildProc, (LPARAM)¶m);
}
void AddExcludeCtrlIDs(UINT nID, ...)
//以-1结尾
{
va_list arglst;
va_start(arglst, nID);
while (nID != (UINT)-1)
{
//防止添加多次
for (INT_PTR i=0; i!=m_aExcludeIDs.GetSize(); ++i)
{
if (nID == m_aExcludeIDs[i]) goto Next;
}
m_aExcludeIDs.Add(nID);
Next:
nID = va_arg(arglst, UINT);
}
va_end(arglst);
}
private:
HWND m_hwndParent;
CArray<UINT, UINT> m_aExcludeIDs;
BOOL m_bDisabled;
CArray<HWND, HWND> m_aStatusChangedChild;
};
class CAutoWndStatusSwitch
//自动转换窗口使能与禁用状态
{
public:
//ID 以-1结尾
CAutoWndStatusSwitch(HWND hwndParent, UINT nID=-1, ...)
: m_hwndParent(hwndParent), m_bSwitched(FALSE)
{
ASSERT(hwndParent != NULL);
AddCtrls(nID);
}
~CAutoWndStatusSwitch()
{
if (m_bSwitched)
SwitchStatus();
}
void AddCtrls(UINT nID, ...)
//以-1结尾
{
va_list arglst;
va_start(arglst, nID);
while (nID != (UINT)-1)
{
//防止添加多次
for (INT_PTR i=0; i!=m_aIDs.GetSize(); ++i)
{
if (nID == m_aIDs[i]) goto Next;
}
m_aIDs.Add(nID);
Next:
nID = va_arg(arglst, UINT);
}
va_end(arglst);
}
void SwitchStatus()
//状态转换
{
m_bSwitched = !m_bSwitched;
for (INT_PTR i=0; i!=m_aIDs.GetSize(); ++i)
{
HWND hCtrl = GetDlgItem(m_hwndParent, m_aIDs[i]);
if (!IsWindow(hCtrl)) continue;
LONG lStyle = GetWindowLong(hCtrl, GWL_STYLE);
if ((lStyle&WS_DISABLED) == WS_DISABLED)
lStyle &= ~WS_DISABLED;
else
lStyle |= WS_DISABLED;
SetWindowLong(hCtrl, GWL_STYLE, lStyle);
::InvalidateRect(hCtrl, NULL, TRUE);
}
}
private:
HWND m_hwndParent;
CArray<UINT, UINT> m_aIDs;
BOOL m_bSwitched;
};
class CAutoHideShowWnd
//自动隐藏窗口
{
public:
CAutoHideShowWnd(HWND hWnd, BOOL bHide=TRUE):m_hWnd(hWnd)
{
ASSERT(IsWindow(hWnd));
if (bHide) Hide();
}
~CAutoHideShowWnd()
{
Restore();
}
void Hide()
{
if (IsWindow(m_hWnd) &&
(GetWindowLong(m_hWnd, GWL_STYLE) & WS_VISIBLE)) {
ShowWindow(m_hWnd, SW_HIDE);
}
}
void Restore()
{
if (IsWindow(m_hWnd) &&
(GetWindowLong(m_hWnd, GWL_STYLE) & ~WS_VISIBLE)) {
ShowWindow(m_hWnd, SW_SHOW);
}
}
private:
HWND m_hWnd;
};
}VC++自释放指针、自释放虚拟内存、自关闭句柄、局部作用域回调函数调用等辅助开发类
原文地址:http://blog.csdn.net/sdhongjun/article/details/42058669