Jump to content
Xtreme .Net Talk

Recommended Posts

  • Leaders
Posted

There is a certain functionality that I am trying to emulate from the tool windows in Photoshop or floating toolbars in Microsoft Word. These tool windows are topmost so that when focus moves to the main MDI window the tool window is not hidden behind it. When the application loses focus, however, (even if the main MDI window is still visible) the topmost toolbars are hidden so that they stay out of the way of other applications.

 

So... I need to detect when my application loses focus. The application class has no "LostFocus" event. I can't use the frmMain.Deactive event because this event fires before the Toolwindow.Active event. Effectively, there is an instant when none of my forms have focus and using the Deactivate and Activate events to determine when my application has focus based on whether or not any of my windows has focus won't work.

 

I need another means of detecting that my application has lost focus or a reliable solution that works around the "focus gap" caused by the fact that the Deactivate event is raised before the next Activate event.

[sIGPIC]e[/sIGPIC]
  • *Experts*
Posted
Dumb question number 1...instead why don't you create the toolbar programmably in a panel then set it's .BringToFront properity to True instead of creating another form and Raising Events to transfer instructions? I've been very successful with this method and it eliminates a lot of possible problems and head aches.

Member, in good standing, of the elite fraternity of mentally challenged programmers.

 

Dolphins Software

  • Leaders
Posted (edited)

To answer your question simply, DiverDan, because I don't want to. But seriously, there is a more mature, realistic answer too. First of all I want my program to look professional, as well as consistent with the OS and other applications. Secondly I prefer the full functionality of a wholly separate window, which can be dragged outside the bounds of the MDI window, has built in draggability and resizability, etc. Your suggestion is a good one, and a method I have used in the past. It even has some useful advantages over my technique (such as easy dockability), however for this specific application, I prefer an actual separate Form. I appreciate the suggestion, though.

 

And Hamburger1984, I have considered using the method in your HidingToolwindows project, but decided against it only for the reason that in some rare cases it may not necessarily behave as expected. It is probably 99.99% reliable, but there is no substitution for 100%.

 

As I was writing this reply, however, I got an idea which I tried and seems to work. I had previously checked the shared property ActiveForm on the frmMain.Deactivate event, which returned frmMain, the main form which has just lost focus. This serves no use in determining if my app has focus. I added an Application.DoEvents and then checked ActiveForm, and it returned the window that was receiving focus. If ActiveForm returns nothing after a DoEvents, as far as I can see this will properly indicate that my application has lost focus under any circumstances (but I will need to check on the Deactivate event of all non-MDI child, not just frmMain). And BAM! Photoshop style tool windows (actually, photoshop tool windows work a little differently. Mine act more like Word toolbars).

 

Thanks for the suggestions though, they were both good ones.

Edited by snarfblam
[sIGPIC]e[/sIGPIC]
  • Leaders
Posted (edited)

And just incase anyone wants the code...

 

Dim WithEvents Palette As New Palette

Dim PaletteWasVisible As Boolean
Dim AppLostFocus As Boolean
Private Sub frmMain_Deactivate(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Deactivate, Palette.Deactivate
	Application.DoEvents()
	If ActiveForm Is Nothing Then
		PaletteWasVisible = Palette.Visible
		Palette.Visible = False
		AppLostFocus = True
	End If
End Sub

Private Sub frmMain_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Activated, Palette.Activated
	If AppLostFocus Then
		Palette.Visible = PaletteWasVisible
		AppLostFocus = False
	End If
End Sub

 

For photoshop style tool windows:

 

Dim WithEvents Palette As New Palette

Dim AppLostFocus As Boolean
Private Sub frmMain_Deactivate(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Deactivate, Palette.Deactivate
	Application.DoEvents()
	If ActiveForm Is Nothing Then
		Palette.TopMost = False
		AppLostFocus = True
	End If
End Sub

Private Sub frmMain_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Activated, Palette.Activated
	If AppLostFocus Then
		Palette.TopMost = True
		AppLostFocus = False
		Me.Focus()
	End If
End Sub

Edited by snarfblam
[sIGPIC]e[/sIGPIC]

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...