-
Oct 20th, 2020, 11:08 PM
#1
Thread Starter
Lively Member
How to set the Explorer window of a specific file as a child window of TopMost form?
Hi, as title says, How can I set the explorer windows of a specifi file as a child window of my TopMost form?
I've been reading online and I found out I should call SetParent function https://docs.microsoft.com/en-us/win...user-setparent but I can't find examples for my case, as they are for calculator or notepad.
I'm opening the explorer window with the answer code in : https://www.vbforums.com/showthread....20#post5497520
I'm using a helper class:
Code:
Imports System.IO
Imports System.Runtime.InteropServices
Public Class NativeMethods
<DllImport("shell32.dll", SetLastError:=True)>
Private Shared Function SHOpenFolderAndSelectItems(
pidlFolder As IntPtr, cidl As UInteger,
<[In], MarshalAs(UnmanagedType.LPArray)> apidl As IntPtr(),
dwFlags As UInteger) As Integer
End Function
<DllImport("shell32.dll", SetLastError:=True)>
Private Shared Sub SHParseDisplayName(
<MarshalAs(UnmanagedType.LPWStr)> name As String,
bindingContext As IntPtr, <Out> ByRef pidl As IntPtr,
sfgaoIn As UInteger, <Out> ByRef psfgaoOut As UInteger)
End Sub
Public Shared Sub OpenFolderAndSelectFile(filePath As String)
Dim dirPath As String = Path.GetDirectoryName(filePath)
Dim fileName As String = Path.GetFileName(filePath)
OpenFolderAndSelectFile(dirPath, fileName)
End Sub
Public Shared Sub OpenFolderAndSelectFile(dirPath As String, fileName As String)
Dim nativeFolder As IntPtr
Dim psfgaoOut As UInteger
SHParseDisplayName(dirPath, IntPtr.Zero, nativeFolder, 0, psfgaoOut)
If nativeFolder = IntPtr.Zero Then
' Log error, can't find folder
Return
End If
Dim nativeFile As IntPtr
SHParseDisplayName(Path.Combine(dirPath, fileName),
IntPtr.Zero, nativeFile, 0, psfgaoOut)
Dim fileArray As IntPtr()
If nativeFile = IntPtr.Zero Then
' Open the folder without the file selected if we can't find the file
fileArray = New IntPtr(-1) {}
Else
fileArray = New IntPtr() {nativeFile}
End If
SHOpenFolderAndSelectItems(nativeFolder, CUInt(fileArray.Length), fileArray, 0)
Marshal.FreeCoTaskMem(nativeFolder)
If nativeFile <> IntPtr.Zero Then
Marshal.FreeCoTaskMem(nativeFile)
End If
End Sub
End Class
On main form:
Code:
Private Async Function ParentMethod() As Task
filePath = Await Task.Run(
Function()
Return Directory.EnumerateFiles(My.Settings.Cartellasalvataggio, titolo & ".mp3",
SearchOption.AllDirectories).FirstOrDefault()
End Function)
End Function
And finally I'm calling it with:
Code:
NativeMethods.OpenFolderAndSelectFile(filePath)
Thanks!!
Last edited by matty95srk; Oct 20th, 2020 at 11:20 PM.
-
Oct 20th, 2020, 11:25 PM
#2
Re: How to set the Explorer window of a specific file as a child window of TopMost fo
Originally Posted by matty95srk
I can't find examples for my case, as they are for calculator or notepad.
A lot of people don't really seem to understand what the word "example" means. An example is something that demonstrates a principle that you can then implement for yourself in other scenarios. The principle is the same no matter what window you are trying to parent so you already have relevant examples. You need to get the handle of the child window and then pass it to SetParent. That's it, that's all. When you say:
I can't find examples for my case
you're not really talking about an example. You're talking about a turnkey solution that you can copy. Software development is all about understanding principles and then applying them in varying scenarios. It's time for you to do some software development.
If what you are actually having trouble with is getting the handle of a specific window then that's the question you should actually be asking. How do they get the child window handle in the examples you've seen? Why can't you do basically the same thing with your child window? If you really can't, have you investigated other means to obtain that specific window handle? Etc.
-
Oct 20th, 2020, 11:27 PM
#3
Re: How to set the Explorer window of a specific file as a child window of TopMost fo
So where exactly in that code is the problem? Do you understand what it's doing? Where exactly does what it does differ from what you expect in your specific case? That's the sort of information that you need to include in a full and clear explanation of a problem.
-
Oct 20th, 2020, 11:47 PM
#4
Thread Starter
Lively Member
Re: How to set the Explorer window of a specific file as a child window of TopMost fo
Hi, you are right, I should atleast post what I've done/found in order to clarify I'm trying to move myself .
So, I noticed that the way you are creating a process is influencing the way I should try to set the explorer window on top .
For example for a process created with CreateProcess I can use STARTUPINFO structure which is passed in with CreateProcess and set SW_SHOW.
https://stackoverflow.com/questions/...-createprocess
For a process created with Process class, I have to use P/Invoke with SetWindowPos as https://stackoverflow.com/questions/...-window-handle or Process.MainWindowHandle.
In my case, I am not really sure which way the class is creating the process, so I'm struggling with this and also how to get the handle of a specific window as a consequence.
Thanks
-
Oct 20th, 2020, 11:56 PM
#5
Re: How to set the Explorer window of a specific file as a child window of TopMost fo
You're likely not going to be able to get the window handle via a process, or not in all cases anyway. Windows/File Explorer has an option "Launch folder windows in a separate process" but I don't think that it is on by default. Even when it is, I'm not sure whether an explorer process would return a value for MainWindowHandle. You may have to use the FindWindow API to find the specific window you want.
-
Oct 21st, 2020, 12:29 AM
#6
Thread Starter
Lively Member
Re: How to set the Explorer window of a specific file as a child window of TopMost fo
Hmm is getting harder than i thought.
What do you think about
Code:
Imports System.Runtime.InteropServices
Public Class Form1
<DllImport("user32.dll", EntryPoint:="FindWindowW")>
Public Shared Function FindWindowW(<MarshalAs(UnmanagedType.LPTStr)> ByVal lpClassName As String, <MarshalAs(UnmanagedType.LPTStr)> ByVal lpWindowName As String) As IntPtr
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim hWnd As IntPtr = FindWindowW("TheClassName", Nothing)
If hWnd <> IntPtr.Zero Then
'do whatever you need with the window handle....
End If
End Sub
End Class
But i think i still need to find the classname, which is changing for every specific file explorer windows..
Otherwise I must think about a workaround like :
If user click linklabel then main form topmost false until user mouse is on top of the main form.
What do you think?
-
Oct 21st, 2020, 12:41 AM
#7
Re: How to set the Explorer window of a specific file as a child window of TopMost fo
Without having looked, I believe that you can find a window by the text in the title bar too.
-
Oct 21st, 2020, 06:41 AM
#8
Thread Starter
Lively Member
Re: How to set the Explorer window of a specific file as a child window of TopMost fo
Hi thanks for your answer. So I ve been searching online but seriously a lot of codes are for process class...
Could you give me an qwery advise?
I found this which is the most interesting to me but still using process class
https://social.msdn.microsoft.com/Fo...orum=vbgeneral
-
Oct 21st, 2020, 03:02 PM
#9
Thread Starter
Lively Member
Re: How to set the Explorer window of a specific file as a child window of TopMost fo
Hi jmcilhinney, I made some research, but I can't find something really "interesting".. And following you advise "An example is something that demonstrates a principle that you can then implement for yourself in other scenarios. " then I tried my best to find any kind of documentation or questions that are closest to my case as following:
How to find main window title name of application
how to get the window title of a process
How to get the Title Bar Text by its Process Id
Get the name of a process
How do I get list of Process Names running
Check to see if process is running
How To Get Process Owner ID
How to get the title/name of the last active window?
Get Process ID from Window Title
and also
and also Process.GetProcessesByName Method
Since I am opening the process as the code in my first post and not with Process class, almost all of them are not suitable to be considered for my case as many of them refer to notepad, while I think the explorer window title and ID changes for every file ( obviously), while "notepad" process, stay "notepad".
I also tried BringToFront, but this latter moves a control in front of other controls, but in this case Explorer is not a control, right?
The least I want to do is to
Get a list of active windows & their process names as It will waiste memory and time usage for no reason as then I will need to "filter" process to find my process.
Hope we can find a solution to this, Thanks in advance.
Mattia
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|