所以我目前需要一个密码字段,用于显示已知密码。但由于我不想直接向用户显示密码,因此我决定使用密码字段而不是普通字段。由于程序本身正在工作,我将只显示我创建编辑字段的代码,因为这是我将根据此程序的要求对其进行更改的唯一地方。
这是我的编辑框的代码片段
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
);
帐户类型的变量struct UserAccount
和GetPassW()
是从转换的功能std::string
,以std::wstring
由于字符串被最初装载和那些第一批存储。
如果它是正常的登录表单,此代码可以正常工作,但这不是登录表单,这是一个登录恢复表单,其中出于安全原因,密码字段显示星号(*)。此密码字段必须支持使用Ctrl+ 选择A并使用Ctrl+ C和Ctrl+ 复制粘贴,而V使用此设置的默认密码字段似乎不是这种情况。
再次像我说的那样。这不是用于登录某个程序的程序。这是一个您选择平台或类似程序的程序,此窗口会弹出您已存储的用户名和密码,已填入输入框,随时可以复制粘贴到相应的程序中。问题是因为我正在使用ES_PASSWORD
密码框,它会自动使编辑框无法选择和复制,这对于此程序的意图是不起作用的。所以我需要找到一种方法来启用编辑框的这些功能,同时保留星号的东西。
我怎么会这样相处? 非常感谢一些代码来说明解决方案。
发布于 2018-10-15 09:22:32
所以我设法解决了这个问题。但是解决方案更多的是补丁工作,而不是直接解决方案,所以我不会说这个答案会对其他人有所帮助,但它对我来说是有用的,因为我打算用它。
所以我做的是保持密码字段,但我做了一个静态变量
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
forward,如下所示
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
。另外在if语句里面WM_KEYUP
我也在检查事件是否是
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;
}
此更改使控件充当普通编辑框,只有更改是在设置文本时,您手动用星号替换输入,并且由于在按键上完成复制,您只需在keyup事件中添加自己的复制。在与输入框交互时,这也会消除所有限制和错误声音。
https://stackoverflow.com/questions/-100008901
复制相似问题