Thread: Need an interface written

  1. #1
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681

    Need an interface written

    I am working on a small project for my family and I want to make a small computer illerate program that they can use to transfer some files inmass to my server. Due to some requirements the normal HTTP method is out and FTP is out for other reasons.
    While I can easily write the file transfer part my UI skills are lacking.

    What I'm looking for is a small UI window that will allow the user to drag and drop file(s) onto the window and have it populate a list of the files. They should also be able to remove file(s) from the list.

    Also there will need to be a field for entering the username and a field for the password. There should also be an option for saving the username and password which would autoload it.

    Upon clicking the submit button the program should call a function from a DLL (I'll provide that stuff) and pass the list of files as a std::vector<std::string> and the username and password as a std::string.

    If anyone is interested please let me know. Sorry but I have nothing to offer but my gratitude

  2. #2
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    I could do it in MFC but I shudder at using std::stirng. MFC CString is much more suited to this and the Serialize() feature of the classes derived from CObject will save these types of objects automatically. CString is derived from CObject and therefore is serializable.

    I might be able to cook something up, but I'm rather busy with my tile editor in MFC at the moment. Perhaps we should talk via PM to see if you are interested in 'altering' some of the requirements a bit. Drag and drop is easy enough as well as the vector stuff and the saving passwords, etc. That's all very easy.

    But what do you want to drag and drop from?
    I could probably do this by using a CWnd and this class:

    COleDropTarget Class Members
    Construction

    COleDropTarget Constructs a COleDropTarget object.


    Operations

    Register Registers the window as a valid drop target.
    Revoke Causes the window to cease being a valid drop target.


    Overridables

    OnDragEnter Called when the cursor first enters the window.
    OnDragLeave Called when the cursor is dragged out of the window.
    OnDragOver Called repeatedly when the cursor is dragged over the window.
    OnDragScroll Called to determine whether the cursor is dragged into the scroll region of the window.
    OnDrop Called when data is dropped into the window, default handler.
    OnDropEx Called when data is dropped into the window, initial handler.


    COleDropTarget Overview | Base Class Members | Hierarchy Chart

  3. #3
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    But what do you want to drag and drop from?
    Regular explorer windows

  4. #4
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    I hope you wanted an interface for Windows!

    Attached is a Dev-C++ project in a zip file. You will have to rename it from .txt to .zip.

    It is a dialog based application. I coded it fairly quickly but it looks pretty good and seems to work well.

  5. #5
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Screenshot

  6. #6
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    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;
    }

  7. #7
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Looks very good anonytmouse. Thanks

  8. #8
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    How do you use those cool XP buttons in MFC? I have to use the crappy old boxy ones. Does it have to be in pure Win32 in order to use them.

    In other words, are the MFC classes using the deprecated functions to create the buttons hence their 'old' appearance.

    Never mind: http://www.developer.com/net/asp/article.php/3101831

    Gotta love google.
    Last edited by VirtualAce; 11-23-2005 at 12:29 PM.

  9. #9
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    anonytmouse I haven't had a chance to test it but does the filename include the full path?

  10. #10
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    anonytmouse I haven't had a chance to test it but does the filename include the full path?
    Yes, the vector includes complete paths.

  11. #11
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Thankee, started looking at it a couple hours ago. Really nice job.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to get RSSI value, send to sensor, sensor receive package, repackage it?
    By techissue2008 in forum Networking/Device Communication
    Replies: 1
    Last Post: 03-04-2009, 10:13 AM
  2. Calling IRichEditOle interface methods
    By Niara in forum C Programming
    Replies: 2
    Last Post: 01-16-2009, 01:23 PM
  3. Cannot get interface flags: Invalid argument
    By nasim751 in forum C Programming
    Replies: 1
    Last Post: 04-15-2008, 02:27 AM
  4. OOP in C
    By lyx in forum C Programming
    Replies: 4
    Last Post: 11-23-2003, 01:12 PM
  5. C++ Share Interface Problem
    By Morphios in forum C++ Programming
    Replies: 0
    Last Post: 04-28-2003, 07:30 PM