Home

File Management

 

Win32 and Files

 

Introduction

Directory and file management consists of creating, copying, moving, deleting, performing various types of operations, or replacing directories and files. To perform these operations, you can use functions from the C/C++ language or from the Win32 library. Some of the functions of the C language are mostly platform independent. The functions of the Win32 library are meant to provide as much functionality and as many features as possible.

Performing an Operation on a File

Microsoft Windows gives you the ability to perform various types of operations on files, including opening, editing, or printing. To perform these operations, one of the functions you can use is named ShellExecute. Its syntax is:

HINSTANCE ShellExecute(
  __in_opt  HWND hwnd,
  __in_opt  LPCTSTR lpOperation,
  __in      LPCTSTR lpFile,
  __in_opt  LPCTSTR lpParameters,
  __in_opt  LPCTSTR lpDirectory,
  __in      INT nShowCmd
);

 

In the following description, we don't present the arguments in the order they appear in the syntax of the function. The reason is that some of these arguments are interelated, or the role of one argument may depend on the value of another argument, not on their positions.

hwnd: The hwnd argument is a handle to the object that called this function. You can pass this argument as Handle or NULL:

ShellExecute(Handle, . . .);

lpFile: The third argument, lpFile, is the name of, or path to, the file on which you want to perform the operation. It can represent a file such as Example.txt:

ShellExecute(Handle, . . ., "Example.txt", . . .);

Or it can be an executable such as write.exe:

ShellExecute(Handle, . . ., "write.exe", . . .);

Or it can be a folder:

ShellExecute(Handle, . . ., "C:\\Exercise", . . .);

The lpFile argument lets the compiler know what file or folder you want to use. You can pass the lpFile argument as just the name of the file or a complete path. If you pass lpFile as a name for the file, the compiler will consider the current directory where your application is located. If the file cannot be found there, the compiler may stop. In some other cases, it would proceed with an algorithm specified by the operating system. For example, it may look in the Documents, the Windows, or the System32 folders. To be safe, you should provide the complete path as the lpFile argument.

lpOperation: The lpOperation argument is called a verb because it specifies the operation, or type of operation, you want to perform on the lpFile argument. This argument is passed as a string. Some of the values this argument can hold are:

  • explore: If you use this verb, you should pass lpFile as the path to a folder and not a file. Here is an example:
    ShellExecute(Handle, "explore", "C:\\Exercise", . . .);
    If you pass lpFile as a folder, the operating system would launch Windows Explorer and display its content. If you pass lpFile as a file or an executable, nothing would happen
  • print: If lpFile represents a file, it would be printed. Otherwise, nothing may happen
  • open: What would happen depends on the value of the lpFile argument:
    • If lpFile represents a file, the operating system will find the application that is configured to open the type of file, at least for viewing. It would launch that application and open the file. For example, if lpFile is passed as a text file such as "Example.txt", the computer would launch Notepad and open the file
      ShellExecute(Handle, "open", "Example.txt", . . .);
    • If lpFile is passed as a file with a graphic file with an extension such as .bmp, .jpg, or gif, the computer would launch the default application used to open graphic files, such as Windows Paint, and open that file
    • If lpFile is passed as a file but with an extension that no application has registered, nothing would happen, or nothing may happen
    • If lpFile is passed as an executable, such as Write.exe, the application would be launched
      ShellExecute(Handle, "open", "Write.exe", . . .);
  • edit: This also depends on the type of value of lpFile:
    • If lpFile represents a computer file, the operating system will launch the application that can be used to edit the file. For example, if lpFile is passed as a text file, the computer would launch the appropriate application and open the file for editing. In most cases, this verb behaves like "open" with some slight differences. For example, some times, for the same type of file, one application can be registered to open the file and another application may be registered to edit the same type of file. For example, if lpFile represents a graphic file and you specify the verb as "edit", the OS will find the application that can be used to edit graphic files, for example Paint Shop Pro or Photoshop, instead of Windows Paint
    •  If lpFile is passed as a file but no application is registered to open the file, nothing would happen
    • If lpFile is passed as an executable, such as Write.exe, nothing would happen
  • NULL: If you pass this argument as NULL, the operating system will consult the registry to get the list of verbs and it would use the default verb depending on the type of value of the lpFile argument. Because the operating system knows most of the time what to do with the ShellExecute() function, you can safely pass the verb as NULL. For example:
    • If lpFile is passed as a file, the OS will look for the application that can open that file
      ShellExecute(Handle, NULL, "Example.txt", . . .);
    • If lpFile is passed as an executable, it would launch
      ShellExecute(Handle, NULL, "Write.exe", . . .);

lpDirectory: As stated already, you can pass the lpFile argument with a complete path. If you do, you can pass the lpDirectory argument as NULL:

ShellExecute(Handle, NULL, "C:\\Exercise\\Example.txt", NULL, . . .);

As an alternative, you can pass the lpFile argument with just a name. Then pass the path without the file for lpDirectory. Here is an example:

ShellExecute(Handle, NULL, "Example.txt", "C:\\Exercise", . . .);

lpParameters: If the lpFile argument represents a file, you should pass this argument as NULL. Here is an example:

ShellExecute(Handle, NULL, "Example.txt", "C:\\Exercise", NULL, . . .);

 If lpFile represents an executable and it needs some parameters to execute, you can pass them in the lpDirectorys placeholder.

nShowCmd: This argument specifies the appearance of the application that will open the file or how Windows Explorer should display to the user. One of the values this argument can hold is SW_SHOWNORMAL. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::btnOpenFileClick(TObject *Sender)
{
	ShellExecute(Handle,
		     "open",
		     "Example.txt",
		     NULL,
		     "C:\\Exercise",
		     SW_SHOWNORMAL);
}
//---------------------------------------------------------------------------

Other possible values are: SW_SHOWDEFAULT, SW_SHOWNORMAL, SW_SHOW, SW_SHOWNA, SW_SHOWNOACTIVATE, SW_HIDE, SW_MAXIMIZE, SW_SHOWMAXIMIZED, SW_MINIMIZE, SW_SHOWMINIMIZED, SW_SHOWMINNOACTIVE, and SW_RESTORE.

An alternative to the ShellExecute() function is to call ShellExecuteEx. Here is an example of calling it:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	SHELLEXECUTEINFO sei;

	sei.cbSize = sizeof(SHELLEXECUTEINFO);
	sei.fMask = SEE_MASK_DEFAULT;
	sei.lpFile = "Example.txt";
	sei.lpDirectory = "C:\\Exercise";
	sei.nShow = SW_SHOWNORMAL;

	ShellExecuteEx(&sei);
}
//---------------------------------------------------------------------------

Creating a File

In Microsoft Windows, the handle of a file is an unsigned integer created and managed by the operating system. The handle is applied to different types of resources and objects but each has its own handle. Before using a file, you must get a handle to it. To get it, you can call the CreateFile() function of the Win32 library. Its syntax is:

HANDLE WINAPI CreateFile(
  __in      LPCTSTR lpFileName,
  __in      DWORD dwDesiredAccess,
  __in      DWORD dwShareMode,
  __in_opt  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  __in      DWORD dwCreationDisposition,
  __in      DWORD dwFlagsAndAttributes,
  __in_opt  HANDLE hTemplateFile
);

Despite its name, this function doesn't really create a file. It only gives you access to it. What you do with the file depends on you.

Writing to a File

One of the operations you can perform on a file consists of writing one or more values to it. To let you do this, the Win32 library provides the WriteFile() function that uses the following syntax:

BOOL WINAPI WriteFile(
  __in         HANDLE hFile,
  __in         LPCVOID lpBuffer,
  __in         DWORD nNumberOfBytesToWrite,
  __out_opt    LPDWORD lpNumberOfBytesWritten,
  __inout_opt  LPOVERLAPPED lpOverlapped
);

The equivalent function in Object Pascal is named FileWrite.

Opening a File

If want to use an existing file, you can first open it. To let you do this, you can call the OpenFile() function of Win32. Its syntax is:

HFILE WINAPI OpenFile(
  __in   LPCSTR lpFileName,
  __out  LPOFSTRUCT lpReOpenBuff,
  __in   UINT uStyle
);

The equivalent function in Object Pascal is FileOpen.

Reading From a File

After opening a file, if you want to read its values, you can call the ReadFile() function. Its syntax appears as:

Closing a Handle

After using a file, to close it, you can call the CloseHandle() function.

File Information

  

Introduction

In its latest release, the VCL has done a tremendously job in the area of file processing. It now provides three wonderful classes in the IOUtils.hpp header file. These are the TDirectory, the TFile, and the TPath classes. All these are static classes in the modern sense of the word (C++ doesn't have a formal concept of a static class; in other languages such as C#, a static class is a class whose all methods are static, meaning you don't declare a variable to access the members of that class, instead you use the :: operator applied to the name of the class). These three class support all types of operations performed on files, their names, and their paths.

The TFileName Data Type

To identify a variable for a file name, the VCL provides a type-defined data type named TFileName. This data type is of type UnicodeString:

typedef System::UnicodeString TFileName;

Based on this, to declare a variable for a file name, you can use either UnicodeString or TFileName.

The Path of a File

The path of a file is a combination of its location and name. One of the ways you can get this information is to call the Object Pascal's ExtractFilePath() function. Its syntax appears as follows:

String ExtractFilePath(const String FileName);

This function takes one argument as the file to be processed. The function returns only the path part. Consider this example:

ExtractFilePath("C:\\Exercise\\Welcome.txt");

This produces C:\Exercise1.

To let you extract the path to a file, the TPath class is equipped with a method named GetFileName. Its syntax is:

static System::UnicodeString __fastcall GetDirectoryName(System::UnicodeString FileName);

The File Name From a Path

If you have a complete combination of a path and its file but you want to get only the file name, you have various options. You can call the Object Pascal's ExtractFileName() function. Its C++ syntax appears as:

UnicodeString ExtractFileName(const UnicodeString FileName);

This function takes the whole path and returns the name of the file. Consider this example:

ExtractFileName("C:\\Exercise\\Welcome.txt");

This produces Welcome.txt

To let you extract a file name from the full name, the TPath class provides the GetFileName(). Its syntax is:

static System::UnicodeString __fastcall GetFileName(System::UnicodeString FileName);

Comparing File Names

To compare the file names of two files, you can call the AnsiCompareFileName() function of Object Pascal:

int AnsiCompareFileName(const String S1, const String S2);

This function takes the names or path of two files. If the names of the files are the same, the function returns 0. If the names are different, the function returns -1 or 1 depending on which file name is higher.

The Extension of a File

An extension makes it possible to identify the type of a file. The extension is made of one, two, or more characters. To get the extension of a file, you have many options. You can call the Object Pascal's ExtractFileExt() function. Its C++ syntax appears as:

String ExtractFileExt(const String FileName);

This function takes the name of a file or its whole path. It returns the extension of the file. Consider this example:

ExtractFileExt("C:\\Exercise\\Welcome.txt");

This produces .txt.

To let you extract the extension of a file, the TPath class is equipped with a method named GetExtention. Its syntax is:

static System::UnicodeString __fastcall GetExtension(System::UnicodeString FileName);
 
 
 

Home Copyright © 2010-2011 FunctionX, Inc.