He asked
Steven Braun 26reputation points
I'm developing a desktop application using the Win32 API. I stored the HWND returned by CreateWindowEx() in a global variable called h_Wnd for future calls to MessageBox() in various functions defined in the program. In the function that my program calls in response to the WM_TIMER received from WndProc, a call to MessageBox(h_Wnd...) fails and GetLastError returns code 1400 "Invalid window handling". To work around this problem, I gave the Timer function an HWND parameter and passed the hWnd parameter from WndProc() and used it in the MessageBox() call.
How can the identifier stored at the time of creation of the main application window become invalid even if the main application window is on the screen?
Windows 10
Windows 10
An operating system from Microsoft that runs on PCs and tablets.
5920 questions
API do Windows - Win32
API do Windows - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Formerly known as Win32 API.
1,890 questions
Log in to follow
0{count} votes
Castorix31 65.366reputation points
2023-01-09T14:56:28.313+00:00 I'm developing a desktop application using Win32 API
the label isAPI do Windows
And you must post a minimum reproducible pattern...
Log in to comment
accepted answer
answered
2023-01-11T21:43:23.42+00:00 RLWA32 28.641reputation points
If only one window is created from the class your WndProc specifies as a window procedure, Windows will not send messages to your WndProc for other windows.
As I suggested earlier, if your h_Wnd global variable becomes corrupted, you can identify the point at which the corruption occurs by setting a data breakpoint that will break if that variable changes unexpectedly. Again you can find instructions on how to set a data breakpointuse breakpoints. Take the time to read the instructions. A data breakpoint is NOT the same as setting a breakpoint on a line of code.
0No comments
Log in to comment
3 additional answers
Sort by:most useful
most useful Last older
answered
2023-01-09T16:44:57.253+00:00 unlimited technology 8.961reputation points
Hey,
Thank you for your order.
Please follow the steps below to resolve your issue.
You can get the MainWindowHandle property only for processes running on the local computer. The MainWindowHandle property is a value that uniquely identifies the window associated with the process.
Go to this link for your reference and other troubleshooting procedureshttps://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.mainwindowhandle?view=net-7.0
Don't hesitate to send us a message if you need further assistance.
If the answer is helpful, click "Accept as answer" and vote.
RLWA32 28.641reputation points
2023-01-09T16:57:09.453+00:00 The questioner wrote about creating a Windows desktop application using the Windows API and referred to CreateWindowEx, WndProc, and window handles.
Your answer is not relevant to the question asked as it applies to .Net and not a Windows desktop application built using the Windows API.
Steven Braun 26reputation points
2023-01-09T19:49:56.34+00:00 The program only works on one computer. An annoying aspect of this issue is that it is not always reproducible. MessageBox() sometimes accepts h_Wnd as valid; Sometimes no. Is there a reason why the MainWindowHandle property would be different from the HWND returned by CrfeateWindowEx() which creates the application window?
RLWA32 28.641reputation points
2023-01-09T19:57:16.887+00:00 Is there a reason why the MainWindowHandle property would be different from the HWND returned by CrfeateWindowEx() which creates the application window?
Yes! read thisThe MainWindowHandle property is just a heuristic-based guess
It would be best if you share your code with us so we can see what it actually does. Without seeing the code, it's just a guessing game.
Log in to comment
answered
2023-01-09T21:23:27.89+00:00 Steven Braun 26reputation points
Here is a skeleton of the program with the code where the error occurred is isolated. So far, the call to MessageBox() on line 149 has not failed. Is there anything about this program that could cause the call to MessageBox() to fail unpredictably due to an "invalid window handle"?
277509-test-appcpp.txt
RLWA32 28.641reputation points
2023-01-09T21:57:05.847+00:00 I see no reason why the h_Wnd global variable should become invalid while the message loop is running. However, after the message loop ends, the call to KillTimer fails because the window has been destroyed, so the global h_Wnd is invalid.
Steven Braun 26reputation points
2023-01-09T22:08:29.837+00:00 I don't think there's a reason for h_Wnd to become invalid while the application window still exists, so why MessageBox() failed is a mystery. I assume the call to KillTimer() must be in response to WM_DESTROY in WndProc().
RLWA32 28.641reputation points
2023-01-09T22:11:52.047+00:00 Therefore, it is better to create an example that reproduces the problem.
They wrote: "Here is a skeleton of the program, in which the code where the error occurred is isolated." Maybe the problem is in the code that was left out?
Steven Braun 26reputation points
2023-01-09T23:00:26.497+00:00 But here's the puzzle: the call to MessageBox(h_Wnd...) in the original program sometimes fails and sometimes succeeds. However, if you pass the hWnd provided by WndProc(), it will always succeed. In that sense, the problem is solved, but I'm curious why passing the HWND to MessageBox() in a global variable sometimes fails.
RLWA32 28.641reputation points
2023-01-09T23:05:05.623+00:00 Just repeating your observations doesn't add additional information.
It seems likely that the difference between the skeleton code and the "original program", the code we haven't seen, is responsible for the problem.
Steven Braun 26reputation points
2023-01-09T23:25:38.687+00:00 I emphasize the information that the value of the global variable is sometimes different from the value of hWnd passed by WndProc(). However, my program does not change the value of the global variable after initializing it by calling CreateWindowEx(). Why should the values be different? Under what circumstances would WndProc() pass an identifier that is not equal to the identifier value returned by CreateWindowEx()???
RLWA32 28.641reputation points
2023-01-09T23:29:06.307+00:00 Your code contains one or more errors.
Steven Braun 26reputation points
2023-01-09T23:30:25.673+00:00 Or maybe Windows has an error. I don't want to post my entire program here as it contains a lot of proprietary code. Suffice it to say that it DOES NOT change the value of h_Wnd after it is initialized.
RLWA32 28.641reputation points
2023-01-09T23:44:03.36+00:00 Have you tried setting a data breakpoint?
use breakpoints
Steven Braun 26reputation points
2023-01-09T23:49:02.683+00:00 Oh yes, right before and right after calling MessageBox(). The hWnd value passed by WndProc() is not always the same as the h_Wnd value returned by CreateWindowEx(). The value passed by WndProc() that is passed to MessageBox() causes it to succeed, while h_Wnd that is passed to MessageBox() causes it to fail.
RLWA32 28.641reputation points
2023-01-09T23:55:34.397+00:00 Did you create more than one window and they all share the same WndProc?
When you say the global variable got corrupted, a data breakpoint referenced in the previously linked documentation can be helpful.
Steven Braun 26reputation points
2023-01-10T00:17:33.463+00:00 My program opens a console window to output information during development. The code for this comes before calling InitInstance, which creates the main window. The code gives the console window a separate global identifier, h_StdOut. Is it possible that Windows is trying to send messages to the console window via WndProc()?
AllocConsole();
freopen("CONOUT$", "w", stdout);
std::cout << "Console initialized to stdout." << std::endl;
h_StdOut = GetConsoleWindow();
SetWindowTextA(h_StdOut, "StandardOut");
SetWindowPos(h_StdOut, HWND_TOPMOST, 0,625*i_HRes, NULL, NULL, NULL, SWP_NOSIZE | SWP_SHOWWINDOW);However, the call to SetTimer() passes h_Wnd and not h_StdOut as the window handle, so I wouldn't expect Windows to send WM_TIMER to h_StdOut via WndProc().
RLWA32 28.641reputation points
2023-01-10T00:44:48.373+00:00 Without meaningful information about your actual code, I think this topic has reached an impasse.
Steven Braun 26reputation points
2023-01-10T01:01:29.467+00:00 Fine. Rest in peace, thread. As said, one solution is to pass MessageBox() the hWnd passed by WndProc(). I was just curious how or why WndProc() would pass a hWnd that doesn't have the same value as the HWND returned by CreateWindowEx().
Xiaopo Yang - MSFT 5.831reputation points •Microsoft employee
2023-01-10T03:09:28.65+00:00 The code provided is not a minimal, reproducible example. You may like the hWnd information passed by WndProc()GetWindowText,GetClassName, etc. and your applicationmultithreaded apps?
Steven Braun 26reputation points
2023-01-10T03:30:43.733+00:00 I tried uploading a folder containing the source, header, and project files, but I couldn't, so I uploaded a copy of the main cpp file, which doesn't compile. However, it does include a programming example of where the error occurred. I'll use your suggestion and call GetWindowText to get the name of the window which hWnd is an identifier if the error occurs again. It's not a bug I can reproduce at will. Occurs by will of the operating system.
But even if the hWnd passed by WndProc is for a different window than the application window, why would MessageBox() reject the application window handle passed in a global variable? When the error occurs, MesssageBox() returns 0, indicating an error, and a call to GetLastError() returns 1400, "Invalid window handle".
Castorix31 65.366reputation points
2023-01-11T08:18:07.19+00:00 Why did you flag an incorrect answer (fromunlimited technology)
like the correct answer?!
RLWA32 28.641reputation points
2023-01-11T08:34:08.5166667+00:00 @Castorix31 I was also confused by assuming an irrelevant answer!
Steven Braun 26reputation points
2023-01-11T21:29:31.2+00:00 The answer posted by RLWA32 on Jan 10, 2023 at 3:41 am is the one I would have chosen as a solution, but that option was not available and I wanted to choose an answer as a solution to close the thread. The answer I chose was the only one that had "Accept as Solution" available. I unchecked.
I don't want to see any more responses on this topic, which I consider closed.
RLWA32 28.641reputation points
2023-01-11T21:47:10.8566667+00:00 thanks for answering
I've turned the Jan 10, 2023 3:41 comment into an answer that you can accept if you wish. The converted response shows a timestamp of Jan 11, 2023 4:43 PM.
Log in to comment
answered
2023-01-11T21:09:47.0633333+00:00 Steven Braun 26reputation points
<marked for deletion>
0No comments
Log in to comment
Enter to answer
activity
Log in to follow questions and users