MRU.cpp
资源名称:vnc3326s.zip [点击查看]
上传用户:sbftbdw
上传日期:2007-01-03
资源大小:379k
文件大小:9k
源码类别:
远程控制编程
开发平台:
Visual C++
- // Copyright (C) 1997, 1998 Olivetti & Oracle Research Laboratory
- //
- // 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.orl.co.uk/vnc or contact
- // the authors on vnc@orl.co.uk 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(' ');
- 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;
- // Read each value in index,
- // noting which is the first unused id
- TCHAR id = _T(' ');
- 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(' ');
- 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(' ');
- 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(' ');
- 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 registry
- void 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 registry
- void 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(' ');
- // Check that no entry occurs more than once.
- DWORD seenCharMask = 0;
- for (i = 0; m_index[i] != _T(' '); 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(' '); 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;
- }
- }