everything works well with the English layout, but for example it does not output anything with the Russian one, and if you use count, not wcout, then just the code of the digit (prail)
what I need to do to make the code work. I need the code to be translated to unicode
MSG msg;
....
update(cursorPos, hWnd, &msg);
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
void update(POINT pos, HWND hWnd, MSG* msg)
{
if (msg->message == WM_KEYDOWN) {
GetSymbolFromVK((msg->wParam));
}
}
WORD GetSymbolFromVK(WPARAM wParam)
{
BYTE btKeyState[256] = {};
HKL hklLayout = GetKeyboardLayout(0);
WCHAR buff[32];
WORD Symbol = NULL;
GetKeyboardState(btKeyState);
/*if ((ToAsciiEx(wParam, MapVirtualKey(wParam, 0), btKeyState, &Symbol, 0, hklLayout) == 1) &&
(GetKeyState(VK_CONTROL) >= 0) && (GetKeyState(VK_MENU) >= 0))
return Symbol;*/
if ((ToUnicodeEx(wParam, MapVirtualKeyEx(wParam, 0, hklLayout), btKeyState, buff, 32, 0, hklLayout) &&
(GetKeyState(VK_CONTROL) >= 0) && (GetKeyState(VK_MENU) >= 0)) == 1)
{
/*int nSize = MultiByteToWideChar(CP_UTF8, 0, (LPCCH)buff, -1, NULL, 0);
MultiByteToWideChar(CP_UTF8, 0, (LPCCH)buff, -1, *buff[0], nSize);*/
std::wcout<<*buff <<std::endl;
}
return -1;
}
I cannot reproduce the behavior using the code except I use OutputDebugString to print. ToUnicodeEx works well to Translates the specified virtual-key code and keyboard state to the corresponding Unicode character or characters.
Related
I would like to set some events with SetWinEventHook and wait.
After five events I want to exit from the message loop. The problem is that the code stucks in getMessage without entering in the loop.
The Callback function is correctly called whenever an event occurred.
HWINEVENTHOOK hEvent = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, NULL,
WinEventProcCallback, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
HWINEVENTHOOK hWinEventHook0 = SetWinEventHook(
EVENT_OBJECT_CREATE, EVENT_OBJECT_CREATE,
NULL, WinEventProcCallback, 0, 0,
WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
HWINEVENTHOOK hWinEventHook1 = SetWinEventHook(
EVENT_OBJECT_DESTROY, EVENT_OBJECT_DESTROY,
NULL, WinEventProcCallback, 0, 0,
WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
while (ret = GetMessage(&msg, NULL, 0, 0) > 0) {
if (ret == -1)
{
return;
}
if (cont >= 5) break;
TranslateMessage(&msg);
DispatchMessage(&msg);
cont++;
std::cout << "Reached : " << cont << std::endl;
}
How I can solve this?
Thank you in advance
if (ret = GetMessage(&msg, NULL, 0, 0) > 0)
is equal to
if (ret = (GetMessage(&msg, NULL, 0, 0) > 0))
while (ret = GetMessage(&msg, NULL, 0, 0) > 0) {
if (ret == -1)
{
return;
}
the if statement won't be true in this case, so you won't get to the return.
ret can't be greater than 0 and -1 at the same time
This question already has answers here:
How to launch Windows' RegEdit with certain path?
(15 answers)
Closed 9 years ago.
I'm looking for way to open registry editor and show some specific key or value. For example, if I pass "HKLM\\SOFTWARE\\Skype\\Installer" I want to get such a result:
All suggestions except system() calls are welcome.
Just call system. To use Raymond Chen's words: It rather involved being on the other side of this airtight hatchway. Any relevant attack requires compromising the machine to the point that your system call is utterly irrelevant. In fact, any attacker that can change RegEdit can change your program as well, so he could just add that system call. (Which he won't, since it is pointless anyway)
Here is, what I needed.
String GetFullHKEY (HKEY hKeyRoot)
{
if (HKEY_LOCAL_MACHINE == hKeyRoot) return _T("HKEY_LOCAL_MACHINE\\");
if (HKEY_CLASSES_ROOT == hKeyRoot) return _T("HKEY_CLASSES_ROOT\\");
if (HKEY_CURRENT_CONFIG == hKeyRoot) return _T("HKEY_CURRENT_CONFIG\\");
if (HKEY_CURRENT_USER == hKeyRoot) return _T("HKEY_CURRENT_USER\\");
if (HKEY_USERS == hKeyRoot) return _T("HKEY_USERS\\");
}
bool RegistryGoTo (HKEY hKeyRoot, const String &lpctPath, String lpctValue)
{
if (lpctPath.empty() || 0 == hKeyRoot)
return false;
if( lpctValue.empty() && lpctValue.empty() == 0)
{
lpctValue.clear();
}
SHELLEXECUTEINFO shi = { 0 };
DEVMODE dm = { 0 };
HWND hWndRegedit = ::FindWindow (_T("RegEdit_RegEdit"), NULL);
if (NULL == hWndRegedit)
{
shi.cbSize = sizeof(SHELLEXECUTEINFO);
shi.fMask = SEE_MASK_NOCLOSEPROCESS;
shi.lpVerb = _T("open");
shi.lpFile = _T("regedit.exe");
shi.nShow = SW_SHOWNORMAL;
ShellExecuteEx (&shi);
if( GetLastError() != 0 )
{
Sleep(200);
ShellExecuteEx (&shi);
}
WaitForInputIdle (shi.hProcess, INFINITE);
hWndRegedit = ::FindWindow (_T("RegEdit_RegEdit"), NULL);
}
if (NULL == hWndRegedit) return FALSE;
SetForegroundWindow (hWndRegedit);
ShowWindow (hWndRegedit, SW_SHOWNORMAL);
HWND hWndTreeView = FindWindowEx (hWndRegedit, NULL, _T ("SysTreeView32"), NULL);
SetForegroundWindow (hWndTreeView);
SetFocus (hWndTreeView);
for (int i = 0; i < 30; i++)
{
SendMessage (hWndTreeView, WM_KEYDOWN, VK_LEFT, 0);
}
dm.dmSize = sizeof (DEVMODE);
EnumDisplaySettings (NULL, ENUM_CURRENT_SETTINGS, &dm);
if (8 < dm.dmBitsPerPel) Sleep (100);
// the path must start with a backslash
String stRegPath = String (_T("\\")) + GetFullHKEY(hKeyRoot) + lpctPath;
// open path
for (int iIndex = 0; iIndex < (int) stRegPath.length (); iIndex++)
{
if (_T('\\') == stRegPath [iIndex])
{
SendMessage (hWndTreeView, WM_KEYDOWN, VK_RIGHT, 0);
if (8 < dm.dmBitsPerPel)
Sleep (100);
}
else SendMessage (hWndTreeView, WM_CHAR, toupper (stRegPath [iIndex]), 0);
}
SetForegroundWindow (hWndRegedit);
SetFocus (hWndRegedit);
if (lpctValue.length())
{
HWND hWndListView = FindWindowEx (hWndRegedit, NULL, _T("SysListView32"), NULL);
SetForegroundWindow (hWndListView);
SetFocus (hWndListView);
Sleep (100);
SendMessage (hWndListView, WM_KEYDOWN, VK_HOME, 0);
String stValue = lpctValue;
for (String::iterator it = stValue.begin (); it != stValue.end (); ++it)
{
SendMessage (hWndListView, WM_CHAR, toupper (*it), 0);
}
}
return true;
}
The following code works fine:
int iLength = SendMessage(hWndEdit, EM_LINELENGTH, 0, 0);
if(iLength > 0) {
TCHAR* szBuffer = new TCHAR[iLength+1];
iLength = SendMessage(hWndEdit, EM_GETLINE, 0, (LPARAM)szBuffer);
szBuffer[iLength] = TEXT('\0');
MessageBox(hWnd, szBuffer, TEXT("Edit content"), MB_OK);
delete[] szBuffer;
}
Now I want to do the same thing using std::vector<TCHAR>:
int iLength = SendMessage(hWndEdit, EM_LINELENGTH, 0, 0);
if(iLength > 0) {
std::vector<TCHAR> data(iLength+1, TEXT('\0'));
iLength = SendMessage(hWndEdit, EM_GETLINE, 0, (LPARAM)&data[0]);
MessageBox(hWnd, &data[0], TEXT("Edit content"), MB_OK);
}
It compiles, but at iLength = SendMessage(hWndEdit, EM_GETLINE, 0, (LPARAM)&data[0]); the variable iLength will always be set to 0, and, accordingly, nothing will have been written into my vector.
What is the problem here? Thanks in advance.
From the documentation:
A pointer to the buffer that receives a copy of the line. Before
sending the message, set the first word of this buffer to the size, in
TCHARs, of the buffer.
I have this function which gives the full file name(path) from the file handle. The only problem is CreateFileMapping fails for directory handles. Is there a workaround for it?
I get the handle using NtCreateFile()
ULONG status = NtCreatefile(&f, GENERIC_ALL, &oa, iosb, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_OPEN_BY_FILE_ID , NULL, 0);
printf("status: %X, handle: %x\n", status, f);
AND
BOOL CHouseKeeper::GetFileNameFromHandle(HANDLE hFile)
{
BOOL bSuccess = FALSE;
TCHAR pszFilename[MAX_PATH+1];
HANDLE hFileMap;
// Get the file size.
DWORD dwFileSizeHi = 0;
DWORD dwFileSizeLo = GetFileSize(hFile, &dwFileSizeHi);
if( dwFileSizeLo == 0 && dwFileSizeHi == 0 )
{
_tprintf(TEXT("Cannot map a file with a length of zero.\n"));
return FALSE;
}
// Create a file mapping object.
//It fails here if a directory handle is passed, it returns 0
hFileMap = CreateFileMapping(hFile,
NULL,
PAGE_READONLY,
0,
1,
NULL);
if (hFileMap)
{
// Create a file mapping to get the file name.
void* pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1);
if (pMem)
{
if (GetMappedFileName (GetCurrentProcess(),
pMem,
pszFilename,
MAX_PATH))
{
// Translate path with device name to drive letters.
TCHAR szTemp[BUFSIZE];
szTemp[0] = '\0';
if (GetLogicalDriveStrings(BUFSIZE-1, szTemp))
{
TCHAR szName[MAX_PATH];
TCHAR szDrive[3] = TEXT(" :");
BOOL bFound = FALSE;
TCHAR* p = szTemp;
do
{
// Copy the drive letter to the template string
*szDrive = *p;
// Look up each device name
if (QueryDosDevice(szDrive, szName, MAX_PATH))
{
size_t uNameLen = _tcslen(szName);
if (uNameLen < MAX_PATH)
{
bFound = _tcsnicmp(pszFilename, szName, uNameLen) == 0
&& *(pszFilename + uNameLen) == _T('\\');
if (bFound)
{
// Reconstruct pszFilename using szTempFile
// Replace device path with DOS path
TCHAR szTempFile[MAX_PATH];
StringCchPrintf(szTempFile,
MAX_PATH,
TEXT("%s%s"),
szDrive,
pszFilename+uNameLen);
StringCchCopyN(pszFilename, MAX_PATH+1, szTempFile, _tcslen(szTempFile));
}
}
}
// Go to the next NULL character.
while (*p++);
} while (!bFound && *p); // end of string
}
}
bSuccess = TRUE;
UnmapViewOfFile(pMem);
}
CloseHandle(hFileMap);
}else {
wcout<<GetLastError()<<endl;
}
_tprintf(TEXT("File name is %s\n"), pszFilename);
return(bSuccess);
}
You can use NtQueryInformationFile with FileNameInformation to retrieve the name associated with a file handle.
I'm writing a text editor and am having some issues with saving files as utf-8.
I have a function that reads text from a rich edit control and writes it to a file
using a flag passed to the function which depends on a user setting. It can be utf-16, ascii, or utf-8. Both utf-16 and ascii file writing segments work fine and produce valid files.
The problem lies in that in the following block of code the call to GetWindowTextLength always returns 0. So, the result is that nothing ever gets retrieved from the window or written to the file.
HANDLE hFile;
if ((hFile = CreateFile (pstrFileName, GENERIC_WRITE, 0,
NULL, CREATE_ALWAYS, 0, NULL)) == INVALID_HANDLE_VALUE) {
return FALSE;
}
int iLength = 0;
DWORD dwBytesWritten = 0;
switch (encoding) {
/*other text encoding cases*/
case ID_SETTINGS_UTF_8: {
try {
iLength = GetWindowTextLength(hwndEdit); //returns 0
unique_ptr<wchar_t> wide_buf(new wchar_t[iLength + 1]);
GetWindowTextW(hwndEdit, wide_buf.get(), iLength + 1);
int bytes_needed = WideCharToMultiByte(CP_UTF8, WC_COMPOSITECHECK |
WC_DEFAULTCHAR | WC_NO_BEST_FIT_CHARS, wide_buf.get(), -1,
NULL, 0, NULL, NULL);
unique_ptr<char> utf8_buf(new char[bytes_needed]);
WideCharToMultiByte(CP_UTF8, WC_COMPOSITECHECK |
WC_DEFAULTCHAR | WC_NO_BEST_FIT_CHARS, wide_buf.get(), -1,
utf8_buf.get(), bytes_needed, NULL, NULL);
WriteFile(hFile, utf8_buf.get(), bytes_needed,
&dwBytesWritten, NULL);
if (bytes_needed != dwBytesWritten) {
CloseHandle (hFile);
return FALSE;
}
CloseHandle (hFile) ;
return TRUE;
} catch (bad_alloc& ba) {
UNREFERENCED_PARAMETER(ba);
CloseHandle (hFile);
return FALSE;
}
}
break;
You corrupt the heap. new[] must be matched by delete[], not delete.
It's simpler to just use std::vector:
std::vector<wchar_t> wide_buf(iLength + 1);
//...
std::vectorchar> utf8_buf(bytes_needed);
Is Your application compiled as UNICODE or ANSI ? (you use GetWindowTextLength and GetWindowTextW declarations)
Can you show code for ANSI and for UTF-16 (where you get proper result).