Recently, someone on the MSDN forum asked if there are any built-in ‘Open File’ and ‘Save File’ dialogs available in the Windows Mobile platform. The answer, of course, is yes. The APIs that get the task done are GetOpenFileName() and GetSaveFileName(). These APIs allow the user to select directories or files for opening or saving. I wrote a small application to demonstrate how to use these APIs. The application has a multiline edit control and menu options for opening or saving text files (see video at the end). When you open a text file, the files contents are shown on the edit control, and saving to a file writes the contents of the edit control to a user selected text file. Pretty simple.
First, lets take a look at GetOpenFileName() API, the DoOpenFile() method in the application reads the contents of the file and writes it to the edit control, here is the function: (error checking is left out, as usual)
1. Get the full path to the file
2. Read the contents of the file into a buffer
3. Convert the buffer into wide char
4. Display the wide chars on the edit control
BOOL DoOpenFile(HWND hDlg)
{
TCHAR szFile[MAX_PATH] = TEXT("\0");
char *szFileContent = NULL;
OPENFILENAME ofn;
HANDLE hFile = INVALID_HANDLE_VALUE;
DWORD dwFileSize = 0, bytesToRead = 0, bytesRead = 0;
memset( &(ofn), 0, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hDlg;
ofn.lpstrFile = szFile;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFilter = TEXT("Txt (*.txt)\0 *.txt\0");
ofn.lpstrTitle = TEXT("Open File");
ofn.Flags = OFN_EXPLORER;
//get the filename the user wants to open
if (GetOpenFileName(&ofn))
{
//ofn.lpstrFile contains the full path to the file, get a handle to it
hFile = CreateFile(ofn.lpstrFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return FALSE;
//get file size in bytes
dwFileSize = GetFileSize(hFile, NULL);
szFileContent = (char*)malloc(dwFileSize+1);
memset(szFileContent, 0, dwFileSize+1);
//read the files contents into a buffer
if (ReadFile(hFile, szFileContent, dwFileSize, &bytesRead, NULL))
{
TCHAR *wszTemp = NULL;
HWND hEdit = NULL;
wszTemp = (TCHAR*)malloc(bytesRead*sizeof(TCHAR));
//convert the chars in buffer to wide chars
mbstowcs(wszTemp, szFileContent, bytesRead);
hEdit = GetDlgItem(hDlg, IDC_EDIT);
//set the content of edit control
SetWindowText(hEdit, wszTemp);
free(wszTemp);
}
//free resources
free(szFileContent);
CloseHandle(hFile);
}
return TRUE;
}
The APIs and the OPENFILENAME structure are explained well in the MSDN documentation, so I am not going to repeat the same things here. Follow the links.
The DoSaveFile() method in the application allows the user to save the contents of edit control into a file, here is the code:
1. Get the full path to the file
2. Read the contents of edit control into a wide char buffer
3. Convert the wide char into char (multibyte string)
4. Write the chars to the file
BOOL DoSaveFile(HWND hDlg)
{
TCHAR szFile[MAX_PATH] = TEXT("\0");
OPENFILENAME ofn;
HANDLE hFile = INVALID_HANDLE_VALUE;
memset( &(ofn), 0, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hDlg;
ofn.lpstrFile = szFile;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFilter = TEXT("Text (*.txt)\0*.txt\0");
ofn.lpstrTitle = TEXT("Save File As");
ofn.Flags = OFN_HIDEREADONLY;
ofn.lpstrDefExt = TEXT("txt");
//get the filename the user wants to save to
if (GetSaveFileName(&ofn))
{
HWND hEdit = NULL;
DWORD dwTextLen = 0, bytesWritten = 0;
TCHAR *wszEditText = NULL;
char *szEditText = NULL;
//ofn.lpstrFile contains the full path of the file, get a handle to it
hFile = CreateFile(ofn.lpstrFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return FALSE;
hEdit = GetDlgItem(hDlg, IDC_EDIT);
//get the text length of the edit controls contents
dwTextLen = GetWindowTextLength(hEdit);
wszEditText = (TCHAR*)malloc((dwTextLen+1)*sizeof(TCHAR));
memset(wszEditText, 0, (dwTextLen+1)*sizeof(TCHAR));
//read edit controls contents into buffer
GetWindowText(hEdit, wszEditText, dwTextLen+1);
szEditText = (char*)malloc(dwTextLen+1);
//convert the wide char read from edit control to char
wcstombs(szEditText, wszEditText, dwTextLen);
//save the contents into file
if (WriteFile(hFile, szEditText, dwTextLen, &bytesWritten, NULL))
{
}
//free resources
free(wszEditText);
free(szEditText);
CloseHandle(hFile);
}
return TRUE;
}
Here is a video demo of how things work,