This question already has answers here:
What is HWND in VC++
(5 answers)
Closed 3 years ago.
I was testing some Win32 apps with c++, and in this code:
LRESULT CALLBACK WindowProc(
_In_ HWND hwnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
Looking at this MSDN Documentation, I couldn't really understand what the HWND is?
It says: A handle to the window.. What does that mean?
The answer is there behind the "Conceptual" section link on the MSDN page you refer to.
About Windows - Window Handle:
Window Handle
After creating a window, the creation function returns a window handle
that uniquely identifies the window. A window handle has the HWND data
type; an application must use this type when declaring a variable that
holds a window handle. An application uses this handle in other
functions to direct their actions to the window.
About Window Procedures
Structure of a Window Procedure
A window procedure is a function that has four parameters and returns
a signed value. The parameters consist of a window handle, a UINT
message identifier, and two message parameters declared with the
WPARAM and LPARAM data types. For more information, see WindowProc.
Related
I'm trying to disable windows keys for a window that uses RawInput to process keyboard events. The usual way to do this is to install a low-level keyboard hook and filter out windows key events there. In order for it to work with RawInput, I have to initialize the keyboard device with RIDEV_NOHOTKEYS. However, when I do that, if I then Alt+Tab from the app, for some reason Windows 10 displays the classic Alt+Tab thing:
I'm not filtering out Alt or Tab events in the low-level keyboard hook, and this also happens if I don't install a low-level keyboard hook at all, just initializing the keyboard device with RIDEV_NOHOTKEYS does it. I tried returning 0 for WM_INPUT messages, and I tried calling the default window proc, nothing seems to be helping... Has anyone had this issue before?
Add a low level hook (WH_KEYBOARD_LL) can prevent Alt key message to pass to other windows. Refer to "LowLevelKeyboardProc callback function".
WH_KEYBOARD_LL hook can be set only with global scope.
// Register hook
hinstDLL = LoadLibrary(TEXT("sysmsg.dll"));
hkprcSysMsg = (SYSMESSAGEPROC)GetProcAddress(hinstDLL, "SysMessageProc");
HHOOK hook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)hkprcSysMsg, hinstDLL, 0);
Hook callback function in DLL:
__declspec(dllexport)
LRESULT __cdecl SysMessageProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode < 0) // do not process message
return CallNextHookEx(NULL, nCode,
wParam, lParam);
if (wParam == WM_SYSKEYDOWN)
{
if(((tagKBDLLHOOKSTRUCT*)lParam)->vkCode == VK_LMENU || ((tagKBDLLHOOKSTRUCT*)lParam)->vkCode == VK_RMENU)
return 1;
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
More reference: "Using Hooks" "Keyboard Input" "WM_SYSKEYDOWN message" "KBDLLHOOKSTRUCT structure" "Virtual-Key Codes"
Note
Hooks tend to slow down the system because they increase the amount of
processing the system must perform for each message. You should
install a hook only when necessary, and remove it as soon as possible.
You should use global hooks only for debugging purposes; otherwise,
you should avoid them. Global hooks hurt system performance and cause
conflicts with other applications that implement the same type of
global hook.
I'm a bit confused by the MSDN page for WM_PRINTCLIENT and related functionality in a few ways:
What value should I return from my window procedure? The documentation is missing a "Return value" section entirely. (It is also missing in the Visual Studio 2012 offline documentation disc's version of the page.) Raymond Chen's original scratch program returns zero; is this the preferred option?
The summary and Remarks section for WM_PRINTCLIENT indicates that I should only draw the client area, but the LPARAM lists all the possible WM_PRINT flags — so what should I do, ignore it and unconditionally draw just the client area or draw everything requested? (My intention with this question is not to second-guess the documentation; I'm just looking to implement this message correctly.)
I want to, as a convenience/kindness, provide the WM_PAINT with DC in wParam functionality mentioned in the WM_PAINT documentation as an option as well. How should I interpret LPARAM in this case? Or is there a reason I shouldn't provide this alternative route? (Corollary: if LPARAM is to be ignored, should I draw the entire client area unconditionally?)
Thanks.
Update Rephrasing the third part:
The documentation for WM_PAINT includes the paragraph
For some common controls, the default WM_PAINT message processing checks the wParam parameter. If wParam is non-NULL, the control assumes that the value is an HDC and paints using that device context.
I would like to provide this behavior in my control in addition to WM_PRINTCLIENT for completeness's sake. Is there a reason I should NOT do so? And if doing so wouldn't hurt, how should I interpret the lParam, and should I draw the entire client rect?
What value should I return from my window procedure?
You return 0 to indicate that the message was handled. Do not call DefWindowProc().
but the LPARAM lists all the possible WM_PRINT flags
That was a bit sloppy, a copy/paste fumble from the WM_PRINT article. The only flags you should test are PRF_ERASEBKGND, but only if you draw method requires having the background painted, and PRF_CLIENT, which will always be set in common usage of the message.
How should I interpret LPARAM in this case?
Hard to decode that question, WM_PAINT doesn't use the lparam argument. But yes, you want a common function that implements the painting so you can call it both from your WM_PAINT and your WM_PRINTCLIENT message handlers. Boilerplate code in your window procedure ought to look like:
case WM_PAINT: {
HDC hdc = BeginPaint(hWnd, &ps);
Draw(hdc);
EndPaint(hWnd, &ps);
break;
}
case WM_PRINTCLIENT: {
HDC hdc = (HDC)wParam;
DWORD flags = (DWORD)lParam;
if (flags & PRF_ERASEBKGND) SendMessage(hWnd, WM_ERASEBKGND, (WPARAM)hdc, NULL);
if (flags & PRF_CLIENT) Draw(hdc);
break;
}
Where void Draw(HDC hdc) is your common paint function.
I need some help. I wrote my questions at the end and will first explain what exactly my code is supposed to do:
I am making a program that will communicate with other programs. What I need my software to do is be able to click on a button on another program, and I believe the appropriate code to do this would be:
SendMessage(hWnd, Msg, wParam, lParam);
with
Msg = B_Click
wParam = 0;
lParam = 0;
however I am not sure how to get the hWnd which is the handle of a specific button on a specific window of another program that is running at the same time. I have read somewhere that I could possibly do the following:
HWND buttonHandle = FindWindowEx(hwndParent, hwndChildAfter, lpszClass, lpszWindow);
where:
HWND hwndParent = A handle to the parent window whose child windows are to be searched
HWND hwndChildAfter = if its null child windows are of the parent window are looked through
LPCTSTR lpszClass = (NOT SURE WHAT THIS IS)
LPCTSTR lpszWindow = (NOT SURE WHAT THIS IS)
I have a few issues with the FindWindowEX() function however.
Question 1: The window I am looking at has various buttons, so how would the function know which one of the 3 i am looking at?
Question 2: What are the lpszClass and lpszWindow variables and how might I get them?
Question 3: Is this even the right approach? If it's not, please point me to the right direction!
You don't need the handle of the button, you need the handle of its parent window. The button sends BN_CLICKED to its parent window. Look up the button's ID with spy++. Then use EnumChildWindows of the parent to look at all the child windows. For each child use GetWindowLong with GWL_ID to check its ID.
I am creating a barcode generator application in win32. I got the library to generate the needed barcodes and if I hardcode the UPC it displays the barcode fine. However I want to be able to enter a string in the text field and have it generate the barcode and display it on the window.
I've looked into UpdateWindow, but the HWND variable that is in
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
is out of scope in the function that I want to call it in, and I've also tried making a global HWND hWnd, but it throws a compiler error.
If this is not enough information, please let me know so I can update it with the necessary information.
I should have read the error more carefully.
The error was the redefinition of a variable. Just deleted the later definition and the problem went away.
Sorry!
CoInitialize(NULL) creates an STA by creating a hidden window. How to get an HWND handle for this window?
Function EnumThreadWindows does not work, in an example I tried:
...
CoInitialize(NULL);
EnumThreadWindows(GetCurrentThreadId(), EnumThreadWndProc, 0);
...
BOOL CALLBACK EnumThreadWndProc(HWND hwnd, LPARAM lParam)
{
m_hwnd = hwnd;
return FALSE;
}
Nothing ever enters the EnumThreadWndProc.
Any ideas?
This hidden window is Message-Only Window, It is not visible, has no z-order, cannot be enumerated, and does not receive broadcast messages. The window simply dispatches messages.
To find message-only windows, specify HWND_MESSAGE in the hwndParent parameter of the FindWindowEx function. In addition, FindWindowEx searches message-only windows as well as top-level windows if both the hwndParent and hwndChildAfter parameters are NULL.
Source:
MSDN
Btw, I would be VERY careful here - you really shouldn't be sending window messages to windows you don't own. Your code is highly likely to break in a future version of Windows.