SetWindowsHookEx - difference between VK_LSHIFT and "Search" keyboard button - c

I use SetWindowsHookEx to catch keyboard events
SetWindowsHookEx(WH_KEYBOARD_LL, HookCallback, NULL, 0)
Here is HookCallback
LRESULT __stdcall HookCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode >= 0)
{
// the action is valid: HC_ACTION.
if (wParam == WM_KEYDOWN)
{
kbdStruct = *((KBDLLHOOKSTRUCT*)lParam);
printf("%ld\n", kbdStruct.vkCode);
}
}
}
When press "left shift" output is
160
when press "search" button (button with loupe icon on notebooks) output is
160
91
132
How to check if "left shift" or "search" button is pressed inside HookCallback ?

160 is VK_LSHIFT, 91 is VK_LWIN, and 132 is VK_F21. See Virtual-Key Codes. The only standardized Search key is VK_BROWSER_SEARCH, so clearly your keyboard manufacturer is using a non-standard key for its Search key.
You need to remember the keys you see from one event to the next as needed, eg:
bool LeftShiftIsDown = false;
bool LeftWinIsDown = false;
bool F21IsDown = false;
bool SearchIsDown = false;
LRESULT __stdcall HookCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HC_ACTION)
{
KBDLLHOOKSTRUCT *kbdStruct = (KBDLLHOOKSTRUCT*) lParam;
if (wParam == WM_KEYDOWN)
{
printf("%ld is down\n", kbdStruct->vkCode);
switch (kbdStruct->vkCode)
{
case VK_LSHIFT:
LeftShiftIsDown = true;
break;
case VK_LWIN:
LeftWinIsDown = true;
break;
case VK_F21:
F21IsDown = true;
break;
}
if (LeftShiftIsDown && LeftWinIsDown && F21IsDown)
{
if (!SearchIsDown)
{
SearchIsDown = true;
printf("Search is down\n");
}
}
}
else if (wParam == WM_KEYUP)
{
printf("%ld is up\n", kbdStruct->vkCode);
switch (kbdStruct->vkCode)
{
case VK_LSHIFT:
LeftShiftIsDown = false;
break;
case VK_LWIN:
LeftWinIsDown = false;
break;
case VK_F21:
F21IsDown = false;
break;
}
if (!(LeftShiftIsDown && LeftWinIsDown && F21IsDown))
{
if (SearchIsDown)
{
SearchIsDown = false;
printf("Search is up\n");
}
}
}
}
return CallNextHookEx(0, nCode, wParam, lParam);
}

Related

How to block printing functionality(CTRL + P) on windows text editors?

I want to block printing functionality(CTRL + P) on windows platform for specific applications. I am doing it using keyboard hook. I am able to detect CTRL + P but I am not able to stop it. I am returning from hook procedure in case of CTRL + P but application still receives this message and process printing.
LRESULT __declspec(dllexport)__stdcall CALLBACK KeyboardProc(
int nCode,
WPARAM wParam,
LPARAM lParam)
{
FILE* f1;
static WPARAM wPrevParam;
if (((DWORD)lParam & 0x40000000) && (HC_ACTION == nCode))
{
if ((wParam == VK_SPACE) || (wParam == VK_RETURN) || (wParam == VK_CONTROL) || (wParam >= 0x2f) && (wParam <= 0x100))
{
char ch;
f1 = fopen("d:\\report.txt", "a+");
if (wParam == VK_CONTROL)
{
if (wPrevParam == 0x50)// 0x50 = P
{
const char* text = "CTRL-P detected.";
fwrite(text, strlen(text), 1, f1);
fclose(f1);
wParam = 0;
lParam = 0;
return 1;
}
const char *text = "CTRL";
fwrite(text, strlen(text), 1, f1);
fprintf(f1, "%02X\n", (unsigned char)wParam);
}
else
{
wPrevParam = wParam;
}
fclose(f1);
}
}
LRESULT RetVal = CallNextHookEx(hkb, nCode, wParam, lParam);
return RetVal;
}
I want to block printing functionality(CTRL + P) on windows platform
for specific applications. I am doing it using keyboard hook. I am
able to detect CTRL + P but I am not able to stop it.
This blocks [Ctrl] + "P" in a WH_KEYBOARD_LL hook... but won't prevent printing by [File] [Print] or other way of course... =>
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
DWORD dwKey = 0;
if (HC_ACTION == nCode)
{
KBDLLHOOKSTRUCT *pkbdll = (KBDLLHOOKSTRUCT*)lParam;
dwKey = pkbdll->vkCode;
BOOL bCtlDown = GetKeyState(VK_CONTROL) < 0;
if (bCtlDown && dwKey == 'P')
{
Beep(6000, 10);
return 1;
}
}
return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}
Windows application to block CTRL + P using WH_KEYBORAD_LL hook works. So working code snippet will be as follows:
#include<fstream>
#include<windows.h>
using namespace std;
ofstream out("logs.txt", ios::out);
LRESULT CALLBACK keyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
static bool controlPressed = false;
PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)(lParam);
if (wParam == WM_KEYDOWN)
{
if (p->vkCode == VK_LCONTROL || p->vkCode == VK_RCONTROL)
{
controlPressed = true;
}
else if (char(tolower(p->vkCode)) == 'p' && true == controlPressed)
{
out << "<CONTROL + P Detected>";
return 1;
}
else
{
controlPressed = false;
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
HHOOK keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL,
keyboardHookProc,
hInstance,
0
);
MessageBox(NULL, TEXT("Press OK to stop blocking of printing."), TEXT("Information"), MB_OK);
out.close();
return 0;
}

Memory increases every time I resize the window

I have created a simple Win32 Application and try to fill the Client Area with a Color. When the line "Clear RenderTarget" is included I see that the memory increases a few KB every time I resize the window.
My WindowProc:
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_SIZE:
{
if (pRenderTarget != NULL)
{
RECT rc;
GetClientRect(globalWindowHandle, &rc);
D2D1_SIZE_U size = D2D1::SizeU(rc.right, rc.bottom);
pRenderTarget->Resize(size);
InvalidateRect(globalWindowHandle, NULL, FALSE);
}
return 0;
}
break;
case WM_CREATE:
{
HRESULT dx = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pFactory);
if (FAILED(dx))
{
MessageBox(globalWindowHandle, "Error creating D2D1Factory", "Error", MB_ICONERROR);
return -1;
}
return 0;
}
break;
case WM_KEYDOWN:
{
int ret = HandleKeyboardInput(uMsg, wParam, lParam);
if (ret == 0)
{
return 0;
}
}
break;
case WM_PAINT:
{
HRESULT hr = CreateGraphicsResources();
if (SUCCEEDED(hr))
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
pRenderTarget->BeginDraw();
// Clear RenderTarget
pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::SkyBlue));
hr = pRenderTarget->EndDraw();
if (FAILED(hr) || hr == D2DERR_RECREATE_TARGET)
{
pRenderTarget->Release();
pSolidBrush->Release();
pRenderTarget = NULL;
pSolidBrush = NULL;
}
EndPaint(hwnd, &ps);
return 0;
}
}
break;
case WM_CLOSE:
{
int box = MessageBox(hwnd, "Would you like to close the editor ?", "Question", MB_OKCANCEL);
if (box == IDOK)
{
DestroyWindow(hwnd);
}
return 0;
}
break;
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
break;
default:
{
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
break;
}
return 0;
}
CreateGraphicsResources
HRESULT CreateGraphicsResources()
{
HRESULT hr = S_OK;
if (pRenderTarget == NULL)
{
RECT rc;
GetClientRect(globalWindowHandle, &rc);
D2D1_SIZE_U size = D2D1::SizeU(rc.right, rc.bottom);
hr = pFactory->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(globalWindowHandle, size),
&pRenderTarget);
if (SUCCEEDED(hr))
{
const D2D1_COLOR_F color = D2D1::ColorF(1.0f, 1.0f, 1.0f, 0);
hr = pRenderTarget->CreateSolidColorBrush(color, &pSolidBrush);
if (SUCCEEDED(hr))
{
}
}
}
return hr;
}
Globals:
BOOL ctrlPressed = FALSE;
HWND globalWindowHandle;
ID2D1Factory *pFactory;
ID2D1SolidColorBrush *pSolidBrush;
ID2D1HwndRenderTarget *pRenderTarget;
Do I miss something to free up memory or what could be the reason? If I resize the window e.g. 5 sec the memory goes from 4KB up to 22KB.
My OS is Windows 10 x64
The issue seems to be solved. In fact the memory did not go up much more so it seems the OS assigns the other memory.

How to respond a mouse message about right-button in listbox item?

If i use the win32 api,how to respond WM_RBUTTONUP?
case WM_RBUTTONUP:
{
break;
}
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId) {
case IDE_FRIEND:
{
switch (wmEvent) {
case WM_RBUTTONUP:
{
POINT pt;
GetCursorPos(&pt);
TrackPopupMenu(g_hMenu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, hWnd, nullptr);
break;
}
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
break;
}
When I click the right mouse button,it will not enter 'case WM_RBUTTONUP'
'IDE_FRIEND' is associated with listbox.
Right-click on listbox will generate context message for parent window. You should be able to catch it like this:
case WM_CONTEXTMENU:
{
if (hListBox == (HWND)wParam)
{
int x = LOWORD(lParam);
int y = HIWORD(lParam);
TrackPopupMenu(g_hMenu, TPM_RIGHTBUTTON, x, y, 0, hWnd, nullptr);
}
break;
}
case WM_RBUTTONUP:
{
//main window's right-click message
break;
}
case WM_COMMAND:
{
//...
}
Edit:
To do the same thing with subclass
#include "CommCtrl.h" //may need to add this
#pragma comment(lib, "comctl32.lib")
LRESULT CALLBACK ListBoxProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
UINT_PTR, DWORD_PTR)
{
switch (msg){
case WM_RBUTTONUP:
{
//add listbox menu here
break;
}
case WM_NCDESTROY://safely remove subclass
{
RemoveWindowSubclass(hwnd, ListBoxProc, 0);
return DefSubclassProc(hwnd, msg, wp, lp);
}
}
return DefSubclassProc(hwnd, msg, wp, lp);
}
LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
//...
case WM_CREATE:
ListBox = CreateWindow(L"listbox", ... )
SetWindowSubclass(ListBox, ListBoxProc, 0, 0);
//...
}

why is this function failing?

I am trying to understand windows hooks by writing a few keyboard hooks.
I have a function:
bool WriteToFile(WPARAM keyCode, char * fileName)
{
ofstream fout("filename");
if(fout.is_open())
{
if(keyCode>=0x030 && keyCode<0x039)
fout<< (keyCode - 0x030);
fout.close();
return true;
}
else fout.close();
return false;
}
...that i try to call from here but it almost always fails. Why?
LRESULT CALLBACK KbHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode > 0)
{
WriteToFile(wParam,"log.txt"); //this function always fails . Why
}
else return CallNextHookEx(hCurrentHook, nCode, wParam, lParam);
}
I think it's because you're trying to open a file called “filename”, rather than using whatever filename was provided. I assume you're writing a keylogger. It should read:
bool WriteToFile(WPARAM keyCode, char * fileName)
{
// cause output to go to the end of the file by using ios_base::app
ofstream fout(fileName, ios_base::app);
if(fout.is_open())
{
if(keyCode>=0x030 && keyCode<0x039)
fout<< (keyCode - 0x030);
fout.close();
return true;
}
else fout.close();
return false;
}

Set static text color Win32

I am making a dll that controls a dialogue box. I like to get a certain area to have red text. This code does compile, but the effect is not seen. Here is the area where the dialogProc is done:
LRESULT CALLBACK DialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_INITDIALOG:
CheckDlgButton(hDlg, IDC_CHECK, FALSE);
EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_CHECK:
if (IsDlgButtonChecked(hDlg, IDC_CHECK))
{
EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
EnableWindow(GetDlgItem(hDlg, IDCANCEL), FALSE);
}
else
{
EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
EnableWindow(GetDlgItem(hDlg, IDCANCEL), TRUE);
}
break;
case IDOK:
{
EndDialog(hDlg, TRUE);
return FALSE;
}
case IDCANCEL:
{
EndDialog(hDlg, FALSE);
return FALSE;
}
case WM_CTLCOLORSTATIC:
// Set the colour of the text for our URL
if ((HWND)lParam == GetDlgItem(hDlg,IDC_WARNING))
{
// we're about to draw the static
// set the text colour in (HDC)lParam
SetBkMode((HDC)wParam,TRANSPARENT);
SetTextColor((HDC)wParam, RGB(255,0,0));
return (BOOL)CreateSolidBrush (GetSysColor(COLOR_MENU));
}
return TRUE;
}
}
return FALSE;
}
WM_CTLCOLORSTATIC is a separate message from WM_COMMAND. Your desired handling of the message appears to be correct except that the check for the message is inside your check for WM_COMMAND specific items. Try reorganizing your outer switch statement. Perhaps something like the following:
LRESULT CALLBACK DialogProc(HWND hDlg, UINT message,
WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_INITDIALOG:
// ...
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_CHECK:
// ...
break;
case IDOK:
// ...
break;
case IDCANCEL:
// ...
break;
}
break;
case WM_CTLCOLORSTATIC:
// Set the colour of the text for our URL
if ((HWND)lParam == GetDlgItem(hDlg, IDC_WARNING))
{
// we're about to draw the static
// set the text colour in (HDC)lParam
SetBkMode((HDC)wParam,TRANSPARENT);
SetTextColor((HDC)wParam, RGB(255,0,0));
// NOTE: per documentation as pointed out by selbie, GetSolidBrush would leak a GDI handle.
return (BOOL)GetSysColorBrush(COLOR_MENU);
}
break;
}
return FALSE;
}
Also note that it would be kinda weird to filter WM_COMMAND's wParam argument when wParam is supposed to provide the HDC for WM_CTLCOLORSTATIC.
WM_CTLCOLORSTATIC Notification at MSDN

Resources