In case anyone wants to look at the code without going through the effort of download/renaming, I'll post it here.
Resource File:
Code:
#include <windows.h>
#include <commctrl.h>
#include "resource.h"
/* Include our manifest which tells Windows to use commctrl version 6
* Equivalent to CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST fileTransfer.exe.manifest
*/
1 24 fileTransfer.exe.manifest
/* Start our dialog definition
*/
IDD_FILE_DIALOG DIALOGEX 20, 20, 434, 284
STYLE DS_FIXEDSYS | DS_SETFONT | DS_MODALFRAME | DS_NOIDLEMSG | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
CAPTION "Transfer Files"
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
FONT 8, "MS Shell Dlg"
{
CONTROL "", IDD_FILES, "SysListView32", LVS_SHOWSELALWAYS | LVS_REPORT | LVS_NOSORTHEADER | LVS_SINGLESEL | WS_TABSTOP | WS_BORDER | WS_CHILD | WS_VISIBLE, 8, 12, 236, 266
CONTROL "Cancel", IDCANCEL, "BUTTON", BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD | WS_VISIBLE, 345, 264, 40, 14
CONTROL "Upload", IDD_UPLOAD, "BUTTON", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD | WS_VISIBLE, 389, 264, 40, 14
CONTROL "Add", IDD_ADDFILE, "BUTTON", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD | WS_VISIBLE, 248, 247, 40, 14
CONTROL "Remove", IDD_REMOVEFILE, "BUTTON", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD | WS_VISIBLE, 248, 264, 40, 14
CONTROL "Username:", 101, "STATIC", SS_RIGHT | WS_CHILD | WS_VISIBLE, 248, 19, 35, 10
CONTROL "Password:", 102, "STATIC", SS_RIGHT | WS_CHILD | WS_VISIBLE, 248, 33, 35, 10
CONTROL "DROP FILES HERE", 103, "STATIC", SS_LEFTNOWORDWRAP | SS_NOPREFIX | WS_CHILD | WS_VISIBLE, 313, 146, 58, 10
CONTROL "", IDD_USERNAME, "EDIT", WS_TABSTOP | WS_BORDER | WS_CHILD | WS_VISIBLE, 287, 18, 142, 10
CONTROL "", IDD_PASSWORD, "EDIT", ES_PASSWORD | WS_TABSTOP | WS_BORDER | WS_CHILD | WS_VISIBLE, 287, 33, 142, 10
CONTROL "Remember Username && Password", IDD_SAVEPASSWORD, "BUTTON", BS_AUTOCHECKBOX | BS_RIGHT | WS_TABSTOP | WS_CHILD | WS_VISIBLE, 306, 47, 123, 14
}
Code:
Code:
/* Windows header files */
#define _WIN32_IE 0x0500
#include <windows.h>
#include <commctrl.h>
#include <shellapi.h>
#include <shlobj.h>
#include <shlwapi.h>
/* Application header files */
#include "resource.h"
/* C++ header files */
#include <vector>
#include <string>
/* Global variable that holds the location of the settings file. */
TCHAR g_szSettingsFile[MAX_PATH];
/*
* Function to save username and password to the settings.ini file.
*/
VOID SaveUserPassword(LPCTSTR szUsername, LPCTSTR szPassword)
{
WritePrivateProfileString(TEXT("FileTransfer"), TEXT("Username"), szUsername, g_szSettingsFile);
WritePrivateProfileString(TEXT("FileTransfer"), TEXT("Password"), szPassword, g_szSettingsFile);
}
/*
* Function to retore the username and password from the settings.ini file.
*/
VOID RestoreUserPassword(HWND hwnd)
{
TCHAR szUsername[500];
TCHAR szPassword[500];
GetPrivateProfileString(TEXT("FileTransfer"), TEXT("Username"), TEXT(""), szUsername, 500, g_szSettingsFile);
GetPrivateProfileString(TEXT("FileTransfer"), TEXT("Password"), TEXT(""), szPassword, 500, g_szSettingsFile);
SetDlgItemText(hwnd, IDD_USERNAME, szUsername);
SetDlgItemText(hwnd, IDD_PASSWORD, szPassword);
if (szUsername[0] != TEXT('\0') || szPassword[0] != TEXT('\0'))
{
/* If settings were successfully retrieved, check the remember settings box
* so that settings are saved again at upload. */
SendDlgItemMessage(hwnd, IDD_SAVEPASSWORD, BM_SETCHECK, BST_CHECKED, 0);
}
}
/*
* Function to set up the list-view control.
*/
VOID SetupDialog(HWND hwnd)
{
HWND hListView = GetDlgItem(hwnd, IDD_FILES);
LVCOLUMN lvc = { 0 };
lvc.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH | LVCF_FMT;
lvc.fmt = LVCFMT_LEFT;
lvc.iSubItem = 0;
lvc.cx = 200;
lvc.pszText = TEXT("Filename");
ListView_InsertColumn(hListView, 0, &lvc);
lvc.fmt = LVCFMT_RIGHT;
lvc.iSubItem = 1;
lvc.cx = 60;
lvc.pszText = TEXT("Size");
ListView_InsertColumn(hListView, 1, &lvc);
lvc.fmt = LVCFMT_LEFT;
lvc.iSubItem = 2;
lvc.cx = 0; /* Hidden by default */
lvc.pszText = TEXT("Path");
ListView_InsertColumn(hListView, 2, &lvc);
/* Size the filename column to be as wide as possible. */
RECT rc; GetClientRect(hListView, &rc);
ListView_SetColumnWidth(hListView, 0, rc.right - 60 - 18);
ListView_SetExtendedListViewStyle(hListView, LVS_EX_FULLROWSELECT | LVS_EX_FLATSB | LVS_EX_HEADERDRAGDROP);
/* Restore username & password from settings.ini file. */
RestoreUserPassword(hwnd);
/* Notify Windows that our window can accept dropped files. */
DragAcceptFiles(hwnd, TRUE);
}
/*
* Function to get the size of the file as a string in kilobytes.
*/
VOID GetFileSize(LPCTSTR szFile, TCHAR szSize[30])
{
LARGE_INTEGER li = { 0 };
WIN32_FIND_DATA wfd = { 0 };
FindClose(FindFirstFile(szFile, &wfd));
li.HighPart = wfd.nFileSizeHigh;
li.LowPart = wfd.nFileSizeLow;
DWORD size = (li.QuadPart / 1024) + 1;
wsprintf(szSize, TEXT("%u KB"), size);
}
/*
* Adds a file item to our list-view control
*/
VOID AddFileItem(HWND hwnd, LPTSTR szFile)
{
HWND hListView = GetDlgItem(hwnd, IDD_FILES);
LVITEM lv = { 0 };
ListView_InsertItem(hListView, &lv);
/* Add file name in column 0. */
ListView_SetItemText(hListView, 0, 0, PathFindFileName(szFile));
/* Add file size in column 1. */
TCHAR szSize[30];
GetFileSize(szFile, szSize);
ListView_SetItemText(hListView, 0, 1, szSize);
/* Add file path in column 2 (which is hidden by default). */
ListView_SetItemText(hListView, 0, 2, szFile);
}
/*
* Remove a file from the list-view.
*/
VOID RemoveFileItem(HWND hwnd)
{
HWND hListView = GetDlgItem(hwnd, IDD_FILES);
/* Get selected item. */
int item = ListView_GetNextItem(hListView, (WPARAM) -1, LVNI_SELECTED);
/* Delete item. */
ListView_DeleteItem(hListView, item);
/* Focus on the item above so that user can do multiple deletes without
* clicking on a file each time. */
ListView_SetItemState(hListView, item > 0 ? item - 1 : item, LVIS_SELECTED, LVIS_SELECTED);
}
/*
* Show a file selection dialog and add the selected file.
* This could be improved by allowing multiple selections.
*/
VOID AddFileDialog(HWND hwnd)
{
OPENFILENAME of = { 0 };
TCHAR buf[MAX_PATH] = { 0 };
of.lStructSize = sizeof(of);
of.hwndOwner = hwnd;
of.lpstrFile = buf;
of.nMaxFile = MAX_PATH;
if (GetOpenFileName(&of))
{
AddFileItem(hwnd, buf);
}
}
/*
* Deal with files that have been dropped on our window.
*/
VOID HandleDroppedFiles(HWND hwnd, HDROP hDrop)
{
UINT count = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);
for (int i = 0; i < count; i++)
{
TCHAR buf[MAX_PATH];
DragQueryFile(hDrop, i, buf, MAX_PATH);
/* Reject directories, remove if you wish to handle directories. */
if ((GetFileAttributes(buf) & FILE_ATTRIBUTE_DIRECTORY) == 0)
{
AddFileItem(hwnd, buf);
}
}
DragFinish(hDrop);
}
/*
* Your function starts here.
* Note: I think using a std::string to hold filenames may cause troubles. Even if you don't use
* unicode characters when naming filenames, they often appear in file names downloaded from the
* web, email, etc.
*/
void ThantosDoUpload(std::vector<std::string>& files, std::string user, std::string password)
{
/* DEBUG CODE:
*
for (int i = 0; i < files.size(); i++)
{
MessageBox(NULL, files[i].c_str(), NULL, 0);
}
MessageBox(NULL, user.c_str(), password.c_str(), 0);
*
* END DEBUG CODE */
}
/*
* Upload button pressed. Save settings, if required, retrieve
* info in specified format and pass to Thantos function.
*/
VOID DoUpload(HWND hwnd)
{
HWND hListView = GetDlgItem(hwnd, IDD_FILES);
int count = ListView_GetItemCount(hListView);
if (count == 0)
{
/* No files have been added. Show a message and return. */
MessageBox(hwnd, TEXT("No files have been selected. Please add some files and try again."),
TEXT("No Files Selected"), MB_ICONWARNING);
return;
}
/* Hide the dialog box while we process the files. */
ShowWindow(hwnd, SW_HIDE);
/* Retrieve the username and password from the dialog. */
TCHAR szUsername[500];
TCHAR szPassword[500];
BOOL fSavePassword = SendDlgItemMessage(hwnd, IDD_SAVEPASSWORD, BM_GETCHECK, 0, 0);
GetDlgItemText(hwnd, IDD_USERNAME, szUsername, 500);
GetDlgItemText(hwnd, IDD_PASSWORD, szPassword, 500);
if (fSavePassword)
{
/* Save the username and password to settings.ini. */
SaveUserPassword(szUsername, szPassword);
}
else
{
/* Delete file so that old username and password are not remembered. */
DeleteFile(g_szSettingsFile);
}
/* Retrieve file paths from the list-view and add to vector of strings. */
std::vector<std::string> files;
for (int i = 0; i < count; i++)
{
TCHAR path[MAX_PATH];
ListView_GetItemText(hListView, i, 2, path, MAX_PATH);
files.push_back(std::string(path));
}
/* Transfer info to Thantos' function */
ThantosDoUpload(files, std::string(szUsername), std::string(szPassword));
/* Destroy dialog */
EndDialog(hwnd, 0);
}
/*
* Dialog window procedure.
*/
INT_PTR CALLBACK DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG:
{
SetupDialog(hwnd);
}
break;
case WM_COMMAND:
{
int idControl = LOWORD(wParam);
int command = HIWORD(wParam);
if (idControl == IDCANCEL && command == BN_CLICKED)
{
EndDialog(hwnd, 0);
}
else if (idControl == IDD_ADDFILE && command == BN_CLICKED)
{
AddFileDialog(hwnd);
}
else if (idControl == IDD_REMOVEFILE && command == BN_CLICKED)
{
RemoveFileItem(hwnd);
}
else if (idControl == IDD_UPLOAD && command == BN_CLICKED)
{
DoUpload(hwnd);
}
}
break;
case WM_DROPFILES:
{
HandleDroppedFiles(hwnd, (HDROP) wParam);
}
break;
default:
{
return FALSE;
}
break;
}
return TRUE;
}
/*
* Entry function.
*/
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE reserved, LPSTR lpCmdLine, int nCmdShow)
{
InitCommonControls();
/* Get the location of the settings.ini file and create directory, if required.
* The usual settings location is:
* Documents and Settings\User\Application Data\FileTransfer\settings.ini
*/
SHGetSpecialFolderPath(NULL, g_szSettingsFile, CSIDL_APPDATA, FALSE);
PathAppend(g_szSettingsFile, TEXT("FileTransfer"));
CreateDirectory(g_szSettingsFile, NULL);
PathAppend(g_szSettingsFile, TEXT("settings.ini"));
/* Create our modal dialog. */
DialogBox(hInstance, MAKEINTRESOURCE(IDD_FILE_DIALOG), NULL, DialogProc);
return 0;
}