I'm not sure if this just happens when running SDI (which is the only way I run) for the VB6 IDE, or if it happens for everyone.
But, when I load the IDE, ever since about the beginning of Windows 10, I get this little window on the center of my screen, If I minimize and then re-normalize the IDE, it goes away. But that's annoying. For years, I've just been ignoring it, but I finally decided to do something about it.
This little add-in attempts to hide it when the IDE loads. Its class is named "IDEOwner", and it seems to be the only window that's part of the IDE with that class name. So, that's how I found it (programmatically).
Here's code in the add-ins DSR module:
Code:
Option Explicit
'
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long ' Returns OUR PID.
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
'
Private Sub AddinInstance_OnConnection(ByVal Application As Object, ByVal ConnectMode As AddInDesignerObjects.ext_ConnectMode, ByVal AddInInst As Object, custom() As Variant)
Dim i As Long
'
' Get all the windows in our PID.
Dim hWnds() As Long
hWnds = hWndOfAllTopLevelWindows(GetCurrentProcessId) ' Only ones belonging to our PID.
'
' Find the IDEOwner Class
Dim hWndIdeBar As Long
For i = LBound(hWnds) To UBound(hWnds)
'If WindowClass(hWnds(i)) = "wndclass_desked_gsk" Then
If WindowClass(hWnds(i)) = "IDEOwner" Then
hWndIdeBar = hWnds(i)
Erase hWnds
Exit For
End If
Next
'
' Now hide it.
Const SW_HIDE As Long = 0&
Const SW_SHOWNORMAL As Long = 1&
Const SW_SHOWMINIMIZED As Long = 2&
If hWndIdeBar Then
ShowWindow hWndIdeBar, SW_SHOWMINIMIZED ' This seems to be all it takes.
End If
End Sub
Private Function WindowClass(hWndOfInterest As Long) As String
WindowClass = String$(1024&, 0&)
WindowClass = Left$(WindowClass, GetClassName(hWndOfInterest, WindowClass, 1024&))
End Function
And here's some code that needed to be in a BAS module (so AddressOf could be used):
Code:
Option Explicit
'
Private Declare Sub SafeArrayAllocDescriptor Lib "oleaut32" (ByVal cDims As Long, ByRef psaInOut As Long)
Private Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Private Declare Function vbaObjSetAddref Lib "msvbvm60" Alias "__vbaObjSetAddref" (ByRef dstObject As Any, ByRef srcObjPtr As Any) As Long
Private Declare Function ArrPtr Lib "msvbvm60" Alias "VarPtr" (a() As Any) As Long
'
Public Function hWndOfAllTopLevelWindows(Optional iSpecificProcessId As Long = -1&) As Long()
' Returns a 0 to -1 array if none found, but it ALWAYS returns a dimensioned array (so that LBound and UBound can be used).
' The caller should use GetCurrentProcessId if you wish to get windows for just this process.
'
Dim hWndsColl As New Collection
' Gather ALL of them.
EnumWindows AddressOf EnumWindowsCallBack, ObjPtr(hWndsColl) ' Doesn't return until done.
' See if we only want a specific PID, and delete non-matches if so.
If iSpecificProcessId <> -1& Then
Dim i As Long
For i = hWndsColl.Count To 1& Step -1&
If ProcessId(CLng(hWndsColl.Item(i))) <> iSpecificProcessId Then hWndsColl.Remove i
Next
End If
' Transfer into our return array.
If hWndsColl.Count Then
hWndOfAllHelper hWndOfAllTopLevelWindows, hWndsColl
Else
SafeArrayAllocDescriptor 1&, ByVal ArrPtr(hWndOfAllTopLevelWindows) ' Makes a 0 to -1 array.
End If
End Function
Private Sub hWndOfAllHelper(hArray() As Long, coll As Collection)
ReDim hArray(coll.Count - 1&)
Dim v As Variant
Dim iPtr As Long
For Each v In coll
hArray(iPtr) = v
iPtr = iPtr + 1&
Next
End Sub
Private Function EnumWindowsCallBack(ByVal hWnd As Long, ByVal lpData As Long) As Long
Dim coll As Collection ' Will de-reference when we fall out of scope.
vbaObjSetAddref coll, ByVal lpData
coll.Add hWnd
EnumWindowsCallBack = 1&
End Function
Public Function ProcessId(hWndOfInterest As Long) As Long
Call GetWindowThreadProcessId(hWndOfInterest, ProcessId)
End Function
And the whole project is attached (minus the actual add-in's DLL).
I also included some little DLLReg and DLLUnreg scripts for registering/unregistering this in case you needed to. However, just compiling it will register it, so long as you save your DLL in a reasonable place. I save my add-in DLLs in the following folder: C:\Program Files (x86)\Microsoft Visual Studio\VB6_Addins
Enjoy.
EDIT: Made a couple of changes. Changed it to just minimize the IDEOwner rather than hide it, as hiding it caused some unintended consequences, and minimizing it accomplishes the same objective without any consequences that I see. I also slipped in my new EnumWindows work (which doesn't use any module level variables to get its work done).
Last edited by Elroy; Dec 27th, 2021 at 01:25 PM.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Thanks for your good AddIn, which saves me at least from the irritation of seeing the IDEOwner window.
But I slightly modifies your code for less flicker on startup.
1) Your dll was just minimizing the VB6 IDE and left there.
I coudn't see the IDE onscreen. I have to then manually normalize it from taskbar.
I have added SW_SHOWNORMAL immediately to resume the IDE on decktop.
2) I have moved your code from AddinInstance_OnConnection() to AddinInstance_OnStartupComplete() for smoother job.
Otherwise fighting was there who first. (IDE vs Addin)
Code:
'soorya moved to avoid too much flickering on startup
'Private Sub AddinInstance_OnConnection(ByVal Application As Object, ByVal ConnectMode As AddInDesignerObjects.ext_ConnectMode, ByVal AddInInst As Object, custom() As Variant)
Private Sub AddinInstance_OnStartupComplete(custom() As Variant)
Dim i As Long
'
' Get all the windows in our PID.
Dim hWnds() As Long
hWnds = hWndOfAllTopLevelWindows(GetCurrentProcessId) ' Only ones belonging to our PID.
'
' Find the IDEOwner Class
Dim hWndIdeBar As Long
For i = LBound(hWnds) To UBound(hWnds)
'If WindowClass(hWnds(i)) = "wndclass_desked_gsk" Then
If WindowClass(hWnds(i)) = "IDEOwner" Then
hWndIdeBar = hWnds(i)
Erase hWnds
Exit For
End If
Next
'
' Now hide it.
Const SW_HIDE As Long = 0&
Const SW_SHOWNORMAL As Long = 1&
Const SW_SHOWMINIMIZED As Long = 2&
If hWndIdeBar Then
ShowWindow hWndIdeBar, SW_SHOWMINIMIZED ' This seems to be all it takes.
'soorya added this to show again on screen
ShowWindow hWndIdeBar, SW_SHOWNORMAL ' This seems to be all it takes.
End If
End Sub
Here is the issue to those who didn't face it yet.