Solved

Determining files selected from Explorer

Posted on 2000-04-17
16
261 Views
Last Modified: 2012-08-13
I am looking for a way to determine what files have been selected from Windows Explorer.

For example, I would like to be able to select a range of files, right click, and from the Menu options, choose my application and fill a list box with the selected files.

Creating the context menu to launch my app is not a problem (by just making the appropriate "command" entry in the HKEY_CLASSES_ROOT registry key), but the problem is how do you know what is selected from Explorer?

If you do a drag and drop, you can just use the data object to iterate the files.  With no drag though, how can can you get this info out the operating system?

I think this might involve some serious APIs so how about 300 points?
0
Comment
Question by:carpbyte
  • 5
  • 4
  • 3
  • +2
16 Comments
 
LVL 14

Accepted Solution

by:
wsh2 earned 150 total points
ID: 2725782
1. Start a new Standard.Exe project
2. Copy and Paste the following into the Form1 code window.
3. Press F5 to run. A blank Form1 will appear on the screen. Open Windows Explorer and Copy some files to the clipboard. Click anywhere on Form1 and you will get a message as to how many Files are on the clipboard.. AND.. the IDE immediate window will be populated with the file names.
4. <smile>

<----- Code Begin ----->

Option Explicit

Private Const CF_HDROP = 15&
Private Declare Function CloseClipboard Lib "USER32" _
   () As Long
Private Declare Function DragQueryFile Lib "shell32.dll" Alias "DragQueryFileA" _
   (ByVal hDrop As Long, ByVal UINT As Long, ByVal lpStr As String, ByVal ch As Long) _
   As Long
Private Declare Function GetClipboardData Lib "USER32" _
   (ByVal wFormat As Long) _
   As Long
Private Declare Function IsClipboardFormatAvailable Lib "USER32" _
    (ByVal wFormat As Long) As Long
Private Declare Function OpenClipboard Lib "USER32" _
   (ByVal hWnd As Long) As Long

Private Sub Form_Click()

   Dim lngFileCount As Long
   Dim strFileNames() As String
   Dim lngIndex As Long
   If xGetClipboardFileList(strFileNames(), lngFileCount) _
   Then
      MsgBox (lngFileCount & " Files are on the Clipboard")
      For lngIndex = LBound(strFileNames) To UBound(strFileNames)
         Debug.Print strFileNames(lngIndex)
      Next lngIndex
   Else
      MsgBox ("No files are on the clipboard")
   End If
   
End Sub

Public Function xGetClipboardFileList _
(ByRef strFileNames() As String, _
ByRef lngFileCount As Long) _
As Boolean

   Dim strFileName As String
   Dim lngIndex As Long
   Dim lngNull As Long
   Dim lngReturn As Long
   
'  Is data available
   lngReturn = IsClipboardFormatAvailable(CF_HDROP)
   If lngReturn = 0 _
   Then
      Exit Function
   End If
   
'  Open the clipboard:
   lngReturn = OpenClipboard(0&)
   If lngReturn <= 0 _
   Then
      Exit Function
   End If
   
   ' Get handle to CF_HDROP if any:
   lngReturn = GetClipboardData(CF_HDROP)
   If lngReturn = 0 _
   Then
      GoTo Tag999
   End If
   
   lngFileCount = DragQueryFile(lngReturn, -1&, "", 0)
   If lngFileCount <= 0 _
   Then
      GoTo Tag999
   End If
   
   ' Allocate space for return and working variables.
   ReDim strFileNames(1 To lngFileCount) As String
   strFileName = String$(255, 0)
   
   ' Retrieve each filename in Dropped Filelist.
   For lngIndex = 1 To lngFileCount
      DragQueryFile lngReturn, lngIndex - 1, strFileName, Len(strFileName)
      lngNull = InStr(strFileName, vbNullChar)
      If (lngNull <> 0) Then
         strFileNames(lngIndex) = Left$(strFileName, lngNull - 1)
      Else
         strFileNames(lngIndex) = strFileName
      End If
   Next lngIndex
   
   xGetClipboardFileList = True
   
Tag999:
       
   CloseClipboard

End Function

<----- Code End ----->


0
 
LVL 43

Expert Comment

by:TimCottee
ID: 2725795
Ok, this is both simple and complex.

The simple part:

The file name selected in explorer is passed as a parameter to the application you specify in your "command" entry. Therefore you can parse the Command() in VB to get the file name.

The complex part:

Depends on how you see it. If you select multiple files, an instance of your application is opened for each file, you would need to determine whether your app was already running using app.Previnstance and if so pass the filename received by this instance to the original one.

0
 
LVL 43

Expert Comment

by:TimCottee
ID: 2725837
Try this, project and form file in text. Create executable TF.exe, this does as I described, if there is an existing instance of tf, it uses DDE to send the filename to the original instance leaving you with a list box containing the files selected in explorer.

TF.VBP

Type=Exe
Form=frmListFiles.frm
Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#C:\WINNT\System32\StdOle2.Tlb#OLE Automation
IconForm="frmListFiles"
Startup="frmListFiles"
HelpFile=""
Title="TF"
ExeName32="TF.exe"
Command32=""
Name="TF"
HelpContextID="0"
CompatibleMode="0"
MajorVer=1
MinorVer=0
RevisionVer=0
AutoIncrementVer=0
ServerSupportFiles=0
VersionCompanyName="TopCat"
VersionFileDescription="TF"
VersionProductName="TF"
CompilationType=0
OptimizationType=0
FavorPentiumPro(tm)=0
CodeViewDebugInfo=0
NoAliasing=0
BoundsCheck=0
OverflowCheck=0
FlPointCheck=0
FDIVCheck=0
UnroundedFP=0
StartMode=0
Unattended=0
Retained=0
ThreadPerObject=0
MaxNumberOfThreads=1

frmListFiles.frm

VERSION 5.00
Begin VB.Form frmListFiles
   Caption         =   "Form1"
   ClientHeight    =   3195
   ClientLeft      =   60
   ClientTop       =   345
   ClientWidth     =   4680
   LinkMode        =   1  'Source
   LinkTopic       =   "Master"
   ScaleHeight     =   3195
   ScaleWidth      =   4680
   StartUpPosition =   3  'Windows Default
   Begin VB.TextBox txtNewFile
      Height          =   495
      Left            =   2880
      LinkItem        =   "txtFile"
      LinkTopic       =   "TF|Master"
      TabIndex        =   2
      Text            =   "Text1"
      Top             =   1320
      Visible         =   0   'False
      Width           =   1575
   End
   Begin VB.TextBox txtFile
      Height          =   495
      Left            =   2880
      TabIndex        =   1
      Text            =   "Text1"
      Top             =   480
      Visible         =   0   'False
      Width           =   1575
   End
   Begin VB.ListBox List1
      Height          =   2790
      Left            =   240
      TabIndex        =   0
      Top             =   120
      Width           =   2415
   End
End
Attribute VB_Name = "frmListFiles"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Dim strCommand As String

Private Sub Form_Load()
    strCommand = Command()
    If App.PrevInstance Then
        LinkTopic = "NOTMASTER"
        PokeFileToPrev
        End
    End If
    List1.AddItem strCommand
End Sub

Private Sub txtFile_Change()
    List1.AddItem txtFile.Text
End Sub

Private Sub PokeFileToPrev()
    txtNewFile.Text = strCommand
    txtNewFile.LinkMode = vbLinkManual
    txtNewFile.LinkPoke
End Sub

Private Sub txtFile_LinkNotify()
    List1.AddItem txtFile.Text
End Sub


0
 
LVL 14

Expert Comment

by:wsh2
ID: 2725971
Tim:
If he doesn't have NT.. this could be a problem:

Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#C:\WINNT\System32\StdOle2.Tlb#OLE Automation

0
 
LVL 43

Expert Comment

by:TimCottee
ID: 2725977
True, but then just change the directory to the correct location for StdOle2.Tlb or remove this line before opening the project and add back the reference from the references dialog.

Thanks though for pointing it out, I didn't see that!
0
 

Author Comment

by:carpbyte
ID: 2727164
Combined, these two solutions are pretty much what I'm looking for.

Split the points?

0
 
LVL 14

Expert Comment

by:wsh2
ID: 2727664
If TimCottee agrees, splitting points is fine by me.. <smile>.
0
 
LVL 14

Expert Comment

by:wsh2
ID: 2727685
Just so you know, to split points..
Ask support to reduce the points on the current question, then allocate the additional points to a targeted Question to the party you want to receive them. (Eg. Question Subject = "For TimCottee" or "Wsh2".. <blush>). Here is the link for Customer Service.

http://www.experts-exchange.com/Customer_Service/Experts_Exchange/

0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:carpbyte
ID: 2729232
Thanks for the info.

I'll award the points shortly.

CarpByte.
0
 
LVL 2

Expert Comment

by:bhamilto
ID: 2729255
There is a totally different solution using the Windows event hook and the Accessibility DLL (oleacc.dll) if you are interested.

1) Advantages:
- Uses the event hook so is totally assynchronous.  For example, a running VB program can detect when explorer files are selected or unselected and get file names using oleacc.dll.  This can be an invisible background process if you wish.
- The same approach can be used to detect/identify a broad range of events in any process or set of processes (e.g. focus changes, menu selection, etc., etc.)
- Works with Win 9x, NT4 or later

2) Disadvantages:
- Requires oleacc.dll (about 150K)

If you want to start an app with explorer file names as parameters then the wsh2/TimCottee solution is great.  I won't elaborate on this unless it suits your needs better than the solution offered.

Good luck - Bob Hamilton
0
 
LVL 14

Expert Comment

by:wsh2
ID: 2729355
bhamilto:
OLEACC.DLL.. Hmmmm.. never looked at (or thought of) that before. From what I just briefly scanned on this.. it seems that MS has been quietly using OLEACC to add functionality to its products as well (ie. Office).

Welp.. thanks to you, I'll have plenty to read when I go to bed tonight.. THANK YOU for a very intriguing tip and then HEAVY (it needs a Redistribution kit.. <sheesh>) eyed sleep.. <smile>.
0
 
LVL 2

Expert Comment

by:bhamilto
ID: 2729403
wsh2

Its not that MS is keeping it secret.  The problem is that it comes under the "Accessibility" umbrella so who would think to look for this sort of functionallity there?  Somebody here on EE answered a similar question I had a few months back with this general solution.  It works great - you can do things that would otherwise require expensive 3rd party software like Desawares SpyWorks.

Most MS and a lot of 3rd party software supports it although you can't get much detail form VB5 apps.

The other disadvantage that I forgot to mention is that there is a lot to read (as you'll soon find out).  Its actually quite easy to use and the samples are easy to follow.  The VB samples use (the non-event driven) "AccessibleObjectFromPoint" API, but I had no problem converting a C sample to use the event hook and "AccessibleObjectFromEvent"

Happy dreams - Bob Hamilton
0
 

Author Comment

by:carpbyte
ID: 2729456
Thank you for the additional info. As I am always open to an education, if you have a workable code sample solution, I'll be more than happy to "rephrase" the question as a new one and thereby "open it".

As I have already agreed to the initial wsh2/TimCottee solutions I'd like to be sure they get their points first.

Thanks.

Carpbyte.

0
 
LVL 3

Expert Comment

by:darinw
ID: 2731681
Community Support has reduced points from 300 to 150
0
 
LVL 3

Expert Comment

by:darinw
ID: 2731682
Hi carpbyte,

I have reduced the points on this question to one half. Please accept one of the Experts comments as an answer. Remember, the Accept Comment as Answer button is in the header of the comment.

For the second Expert, post a question in this topic area. The new question title should be 'For ExpertName - 10330014'.

For your convenience, you can use this link to create the new question:

http://www.experts-exchange.com/bin/NewQForm?ta=31

darinw
Customer Service
0
 

Author Comment

by:carpbyte
ID: 2733243
Thanks for the code & splitting the points.

carpbyte.
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

When designing a form there are several BorderStyles to choose from, all of which can be classified as either 'Fixed' or 'Sizable' and I'd guess that 'Fixed Single' or one of the other fixed types is the most popular choice. I assume it's the most p…
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now