Link to home
Start Free TrialLog in
Avatar of TechMonster
TechMonster

asked on

keep track of focus vb.net

how do you keep track of focus for different applications?

When I click on "Go" in VB it's supposed to paste the contents from clipboard to whatever
the last application the user clicked on.  appActivate is only specific to a applicaiton.  

Help!!
 
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Here is how to create a form that does not steal the focus (thus allowing your paste to work since the the app with the focus keeps the focus even when you click your button).  Set the TopMost property to true.

Imports System.Runtime.InteropServices

Public Class Form1
    Inherits System.Windows.Forms.Form

    Private Const WS_EX_NOACTIVATE = &H8000000
    Private Const WM_MOVING = &H216

    Private Structure RECT
        Public Left As Integer
        Public Top As Integer
        Public Right As Integer
        Public Bottom As Integer
    End Structure

    Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
        Get
            Dim cp As CreateParams = MyBase.CreateParams
            cp.ExStyle = cp.ExStyle Or WS_EX_NOACTIVATE
            Return cp
        End Get
    End Property

    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        If m.Msg = WM_MOVING Then
            Dim r As RECT
            r = DirectCast(Marshal.PtrToStructure(m.LParam, GetType(RECT)), RECT)
            Me.Location = New Point(r.Left, r.Top)
        End If

        MyBase.WndProc(m)
    End Sub

End Class
Avatar of TechMonster
TechMonster

ASKER

Not sure I follow this code.  
The users have a option button that will set the VB application to topmost or not.
THe program was designed to have users click in a application with mouse to activate the form than
click on the GO in VB.net.  The Go will paste some text into the last place the mouse was pointed.

The end goal is to somehow capture the focus from the previous mouse click.  

With the above code are you stating that I can create a form that will not steal the focus?  How do you think I can still use the topmost feature?

"With the above code are you stating that I can create a form that will not steal the focus?  How do you think I can still use the topmost feature?"

Exactly...your form can be topmost and NOT steal the focus.  The user simply selects the form with the box they want to paste into so that the cursor is sitting there.  Then they click the "Go" button on your form and it will simply paste by putting want you want on the clipboard and then using SendKeys with Ctrl-V or by sending each letter that you want individually to paste with SendKeys.

It's that simple....

The code I posted keeps your form from stealing focus when you click on it.  Try it with Notepad or something.  =)
Yeah, the code works as you said except I have 1 minor problem.
I have created text boxes by code which are created everytime I run through this program.  
Now after 1 run of the application the controls do not go back to the text boxes unless I close it out and re-launch.  

 'Creation of textboxes and labels.
            NewTextBox(i) = New TextBox
            NewTextBoxLabel1(i) = New Label
            Me.Controls.Add(NewTextBox(i))
            NewTextBox(i).BackColor = BackColor.LemonChiffon

            Me.Controls.Add(NewTextBoxLabel1(i))
            NewTextBoxLabel1(i).Text = nostars
any ideas?
Could you describe that in a little more detail?  I'm not following...   =\
Sure.  It seems that the application never regains focus.  If I minimize the form and maximize it works fine.
To regain focus in VB.Net2003 it should be a simple one liner "me.focus" or appActivate().  I was not able to implement either one.  I have a treeview when a node is calls the textbox creation function.  I have some buttons which were created using the toolbox in VB.net.  The buttons work fine.  The text boxes losses functionallity.  They still get created but when I type in the text box it reverts back to the last application I selected such as NotePad and puts it there.
LOL....ok I follow you now.

This is a double edged sword.

The code I gave you makes it easy to paste into the "last focused app" because our app does not take the focus.

But because our app doesn't get the focus, controls that normally require focus (like a TextBox) won't behave well.

We would need to use a different approach other than the WS_EX_NOACTIVATE option.

I remember coding this type of thing in a different way awhile back...I'll see if I can find it.   =\
here is a C++ or C code and sample code some guy suggested but I really have no clue how to make it work.
****************************************************************************
... simply any (and every) window that MS-Windows creates.

What was done is (1) In the application's initialization section, an event hook:
SetWinEventHook( EVENT_MIN, EVENT_MAX, NULL, (WINEVENTPROC)( sbWindowsEventHook ), 0, 0, 0 );

… and (2) Then the hook keeps the appropriate handle:

WINEVENTPROC sbWindowsEventHook(
                                HWINEVENTHOOK  hEvent,
                                DWORD   event,
                                HWND    hwnd,
                                LONG    idObject,
                                LONG    idChild,
                                DWORD   idEventThread,
                                DWORD   dwmsEventTime)
{
    switch ( event )
    {
    case EVENT_SYSTEM_FOREGROUND:
        // Remember this window as the paste-to window
        sbGetApp()->SetFocusWindow( hwnd );
        break;
    }

    return 0;
}

Can't do it that way in VB.Net as it is using a system wide hook...
Do you think your ShellHook will work?  I past the code and it doesn't reconize form1 or me.

 If curWnd <> Form1.hWnd Then
                            ' store the last activated window
                            lastWnd = curWnd
                        Else
                            ' we have switched back to our window
                            Form1.Cls()
                            Form1.Caption = "Activated @ " & Now
                            Form1.Print("Last Windows Handle = " & lastWnd)
                            Form1.Print("Last Windows Caption: " & GetWindowCaption(lastWnd))
That is VB6 code...I haven't tried it in VB.Net yet...I'll see what I can do...
Found this code from IMRAM and having a few errors.

Intercepting WM_ACTIVATE message for any window (detecting activation with hooks/subclassing)

https://www.experts-exchange.com/questions/21083100/Intercepting-WM-ACTIVATE-message-for-any-window-detecting-activation-with-hooks-subclassing.html

uMsgNotify = RegisterWindowMessage("SHELLHOOK")

    ' This basically registers our window to receive the shell events
Call RegisterShellHookWindow = (Me.Handle)

UMsgNotify has an error that it expects a declaration
Call states Syntax error.

Using VB.NET2003...


ASKER CERTIFIED SOLUTION
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Have not had a chance to view this code.  I actually, gave up on it and just send a Alt Tab.
I am sure that the code above is it and I will keep it in my history files to review later.

thanks.