I have an application on C++ (on Windows API) and I ask the user to approve a task using MessageBox. However, as it's a bit sensible task and nobody reads the message, I want to change it to have an input box and the user type "I agree".
Does anybody know a simple way to do that? I find DialogBoxParam() which can do it, but it's overkilling for my needs, can you think on something more simple (or a simple way to use it)?
I found Prompting a user with an input box? [C++] quite similar to my question, but there is no satisfactory answer for me (using another lib is not an option).
You would have to write your own dialog for that. The MessageBox and related APIs do not offer such functionality. You could use the task dialog API (introduced in Vista) to show a dialog box with a button having customised caption. That might be a little better than plain MessageBox with its limited set of buttons.
I'm a little cynical about what you are trying to achieve in any case. If you force the users to type I agree they will ignore the content of the dialog box and type what you ask them to type.
The difference in outcome between your typing dialog and a standard button press dialog is that the user will take longer to get past the dialog, and will dislike your software, but the still not have read the content of the dialog. In other words, the only thing you will achieve by doing this is to hold up the user.
At some point you have to accept that the user takes responsibility for their actions. If you give them a helpful message and they choose to ignore it, ultimately that is on them.
Related
I am working on an application for a customer and have hit a problem.
The application talks to the mobile phone and does a bunch of call handling. One of the things it does is to show an "answer call" button. Clicking this with the mouse works fine.
But the customer wants to have a keyboard shortcut for this, and that's a problem. I can get the focus if a window in the application has focus. But Windows focus steal prevention doesn't allow me to take focus if the user is in a different application.
Please don't discuss the pros and cons of focus stealing here. I know them already and have given them to my customer. Wrong or not, they still want to do this, and they are paying the bill, so they get to decide.
There are a number of workarounds for this, but they do not seem to work anymore. For example, I set HKEY_CURRENT_USER\Control Panel\Desktop\ForegroundFlashCount to 3 and ...\ForegroundLockTimeout to 0.
So what are my options? Is this impossible? Or do I have to build a keyboard hook application that virus checkers will hate?
This is a Qt/C++ application, but if you have C# example code that can do this, that is great as well.
I hope you can help.
I do not know how dated this is but you could try RegisterHotKey.
It allows you listen for keyboard events system wide and not just when your application has focus. You don't have to provide your window handle, if you leave that argument null the events are still posted to your thread.
As the context menu for the desktop and explorer windows is disabled, I wanted to make a little something to bring back some functionality. My idea was to just list out things in a context menu (copy, paste, new, open with, etc) whenever a user right-clicks one of these windows, and then just simulate the appropriate event in the actual menu (file->new, edit->copy, etc). It wouldn't look perfectly pretty, but it would hopefully allow for the use of right-clicking.
The problem is that I cannot seem to get the actual menu. I opened My Documents and tried going down the child list towards SysListView32, calling GetMenuItemCount each time. Most returned -1, and the only other return value than that was 0.
How am I supposed to get a handle to the (file, edit, view...) menu?
If this isn't possible, is there a way I could simulate the user clicking something on the normal context menu, even if it's disabled?
Also, is there a way of making this work for the desktop? You can get the same type of thing if you view it in the explorer window, so I figured there might be a way.
I'm running Windows XP and any help is appreciated.
As per David Heffernan's comment,
As for your question, you are on the wrong track.
GetMenuItemCount needs an HMENU but you've been feeding it HWND.
That won't work. It also won't work from a different process.
You could possibly write a program that use the shell COM APIs
to show a context menu for a shell item. But your basic problem
is the bone-headed group policy. You really need to get that fixed.
Tell the IT guy that takes the decision that I said he was a fool
and was stopping you doing any useful work. ;-)
This led me onto the path of using the correct alternative method to achieve my goal.
I've been messing with Win32 API for abit, and I've got a question regarding the GUI functions.
How does one handle user input that is not managed through popup windows? I've been reading http://www.winprog.org/ but right when the interesting features comes -- lesson9 -- it becomes more abstract and I'm not sure how to do it.
Basically what I am after is the user to write input in two windows and then press a button to send a message that the content of the input is to be processed.
I think the input windows would be some EDIT-class windows and the input BUTTON-class but that's about it.
Any ideas? I'm sure it's simple, it's just makes me want to rip my hair of in native code :p
Cheers
You're correct, you want and EDIT control which is more commonly known as a TextBox and a BUTTON class which is a command button.
To get the the input the Button will send a WM_COMMAND message to its parent window with a BN_CLICKED in the wParam high word. You can identify the particular button from the hWnd you get in that message.
After that you'll need to post a WM_GETTEXT to the edit control to retrieve the users input.
This is all from memory so I highly recommend looking up the msdn pages before you code.
I'm not sure I follow 100%. Yes, you would use EDIT and BUTTON-class controls for that. Where are you getting stuck?
I want to make a C++ button on Start>Run i.e but when I do it will not do signalled event?
Im sorry I have seen that you do not get the question.
Ok basically when you create a button with CreateWindowEx(); I want to do that but put on a different window with SetPArent which I have already done now the button does not work so I need my program to someone get when it is clicked from the Run window as example!
And yes you have it, but it's not making the button is the problem it's getting when it's clicked with my program since it does not belong to it anymore!
You need to apply the ancient but still-supported technique known in Windows as subclassing; it is well explained here (15-years-old article, but still quite valid;-). As this article puts it,
Subclassing is a technique that allows
an application to intercept messages
destined for another window. An
application can augment, monitor, or
modify the default behavior of a
window by intercepting messages meant
for another window.
You'll want "instance subclassing", since you're interested only in a single window (either your new button, or, the one you've SetParented your new button to); if you decide to subclass a window belonging to another process, you'll also need to use the injection techniques explained in the article, such as, injecting your DLL into system processes and watching over events with a WH_CBT hook, and the like. But I think you could keep the button in your own process even though you're SetParenting it to a window belonging to a different process, in which case you can do your instance subclassing entirely within your own process, which is much simpler if feasible.
"Superclassing" is an alternative to "subclassing", also explained in the article, but doesn't seem to offer that many advantages when compared to instance subclassing (though it may compared with global subclassing... but, that's not what you need here anyway).
You'll find other interesting articles on such topics here, here, and here (developing a big, rich C++ library for subclassing -- but, also showing a simpler approach based on hooks which you might prefer). Each article has a pretty difference stance and code examples, so I think that having many to look at may help you find the right mindset and code for your specific needs!
OK, I'll do my very best - as I understand you, you're trying to inject a button into some existing window. That meaning: Your tool creates a button in some window that does not belong to your application. Now, you want to be notified when that button is pressed. Am I correct so far?
To be notified about the button being pressed, you need to get the respective window message, which will only work if you also "inject" a different WndProc into the window. Actually I have no idea how that should work, but I faintly remember functions like GetWindowLong and SetWindowLong. Maybe they will help?
EDIT
I've searched MSDN a little: While you can get the address of a window's WndProc using GetWindowLong, you can not set the WndProc using SetWindowLong on Windows NT/2000/XP (and up I suppose). See here (MSDN).
So what you could do is install a global message hook that intercepts all window messages, filter those for the window you've injected the button into and then find your message. If you have trouble with this, however, I'm the wrong person to ask, because it's been years ago since I've done anything like that, but it would be stuff for a new question.
EDIT 2
Please see Alex Martinellis answer for how to define the hook. I think he's describing the technique I was referring to when I talked about defining global message hooks to intercept the window messages for the window you injected your button into.
In win32, how do I setup a callback mechanism for RichEdit I have not created myself?
PART 1
I'm reading from a textedit field in another application's GUI. This works just fine now, except after the first read I'd like to fetch only new or modified lines. In GTK+ or Qt I'd just install a callback on some signal the field edits when its changed, but how does it work on Win32?
My MSDN searches result with nothing useful, probably because I don't know the exact term to search for. The class of the textedit is RichText20W, and it has some messages that are probably used somehow, though that article just discusses using them for the parent of the class.
PART 2
Also, if there is no such "text changed, here is the newly inserted text" callback which returns the new content immediately, I need some way to easily detect what is new. From top-of-my-head:
Have a marker at the end of the text block we've read, and only read between that and the end.
Store what we've read previously, and after a second read, remove the duplicate part from the latter to have the newly inserted stuff.
Option 2 might not be viable, since the textedit can contain any amount of text. The marker part sounds doable, but yet again, my feeble Win32 skills and horrible Win32 function names prevent me from finding the right way to do it.
Note that all these must be doable for a textedit I do not own and have not created, they belong to a third party process.
Code samples in C++ highly appreciated.
Disclaimer
Obviously, if there is some better way of doing it, let me know. I only assumed callback would be the way to go based on my previous experience with GTK+/Qt. Feel free to show me the path :)
Win32 controls don't work on message-specific callbacks that you can subscribe to. They just send messages to their parent window when something happens, in this case EN_UPDATE, EN_CHANGE and all that. Even these events don't tell you what text changed. They only tell you that it did change.
You could subclass the parent, but the documentation for SetWindowLongPtr explicitly says you "should not subclass a window class created by another process." Something like this is probably possible with hooks, but I haven't used them enough to say for certain how you'd actually do it.
I realize it's an old post, but this article seems to be doing something similar.
Based on Joel's answer, I quit looking for callbacks and just made a small class that hooks itself (not by a real API hook though) to the richedit and polls it once a second for content length, and if it has changed since the last poll, it asks for the content, compares that to previous known content and emits a signal with the changed content.
This seems to work OK for this purpose, but if someone knows a better way still (some real and tested way of doing it via API hooks or something), please post.