File Processing: Win32 |
|
File Creation |
In your VCL applications, even on console applications created on the Microsoft Windows operating system, besides the C, the C++, and the VCL means of saving and opening files, the Win32 library provides its mechanism of file processing. In order to use a file, you must obtain a handle for it. You can obtain a file handle by calling the CreateFile() function. Its syntax is: HANDLE CreateFile( LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile ); |
The lpFileName argument is a null-terminated string that represents the name of the file. You can explicitly specify it as a double-quoted string. If you want the user to save the current file or to open an existing file by the user specifying the name of the file, you can use an OpenDialog or a SaveDialog objects. In this case the lpFileName can be obtained with the TOpenDialog::FileName or the TSaveDialog::FileName member variables. The dwDesiredAccess argument specifies the type of operation that will be performed on the file. It can have one or a combination of the following values:
Omitting the 0 value, the above flags can be combined using the bitwise OR operator. Alternatively, you can pass one of the following values for a combination of flags:
The dwShareMode argument controls how the file can be shared. Its possible values are:
The lpSecurityAttributes argument specifies some security attributes used when creating the file. Such attributes are defined as SECURITY_ATTRIBUTES value. You can pass this argument as NULL, in which case the security attributes would be ignored. The dwCreationDisposition argument specifies the behavior to adopt whether the file already exists or is just being created. It can have one of the following values:
The dwFlagsAndAtributes argument specifies the attribute(s) to apply to the file. It can have one or a combination of the following values:
The above attributes can also be combined with the following values:
The hTemplateFile argument is a handle to a template file. If you do not have or cannot use a file template (for example they are not supported on home operating systems), pass this argument as NULL. If the CreateFile() function succeeds, it returns a handle to the file and you can use it as you see fit, to analyze it, to read its contents if allowed, or to write data to it if permitted. If this function fails, it returns INVALID_HANDLE_VALUE.
As its name suggests, the CreateFile() function is used to create a stream. Actually, it initiates a file object. After calling it, since it returns a file handle, your next action is to decide what to do with this handle and one of the actions you can take is to store a newly created file into a drive. To save a file in Win32, you can call the WriteFile() function. Of course, in order to save a file, you must first retrieve the value to be saved. This value can be made of a single variable or a complex class. Therefore, you must know what the value to save is made of because it must be supplied to the WriteFile() function. The syntax of this function is: BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped); The hFile argument is the handle to the file. It is typically the return value of a call to the CreateFile() function. Since in this case we are trying to save a file, the file should/must have been created with at least the GENERIC_WRITE flag for the dwDesiredAccess argument of the CreateFile() function. The lpBuffer argument is the object that will be saved. As you can see, it is defined as a pointer to VOID, meaning that its type is not known to the function, which leaves it up to you to decide what type of value is being saved. It can be a C/C++ generic type (integer, character, floating-point value, or their variants). It can be a VCL or a Win32 type of object. It can also be a completely new type that you create as a simple C structure or a more elaborate C++, VCL, or Win32 class.
Besides saving a file, another operation you can perform on streams using the Win32 approach is to open an existing file. Reading a file is performed sing the ReadFile() function. Its syntax is: BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped); The hFile parameter is a handle to the file to be opened. It can be the return value of a previous call to the CreateFile() function. The lpBuffer parameter is the object or value to be opened. As its type suggests, it can be anything and it is up to you to define what type of value is being opened. The nNumberOfBytesToRead parameter is the number of bytes to read. The lpNumberOfBytesRead parameter is a returned value of the function, indicating the number of bytes that were read. The lpOverlapped parameter is used if the file is being opened as “overlapped”, in which case the lpOverlapped argument of the CreateFile() function would have received the FILE_FLAG_OVERLAPPED flag. |
Practical Learning: Opening a File |
//--------------------------------------------------------------------------- void __fastcall TfrmMain::btnOpenClick(TObject *Sender) { HANDLE hFile; DWORD dFileSize, dBytesRead; BOOL bResult; if( OpenDialog1->Execute() == True ) { __try { hFile = CreateFile(OpenDialog1->FileName.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if( hFile == INVALID_HANDLE_VALUE ) { ShowMessage("There was a problem opening the file"); return; } dFileSize = GetFileSize(hFile, NULL); if( dFileSize == 0xFFFFFFFF ) { ShowMessage("Invalid file size"); return; } bResult = ReadFile(hFile, &CustOrder, dFileSize, &dBytesRead, NULL); if( bResult == FALSE ) { ShowMessage("The file could not be read"); return; } edtClerk->Text = CustOrder.strClerk; edtOrderDate->Text = CustOrder.dteOrderDate; if( CustOrder.iBread == 0 ) rdoBun->Checked = True; else if( CustOrder.iBread == 1 ) rdoRoll->Checked = True; if( CustOrder.iMeat == 0 ) rdoBeefPatty->Checked = True; else if( CustOrder.iMeat == 1 ) rdoGrilledChicken->Checked = True; else if( CustOrder.iMeat == 2 ) rdoChickenBreast->Checked = True; bLettuce = CustOrder.bLettuce; bOnion = CustOrder.bOnion; bTomato = CustOrder.bTomato; bPickles = CustOrder.bPickles; if( (bLettuce == False) && (bOnion == False) && (bTomato == False) && (bPickles == False) ) chkRegulars->State = cbUnchecked; else if( (bLettuce == True) && (bOnion == True) && (bTomato == True) && (bPickles == True) ) chkRegulars->State = cbChecked; else chkRegulars->State = cbGrayed; chkCheese->Checked = CustOrder.bCheese; chkBacon->Checked = CustOrder.bBacon; if( CustOrder.iIngredients == 0 ) rdoMayonnaise->Checked = True; else if( CustOrder.iIngredients == 1 ) rdoKetchup->Checked = True; else if( CustOrder.iIngredients == 2 ) rdoMustard->Checked = True; chkSweetenerClick(Sender); EvaluatePrice(); } __finally { if( hFile != INVALID_HANDLE_VALUE ) CloseHandle(hFile); } } } //--------------------------------------------------------------------------- |
Home | Copyright © 2005-2012, FunctionX, Inc. | |