When establishing the form object, you’ll need to set 2 variables on instantiation, the ‘method’ and ‘enctype’. For anyone familiar with html forms, this should be second nature. This sets the form to post the data in a “post” method, and tells the browser that there’s going to be data in the format of a file being transferred. It’ll look for that data in the “file” input type within the form.

        $form = new Varien_Data_Form(
                        array(
                            'id' => 'edit_form',
                            'action' => $this->getUrl('*/*/save', array('id' => $this->getRequest()->getParam('id'),
                                                                        'store' => $this->getRequest()->getParam('store'))),
                            'method' => 'post',
                            'enctype' => 'multipart/form-data',
                        )
        );
        $this->setForm($form);
 //best practice is to load the object into the registry on controller load,
        $form->setDataObject(Mage::registry('current_object'));
        $fieldset = $form->addFieldset('neotheme_example_form', array('legend' => Mage::helper('neotheme_example')->__('ExampleConfiguration')));
        $form->setFieldNameSuffix('neotheme_example');
 

Once it’s submitted you’ll need to save the file. In this example, I’ve written a function to upload an image to the media directory [This hasn’t been tested, so anyone that wants to poke holes and correct it, let me know and I’ll correct it]:

    public function upload_file($file_name){
    if (!empty($_FILES[$file_name]['name'])){
            $result = array();
            $saveTo =  Mage::getBaseDir('media') . $saveTo;
            try{
                $uploader = new Varien_File_Uploader($file_name);

                //this sets the allowed extension Types, in this case we’re uploading images.
                $uploader->setAllowedExtensions(array('jpg','jpeg','gif','png'));

//this allows the uploader to rename files if it has to. Essentially, if you’re uploading an image,
//where you could run into a conflict, this should be true. But if you’re uploading a pdf for
// instance, you’ll want to replace that pdf next time it’s uploaded.
                $uploader->setAllowRenameFiles(true);

//this allows the uploader place this is a dispersed folder structure. I.e. an image like
// “prod-5.jpg” would be put in p/r/prod-5.jpg. Turning this off will insure that it only
// gets put in the base directory.
                $uploader->setFilesDispersion(false);
                $result = $uploader->save($saveTo);
                if ($result == false){
                    Mage::throwException($this->__("Image Upload Failed: Make sure PHP can write to: ". $saveTo));
           }
           $result['uploaderdetails'] = $result;
$url =  str_replace(DS, '/', Mage::getBaseUrl('media') . $saveTo. $file_name);
           $result['fieldname'] = $file_name;
          $result['url'] = $url ;
            return $result;
            }
            catch(Exception $e){
                throw new Exception($this->__("Image Upload Failed: Make sure PHP can write to: ". $saveTo) ,0, $e);
            }
    }
     else
    {
            throw new Exception($this->__("Upload Failed: No Post Upload Found"));
    }
    }