Так мне удалось так решить проблему.Но решение - это скорее патч-работа, чем прямое решение, поэтому я бы не сказал, что этот ответ поможет другим, но он помог мне в том, для чего я собираюсь его использовать.
Так что я сделалчтобы сохранить это поле пароля, но я сделал статическую переменную
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.Это также устраняет все ограничения и звуки ошибок при взаимодействии с полем ввода.