2025-11-28 00:35:46 +09:00

353 lines
8.3 KiB
C++

//------------------------------------------------------------------------------
// File: persist.cpp
//
// Desc: DirectShow sample code
// - State persistence helper functions
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include "project.h"
// Global data
RECENTFILES aRecentFiles[MAX_RECENT_FILES]={0};
int nRecentFiles=0;
// Global static data
static TCHAR cszWindow[] = TEXT("Window\0");
static TCHAR cszAppKey[] = TEXT("Software\\Microsoft\\Multimedia Tools\\VMRPlayer9\0");
#ifndef CheckPointer
#define CheckPointer(x, hr) if (x == NULL) { return hr; }
#endif
// Constants
const int CX_DEFAULT = 400; /* Default window width */
const int CY_DEFAULT = 400; /* Default window height */
/******************************Public*Routine******************************\
* GetAppKey
*
\**************************************************************************/
HKEY
GetAppKey(
BOOL fCreate
)
{
HKEY hKey = 0;
if(fCreate)
{
if(RegCreateKey(HKEY_CURRENT_USER, cszAppKey, &hKey) == ERROR_SUCCESS)
return hKey;
}
else
{
if(RegOpenKey(HKEY_CURRENT_USER, cszAppKey, &hKey) == ERROR_SUCCESS)
return hKey;
}
return NULL;
}
/******************************Public*Routine******************************\
* ProfileStringIn
*
\**************************************************************************/
UINT
ProfileStringIn(
LPTSTR szKey,
LPTSTR szDefault,
LPTSTR szProfileString,
DWORD cb
)
{
CheckPointer(szKey,0);
CheckPointer(szDefault,0);
CheckPointer(szProfileString,0);
HKEY hKey;
DWORD dwType;
if((hKey = GetAppKey(FALSE)) == 0)
{
StringCbCopy(szProfileString, cb, szDefault);
return lstrlen(szProfileString);
}
if((RegQueryValueEx(hKey, szKey, NULL, &dwType,
(LPBYTE)szProfileString, &cb) != ERROR_SUCCESS)
|| dwType != REG_SZ)
{
StringCbCopy(szProfileString, cb, szDefault);
cb = lstrlen(szProfileString);
}
RegCloseKey(hKey);
return cb;
}
/******************************Public*Routine******************************\
* ProfileStringOut
*
\**************************************************************************/
void
ProfileStringOut(
LPTSTR szKey,
LPTSTR szProfileString
)
{
assert(szKey);
assert(szProfileString);
HKEY hKey;
hKey = GetAppKey(TRUE);
if (hKey)
{
RegSetValueEx(hKey, szKey, 0, REG_SZ, (LPBYTE)szProfileString,
sizeof(TCHAR) * (lstrlen(szProfileString)+1));
RegCloseKey(hKey);
}
}
/******************************Public*Routine******************************\
* LoadWindowPos
*
* Retrieve the window position information from the registry
*
\**************************************************************************/
#ifndef SPI_GETWORKAREA
#define SPI_GETWORKAREA 48 // because NT doesnt have this define yet
#endif
BOOL
LoadWindowPos(
LPRECT lprc
)
{
CheckPointer(lprc,FALSE);
static RECT rcDefault = {0,0,CX_DEFAULT,CY_DEFAULT};
RECT rcScreen, rc;
HKEY hKey = GetAppKey(FALSE);
// Read window placement from the registry.
//
*lprc = rcDefault;
if(hKey)
{
DWORD cb = sizeof(rc);
DWORD dwType;
if(ERROR_SUCCESS == RegQueryValueEx(hKey, cszWindow, NULL, &dwType, (LPBYTE)&rc, &cb)
&& dwType == REG_BINARY && cb == sizeof(RECT))
{
*lprc = rc;
}
RegCloseKey(hKey);
}
// If we fail to get the working area (screen-tray), then assume
// the screen is 640x480
//
if(! SystemParametersInfo(SPI_GETWORKAREA, 0, &rcScreen, FALSE))
{
rcScreen.top = rcScreen.left = 0;
rcScreen.right = 640;
rcScreen.bottom = 480;
}
// If the proposed window position is outside the screen,
// use the default placement
//
if(! IntersectRect(&rc, &rcScreen, lprc))
{
*lprc = rcDefault;
}
return ! IsRectEmpty(lprc);
}
/*****************************Public*Routine******************************\
* SaveWindowPos
*
* Store the window position information in the registry
*
\**************************************************************************/
BOOL
SaveWindowPos(
HWND hwnd
)
{
WINDOWPLACEMENT wpl;
HKEY hKey = GetAppKey(TRUE);
if(!hKey)
{
return FALSE;
}
// Save the current size and position of the window to the registry
//
ZeroMemory(&wpl, sizeof(wpl));
wpl.length = sizeof(wpl);
GetWindowPlacement(hwnd, &wpl);
RegSetValueEx(hKey, cszWindow, 0, REG_BINARY,
(LPBYTE)&wpl.rcNormalPosition,
sizeof(wpl.rcNormalPosition));
RegCloseKey(hKey);
return TRUE;
}
/*****************************Private*Routine******************************\
* GetRecentFiles
*
* Reads at most MAX_RECENT_FILES from the app's registry entry.
* Returns the number of files actually read.
* Updates the File menu to show the "recent" files.
*
\**************************************************************************/
int
GetRecentFiles(
int iLastCount,
int iMenuPosition // Menu position of start of MRU list
)
{
int i;
TCHAR FileName[MAX_PATH];
TCHAR szKey[32];
HMENU hSubMenu;
//
// Delete the files from the menu
//
hSubMenu = GetSubMenu(GetMenu(hwndApp), 0);
// Delete the separator at the requested position and all the other
// recent file entries
if(iLastCount != 0)
{
DeleteMenu(hSubMenu, iMenuPosition, MF_BYPOSITION);
for(i = 1; i <= iLastCount; i++)
{
DeleteMenu(hSubMenu, ID_RECENT_FILE_BASE + i, MF_BYCOMMAND);
}
}
for(i = 1; i <= MAX_RECENT_FILES; i++)
{
DWORD len;
TCHAR szMenuName[MAX_PATH + 3];
(void)StringCchPrintf(szKey, NUMELMS(szKey), TEXT("File %d\0"), i);
len = ProfileStringIn(szKey, TEXT(""), FileName, MAX_PATH * sizeof(TCHAR));
if(len == 0)
{
i = i - 1;
break;
}
StringCchCopy(aRecentFiles[i - 1], NUMELMS(aRecentFiles[i-1]), FileName);
(void)StringCchPrintf(szMenuName, NUMELMS(szMenuName), TEXT("&%d %s\0"), i, FileName);
if(i == 1)
{
InsertMenu(hSubMenu, iMenuPosition, MF_SEPARATOR | MF_BYPOSITION, (UINT)-1, NULL);
}
InsertMenu(hSubMenu, iMenuPosition + i, MF_STRING | MF_BYPOSITION,
ID_RECENT_FILE_BASE + i, szMenuName);
}
//
// i is the number of recent files in the array.
//
return i;
}
/*****************************Private*Routine******************************\
* SetRecentFiles
*
* Writes the most recent files to the registry.
* Purges the oldest file if necessary.
*
\**************************************************************************/
int
SetRecentFiles(
TCHAR *FileName, // File name to add
int iCount, // Current count of files
int iMenuPosition // Menu position of start of MRU list
)
{
TCHAR FullPathFileName[MAX_PATH];
TCHAR *lpFile=0;
TCHAR szKey[32];
int iCountNew, i;
//
// Check for duplicates - we don't allow them
//
for(i = 0; i < iCount; i++)
{
if(0 == lstrcmpi(FileName, aRecentFiles[i]))
{
return iCount;
}
}
//
// Throw away the oldest entry
//
MoveMemory(&aRecentFiles[1], &aRecentFiles[0],
sizeof(aRecentFiles) - sizeof(aRecentFiles[1]));
//
// Copy in the full path of the new file.
//
GetFullPathName(FileName, MAX_PATH, FullPathFileName, &lpFile);
StringCchCopy(aRecentFiles[0], NUMELMS(aRecentFiles[0]), FullPathFileName);
//
// Update the count of files, saturate to MAX_RECENT_FILES.
//
iCountNew = min(iCount + 1, MAX_RECENT_FILES);
//
// Clear the old stuff and the write out the recent files to disk
//
for(i = 1; i <= iCountNew; i++)
{
(void)StringCchPrintf(szKey, NUMELMS(szKey),TEXT("File %d\0"), i);
ProfileStringOut(szKey, aRecentFiles[i - 1]);
}
//
// Update the file menu
//
GetRecentFiles(iCount, iMenuPosition);
return iCountNew; // the updated count of files.
}