SteganoPad - 隐写文本编辑器
只有用户才能看到屏幕上的文字

引言
这是我在The Code Project上的第一篇文章,我希望我能带来一些有用的东西,这些东西是我在网上(包括CodeProject)找不到的。
请不要忘记为我的文章评分,这样我才能知道我的贡献有多大用处。 :)
在办公室环境中,人们通常会在你写或读一些(私人)邮件或文档时盯着你的屏幕。很多时候你甚至不知道,别人就通过仅仅看你的屏幕并阅读内容来分享你的信息。SteganoPad确保只有你知道你在写什么和读什么。这基本上给了你和密码框一样的效果。唯一的区别是,只有字母(A-Z,a-z)会被“#”隐藏。这意味着所有其他字符,如空格、逗号、句号、数字以及其他所有内容都会显示在屏幕上,让你对单词的边界和位置有清晰的认识。
免责声明
这部分主要是给批评者看的。我在CodeProject上看到过很多文章,人们宁愿批评他人也不愿支持他们,这主要是因为一些代码的复制。我个人不赞成在发明者的名字被清楚提及的情况下重新发明轮子。
这个应用程序的创意完全属于我。在开发这个应用程序之前,我甚至搜索了CodeProject和互联网,也没有找到任何类似/相关的应用程序。
剪贴板复制代码来自MSDN。我只是使用了它。为了给对话框添加工具栏,我使用了 Randy More 的文章中的代码 - "如何为对话框中的工具栏显示工具提示"。
这个应用程序的代码是我为了实现应用程序行为而编写的方法。就像有很多种“剥猫皮”的方法一样,也有很多种写代码的方法!欢迎提出用不同方式完成同一任务的想法。
使用应用程序
SteganoPad应用程序就像记事本一样,只是它不允许别人看到屏幕上的内容。每当按下任何字母键(a-z, A-Z)时,屏幕上就会显示一个“#”。鼠标光标下的真实单词会显示在状态栏上。
双击一个加密的单词(“####”)会将该单词转换为真实单词。
刷新按钮会根据“隐藏”复选框的内容重新加载文本框的内容。
你可以从SteganoPad中剪切、复制或粘贴内容。剪贴板上的数据会以“#####”的形式粘贴,而编辑框中的数据将以真实文本的形式移到剪贴板上。
还提供了文件打开和保存按钮,用于从文本文件打开/保存应用程序的数据。
关于代码
这个应用程序主要建立在CSteganoEdit
类之上,该类派生自CEdit
类。
原始文本存储在成员变量m_OriginalText
中,该变量会根据用户的行为定期更新。
class CSteganoEdit : public CEdit
{
public:
CSteganoEdit();
virtual ~CSteganoEdit();
inline void SetMask(BOOL mask){ m_mask = mask; }
LRESULT OnPaste (WPARAM wParam, LPARAM lParam);
LRESULT OnCut (WPARAM wParam, LPARAM lParam);
LRESULT OnCopy (WPARAM wParam, LPARAM lParam);
LRESULT OnClear (WPARAM wParam, LPARAM lParam);
BOOL CopyToClipBoard (CString strCpy);
void SetOriginalText(CString StrData);
void ShowSelectedText();
void RefreshCtrl();
void EmptyEditCtrl();
void OnMouseMove(UINT nFlags, CPoint point);
void SetStatusWindowPtr (CWnd *pStatusWnd);
CString GetOriginalText();
CString CopyFromClipBoard ();
CString EncryptText (CString EncStr);
CString GetWordFromPoint (CPoint pt);
virtual BOOL PreTranslateMessage(MSG* pMsg);
private:
CString m_OriginalText;
BOOL m_mask;
CWnd* m_pStatusWindow;
protected:
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
DECLARE_MESSAGE_MAP()
};
应用程序的加密功能是通过重写PreTranslateMessage
来实现的,它会即时将按下的键更改为“#”。
BOOL CSteganoEdit::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_CHAR && ::GetKeyState (VK_CONTROL) >= 0 &&
::GetKeyState (VK_MENU) >= 0 )
{
if (isprint ((int)pMsg->wParam))
{
int CurStart, CurEnd;
GetSel( CurStart, CurEnd );
m_OriginalText.Delete (CurStart, CurEnd - CurStart);
m_OriginalText.Insert (CurStart, (char)pMsg->wParam);
if (m_mask == TRUE && (
(pMsg->wParam >= 65 && pMsg->wParam <= 90) ||
(pMsg->wParam >= 97 && pMsg->wParam <= 122)))
{
pMsg->wParam = '#';
}
}
}
return CEdit::PreTranslateMessage(pMsg);
}
加密文本的编辑是通过捕获WM_KEYDOWN
消息来实现的,该消息处理Delete、Backspace和Enter键。
void CSteganoEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar == VK_DELETE)
{
int CurStart, CurEnd;
GetSel( CurStart, CurEnd );
if (CurStart == CurEnd)
{
CurEnd = CurEnd + 1;
}
m_OriginalText.Delete (CurStart, CurEnd - CurStart);
}
else if (nChar == VK_BACK)
{
int CurStart, CurEnd;
GetSel( CurStart, CurEnd );
if (CurStart == CurEnd)
{
CurStart = CurStart - 1;
}
m_OriginalText.Delete (CurStart, CurEnd - CurStart);
}else if (nChar == VK_RETURN)
{
int CurStart, CurEnd;
GetSel( CurStart, CurEnd );
m_OriginalText.Delete (CurStart, CurEnd - CurStart);
m_OriginalText.Insert (CurStart, "\r\n");
}
CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
}
有改进空间
这个应用程序还有很多改进的空间。
- 目前,这个应用程序具有从其他用户隐藏文本的基本功能,但仍然缺乏一些“奢侈”功能,如撤销、查找、自动换行等。
- 此外,由于用户看不到屏幕上写的内容,因此应该有一个自动拼写检查器,可以自动纠正用户输入的错误。
- 可以选择将可见字符从“#”更改为其他字符(“*”或任何单词)。
我将尝试在未来添加上述功能。(不保证!)
关注点
通过使用编辑框的密码样式,可以实现一个类似但功能非常有限的功能。在密码模式下,文本框不提供以下功能:
- 多行支持
- 剪切、复制和粘贴
- 单词临时可见性
最主要的区别是,在密码样式的编辑框中,每个字符都显示为一个点。这使得一行中的单词难以识别,因为两个单词之间没有可见的单词边界(空格)。
历史
- 2008 年 12 月 24 日:初始发布