C++ win32 如何使密码字段可选并启用复制和粘贴?
C++ win32 How do I make a password field selectable and enable copying and pasting?
所以我目前需要一个密码字段,用于显示已知的密码。但由于我不想直接向用户显示密码,因此我决定使用密码字段而不是普通字段。由于程序本身正在工作,我只会显示我创建编辑字段的代码,因为这是我根据该程序的要求对其进行更改的唯一地方。
这是我的编辑框的代码片段
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和Ctrl+V进行复制粘贴,而此设置的默认密码字段似乎并非如此。
就像我说的。这不是用于登录某些内容的程序。这是一个程序,您可以在其中选择一个平台或类似平台,此窗口会弹出您存储的用户名和密码,这些用户名和密码已经填充到输入框中,准备复制粘贴到相应的程序中。问题是由于我对密码框使用ES_PASSWORD
,它会自动使编辑框无法选择和复制,这与该程序的意图不符。所以我需要找到一种方法来启用编辑框的这些功能,同时保留星号的东西。
我怎么会相处?非常感谢一些代码来说明解决方案。
所以我设法解决了这个问题。但是该解决方案更像是一个补丁工作而不是直接解决方案,所以我不会说这个答案会对其他人有所帮助,但它对我打算使用它的地方有用。
所以我所做的是将其保留为密码字段,但我做了一个静态变量
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;
然后我在底部声明并实现了一个名为WndProcPassword
forward 的WNDPROC
,如下所示
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;
}
然而,这不会消除声音,但这与我打算如何使用这个程序没什么大不了的,但我决定留下这个答案,因为我找不到任何其他关于如何在仍然让字符显示星号的同时复制编辑字段的信息。
编辑:我现在已经找到了一个比上述更好的解决方案,但我决定保留两者。
WndProcPassword
WM_KEYDOWN
事件已更改为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 事件中添加自己的复制即可。 这也消除了与输入框交互时的所有限制和错误声音。
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 编译时未启用intel oneApi CUDA支持
- 使用strcpy将char数组的元素复制到另一个数组
- 是否可以初始化不可复制类型的成员变量(或基类)
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到
- 复制列表初始化的隐式转换的等级是多少
- 当从函数参数中的临时值调用复制构造函数时
- 有可能在Armadillo中复制MATLAB circshift方法吗
- 复制几乎为空的数组的最快方法
- 以下示例中如何避免代码复制?C++/库达
- OpenGL在启用深度测试时不会丢弃我的碎片
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- C++ win32 如何使密码字段可选并启用复制和粘贴?
- 是否可以/希望创建不可复制的共享指针模拟(以启用weak_ptr跟踪/借用类型语义)?
- QStyledItemDelegate 和 QStandardItem 阻止更改文本,仅启用选择和复制
- 如何为显式重载构造函数启用复制初始化
- 启用基于类模板形参的构造函数时,是否总是需要复制该类模板形参?
- 类设计-在C++类中显式启用/禁用复制的指导