4

We have a 3rd party control loaded in our C# WinForms app.

When we call a method on this 3rd party ActiveX control, it asynchronously steals focus. For example:

// This call causes 3rd party to spawn a thread and steal focus 
// milliseconds later.
foo3rdParty.DoSomething();

Is there a way to prevent a control from stealing focus?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Judah Gabriel Himango
  • 58,906
  • 38
  • 158
  • 212
  • You'd probably have to do a message hook to intercept and cancel the focus change. This is pretty rude behavior from a control - no chance of removing it entirely, I assume. – MusiGenesis Jul 13 '09 at 22:06
  • No kidding, it really is rude behavior. We asked the developer how to prevent/workaround this behavior, he told us, *"Use Win32 APIs to take the focus back."* Problem is, there's no notification of when the thread is done stealing focus, so we're kind of SOL. We explained this to the developer, but never received a response back. – Judah Gabriel Himango Jul 13 '09 at 22:26
  • 1
    Did he explain why his control needed to steal the focus in the first place? If there's any rational reason for it at all, it's probably a hack fix that's masking a deeper problem. I hope this isn't something like a space-shuttle-life-support-maintenance control. – MusiGenesis Jul 13 '09 at 22:56
  • It's not a "he". It's a "they" -- a really, really big corporation whose 3rd party control is all over the 'net. :-) They figure their control is important enough that when you call DoSomething() on it, it should take the focus. – Judah Gabriel Himango Jul 24 '09 at 20:19

4 Answers4

3

If the control has a GotFocus() event (and it's correctly raised by the control whenever it steals the focus), you could attach a handler to that and set the focus back to the last control that had the focus (or the OK button or whatever).

This might produce weirdness if someone is typing in a textbox in the middle of this. My solution would be to give my money to someone who was willing to do maybe 15 minutes of work to help me.

MusiGenesis
  • 74,184
  • 40
  • 190
  • 334
  • Yeah, pretty hackish. I tried this, and found the control itself steals the focus 2-3 times during this period, so even this hack doesn't work entirely. – Judah Gabriel Himango Jul 14 '09 at 00:21
3

If this evil little control isn't meant to be visible, you could place it on an invisible form and call DoSomething() on it there. Then, who cares if it grabs the focus?

MusiGenesis
  • 74,184
  • 40
  • 190
  • 334
2

You could try this rough approach:

  1. Find which control has focus before you make the call, say using Form.ActiveControl.
  2. Attach a handler to the active control which gets called when it loses focus.
  3. Make the call to the third-party control's method.
  4. If all goes as expected, the third-party control will gain focus, and the previously focused control will lose focus, and the handler will be called.
  5. In that handler, either set focus back to the previous control, or schedule some code to run on a thread to do so a little later.
Vinay Sajip
  • 95,872
  • 14
  • 179
  • 191
  • Thanks, tried this. Turns out, this 3rd party activex control steals the focus multiple times, usually 2 to 3 times, after the the call to DoSomething(). This complicates your above hackish solution. Thanks anyways. – Judah Gabriel Himango Jul 14 '09 at 00:24
2

ugh. you've probably already thought of this but can you disable the control's window during the period (or a guesstimation) when it tries to take focus, without hurting the user experience?