📄 win32utils.cpp
字号:
//////////////////////////////////////////////////////////////////////////////
// Win32Utils.cpp
//
// Common Win32 utils.
//////////////////////////////////////////////////////////////////////////////
// $Id: Win32Utils.cpp,v 1.4 1998/12/15 01:25:05 nryan Exp $
// Copyright (C) 1998 by Network Associates, Inc.
// All rights reserved.
#if defined(PGPDISK_MFC)
#include "StdAfx.h"
#include "AfxPriv.h"
#include <Objbase.h>
#include <Shlobj.h>
#include <Dbt.h>
#else
#error Define PGPDISK_MFC.
#endif // PGPDISK_MFC
#include "Required.h"
#include "LinkResolution.h"
#include "PGPdiskPrefs.h"
#include "StringAssociation.h"
#include "UtilityFunctions.h"
#include "Win32Utils.h"
#include "WindowsVersion.h"
////////////
// Constants
////////////
const char kInvalidCharReplacement = '_';
const HKEY kRegistryMappedDriveRoot = HKEY_CURRENT_USER;
static LPCSTR kRegistryMappedDrive98Section = "Network\\Persistent";
static LPCSTR kRegistryMappedDriveNTSection = "Network";
//////////
// Globals
//////////
static CWnd *MessageBoxParent;
////////////////////////
// Message box functions
////////////////////////
// RegisterPGPdiskMsgBoxParent registers a window to be used as a message-box
// parent.
void
RegisterPGPdiskMsgBoxParent(CWnd *pWnd)
{
MessageBoxParent = pWnd;
}
// GetLastPGPdiskWindow returns the frontmost PGPdisk window.
CWnd *
GetLastPGPdiskWindow()
{
if (MessageBoxParent->GetSafeHwnd())
return MessageBoxParent->GetLastActivePopup();
else
return NULL;
}
// PGPdiskMessageBox shows a message box with the specified options. It
// returns the button the user pressed.
UserResponse
PGPdiskMessageBox(
LPCSTR message,
CWnd *pParent,
LPCSTR title,
PGDMessageBoxStyle style,
PGDMessageBoxFocus focus)
{
MSGBOXPARAMS mbParams;
PGPdiskWin32Prefs prefs;
PGPUInt32 button, defaultButton, flags;
pgpAssertStrValid(message);
pgpAssertStrValid(title);
mbParams.cbSize = sizeof(MSGBOXPARAMS);
mbParams.hwndOwner = pParent->GetSafeHwnd();
mbParams.hInstance = NULL;
mbParams.lpszText = message;
mbParams.lpszCaption = title;
mbParams.lpszIcon = NULL;
mbParams.dwContextHelpId = NULL;
mbParams.lpfnMsgBoxCallback = NULL;
mbParams.dwLanguageId = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);
flags = MB_SETFOREGROUND;
// If main window on top, always on top.
if (GetPGPdiskWin32Prefs(prefs).IsntError())
{
if (prefs.mainStayOnTop == MF_CHECKED)
flags |= MB_TOPMOST;
}
switch (style)
{
case kPMBS_Ok:
flags |= MB_OK | MB_ICONERROR;
mbParams.dwStyle = flags;
button = MessageBoxIndirect(&mbParams);
break;
case kPMBS_OkCancel:
switch (focus)
{
case kPMBF_OkButton:
defaultButton = MB_DEFBUTTON1;
break;
case kPMBF_CancelButton:
defaultButton = MB_DEFBUTTON2;
break;
default:
pgpAssert(FALSE);
break;
}
flags |= defaultButton | MB_OKCANCEL | MB_ICONERROR;
mbParams.dwStyle = flags;
button = MessageBoxIndirect(&mbParams);
break;
case kPMBS_YesNo:
switch (focus)
{
case kPMBF_YesButton:
defaultButton = MB_DEFBUTTON1;
break;
case kPMBF_NoButton:
defaultButton = MB_DEFBUTTON2;
break;
default:
pgpAssert(FALSE);
break;
}
flags |= defaultButton | MB_YESNO | MB_ICONEXCLAMATION;
mbParams.dwStyle = flags;
button = MessageBoxIndirect(&mbParams);
break;
case kPMBS_YesNoCancel:
switch (focus)
{
case kPMBF_YesButton:
defaultButton = MB_DEFBUTTON1;
break;
case kPMBF_NoButton:
defaultButton = MB_DEFBUTTON2;
break;
case kPMBF_CancelButton:
defaultButton = MB_DEFBUTTON3;
break;
default:
pgpAssert(FALSE);
break;
}
flags |= defaultButton | MB_YESNOCANCEL | MB_ICONEXCLAMATION;
mbParams.dwStyle = flags;
button = MessageBoxIndirect(&mbParams);
break;
default:
pgpAssert(FALSE);
break;
}
// Finally return the choice the user made in the message box.
switch (button)
{
case IDYES:
return kUR_Yes;
case IDNO:
return kUR_No;
case IDOK:
return kUR_OK;
default:
return kUR_Cancel;
}
}
// ReportError reports an error to the user.
UserResponse
ReportError(
PGDMajorError perr,
DualErr derr,
PGPUInt8 drive,
PGDMessageBoxStyle style,
PGDMessageBoxFocus focus)
{
UserResponse button = kUR_Cancel;
// Don't display dialog if we fail silently or if user canceled.
if ((derr.mMinorError == kPGDMinorError_FailSilently) ||
(derr.mMinorError == kPGDMinorError_UserAbort))
{
return kUR_Cancel;
}
MessageBeep(MB_ICONHAND);
try
{
CString errorString;
// Get the error string.
FormatErrorString(perr, derr, drive,
errorString.GetBuffer(kMaxStringSize), kMaxStringSize);
errorString.ReleaseBuffer();
// Show the error message.
button = PGPdiskMessageBox(errorString, GetLastPGPdiskWindow(),
kPGPdiskErrorMsgBoxTitle, style, focus);
}
catch (CMemoryException *ex)
{
// Guaranteed to succeed with these flags.
MessageBox(NULL, kPGPdiskErrorMsgBoxTitle,
GetCommonString(kPGPdiskNoMemForErrorString),
MB_ICONHAND | MB_SYSTEMMODAL);
ex->Delete();
}
return button;
}
// DisplayMessage displays a message to the user.
UserResponse
DisplayMessage(
PGPUInt32 stringId,
PGDMessageBoxStyle style,
PGDMessageBoxFocus focus)
{
UserResponse button = kUR_Cancel;
// Show the message.
button = PGPdiskMessageBox(GetCommonString(stringId),
GetLastPGPdiskWindow(), kPGPdiskNormalMsgBoxTitle, style, focus);
return button;
}
////////////////
// GUI functions
////////////////
// FindMenuItemPosition returns the position of the menu item with the given
// text in the given menu, or -1 otherwise.
PGPInt32
FindMenuItemPosition(CMenu *pMenu, LPCSTR menuString)
{
PGPInt32 position = -1;
try
{
CString itemText;
PGPInt32 i, numItems;
pgpAssertAddrValid(pMenu, CMenu);
pgpAssertStrValid(menuString);
numItems = pMenu->GetMenuItemCount();
if (numItems == -1)
return -1;
for (i = 0; i < numItems; i++)
{
pMenu->GetMenuString(i, itemText, MF_BYPOSITION);
if (itemText.Compare(menuString) == 0)
{
position = i;
break;
}
}
}
catch (CMemoryException *ex)
{
ex->Delete();
}
return position;
}
////////////////////////////////
// Pathname Processing Functions
////////////////////////////////
// ConvertPathToLong converts a short pathname to a long pathname.
DualErr
ConvertPathToLong(CString *path)
{
DualErr derr;
try
{
CString longPath, piece, prefix, temp;
HANDLE findHandle;
PGPUInt32 length;
WIN32_FIND_DATA findData;
pgpAssertAddrValid(path, CString);
length = path->GetLength();
// Get the prefix.
if (path->GetAt(length - 1) == '\\')
{
(* path) = path->Left(length - 1);
length--;
}
derr = GetRoot((* path), &prefix);
// Take out the prefix and save it for later.
if (derr.IsntError())
{
(* path) = path->Right(length - prefix.GetLength());
}
// Convert each component of the pathname to its long form.
while (derr.IsntError() && !path->IsEmpty())
{
temp = prefix + (* path);
findHandle = FindFirstFile(temp, &findData);
if (findHandle == INVALID_HANDLE_VALUE)
{
derr = DualErr(kPGDMinorError_FindFirstFileFailed,
GetLastError());
}
else
{
FindClose(findHandle);
(* path) = path->Left(path->ReverseFind('\\'));
piece = findData.cFileName;
longPath = piece + '\\' + longPath;
}
}
// Prepare the output.
if (derr.IsntError())
{
longPath = longPath.Left(longPath.GetLength() - 1);
longPath = prefix + longPath;
(* path) = longPath;
}
}
catch (CMemoryException *ex)
{
derr = DualErr(kPGDMinorError_OutOfMemory);
ex->Delete();
}
return derr;
}
// GetRoot takes any legal path and returns a string of the form "C:\" or
// "\\UncVolumeName\share\".
DualErr
GetRoot(LPCSTR path, CString *root)
{
DualErr derr;
pgpAssertStrValid(path);
pgpAssertAddrValid(root, CString);
try
{
CString tempString;
tempString = path;
root->Empty();
if (HasPlainLocalRoot(path))
{
(* root) = tempString.Left(3);
}
else if (IsUNCPath(path))
{
PGPInt32 i;
PGPUInt32 numSlashes;
for (i = 0, numSlashes = 0; i < tempString.GetLength(); i++)
{
if (path[i] == '\\')
numSlashes++;
if (numSlashes == 4)
{
(* root) = tempString.Left(i + 1);
break;
}
}
}
}
catch (CMemoryException *ex)
{
derr = DualErr(kPGDMinorError_OutOfMemory);
ex->Delete();
}
return derr;
}
// MakeRoot makes a root out of a drive number.
DualErr
MakeRoot(PGPUInt8 drive, CString *root)
{
DualErr derr;
pgpAssert(IsLegalDriveNumber(drive));
pgpAssertAddrValid(root, CString);
try
{
root->Format("%c:\\", DriveNumToLet(drive));
}
catch (CMemoryException *ex)
{
derr = DualErr(kPGDMinorError_OutOfMemory);
ex->Delete();
}
return derr;
}
// StripRoot removes the root from a pathname.
DualErr
StripRoot(LPCSTR path, CString *nonRoot)
{
DualErr derr;
pgpAssertStrValid(path);
pgpAssertAddrValid(nonRoot, CString);
try
{
CString csInPath, root;
csInPath = path;
derr = GetRoot(path, &root);
if (derr.IsntError())
{
(* nonRoot) = csInPath.Right(csInPath.GetLength() -
root.GetLength());
}
}
catch (CMemoryException *ex)
{
derr = DualErr(kPGDMinorError_OutOfMemory);
ex->Delete();
}
return derr;
}
// GetServer takes a UNC path and returns the server component.
DualErr
GetServer(LPCSTR path, CString *server)
{
DualErr derr;
pgpAssertStrValid(path);
pgpAssertAddrValid(server, CString);
try
{
CString tempString;
server->Empty();
if (IsUNCPath(path))
{
tempString = path + 2;
(* server) = tempString.Left(tempString.Find('\\'));
}
}
catch (CMemoryException *ex)
{
derr = DualErr(kPGDMinorError_OutOfMemory);
ex->Delete();
}
return derr;
}
// GetShare takes a UNC path and returns the share component.
DualErr
GetShare(LPCSTR path, CString *share)
{
DualErr derr;
pgpAssertStrValid(path);
pgpAssertAddrValid(share, CString);
try
{
CString tempString;
tempString = path;
share->Empty();
if (IsUNCPath(path))
{
PGPInt32 i;
PGPUInt32 numSlashes;
for (i = 0, numSlashes = 0; i < tempString.GetLength(); i++)
{
if (path[i] == '\\')
numSlashes++;
if (numSlashes == 3)
{
tempString = path + i + 1;
(* share) = tempString.Left(tempString.Find('\\'));
break;
}
}
}
}
catch (CMemoryException *ex)
{
derr = DualErr(kPGDMinorError_OutOfMemory);
ex->Delete();
}
return derr;
}
// GetCurrentDirectory gets the current working directory.
DualErr
GetCurrentDirectory(CString *outDir)
{
DualErr derr;
pgpAssertAddrValid(outDir, CString);
try
{
LPSTR outDirBuf;
outDirBuf = outDir->GetBuffer(kMaxStringSize);
GetCurrentDirectory(kMaxStringSize, outDirBuf);
outDir->ReleaseBuffer();
}
catch (CMemoryException *ex)
{
derr = DualErr(kPGDMinorError_OutOfMemory);
ex->Delete();
}
return derr;
}
// GetDirectory strips the file name off of a path.
DualErr
GetDirectory(LPCSTR path, CString *dir)
{
DualErr derr;
pgpAssertStrValid(path);
pgpAssertAddrValid(dir, CString);
try
{
CString tempString;
dir->Empty();
tempString = path;
if (tempString.GetAt(tempString.GetLength() - 1) != '\\')
{
PGPInt32 lastSlash;
lastSlash = tempString.ReverseFind('\\');
if (lastSlash != -1)
(* dir) = tempString.Left(lastSlash + 1);
}
else
{
(* dir) = tempString;
}
}
catch (CMemoryException *ex)
{
derr = DualErr(kPGDMinorError_OutOfMemory);
ex->Delete();
}
return derr;
}
// GetDirectorySmart is like GetDirectory except it tacks on a working
// directory path to incomplete directories.
DualErr
GetDirectorySmart(LPCSTR path, CString *dir)
{
DualErr derr;
pgpAssertStrValid(path);
pgpAssertAddrValid(dir, CString);
try
{
CString tempString;
dir->Empty();
tempString = path;
if (tempString.GetAt(tempString.GetLength() - 1) != '\\')
{
PGPUInt32 lastSlash;
lastSlash = tempString.ReverseFind('\\');
if (lastSlash != -1)
{
(* dir) = tempString.Left(lastSlash);
(* dir) += "\\";
}
}
else
{
(* dir) = tempString;
}
if (!HasPlainLocalRoot((* dir)) && !IsUNCPath((* dir)))
{
CString workingDir;
derr = GetCurrentDirectory(&workingDir);
if (derr.IsntError())
{
tempString = (* dir);
if (tempString.IsEmpty() || (tempString.GetAt(0) != '\\'))
(* dir) = workingDir + "\\" + tempString;
else
(* dir) = workingDir + tempString;
}
}
}
catch (CMemoryException *ex)
{
derr = DualErr(kPGDMinorError_OutOfMemory);
ex->Delete();
}
return derr;
}
// GetBareName takes a full pathname to a file and returns just the name of
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -