⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mru.cpp

📁 realvnc是一个非常流行的远程控制程序
💻 CPP
字号:
//  Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.////  This file is part of the VNC system.////  The VNC system is free software; you can redistribute it and/or modify//  it under the terms of the GNU General Public License as published by//  the Free Software Foundation; either version 2 of the License, or//  (at your option) any later version.////  This program is distributed in the hope that it will be useful,//  but WITHOUT ANY WARRANTY; without even the implied warranty of//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the//  GNU General Public License for more details.////  You should have received a copy of the GNU General Public License//  along with this program; if not, write to the Free Software//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,//  USA.//// If the source code for the VNC system is not available from the place // whence you received this file, check http://www.uk.research.att.com/vnc or contact// the authors on vnc@uk.research.att.com for information on obtaining it.//// MRU maintains a list of 'Most Recently Used' strings in the registry// #include "MRU.h"static const TCHAR * INDEX_VAL_NAME = _T("index");static const int MRU_MAX_ITEM_LENGTH = 256;MRU::MRU(LPTSTR keyname, unsigned int maxnum){	DWORD dispos;    // Create the registry key.  If unsuccessful all other methods will be no-ops.    if ( RegCreateKeyEx(HKEY_CURRENT_USER, keyname, 0, NULL, 		REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &m_hRegKey, &dispos)  != ERROR_SUCCESS ) {        m_hRegKey = NULL;    }    m_index[0] = _T('\0');    m_maxnum = maxnum;    // Read the index entry    ReadIndex();    Tidy();}// Add the item specified at the front of the list// Move it there if not already.  If this makes the// list longer than the maximum, older ones are deleted.void MRU::AddItem(LPTSTR txt) {    if (m_hRegKey == NULL) return;	// We don't add empty items.	if (_tcslen(txt) == 0) return;    // Read each value in index,    // noting which is the first unused id    TCHAR id = _T('\0');    TCHAR firstUnusedId = _T('A');    TCHAR itembuf[MRU_MAX_ITEM_LENGTH+1];	// Find first unused letter.	while (_tcschr(m_index, firstUnusedId) != NULL)		firstUnusedId++;    for (int i = 0; i < (int) _tcslen(m_index); i++) {                // Does this entry already contain the item we're adding        if (GetItem(i, itembuf, MRU_MAX_ITEM_LENGTH) != 0) {                        // If a value matches the txt specified, move it to the front.            if (_tcscmp(itembuf, txt) == 0) {                id = m_index[i];                for (int j = i; j > 0; j--)                    m_index[j] = m_index[j-1];                m_index[0] = id;                WriteIndex();                // That's all we need to do.                return;            }        }    }    // If we haven't found it, then we need to create a new entry and put it    // at the front of the index.    TCHAR valname[2];    valname[0] = firstUnusedId;    valname[1] = _T('\0');    RegSetValueEx(m_hRegKey, valname, NULL, REG_SZ,         (CONST BYTE *) txt, (_tcslen(txt) + 1) * sizeof(TCHAR));        // move all the current ids up one    for (int j = _tcslen(m_index); j >= 0; j--)        m_index[j] = m_index[j-1];        // and insert this one at the front    m_index[0] = firstUnusedId;    WriteIndex();    // Tidy, to truncate index if too long.    Tidy();}// How many items are on the list?int MRU::NumItems(){    if (m_hRegKey == NULL) return 0;    // return the length of index    return _tcslen(m_index);}// Return them in order. 0 is the newest.// NumItems()-1 is the oldest.// Returns length, or 0 if unsuccessful.int MRU::GetItem(int index, LPTSTR buf, int buflen){    if (m_hRegKey == NULL)      return 0;    if (index > NumItems() - 1) return 0;    TCHAR valname[2];    valname[0] = m_index[index];    valname[1] = _T('\0');    DWORD valtype;    DWORD dwbuflen = buflen;    if ( RegQueryValueEx( m_hRegKey,  valname,             NULL, &valtype,             (LPBYTE) buf, &dwbuflen) != ERROR_SUCCESS)          return 0;    if (valtype != REG_SZ)        return 0;  // should really be an assert    // May not be one byte per char, so we won't use dwbuflen    return _tcslen(buf);}// Remove the specified item if it exists.// Only one copy will be removed, but nothing should occur more than once.void MRU::RemoveItem(LPTSTR txt){    if (m_hRegKey == NULL) return;    TCHAR itembuf[MRU_MAX_ITEM_LENGTH+1];    for (int i = 0; i < NumItems(); i++) {        GetItem(i, itembuf, MRU_MAX_ITEM_LENGTH);        if (_tcscmp(itembuf, txt) == 0) {            RemoveItem(i);            break;        }    }}// Remove the item with the given index.// If this is greater than NumItems()-1 it will be ignored.void MRU::RemoveItem(int index){    if (m_hRegKey == NULL) return;    if (index > NumItems()-1) return;    TCHAR valname[2];    valname[0] = m_index[index];    valname[1] = _T('\0');    RegDeleteValue(m_hRegKey, valname);    for (unsigned int i = index; i <= _tcslen(m_index); i++)        m_index[i] = m_index[i+1];        WriteIndex();}// Load the index string from the registryvoid MRU::ReadIndex(){    if (m_hRegKey == NULL) return;    // read the index    DWORD valtype;    DWORD dwindexlen = sizeof(m_index);    if (RegQueryValueEx( m_hRegKey, INDEX_VAL_NAME,        NULL, &valtype, (LPBYTE) m_index, &dwindexlen) == ERROR_SUCCESS) {    } else {        // If index entry doesn't exist, create it        WriteIndex();    }}// Save the index string to the registryvoid MRU::WriteIndex(){   if (m_hRegKey == NULL) return;   RegSetValueEx(m_hRegKey, INDEX_VAL_NAME, NULL, REG_SZ,         (CONST BYTE *)m_index, (_tcslen(m_index) + 1) * sizeof(TCHAR));}// Tidy is called from time to time to preserve the integrity of the MRU// list.  It does three things://  * Check the length and integrity of the index//  * Check that all other values in the registry key have an //    entry in the index and delete them from registry if not.//  * Check that all entries in the index have a corresponding//    value in the registry key and delete them from index if not.void MRU::Tidy(){    if (m_hRegKey == NULL) return;    int i;    	// First some checks on the index itself.    // Truncate the index.    m_index[m_maxnum] = _T('\0');    // Check that no entry occurs more than once.	DWORD seenCharMask = 0;	for (i = 0; m_index[i] != _T('\0'); i++) {		DWORD mask = 1 << (m_index[i]-_T('A'));		if (seenCharMask & mask) {			// The current character has been used before.			// Delete it and move everything up.			for (int j = i; m_index[j] != _T('\0'); j++)				m_index[j] = m_index[j+1];			// Start next check at new current character			i--;		}		seenCharMask |= mask;	}	// Then check that all entries in registry have entry in index.    TCHAR valname[256];    DWORD valtype;    DWORD valnamelen;    DWORD numValues;    RegQueryInfoKey ( m_hRegKey,          NULL, NULL,         NULL, NULL,         NULL, NULL,          &numValues,          NULL, NULL,        NULL, NULL);    // We're being good here.  The documentation says we shouldn't    // modify a key while enumerating its values. So this array will    // hold the names of keys which should be deleted    TCHAR **dudValues = new TCHAR* [numValues];    for (i = 0; i < (int) numValues; i++)        dudValues[i] = NULL;    unsigned int numDudValues = 0;    i = 0;    while (1) {        valnamelen = 255;                if (RegEnumValue(m_hRegKey, i,                         valname, &valnamelen, NULL,                        &valtype, NULL, NULL) == ERROR_NO_MORE_ITEMS)            break;        i++;                // ignore the index        if (_tcscmp(valname, INDEX_VAL_NAME) == 0)            continue;        // Record as invalid other non-single-char entries        if (_tcslen(valname) > 1) {            dudValues[numDudValues++] = _tcsdup(valname);            continue;        }        // Record as invalid if not in the index        if (_tcschr(m_index, valname[0]) == 0) {            dudValues[numDudValues++] = _tcsdup(valname);            continue;        }       }    // Now delete the invalid ones    for (i = 0; i < (int) numDudValues; i++) {        RegDeleteValue(m_hRegKey, dudValues[i]);        free(dudValues[i]);    }    delete[] dudValues;    // Lastly, check that all entries in the index have a corresponding     // entry in registry and delete them if not.    for (i = _tcslen(m_index)-1; i >= 0;  i--) {        TCHAR itembuf[MRU_MAX_ITEM_LENGTH+1];        if (GetItem(i, itembuf, MRU_MAX_ITEM_LENGTH) == 0) {            for (unsigned int j = i; j <= _tcslen(m_index)-1; j++)                m_index[j] = m_index[j+1];        }    }	// Save any changes to the index.    WriteIndex();}MRU::~MRU(){    if (m_hRegKey != NULL) {        Tidy();        RegCloseKey(m_hRegKey);        m_hRegKey = NULL;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -