How do you use MFC CScrollbar controls? - mfc

I have dropped a horizontal CScrollBar control onto a dialog box. How on earth do you use it??
I tried moving the grip to the right and it jumped straight back to the left.. so I figured I may need to set the range. I called SetScrollRange( 0, 100 ) and it still does the same thing. I can't find any examples on Google that help - all scrollbar references seem to refer to using the view class etc etc but thats not what I want to do.
All I want to do is move the grip and get a notification message back of some description, how do I do that (please)?

For anybody that wants to know, you need to handle the WM_HSCROLL/WM_VSCROLL messages yourself.. and call SetScrollPos() yourself when receiving the SB_THUMBPOSITION messages.

Related

Simulate mouse click in background window

I'm trying to use SendMessage to post mouse clicks to a background window (Chrome), which works fine, but brings the window to front after every click. Is there any way to avoid that?
Before anyone says this is a duplicate question, please make sure that the other topic actually mentions not activating the target window, because I couldn't find any.
Update: aha, hiding the window does the trick, almost. It receives simulated mouse/keyboard events as intended, and doesn't show up on screen. However, I can just barely use my own mouse to navigate around the computer, and keyboard input is completely disrupted.
So my question is, how does sending messages to a window affect other applications? Since I'm not actually simulating mouse/keyboard events, shouldn't the other windows be completely oblivious to this?
Is it possibly related to the window calling SetCapture when it receives WM_LBUTTONDOWN? And how would I avoid that, other than hooking the API call (which would be very, very ugly for such a small task)?
The default handling provided by the system (via DefWindowProc) causes windows to come to the front (when clicked on) as a response to the WM_MOUSEACTIVATE message, not WM_LBUTTONDOWN.
The fact that Chrome comes to the front in response to WM_LBUTTONDOWN suggests that it's something Chrome is specifically doing, rather than default system behaviour that you might be able to prevent in some way.
The source code to Chrome is available; I suggest you have a look at it and see if it is indeed something Chrome is doing itself. If so, the only practical way you would be able to prevent it (short of compiling your own version of Chrome) is to inject code into Chrome's process and sub-class its main window procedure.

How to globally capture every mouse click in X11?

I want to capture every mouse click event in X11 and pass them to my C++ application. I don't only want to capture the clicks made on top of my main window but each and every one with no regard to my main window. It looks like I could easily accomplish this using XGrabPointer. However, I want everything to behave as though I never grabbed the event. That is, I want the events to continue on their normal journey to other clients down the hierarchy, I merely want to be the first one to snoop in on events. I don't want the events to be "eaten".
There seem to be a couple of solutions to this that come up when Googling the issue but apparently all of them are broken or deprecated. The most promising one was Xrecord + Xtest but that seems deprecated as well.
It looks like this should be done using Xinput2 nowadays but information on how to use it is really scarce. I'd appreciate some insight.
Somewhat late in the day, but still - you might want to take a look at the "xkey" application[1], which snoops on all key events to all open windows. If you went that way you would also want to watch for new window creation.
[1] http://www.stllinux.org/meeting_notes/1997/0619/xkey.html
I know kcolorchooser does that and is written in C
Maybe it is worth the reference:
http://www.kde.org/applications/graphics/kcolorchooser/development
Maybe you should have a look at the xev code: it captures each and every X event imaginable.

Creating Drawer-like window

How do you create a window that is attached to the side of parent window opens like a drawer?
In such a way that you don't lose focus of parent window.
What you basically need to do is create yourself a custom control representing your drawer. I'm not sure if that's something you're familiar with or not, but if not there are plenty of tutorials about, such as this one.
I imagine what you'd do is designate part of your control to be the "handle", which if clicked upon "opens" the drawer. You would achieve this by handling the WM_LBUTTONDOWN/WM_LBUTTONUP messages in your control's window procedure, and changing its size from its closed size to its open size when clicks are detected. I haven't used it before, but you might be able to simply achieve animation using AnimateWindow.
You'd probably also want to have your control send it's parent window a notification whenever it is opened or closed, so that your parent window can re-size or move other controls if necessary. You can achieve this by sending a WM_NOTIFY message to the parent window with your own notification code, or using your own custom message. Your parent window would then have to respond to such messages in its window procedure.
As far as I'm aware there's no specific examples to be found addressing your exact requirements, so I probably can't supply much more info at the moment. If there's anything else in particular you need to know to get this running, don't hesitate to ask.

How do I have my apps dialog box pop up and take focus from the current running app?

I know this type of thing is looked negatively upon but I write software for people with disabilities and sometimes good gui practices don't make sense. In this case, the user interacts with a assistive interface and under certain conditions, my control app needs to prompt the user with a question. My background process creates a dialog (I'm using wxwidgets wxDialog class) and calls Show(). The dialog box appears but it does not have focus (the application that the user was previously using keeps it). Since my users can't use mice, they can't simply click on the window. I've tried calling show and then followed by SetFocus(HWND) but that doesn't do it. What's the problem? Is this even possible? Window7. I'm thinking that it might have something to do with it being a dialog and not a full window (wxFrame). Any help is greatly appreciated.
Try using SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE)
Unfortunately, not only is it 'looked negatively upon', but it is not possible. There's no getting around this; ask yourself what would happen if every application could do this? Obviously, if you can put your dialog on top of the other application, it can do exactly the same back to you.
http://blogs.msdn.com/b/oldnewthing/archive/2010/11/25/10096329.aspx
The only think I can think of would be for you to put a notification icon in the system tray, and then have it display a notification balloon.
I had to do something like this before. Simply calling functions like SetForegroundWindow or SetWindowPos didn't do the trick.
I ended up using this ForceForegroundWindow function (1st one) and it works pretty well.
I know this is Delphi code, but the API is the same and Delphi is a pretty simple language.

How to mix C++ and external buttons on seperate window?

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.