📄 csecureedit.cpp
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: CSecureEdit.cpp,v 1.6 2002/08/06 20:10:46 dallen Exp $
____________________________________________________________________________*/
#include "pgpClassesConfig.h"
#include <stdlib.h>
#include "CArray.h"
#include "CString.h"
#include "UMath.h"
#include "UTime.h"
#include "CSecureEdit.h"
_USING_PGP
// Class CSecureEdit member functions
CSecureEdit::CSecureEdit() : mSpacesPerChar(CString::kBigStringSize)
{
Init();
}
CSecureEdit::CSecureEdit(HWND hWnd) :
mSpacesPerChar(CString::kBigStringSize), CEdit(hWnd)
{
Init();
}
void
CSecureEdit::ClearContents()
{
mContents.Clear();
SetWindowText("");
mCurCharPos = -1;
// Notify parent of the edit box change.
SendParentEvent(kContentsChangedEvent);
}
void
CSecureEdit::SetContents(const CSecureString& newContents)
{
ClearContents();
mContents = newContents;
if (HidingTyping())
FillEditBoxWithSpaces();
else
FillEditBoxWithContents();
}
PGPBoolean
CSecureEdit::SetHideTypingPref(PGPBoolean hideValue)
{
PGPBoolean oldHideValue = HidingTyping();
mHideTyping = hideValue;
if (!oldHideValue && hideValue)
FillEditBoxWithSpaces();
else if (oldHideValue && !hideValue)
FillEditBoxWithContents();
return oldHideValue;
}
PGPUInt32
CSecureEdit::SetMaxSizeContents(PGPUInt32 maxSize)
{
PGPUInt32 oldSize = MaxSize();
ClearContents();
mMaxSize = maxSize;
return oldSize;
}
void
CSecureEdit::Init()
{
mHideTyping = TRUE;
mMaxSize = 0;
mCurCharPos = -1;
mCurNumSpaces = 0;
// Pick from 1-3 random spaces to be used for each character.
srand(static_cast<PGPUInt32>(UTime::GetSystemTicks()));
for (PGPUInt32 i = 0; i < mSpacesPerChar.Size(); i++)
{
PGPUInt32 num = rand(); // rand r00lz!
if (num < RAND_MAX/3)
mSpacesPerChar[i] = 1;
else if (num < RAND_MAX*2/3)
mSpacesPerChar[i] = 2;
else
mSpacesPerChar[i] = 3;
}
}
void
CSecureEdit::FillEditBoxWithContents()
{
pgpAssert(!HidingTyping());
CSecureArray<char> text;
mContents.Extract(text);
SetWindowText(text.Get());
SetSel(mCurCharPos + 1, mCurCharPos + 1);
SendParentEvent(kContentsChangedEvent);
}
void
CSecureEdit::FillEditBoxWithSpaces()
{
pgpAssert(HidingTyping());
CString spaces;
mCurNumSpaces = 0;
// Construct string of spaces.
for (PGPUInt32 i = 0; i < mContents.Length(); i++)
{
mCurNumSpaces += mSpacesPerChar[i];
}
pgpFillMemory(spaces.GetBuffer(mCurNumSpaces + 1), mCurNumSpaces, ' ');
spaces.SetAt(mCurNumSpaces, '\0');
spaces.ReleaseBuffer();
SetWindowText(spaces);
SetSel(mCurNumSpaces + 1, mCurNumSpaces + 1);
SendParentEvent(kContentsChangedEvent);
}
LRESULT
CALLBACK
CSecureEdit::SecurityHookProc(INT iCode, WPARAM wParam, LPARAM lParam)
{
return 0;
}
void
CSecureEdit::InstallSecurityHooks()
{
PGPUInt32 dwPhraseThreadID = GetCurrentThreadId();
// These are just to prevent sniffers from seeing these messages.
mHhookKeyboard = SetWindowsHookEx(WH_KEYBOARD, SecurityHookProc, NULL,
dwPhraseThreadID);
mHhookCBT = SetWindowsHookEx(WH_CBT, SecurityHookProc, NULL,
dwPhraseThreadID);
mHhookGetMessage = SetWindowsHookEx(WH_GETMESSAGE, SecurityHookProc,
NULL, dwPhraseThreadID);
mHhookMsgFilter = SetWindowsHookEx(WH_MSGFILTER, SecurityHookProc, NULL,
dwPhraseThreadID);
}
void
CSecureEdit::UninstallSecurityHooks()
{
UnhookWindowsHookEx(mHhookMsgFilter);
UnhookWindowsHookEx(mHhookGetMessage);
UnhookWindowsHookEx(mHhookCBT);
UnhookWindowsHookEx(mHhookKeyboard);
}
PGPUInt32
CSecureEdit::SendParentEvent(PGPUInt32 event) const
{
return CWindow(GetParent()).SendMessage(WM_SECUREEDIT_EVENT,
reinterpret_cast<WPARAM>(Handle()), event);
}
void
CSecureEdit::OnChar(char c, PGPUInt32 keyData)
{
// Instead of placing the character in the edit box, we place a space
// there instead and update only the secure mContents variable with the
// new character.
PGPBoolean isPrintable = ((unsigned char)c >=32);
if (isPrintable)
{
if ((MaxSize() > 0) && (mContents.Length() == MaxSize()))
{
MessageBeep(MB_ICONHAND);
}
else
{
// Insert the new character in the contents.
mContents.InsertAfter(mCurCharPos++, c);
if (HidingTyping())
FillEditBoxWithSpaces();
else
FillEditBoxWithContents();
}
}
}
BOOL
CSecureEdit::OnCommand(PGPUInt16 notifyCode, PGPUInt16 itemId, HWND ctrl)
{
if (ctrl == Handle())
{
switch (notifyCode)
{
case EN_SETFOCUS:
SetSel(-1, -1);
InstallSecurityHooks();
return TRUE;
case EN_KILLFOCUS:
UninstallSecurityHooks();
return TRUE;
default:
return FALSE;
}
}
else
{
return CEdit::OnCommand(notifyCode, itemId, ctrl);
}
}
void
CSecureEdit::OnKeyDown(PGPUInt32 vKey, PGPUInt32 keyData)
{
switch (vKey)
{
case VK_DELETE:
case VK_HOME:
case VK_END:
case VK_UP:
case VK_DOWN:
case VK_LEFT:
case VK_RIGHT:
case VK_NEXT:
case VK_PRIOR:
// Disallow caret movement.
break;
case VK_BACK:
// Delete the current character.
if (mContents.Length() > 0)
mContents.RemoveAt(mCurCharPos--);
if (HidingTyping())
FillEditBoxWithSpaces();
else
FillEditBoxWithContents();
break;
case VK_RETURN:
SendParentEvent(kSawReturnKeyEvent);
break;
default:
CEdit::OnKeyDown(vKey, keyData);
break;
}
}
void
CSecureEdit::OnKeyUp(PGPUInt32 vKey, PGPUInt32 keyData)
{
// Tell parent about caps lock presses.
switch (vKey)
{
case VK_CAPITAL:
SendParentEvent(kSawCapsLockKeyEvent);
break;
default:
CEdit::OnKeyUp(vKey, keyData);
break;
}
}
void
CSecureEdit::OnLButtonDown(PGPUInt32 keyFlags, CPoint coords)
{
SetFocus();
}
void
CSecureEdit::OnLButtonDblClk(PGPUInt32 keyFlags, CPoint coords)
{
SetFocus();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -