How does lparam and wparam work in this specific code example? - windows

I'm reading at some coding examples from Microsoft. And get confused by this combined key part.
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_SYSKEYDOWN:
if (wParam == VK_RETURN && (lParam & 0x60000000) == 0x20000000)
{
//Do something
}
}
}
Here is what I don't understand, this code is about switching the application between fullscreen and windowed when pressing Alt+Enter. I get that WM_SYSKEYDOWN is holding Alt, and VK_RETURN is pressing Enter. So when they put together it means pressing Enter while holding Alt, but how do these two parameters work? Why Enter is in wParam and what does the lParam part on the right mean? What does the value of lParam represents? Please help.
I have another thing I'd like to ask.
Why it uses 0x60000000? It is a 31 bit start with 2 "1"s followed by 29 "0"s. From the document provided by tkausl, the 31th bit of WM_SYSKEYDOWN is always 0, so with a "&" operator, there should be no way the output will have a "1" at that bit, so why not just use 0x20000000 which should give the exactly same result?

Related

How can I get the mouse cursor type in windows (default, hand, wait, resize etc)?

I would like to receive a notification when the mouse cursor change from arrow to hour glass etc.
Until now I managed to get notified for mouse position change events, but I can not figure out how to get the cursor type. It looks like the PCURSORINFO struct does not contain any information about the cursor type.
This is the code I have until now:
static LRESULT CALLBACK WinEventCallback(_In_ int nCode,
_In_ WPARAM wParam,
_In_ LPARAM lParam)
{
PCURSORINFO curInfo;
curInfo->cbSize = sizeof(curInfo);
GetCursorInfo(curInfo);
}
void MouseCursorHook::setMouseCursorHook()
{
HHOOK evntHook = SetWindowsHookEx(WH_MOUSE_LL,
WinEventCallback,
GetModuleHandle(0),
0
);
}
First off, your call to GetCursorInfo() is wrong. You are passing it an uninitialized pointer. It should be like this instead:
CURSORINFO curInfo = {};
curInfo.cbSize = sizeof(curInfo);
GetCursorInfo(&curInfo);
Second, CURSORINFO has a hCursor field. You can compare that against the return value of LoadCursor()/LoadImage() to see if a standard cursor is being used or not. You will have to compare each standard cursor individually, though.

WINAPI keyboards detect other application hotkeys

Goal : I want to know that the user did or did't press on some hotkeys that i want to know it, like i want to know he/she press Ctrl + N on chrome
i try to detect the application hotkeys, like maybe chrome Ctrl + N is open new tab.
How winapi can detect this?
i have seen some article that said WM_KEYUP + WM_KEYDOWN, but the wParam one times can get one WM_KEYUP or WM_KEYDOWN, how implement it ?
int main(int argc, char *argv[])
{
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyBoardHookProc, hInstance, 0);
hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, hInstance, 0);
while (GetMessage(&message,NULL,0,0)) {
TranslateMessage( &message );
DispatchMessage( &message );
}
UnhookWindowsHookEx(hHook);
UnhookWindowsHookEx(hMouseHook);}
KeyBoardHookProc(int nCode, WPARAM wParam, LPARAM lParam){
KBDLLHOOKSTRUCT cKey = *((KBDLLHOOKSTRUCT*)lParam);
.................
if(wParam == WM_KEYUP)
{
kp.HandlekeyboardInfo(lpszName, buffer);
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
Thanks for helping!!
There are a few different ways you can do this. The easiest is probably to register a hotkey within your application and let windows notify you when the key combination is pressed.
RegisterHotKey
Another method would be to register a keyboard hook. All keypresses will be passed to your application, but you'll have to determine what keys were pressed. If you go this route, make sure to call CallNextHookEx().
SetWindowsHookEx

WM_CHAR send unicode character

I'm hooking windows WM_CHAR message. When I'm replacing (in hook) given char code to something simple like 'a', every character I type is turning into a. And that's ok. But when I'm trying to send unicode character, like ф ('ф'.charCodeAt(0) gives 1092, so I'm replacing 'a' to 1092 in my code), all letters are turned into D. Also, when I type Alt+1092 in every text editor I'm getting D. Why? And can I send unicode char using WM_CHAR? Documentation says "The WM_CHAR message uses Unicode Transformation Format (UTF)-16.".
LRESULT CALLBACK Proc(int code, WPARAM wParam, LPARAM lParam)
{
if(code >= HC_ACTION)
{
MSG* msg=(MSG *)lParam;
if(msg->message==WM_CHAR)
{
int charCode = msg->wParam;
if(IsCharLower(charCode))
{
charCode = 1092;
msg->wParam=(WPARAM)charCode;
}
}
}
return CallNextHookEx(hHook, code, wParam, lParam);
};

KeyPress with multiple modifiers not working in QWidget

I have added an override for my main widget's keyPressEvent:
void MainWindow::keyPressEvent(QKeyEvent* e)
{
if (e->key() == Qt::Key_F11)
{
if (e->modifiers() & Qt::AltModifier && e->modifiers() & Qt::ControlModifier)
{
// do stuff
}
}
}
The problem is that it does not work. If I try the AltModifier or ControlModifier alone it works (while changing the second condition of course), but not for both of them. The key() won't equal to Qt::Key_F11 while I do press F11. I'm using windows.
Edit: checked with logging and the result is that Ctrl+Alt+F11 and Ctrl+Alt+F12 do not send a key event (while other Ctrl+Alt+Fxx keys do).
Oook, so I managed to solve it though I'm not exactly pleased with the solution. At least there is no mystery and it works :).
The reason why I didn't receive the hotkeys Ctrl+Alt+F11 and Ctrl+Alt+F12
They were registered as global hotkeys. I managed to find this out using the ActiveHotkeys program of the fellow stackoverflow member moodforaday (thanks a lot for it!). Apparently there is no documented way to find out which program registered a particular hotkey (and it didn't do anything on my system). See moodforaday's thread about the issue.
The solution
One of the answers in the aforementioned thread led me to another question. Efotinis' answer was absolutely perfect for me. I did not have experience with setting up low-level keyboard hooks, but it was not nearly as difficult as it sounds. For future's sake, here is how I did it in my Qt application:
In my mainwindow.h:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
// ... code
private:
void tryLogin();
friend LRESULT CALLBACK LowLevelKeyboardProc(int code, WPARAM wparam, LPARAM lparam);
};
LRESULT CALLBACK LowLevelKeyboardProc(int code, WPARAM wparam, LPARAM lparam);
In my mainwindow.cpp:
// setting up the hook in the constructor
SetWindowsHookEx(WH_KEYBOARD_LL,
LowLevelKeyboardProc,
NULL,
0);
The hook code (mostly from efotinis' answer):
LRESULT CALLBACK LowLevelKeyboardProc(int code, WPARAM wparam, LPARAM lparam)
{
KBDLLHOOKSTRUCT* kllhs = reinterpret_cast<KBDLLHOOKSTRUCT*>(lparam);
if (code == HC_ACTION)
{
if (wparam == WM_KEYDOWN && kllhs->vkCode == VK_F12 &&
(GetAsyncKeyState(VK_MENU) < 0 && GetAsyncKeyState(VK_CONTROL) < 0))
{
MainWindow* w = dynamic_cast<MainWindow*>(qApp->activeWindow());
if (NULL != w)
{
w->tryLogin(); // this should not be blocking!
return 1;
}
}
}
return CallNextHookEx(0, code, wparam, lparam);
}
As you can see, we get the pointer to the application window from the global QApplication object. We use dynamic_cast so in the active window happens to not be a MainWindow instance we would get a NULL pointer.
If you are wondering why the GetAsyncKeyState calls are checked for < 0, it's because this function returns with MSB set if the key is down. And when the MSB is set, the SHORT number is negative (on x86/x64 and compatible platforms). If windows ever gets ported to a platform where signed integers are represented differently, this code might break. The absolutely proper way would be to create a 16-bit mask and use that to check the MSB, but I'm lazy to do that. :)
One thing to note is that when you call a function from your hook, the Qt event loop has just begun processing. That means until you don't return from your function, it will block the UI (freezing it for a few seconds). If you wanted to show a dialog like I did, instead of exec(), call raise, activateWindow and show, while setting the window modality of the dialog to modal (in its constructor maybe).
You can unregister the hook with UnHookWindowsHookEx if you want to (which happens when the module containing the hook is unloaded). To do this, save the return value of the SetWindowsHookEx call.

TreeView Controls - HTREEVIEW

I'm new to win32 API programming and I try to understand source code of treeview from codeproject.
But I really don't understand this :
BOOL TreeView::DoNotify(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// blah blah
HTREEVIEW Selected = (HTREEITEM)SendDlgItemMessage(hWnd,ID_TREE,TVM_GETNEXTITEM,TVGN_CARET,(LPARAM)Selected);
// halb halb
}
It doesn't work ( Selected is used without initializing) until I declare Selected as global variable.
Thanks for reading this and I need your help .
TVM_GETNEXTITEM with TVGN_CARET does not use the LParam (So you can just pass NULL). You can verify this by looking at the macro for the same action:
#define TreeView_GetSelection(hwnd) TreeView_GetNextItem(hwnd, NULL, TVGN_CARET)

Resources