regbinding.cpp
来自「zip的全部算法源代码」· C++ 代码 · 共 343 行
CPP
343 行
// RegBinding.cpp: implementation of the CRegBinding class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "RegBinding.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
// CEntry class
class CEntry : public CObject
{
public:
enum Type
{
CR_INVALID,
CR_INT,
CR_DWORD,
CR_STRING,
CR_BYTE_ARR,
CR_CWND,
CR_BOOL
};
Type m_eType;
CString m_strName;
LPVOID m_pData;
CEntry() :
m_eType(CR_INVALID), m_pData(NULL) { }
CEntry(const CEntry &e) :
m_eType(e.m_eType), m_pData(e.m_pData), m_strName(e.m_strName) { }
};
// CRegBinding class members
BOOL CRegBinding::Hook(const HWND hwnd)
{
CEntry *e;
if (FindAndRemove(e, hwnd)) {
SaveWindowState(*e);
delete e;
return TRUE;
}
return FALSE;
}
BOOL CRegBinding::FindAndRemove(CEntry *&e, const HWND hwnd)
{
POSITION pos = m_list.GetHeadPosition(), spos;
while (pos != NULL) {
spos = pos;
CObject *o = m_list.GetNext(pos);
ASSERT_VALID(o);
e = (CEntry *)o;
if (e->m_eType == CEntry::CR_CWND) {
CWnd *wnd = (CWnd *)e->m_pData;
if (wnd->GetSafeHwnd() == hwnd) {
m_list.RemoveAt(spos);
return TRUE;
}
}
}
return FALSE;
}
void CRegBinding::Bind(bool &value, const char *name, const bool def)
{
value = m_pApp->GetProfileInt(m_strSection, name, def) != 0;
CEntry e;
e.m_eType = CEntry::CR_BOOL;
e.m_pData = &value;
e.m_strName = name;
Insert(e);
}
void CRegBinding::Bind(int &value, const char *name, const int def)
{
value = m_pApp->GetProfileInt(m_strSection, name, def);
CEntry e;
e.m_eType = CEntry::CR_INT;
e.m_pData = &value;
e.m_strName = name;
Insert(e);
}
void CRegBinding::Bind(DWORD &value, const char *name, const DWORD def)
{
value = m_pApp->GetProfileInt(m_strSection, name, def);
CEntry e;
e.m_eType = CEntry::CR_DWORD;
e.m_pData = &value;
e.m_strName = name;
Insert(e);
}
void CRegBinding::Bind(CString &value, const char *name, const char *def)
{
const char *ds = def ? def : "";
value = m_pApp->GetProfileString(m_strSection, name, ds);
CEntry e;
e.m_eType = CEntry::CR_STRING;
e.m_pData = &value;
e.m_strName = name;
Insert(e);
}
void CRegBinding::Bind(CByteArray &value, const char *name,
const CByteArray *def)
{
LPBYTE data = NULL;
UINT bytes;
m_pApp->GetProfileBinary(m_strSection, name, &data, &bytes);
if (bytes > 0) {
// registry contains some data
value.SetAtGrow(bytes - 1, 0);
BYTE *p = value.GetData();
CopyMemory(p, data, bytes);
delete data;
} else {
// assume default value
if (def) {
ASSERT_VALID(def);
value.Copy(*def);
}
}
CEntry e;
e.m_eType = CEntry::CR_BYTE_ARR;
e.m_pData = &value;
e.m_strName = name;
Insert(e);
}
void CRegBinding::Bind(CWnd *wnd, const char *name)
{
ASSERT_VALID(wnd);
ASSERT(wnd->GetSafeHwnd() != NULL);
CString n;
if (name)
n = name;
else {
wnd->GetWindowText(n);
if (n.IsEmpty())
n = "Window";
}
n += '_';
WINDOWPLACEMENT wp;
wp.length = sizeof (WINDOWPLACEMENT);
wnd->GetWindowPlacement(&wp);
if (((wp.flags =
m_pApp->GetProfileInt (m_strSection, n + "flags", -1)) != -1) &&
((wp.showCmd =
m_pApp->GetProfileInt (m_strSection, n + "showCmd", -1)) != -1) &&
((wp.rcNormalPosition.left =
m_pApp->GetProfileInt (m_strSection, n + "x1", -1)) != -1) &&
((wp.rcNormalPosition.top =
m_pApp->GetProfileInt (m_strSection, n + "y1", -1)) != -1) &&
((wp.rcNormalPosition.right =
m_pApp->GetProfileInt (m_strSection, n + "x2", -1)) != -1) &&
((wp.rcNormalPosition.bottom =
m_pApp->GetProfileInt (m_strSection, n + "y2", -1)) != -1)) {
wp.rcNormalPosition.left = min (wp.rcNormalPosition.left,
::GetSystemMetrics (SM_CXSCREEN) -
::GetSystemMetrics (SM_CXICON));
wp.rcNormalPosition.top = min (wp.rcNormalPosition.top,
::GetSystemMetrics (SM_CYSCREEN) -
::GetSystemMetrics (SM_CYICON));
wnd->SetWindowPlacement (&wp);
}
CEntry e;
e.m_eType = CEntry::CR_CWND;
e.m_pData = wnd;
e.m_strName = n;
Insert(e);
}
CWinApp *CRegBinding::m_pApp;
HHOOK CRegBinding::m_hHook;
CRegBinding::CRegBinding(const char *section) : m_strSection(section)
{
m_pApp = AfxGetApp();
ASSERT_VALID(m_pApp);
if (m_lInstances.IsEmpty()) {
m_hHook = ::SetWindowsHookEx(WH_CBT, FilterHook, NULL, ::GetCurrentThreadId());
if (m_hHook == NULL)
AfxThrowMemoryException();
}
Bind(this);
}
void CRegBinding::Insert(const CEntry &e)
{
// in autosave Mode the destructor of the CRegBinding Member Object
// must be called before any other member destructor is executed
#ifdef _DEBUG
LPVOID tp = (const LPVOID)this;
LPVOID mp = (const LPVOID)(e.m_pData);
if (!(mp < tp)) {
TRACE("Please put the CRegBinding Object behind"
"the last member to bind\n"
"Only class members can registerd by CRegBinding\n");
ASSERT(0);
}
POSITION pos = m_list.GetHeadPosition();
while (pos != NULL) {
CObject *o = m_list.GetNext(pos);
ASSERT_VALID(o);
CEntry *le = (CEntry *)o;
if (le->m_strName == e.m_strName) {
TRACE("The same key already exists in this section\n");
ASSERT(0);
}
}
#endif
CEntry *ne = new CEntry(e);
ASSERT_VALID(ne);
m_list.AddTail(ne);
}
void CRegBinding::SaveWindowState(const CEntry &e)
{
ASSERT(e.m_eType == CEntry::CR_CWND);
CWnd *wnd = (CWnd *)e.m_pData;
ASSERT_VALID(wnd);
CString n = e.m_strName;
WINDOWPLACEMENT wp;
wp.length = sizeof (WINDOWPLACEMENT);
wnd->GetWindowPlacement(&wp);
m_pApp->WriteProfileInt(m_strSection, n + "flags", wp.flags);
m_pApp->WriteProfileInt(m_strSection, n + "showCmd", wp.showCmd);
m_pApp->WriteProfileInt(m_strSection, n + "x1", wp.rcNormalPosition.left);
m_pApp->WriteProfileInt(m_strSection, n + "y1", wp.rcNormalPosition.top);
m_pApp->WriteProfileInt(m_strSection, n + "x2", wp.rcNormalPosition.right);
m_pApp->WriteProfileInt(m_strSection, n + "y2", wp.rcNormalPosition.bottom);
}
CRegBinding::~CRegBinding()
{
Write(TRUE);
UnBind(this);
if (m_lInstances.IsEmpty()) {
UnhookWindowsHookEx(m_hHook);
}
}
void CRegBinding::Write(BOOL del)
{
POSITION pos1 = m_list.GetHeadPosition(), pos2;
while (pos1 != NULL) {
pos2 = pos1;
CEntry *o = (CEntry *)m_list.GetNext(pos1);
ASSERT_VALID(o);
Write(o);
if (del) {
m_list.RemoveAt(pos2);
delete o;
}
}
}
void CRegBinding::Write(const CEntry *e)
{
ASSERT_VALID(e);
switch (e->m_eType) {
case CEntry::CR_BOOL:
{
bool *pb = (bool *)e->m_pData;
int i = (int)*pb;
int *pi = &i;
m_pApp->WriteProfileInt(m_strSection, e->m_strName, *pi);
return;
}
case CEntry::CR_INT:
{
int *i = (int *)(e->m_pData);
m_pApp->WriteProfileInt(m_strSection, e->m_strName, *i);
return;
}
case CEntry::CR_DWORD:
{
DWORD *dw = (DWORD *)(e->m_pData);
m_pApp->WriteProfileInt(m_strSection, e->m_strName, *dw);
return;
}
case CEntry::CR_STRING:
{
CString *str = (CString *)(e->m_pData);
m_pApp->WriteProfileString(m_strSection, e->m_strName, *str);
return;
}
case CEntry::CR_BYTE_ARR:
{
CByteArray *p = (CByteArray *)(e->m_pData);
ASSERT_VALID(p);
m_pApp->WriteProfileBinary(m_strSection, e->m_strName, p->GetData(),
p->GetSize());
return;
}
case CEntry::CR_CWND:
SaveWindowState(*e);
return;
}
ASSERT(0);
}
CObList CRegBinding::m_lInstances;
LRESULT CALLBACK
CRegBinding::FilterHook(int code, WPARAM wParam, LPARAM lParam)
{
if (code == HCBT_DESTROYWND) {
ASSERT(wParam != NULL); // should be non-NULL HWND
POSITION pos = m_lInstances.GetHeadPosition();
while (pos != NULL) {
CObject *o = m_lInstances.GetNext(pos);
ASSERT_VALID(o);
CRegBinding *rs = (CRegBinding *)o;
if (rs->Hook((HWND)wParam))
break;
}
}
return CallNextHookEx(m_hHook, code, wParam, lParam);
}
void CRegBinding::Bind(CRegBinding *rs)
{
m_lInstances.AddTail(rs);
}
void CRegBinding::UnBind(CRegBinding *rs)
{
ASSERT_VALID(rs);
POSITION f = m_lInstances.Find(rs);
ASSERT(f != NULL);
m_lInstances.RemoveAt(f);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?