You can get the window state of the process and use that to determine whether or not it is currently visible to the user, as described in this StackOverflow question:
Get window state of another process
This will involve using P/Invoke (unmanaged code), just FYI.
For your convenience, here's the same code from that answer translated to VB:
Shared Sub Main(args() As String)
Dim procs() As Process = Process.GetProcesses()
For Each proc As Process In procs
If proc.ProcessName = "notepad" Then
Dim placement = GetPlacement(proc.MainWindowHandle)
MessageBox.Show(placement.showCmd.ToString())
End If
Next
End Sub
Private Shared Function GetPlacement(hwnd As IntPtr) As WINDOWPLACEMENT
Dim placement As WINDOWPLACEMENT = New WINDOWPLACEMENT()
placement.length = Marshal.SizeOf(placement)
GetWindowPlacement(hwnd, placement)
Return placement
End Function
<DllImport("user32.dll", SetLastError:=True)>
Friend Shared Function GetWindowPlacement(ByVal hWnd As IntPtr, ByRef lpwndpl As WINDOWPLACEMENT) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<Serializable>
<StructLayout(LayoutKind.Sequential)>
Friend Structure WINDOWPLACEMENT
Public length As Integer
Public flags As Integer
Public showCmd As ShowWindowCommands
Public ptMinPosition As System.Drawing.Point
Public ptMaxPosition As System.Drawing.Point
Public rcNormalPosition As System.Drawing.Rectangle
End Structure
Friend Enum ShowWindowCommands As Integer
Hide = 0
Normal = 1
Minimized = 2
Maximized = 3
End Enum
If the window is indeed in a "Normal" window state, then perhaps its position is not one to which you have access. Try using this code to show the position of the window.
Dim procs() As Process = Process.GetProcesses()
For Each proc As Process In procs
If proc.ProcessName = "notepad" Then
Dim placement = GetPlacement(proc.MainWindowHandle)
MessageBox.Show(placement.showCmd.ToString())
Dim windowRect As Rectangle = New Rectangle()
GetWindowRect(proc.MainWindowHandle, windowRect)
MessageBox.Show(windowRect.Top.ToString() + " | " + windowRect.Left.ToString() + " | " + windowRect.Bottom.ToString() + " | " + windowRect.Right.ToString())
End If
Next
And here's the declaration for GetWindowRect
<DllImport("user32.dll", SetLastError:=True)> _
Friend Shared Function GetWindowRect(ByVal hWnd As IntPtr, ByRef lprect As Rectangle) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
Since the window border is non-traditional, let's try this guy:
<DllImport("user32.dll", CharSet:=CharSet.Auto)> _
Friend Shared Function IsWindowVisible(ByVal hWnd As IntPtr) As Boolean
End Function