因此,我目前需要一个密码字段,用于显示已知的密码。但是由于我不想直接向用户显示密码,所以我决定使用密码字段代替普通字段。由于程序本身正在运行,因此我只会在创建编辑字段的地方显示代码,因为那是我根据该程序的要求对其进行更改的唯一位置。
这是我的编辑框的代码段
std::wstring password = account.GetPassW();
HWND hWndEditPassword = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("Edit"),
password.c_str(), WS_CHILD | WS_VISIBLE | ES_PASSWORD, 85, 30, 245,
20, hWnd, NULL, NULL, NULL
);
account是类型为struct UserAccount
的变量,而GetPassW()
是一个函数,由于字符串最初是作为第一个字符串加载和存储的,因此它可以从std::string
转换为std::wstring
。
如果该代码是普通的登录表单,则此代码可以正常工作,但它不是登录表单,这是登录恢复表单,出于安全原因,其中密码字段显示星号(*)。并且必须支持使用 Ctrl + A 选择此密码字段,并使用 Ctrl + C 和< kbd> Ctrl + V ,使用此设置的默认密码字段似乎不是这种情况。
再次如我所说。这不是用于登录某些程序的程序。这是一个您选择平台或类似程序的程序,该窗口会弹出,其中已存储您的用户名和密码,该用户名和密码已填充到输入框中,可以复制粘贴到相应的程序中。问题是因为我在密码框中使用了ES_PASSWORD
,所以它自动使编辑框无法选择和复制,这对本程序的目的是行不通的。因此,我需要找到一种在保留星号的同时启用编辑框的功能的方法。
我将如何做到这一点? 非常感谢一些代码来说明解决方案。
答案 0 :(得分:0)
所以我设法解决了这个问题。但是,该解决方案比直接解决方案更多的是修补工作,因此我不会说这个答案会帮助其他人,但对于我打算将其用于什么用途,它对我来说很有用。
所以我要做的是将其保留为密码字段,但是我做了一个静态变量
static WNDPROC wndProcPasswordOld;
static UserAccount currentAccount;
static HWND hWndEditPassword;
然后在初始化密码框的地方,现在有了这个
hWndEditPassword = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("Edit"), password.c_str(),
WS_CHILD | WS_VISIBLE | ES_PASSWORD | ES_READONLY, 85, 30, 245,
20, hWnd, NULL, NULL, NULL);
wndProcPasswordOld = (WNDPROC)SetWindowLongPtr(hWndEditPassword, GWLP_WNDPROC,
(LONG_PTR)WndProcPassword);
// This is further down
currentAccount = account;
然后我有一个WNDPROC
名为WndProcPassword
的正向声明,并在底部按如下方式实现
LRESULT CALLBACK WndProcPassword(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_KEYDOWN:
if ((wParam == 'C' || wParam == 'c') && GetKeyState(VK_CONTROL) & 0x8000)
{
std::string data = currentAccount.password;
const char *output = data.c_str();
const size_t len = strlen(output) + 1;
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);
memcpy(GlobalLock(hMem), output, len);
GlobalUnlock(hMem);
OpenClipboard(0);
EmptyClipboard();
SetClipboardData(CF_TEXT, hMem);
CloseClipboard();
break;
}
return CallWindowProc(wndProcPasswordOld, hWnd, message, wParam, lParam);
break;
default:
return CallWindowProc(wndProcPasswordOld, hWnd, message, wParam, lParam);
}
return 0;
}
但是这并不能消除声音,但是与我打算如何使用该程序无关紧要,但是我决定离开这个答案,因为我找不到有关如何复制编辑字段的任何其他信息。同时仍然让字符显示星号。
编辑: 现在,我找到了比上述更好的解决方案,但我决定同时保留两者。
WM_KEYDOWN
中的WndProcPassword
事件已更改为WM_KEYUP
。
WM_KEYUP
中if语句中的Extral我也在检查事件是否是
if (((wParam == 'C' || wParam == 'c') && GetKeyState(VK_CONTROL) & 0x8000) || (wParam == VK_CONTROL && (GetKeyState('C') & 0x8000 || GetKeyState('c') & 0x8000)))
{
// copy to clipboard
}
然后我继续进行操作,将框的创建更改为
hWndEditPassword = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("Edit"), L"",
WS_CHILD | WS_VISIBLE | ES_READONLY, 85, 30, 245,
20, hWnd, NULL, NULL, NULL);
SetEditText(password);
此SetEditText
如下所示
void SetEditText(std::wstring text)
{
int buffersize = text.length() + 1;
WCHAR *wchars = new WCHAR[buffersize];
memset(wchars, 0, sizeof(WCHAR) * buffersize);
for (int i = 0; i < text.length(); i++)
wchars[i] = L'*';
SetWindowText(hWndEditPassword, wchars);
delete[] wchars;
}
此更改使控件充当普通的编辑框,唯一的变化是,在设置文本时,您将输入手动替换为星号,并且由于复制是在按下键的情况下完成的,因此您只需将自己的复制添加到按键事件。 与输入框进行交互时,这也消除了所有限制和错误提示。