Click here to Skip to main content
15,886,007 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
I have an App that I inherited in VB6 and have ported mostly to VB.net
When I compile / run the app - it highlights all the files in the current selected folder.

What makes it worse, is it's very difficult to search online as what search terms does one use?

The app was ported to VS 2005 - quite successfully - but this has me stumped...

I have tried commenting out all the code that's run on startup and it still does it, so it must be some sort of background thing...

Any ideas?
I can't find an old version to see if it's changes I have made and I don't know where to begin
See the image:http://postimg.org/image/v7o0a4gh7/[^]

The top part is before I run the app, the bottom is once tha app is running and has focus. I hope it makes sense

Also, if I'm browsing and then run the app, and go back to the browser, when my app gets the focus again, the webpage goes back to the top...

This is very odd - earlier today I thought I'd resolved this - by removing a line setting focus to a particular edit box (with Tabindex of 3), but soon after it reared its ugly head - hence my post...

Found a few Windows calls, but commenting them out doesn't help...
Posted
Updated 24-Apr-15 7:29am
v2
Comments
CHill60 24-Apr-15 12:37pm    
Try searching the code for anything to do with "File", "Directory", "FileInfo" etc and systematically comment out the code until the problem goes away - that last bit will be what's causing the problem.
You will need to share that code for us to have any chance of working out what's wrong
Kenneth Haugland 24-Apr-15 14:44pm    
Process.Start("explorer.exe", "/select," & "myfile.txt")?
or this i suppose:
https://gist.github.com/551626/680a8d371b7c693e4fea5a9c915229c89f4b1e1b
Sergey Alexandrovich Kryukov 24-Apr-15 15:06pm    
"Highlight" — where? "Folder" is not a visual thing, it has no concept of "highlight", it should be some UI. What is it? There is no anything predefined which shows the folders and files, even if standard Shell API is used.

Now, about "commenting out" and stuff: you should not leave in the code something which you don't understand. Such "ported" code is not the real code yet.

—SA
craigba 25-Apr-15 1:31am    
Hi SA
Yeah, I agree - I am still working though porting the entire project - I just came across this and got stuck...
As I am going I am removing unnecessary code - I am hesitant to just remove code - as I have done this before and messed things up...

It seems that whatever folder I am in in Windows Explorer when I run the app and it gets focus, seems to highlight all files in that folder...



1 solution

Ok. I got a little bored so I converted the code into VB.net:

VB
Imports System.Collections.Generic
Imports System.IO
Imports System.Linq
Imports System.Runtime.CompilerServices
Imports System.Runtime.InteropServices
Imports System.Runtime.InteropServices.ComTypes

Partial Class MainWindow

    Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)
        Main()
    End Sub

    Private Sub Main(Optional ByVal test As Integer = 1)
        '   Dim test = 1
        Select Case test
            Case 0
                Dim mydocs = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
                ShowSelectedInExplorer.FileOrFolder(Path.Combine(mydocs, "Visual Studio 2010"), edit:=True)

                Exit Select

            Case 1
                ShowSelectedInExplorer.FileOrFolder(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile))
                Exit Select

            Case 2
                ShowSelectedInExplorer.FilesOrFolders("C:\Windows\", New List(Of String) From {"Microsoft.NET", "System32", "Setup"})
                Exit Select

            Case 3
                ShowSelectedInExplorer.FilesOrFolders(New List(Of String) From {"C:\Windows\Microsoft.NET", "C:\Windows\System32", "C:\Windows\Setup"})
                Exit Select
        End Select
    End Sub
End Class

NotInheritable Class ShowSelectedInExplorer
    Private Sub New()
    End Sub
    <Flags> _
    Friend Enum SHCONT As UShort
        SHCONTF_CHECKING_FOR_CHILDREN = &H10
        SHCONTF_FOLDERS = &H20
        SHCONTF_NONFOLDERS = &H40
        SHCONTF_INCLUDEHIDDEN = &H80
        SHCONTF_INIT_ON_FIRST_NEXT = &H100
        SHCONTF_NETPRINTERSRCH = &H200
        SHCONTF_SHAREABLE = &H400
        SHCONTF_STORAGE = &H800
        SHCONTF_NAVIGATION_ENUM = &H1000
        SHCONTF_FASTITEMS = &H2000
        SHCONTF_FLATLIST = &H4000
        SHCONTF_ENABLE_ASYNC = &H8000
    End Enum

    <ComImport, Guid("000214E6-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), ComConversionLoss> _
    Friend Interface IShellFolder
        <MethodImpl(MethodImplOptions.InternalCall, MethodCodeType:=MethodCodeType.Runtime)> _
        Sub ParseDisplayName(hwnd As IntPtr, <[In], MarshalAs(UnmanagedType.[Interface])> pbc As IBindCtx, <[In], MarshalAs(UnmanagedType.LPWStr)> pszDisplayName As String, <Out> ByRef pchEaten As UInteger, <Out> ByRef ppidl As IntPtr, <[In], Out> ByRef pdwAttributes As UInteger)
        <PreserveSig> _
        <MethodImpl(MethodImplOptions.InternalCall, MethodCodeType:=MethodCodeType.Runtime)> _
        Function EnumObjects(<[In]> hwnd As IntPtr, <[In]> grfFlags As SHCONT, <MarshalAs(UnmanagedType.[Interface])> ByRef ppenumIDList As IEnumIDList) As Integer

        <PreserveSig> _
        <MethodImpl(MethodImplOptions.InternalCall, MethodCodeType:=MethodCodeType.Runtime)> _
        Function BindToObject(<[In]> pidl As IntPtr, <[In], MarshalAs(UnmanagedType.[Interface])> pbc As IBindCtx, <[In]> ByRef riid As Guid, <Out, MarshalAs(UnmanagedType.[Interface])> ByRef ppv As IShellFolder) As Integer

        <MethodImpl(MethodImplOptions.InternalCall, MethodCodeType:=MethodCodeType.Runtime)> _
        Sub BindToStorage(<[In]> ByRef pidl As IntPtr, <[In], MarshalAs(UnmanagedType.[Interface])> pbc As IBindCtx, <[In]> ByRef riid As Guid, ByRef ppv As IntPtr)

        <MethodImpl(MethodImplOptions.InternalCall, MethodCodeType:=MethodCodeType.Runtime)> _
        Sub CompareIDs(<[In]> lParam As IntPtr, <[In]> ByRef pidl1 As IntPtr, <[In]> ByRef pidl2 As IntPtr)

        <MethodImpl(MethodImplOptions.InternalCall, MethodCodeType:=MethodCodeType.Runtime)> _
        Sub CreateViewObject(<[In]> hwndOwner As IntPtr, <[In]> ByRef riid As Guid, ByRef ppv As IntPtr)

        <MethodImpl(MethodImplOptions.InternalCall, MethodCodeType:=MethodCodeType.Runtime)> _
        Sub GetAttributesOf(<[In]> cidl As UInteger, <[In]> apidl As IntPtr, <[In], Out> ByRef rgfInOut As UInteger)


        <MethodImpl(MethodImplOptions.InternalCall, MethodCodeType:=MethodCodeType.Runtime)> _
        Sub GetUIObjectOf(<[In]> hwndOwner As IntPtr, <[In]> cidl As UInteger, <[In]> apidl As IntPtr, <[In]> ByRef riid As Guid, <[In], Out> ByRef rgfReserved As UInteger, ByRef ppv As IntPtr)

        <MethodImpl(MethodImplOptions.InternalCall, MethodCodeType:=MethodCodeType.Runtime)> _
        Sub GetDisplayNameOf(<[In]> ByRef pidl As IntPtr, <[In]> uFlags As UInteger, ByRef pName As IntPtr)

        <MethodImpl(MethodImplOptions.InternalCall, MethodCodeType:=MethodCodeType.Runtime)> _
        Sub SetNameOf(<[In]> hwnd As IntPtr, <[In]> ByRef pidl As IntPtr, <[In], MarshalAs(UnmanagedType.LPWStr)> pszName As String, <[In]> uFlags As UInteger, <Out> ppidlOut As IntPtr)
    End Interface

    <ComImport, Guid("000214F2-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
    Friend Interface IEnumIDList
        <PreserveSig> _
        <MethodImpl(MethodImplOptions.InternalCall, MethodCodeType:=MethodCodeType.Runtime)> _
        Function [Next](celt As UInteger, rgelt As IntPtr, ByRef pceltFetched As UInteger) As Integer

        <PreserveSig> _
        <MethodImpl(MethodImplOptions.InternalCall, MethodCodeType:=MethodCodeType.Runtime)> _
        Function Skip(<[In]> celt As UInteger) As Integer

        <PreserveSig> _
        <MethodImpl(MethodImplOptions.InternalCall, MethodCodeType:=MethodCodeType.Runtime)> _
        Function Reset() As Integer

        <PreserveSig> _
        <MethodImpl(MethodImplOptions.InternalCall, MethodCodeType:=MethodCodeType.Runtime)> _
        Function Clone(<MarshalAs(UnmanagedType.[Interface])> ByRef ppenum As IEnumIDList) As Integer
    End Interface

    Private Class NativeMethods
        Shared ReadOnly pointerSize As Integer = Marshal.SizeOf(GetType(IntPtr))

        <DllImport("ole32.dll", EntryPoint:="CreateBindCtx")> _
        Public Shared Function CreateBindCtx_(reserved As Integer, ByRef ppbc As IBindCtx) As Integer
        End Function

        Public Shared Function CreateBindCtx() As IBindCtx
            Dim result As IBindCtx = Nothing
            Marshal.ThrowExceptionForHR(CreateBindCtx_(0, result))
            Return result
        End Function

        <DllImport("shell32.dll", EntryPoint:="SHGetDesktopFolder", CharSet:=CharSet.Unicode, SetLastError:=True)> _
        Friend Shared Function SHGetDesktopFolder_(<MarshalAs(UnmanagedType.[Interface])> ByRef ppshf As IShellFolder) As Integer
        End Function

        Public Shared Function SHGetDesktopFolder() As IShellFolder
            Dim result As IShellFolder = Nothing
            Marshal.ThrowExceptionForHR(SHGetDesktopFolder_(result))
            Return result
        End Function

        <DllImport("shell32.dll", EntryPoint:="SHOpenFolderAndSelectItems")> _
        Private Shared Function SHOpenFolderAndSelectItems_(<[In]> pidlFolder As IntPtr, cidl As UInteger, <[In], [Optional]> apidl As IntPtr, dwFlags As Integer) As Integer
        End Function

        Public Shared Sub SHOpenFolderAndSelectItems(pidlFolder As IntPtr, cidl As UInteger, apidl As IntPtr, dwFlags As Integer)
            Dim result = NativeMethods.SHOpenFolderAndSelectItems_(pidlFolder, cidl, apidl, dwFlags)
            Marshal.ThrowExceptionForHR(result)
        End Sub

        <DllImport("shell32.dll", CharSet:=CharSet.Unicode)> _
        Public Shared Function ILCreateFromPath(<[In], MarshalAs(UnmanagedType.LPWStr)> pszPath As String) As IntPtr
        End Function

        <DllImport("shell32.dll")> _
        Public Shared Sub ILFree(<[In]> pidl As IntPtr)
        End Sub
    End Class

    Private Shared Sub SHOpenFolderAndSelectItems(pidlFolder As IntPtr, apidl As ICollection(Of IntPtr), edit As Boolean)
        Dim array As IntPtr = IntPtr.Zero
        Dim itemCount As UInteger = 0
        Try
            If apidl IsNot Nothing AndAlso apidl.Count > 0 Then
                itemCount = CUInt(apidl.Count)
                array = Marshal.AllocHGlobal(pointerSize * apidl.Count)

                Dim i = 0
                For Each filePIDL In apidl
                    Marshal.WriteIntPtr(array, i * pointerSize, filePIDL)
                    i += 1
                Next
            End If

            NativeMethods.SHOpenFolderAndSelectItems(pidlFolder, itemCount, array, If(edit, 1, 0))
        Finally
            Marshal.FreeHGlobal(array)
        End Try
    End Sub

    Private Shared Function GetShellFolderChildrenRelativePIDL(parentFolder As IShellFolder, displayName As String) As IntPtr
        Dim bindCtx = NativeMethods.CreateBindCtx()

        Dim pchEaten As UInteger
        Dim pdwAttributes As UInteger = 0
        Dim ppidl As IntPtr
        parentFolder.ParseDisplayName(IntPtr.Zero, Nothing, displayName, pchEaten, ppidl, pdwAttributes)

        Return ppidl
    End Function

    Private Shared Function PathToAbsolutePIDL(path As String) As IntPtr
        Dim desktopFolder = NativeMethods.SHGetDesktopFolder()
        Return GetShellFolderChildrenRelativePIDL(desktopFolder, path)
    End Function

    Shared IID_IShellFolder As Guid = GetType(IShellFolder).GUID
    Shared pointerSize As Integer = Marshal.SizeOf(GetType(IntPtr))

    Private Shared Function PIDLToShellFolder(parent As IShellFolder, pidl As IntPtr) As IShellFolder
        Dim folder As IShellFolder = Nothing
        Dim result = parent.BindToObject(pidl, DirectCast(Nothing, IBindCtx), IID_IShellFolder, folder)
        Marshal.ThrowExceptionForHR(CInt(result))
        Return folder
    End Function

    Private Shared Function PIDLToShellFolder(pidl As IntPtr) As IShellFolder
        Return PIDLToShellFolder(NativeMethods.SHGetDesktopFolder(), pidl)
    End Function

    Public Shared Sub FileOrFolder(path As String, Optional edit As Boolean = False)
        If path Is Nothing Then
            Throw New ArgumentNullException("path")
        End If

        Dim pidl = PathToAbsolutePIDL(path)
        Try
            SHOpenFolderAndSelectItems(pidl, Nothing, edit)
        Finally
            NativeMethods.ILFree(pidl)
        End Try
    End Sub

    Private Shared Function PathToFileSystemInfo(paths As IEnumerable(Of String)) As IEnumerable(Of FileSystemInfo)

        Dim result As New List(Of FileSystemInfo)
        For Each path As String In paths
            If Directory.Exists(path) Then
                result.Add(New DirectoryInfo(path))
            Else
                result.Add(New FileInfo(path))
            End If
        Next
        Return result
    End Function

    Public Shared Sub FilesOrFolders(parentDirectory As String, filenames As ICollection(Of String))
        If filenames Is Nothing Then
            Throw New ArgumentNullException("filenames")
        End If
        If filenames.Count = 0 Then
            Return
        End If

        Dim parentPidl = PathToAbsolutePIDL(parentDirectory)
        Try
            Dim parent = PIDLToShellFolder(parentPidl)

            Dim filesPidl As New List(Of IntPtr)(filenames.Count)
            For Each filename As String In filenames
                filesPidl.Add(GetShellFolderChildrenRelativePIDL(parent, filename))
            Next

            Try
                SHOpenFolderAndSelectItems(parentPidl, filesPidl, False)
            Finally
                For Each pidl As IntPtr In filesPidl
                    NativeMethods.ILFree(pidl)
                Next
            End Try
        Finally
            NativeMethods.ILFree(parentPidl)
        End Try
    End Sub

    Public Shared Sub FilesOrFolders(paths As IEnumerable(Of String), Optional showOnDesktop As Boolean = False)
        FilesOrFolders(PathToFileSystemInfo(paths), showOnDesktop)
    End Sub

    Public Shared Sub FilesOrFolders(paths As IEnumerable(Of FileSystemInfo), Optional showOnDesktop As Boolean = False)
        If paths Is Nothing Then
            Throw New ArgumentNullException("paths")
        End If
        If paths.Count() = 0 Then
            Return
        End If

        Dim parentDirectories = paths.[Select](Function(p) Path.GetDirectoryName(p.FullName))
        Dim parentDirectory = parentDirectories.First()
        Dim otherDirectories = parentDirectories.Skip(1)
        If otherDirectories.Any(Function(p) p <> parentDirectory) Then
            Throw New ArgumentException("At least one path is not in the same directory as the others", "paths")
        End If

        FilesOrFolders(parentDirectory, paths.[Select](Function(fsi) fsi.Name).ToList())
    End Sub
End Class


I have tested it, adn it seems to work as you desire. The original C# code could be found here:
https://gist.github.com/551626/680a8d371b7c693e4fea5a9c915229c89f4b1e1b[^]
 
Share this answer
 
Comments
craigba 26-Apr-15 0:02am    
@Kenneth: Thanks, but it looks like yours is written in VS 2010 my project is currently 2005 (There's 18 errors preventing me from compiling). Thanks for helping out though.
Kenneth Haugland 26-Apr-15 0:41am    
Found another one, not sure if it will help you, but that worked right:
http://www.pinvoke.net/default.aspx/shell32/SHOpenFolderAndSelectItems.html

I think this is the only way to go other then using Proccess.Start() etc.
craigba 26-Apr-15 0:48am    
Thanks again Kenneth, but I'm not too sure that will help me (I found the same page before posting here like a good asker ;)
My problem is the first time my app runs (if i go to windows explorer whilst waiting for it to load), then it goes to the first file, the second time (if the first file is already highlighted, it highlights all files in that folder?

Unless with this code, I force a "deselect"?
Kenneth Haugland 26-Apr-15 12:49pm    
In my case it just selects the files you specify. Everything else is deselected.
craigba 2-May-15 2:27am    
Hey everyone,

I found the problem - after going back to the vb6 project and removing everything except for the 5 modules needed to startup and I eventually tracked the problem.

There was some code being called when two edit boxes received focus which called send keys home and end - hence it would go home - select all files to the end. I had deactivated one of the edit boxes to not receive focus and it helped temporarily(obviously until the other box got focus), but since deactivating the send keys when they get focus has helped. Albeit an arbitrary problem, maybe it will help someone in the future..

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900