I recently got into Win32 programming and I bumped into a bug I couldn't seem to find anywhere on the net yet. I have an Edit Control that behaves a bit odd. I have a maximum of 3 characters set for the control. When I enter a number (ES_NUMBER is set) it keeps adding it to the control - if it weren't for the limit.
Image of when I enter a 0:
It does the same for Delete and Backspace - the entire control is cleared instantly.
I have the feeling that window procedure messages that are sent to the edit control's default window procedure might not be cleared from the message queue. Is there any way to find out if this is the case? Has anyone ever experienced this kind of behavior? I don't manually process any of the messages for the Edit Control.
This seems to have been a problem with PeekMessage/GetMessage. Message intended for Dialog Windows (while my window was not a dialog) were not being removed by PeekMessage until a new message appeared in queue, even though PM_REMOVE was specified. Replacing the line with GetMessage fixed the issue.
Related
I see this message in VB6 again and again from time to time since I can remember, and now after like 15 years, I would like to ask if somebody knows how to get rid of this message.
I don't know when it occurs, but when it does, I can not click this window away.
It keeps flickering and does not go away:
In English:
"The action cannot be completed because the other application is unavailable. Click 'Switch to' to activate the other application and fix the problem. 'Switch to...', 'Repeat', 'Cancel' "
I don't really know what the message means. I would guess it wants to tell me that it waits for a component to respond.
But no longer how long I wait, it does not finish.
Does anybody know a trick how to close this window?
Sometimes I can still try to close VB6, and it will go away and allow me to save the edited files, but often, I have to terminate VB6 using the task mananger, and then my changes are lost.
I would like to avoid this.
Thank you!
Edit: It seems that the problem occurs when I use the clipboard.
Each time right now when I use Ctrl + V to paste something, this happens.
I want to prevent users from closing a window by Alt + F4 or by clicking the close button.
How to achieve this?
I guess the windows API can do it, but I don't have any experience, and I can't find a specific solution.
Of course, it's good to be able to implement it,don't have to use a specific API.
Background: it is very difficult to find the last place in Word after closing it for a few days. After word2013, word2013 brought with it a way to return to the previous reading position, but that thing is very unstable and often can't be saved. When word is closed, I want to stop closing and pop up a notice to remind me to add a bookmark before exiting.
EDIT: This won't work, as it turned out. At least the message hook won't work because the message is posted and not sent, and about the CBT hook I'm not sure either, and I can't test it at the moment to give an evidence-based statement. The solution is probably to subclass the window but this is also non-trivial and I can't explain it properly and with working examples right now. I can't delete this answer though because it already has a comment. See here for more info. So take it with a grain of salt. I'm turning the answer to community wiki, feel free to edit it and fix/improve the solution!
EDIT2: Seems even subclassing won't be enough because Word is doing things its own way.
You need a windows hook. Either a CBT hook or a getmessage hook will do.
You have to create a DLL for this to work. The hook handler must be located in the DLL. It must have the same bitness as Word (probably 64 Bit). Then you call SetWindowsHookEx to install a global hook.
In the hook, you will have to check whether the current action is a window-closing attempt (in a CBT hook you would check for a HCBT_SYSCOMMAND of SC_CLOSE, in a getmessage hook you would check for a WM_CLOSE message), and whether it is about a Word window (for example using the window class - not sure if it has a recognizable class, you'd have to check - or the process' executable file name which you can get using GetModuleFileName since you will run inside Word's process) and prevent the action (by returning 1 from a CBT hook or returning 0 from a getmessage hook - to allow, call CallNextHookEx).
I have found in my company's codebase a code to open default mail program using ShellExecute. The code is written long time ago, but I've notice strange behavior on it, the problem only occurs when the debugger is not attached.
if ShellExecute(Handle, PChar('open'), PChar('mailto:donotreply#nonono.com'), nil, nil, SW_SHOWDEFAULT) <= 32 then
begin
//...
end;
Above is the relevant part of the code. Handle is the Form handle.
To reproduce the problem, simply create a new project, add a button on it and call this code on the button onClick event handler. It is also necessary to not have a default mail installed, so windows will display an message warning about that.
When debugging, the message Z order is higher than the application, so the message box is properly displayed and the user can close this message.
When not debugging, the message Z order is lower than the application, so the user has to alt+tab to see that message.
I don't have enough knowledge to understand what is happening nor to state if that behavior is correct or not.
Is there anything I can do to properly display the message box in a higher Z order than my application?
Is this code deprecated? Should I move forward to a different way of doing this, if so, how?
Here's the problem: The main GUI thread is performing a SendMessage to another GUI thread (yes, there are multiple GUI threads, and unfortunately this cannot change). When that second GUI thread receives the SendMessage, it may decide to display a message box. Some of the time, that MessageBox will 'freeze' the entire application.
More specifically, the message box shows up, but the entire GUI is hung (user input does not work anywhere).
I've verified with a debugger that the second GUI thread is spinning in the DialogBox2() function defined in user32.dll. I can see in the disassembly that a message pump is being executed (I see IsDialogMessage/TranslateMessage/DispatchMessage being called). Using spy++, I do not see any messages being processed for the message dialog box window. I do see messages getting processed on the main GUI window (such as WM_SETCURSOR, though I do not thin they are being processed as I believe SendMessage doesn't execute a message pump).
The second thread is executing code that is part of an MFC extension DLL, if that matters.
I've tried using AfxMessageBox() / CWnd::MessageBox / ::MessageBox(NULL parent window,...). All exhibit the same problem.
Has anyone seen anything similar before?
Thanks,
Andrew
It must be that blocking one of the GUI threads causes the problem.
Try this:
Replace the ::SendMesage with ::PostMessage followed by a ::MsgWaitForMultipleObjects loop. You will need to pass an event handle that signals when the message box is closed.
It will probably solve the problem.
Just be careful which messages you dispatch in you ::MsgWaitForMultipleObjects loop.
I'm writing a DLL that is automatically injected on load in a specific application. Because I'd like to run the program while working on it, and my users might want to load the program without it in specific cases (e.g. bug hunting), I sometimes want to prevent loading the DLL.
Currently I do this by checking GetKeyState for VK_LCONTROL, VK_LSHIFT , and VK_LMENU on load, and if all are down, I silently unload myself.
However, it can take quite a few seconds for the program to load and to see if the DLL was loaded or not, so I want to inform the users when we're unloading. I've considered a MessageBox, but that's too disruptive. I've tried MessageBeep, but that didn't seem to do anything on my setup. Currently I'm using a simple dual beep (Beep, Sleep, Beep) to indicate unloading, but that will probably become rather annoying to my co workers. I've also considered a system-tray icon, but that would introduce a lot of code and bug potential, while I'm aiming for a minimal notification as to not introduce any subtle bugs.
Would anyone else know a subtle way (preferably visual) to inform the user that their input has been succesfully received?
Given the limited scope of your goal, this might actually be an appropriate use of a taskbar notification balloon tip.
Edit: Added link the Joe posted in his concurring answer. Thanks, Joe! :)
If your app has a status bar at the bottom, you could place some message text there...
Have you considered a timed messagebox that closes itself?
http://www.codeguru.com/cpp/misc/misc/messageboxhandling/article.php/c203
You could open a window with a short message and close it automatically again after 0.5 seconds or so. It doesn't need user interaction so I don't think it's very disruptive.
Change the window title, then change it back afterwards. Then you can see the change even if the user has Alt-Tabbed over to some other program in the meanwhile, without stealing the focus from the user.
Concur with Greg D.
Look here: http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/15cbdc8d-fde3-44ab-bbbc-e50cb2071674/
Two ideas:
Turn it around. Have a visual indication when the DLL is loaded, and have the absence of the indicator let you know that the DLL has been unloaded. Perhaps a suffix in the title bar. That way, you can tell at any time, not just during startup.
FlashWindowEx.