.netPlus / Samples / VB

 

SHFileOperation

VBBubble screenshot

 

Filename: shfileop.zip
Last update: 04/28/01
Size: 15 kb

 

Overview
There are *lots* of examples of how to use the SHFileOperation API from VB available already. A search on CodeHound currently gives you more than 100 hits. So why another one?

First, you have to know that there's a problem with the SHFILEOPSTRUCT structure used with this API. It's designed to have byte aligned members, rather than DWORD aligned that VB wants. Some examples simply ignore this and don't deal with the members affected by the problem. Other deals with it by using CopyMemory to move the data to the offset where VB wants it. Neither is ideal IMO, since VB *does* support non-DWORD aligned structures. You just have to declare them in a type library, which is how it's done in this example.

Also, few examples (if any) demonstrates how to (correctly) handle the hNameMappings member and the related SHNAMEMAPPING structure, which can be more tricky than it appears (because of poor documentation). This example does.

 

Details
If you don't know anything about ODL/IDL, I suggest you read the article Extending Visual Basic with C++ DLLs (at least chapter 1 of it) by Bruce McKinney.

MIDL lets you control the alignment of a structure members (aka packing) with the pack pragma. For the SHFILEOPSTRUCT structure, it looks like this

#pragma pack(push, 1)
typedef struct SHFILEOPSTRUCT {
  long hwnd;
  long wFunc;
  long pFrom;
  long pTo;
  FILEOP_FLAGS fFlags;
  long fAnyOperationsAborted;
  long hNameMappings;
  long lpszProgressTitle;
} SHFILEOPSTRUCT, *LPSHFILEOPSTRUCT;
#pragma pack(pop)

The only bad thing about declaring SHFILEOPSTRUCT in a type library is that you can't declare the string members (pFrom, pTo and lpszProgressTitle) as strings (LPTSTR). VB wont accept that, so you have to type it as long and do a little extra work in the calling code instead.

Like I said above, the documentation for the hNameMappings member isn't very good. hNameMappings should be treated as a pointer to a memory block that looks like this

Type NAMEMAP_INFO
  nMappings As Long
  pMappings As Long
End Type

NAMEMAP_INFO is not a standard API structure, it's one I made up myself for easy access to the members. The pMappings member is a pointer to an array of SHNAMEMAPPING structures. There are nMappings elements in the array. The string pointers in the SHNAMEMAPPING structures point to ANSI strings on Windows 9x/Me, and Unicode strings on Windows NT/2000/XP. It doesn't matter if you call the ANSI or Unicode version of SHFileOperation.

 

See also
How to Copy or Move an Entire Directory using the API
Utilizing Windows SHFileOperation API, Advanced

 

©2000-2024, .netPlus