• VC档(夹)文件夹路径的经营方针和代码


    ***********************************************声明************************************************************

          原创作品,出自 “晓风残月xj” 博客,欢迎转载。转载时请务必注明出处(http://blog.csdn.net/xiaofengcanyuexj)。

          因为各种原因。可能存在诸多不足。欢迎斧正。

    ****************************************************************************************************************

           近期在做安装包解压,涉及到非常多关于路径的操作。当然非常须要调用非常多Windows API函数,本来是没有什么技术含量的,但因为Windows中关于文件夹、路径的操作较为重要。并且当中蕴含着一些重要的编程思想及技巧,所以在此加以总结,希望对以后的学习工作起到作用,同一时候更希望能帮助大家解决这个问题。共同创建一个知识分享型的网络社区。

         如今提供下面几个操作方法。持续更新中…

           1、在指定路径下创建目录

           2、获取程序的安装路径

           3、对话框支持文件拖拽

           4、获取当前进程已载入模块的文件的完整路径

           5、文件(夹)的操作,如复制、删除、移动等

        下面是具体介绍。

    1、在指定路径下创建目录

    void PathRemoveFileSpec(CString& strPath)
    {
    	int nPos = strPath.ReverseFind(_T('\'));
    	if (nPos == -1)
    	{
    		strPath.Empty();
    	}
    	else
    	{
    		strPath = strPath.Left(nPos);
    	}
    }
    
    BOOL CreateDeepDirectory(LPCTSTR szPath)
    {
    	BOOL bRetCode = FALSE;
    	CString strPath(szPath);	
    	if (GetFileAttributes(szPath) != INVALID_FILE_ATTRIBUTES)
    		return TRUE;	
    	bRetCode = CreateDirectory(szPath, NULL);
    	if (!bRetCode && GetLastError() != ERROR_ALREADY_EXISTS)
    	{
    		PathRemoveFileSpec(strPath);
    		if (strPath.IsEmpty()) return FALSE;
    		bRetCode = CreateDeepDirectory(strPath);
    		if (!bRetCode) return FALSE;
    		bRetCode = CreateDirectory(szPath, NULL);
    		if (!bRetCode && GetLastError() != ERROR_ALREADY_EXISTS)
    			return FALSE;
    	}
    	return TRUE;
    }

    2、获取程序的安装路径

         非常多应用程序会在注冊表中存储对应信息,此时能够从注冊表中获取应用程序的安装路径

    //InstallSoftwarePath.h
    
    #ifndef _InstallSoftwarePath_H
    #define _InstallSoftwarePath_H
    
    class CInstallSoftwarePath
    {
    public:
    	CInstallSoftwarePath(void);
    	~CInstallSoftwarePath(void);
    	 CString GetSoftwarePath(void);
    private:
    	CString m_cstrSoftwarePath;
    };
    
    
    #endif

    //InstallSoftwarePath.cpp
    #include "StdAfx.h"
    #include "InstallSoftwarePath.h"
    
    TCHAR g_szName[] = _T("XXX");//代表应用程序名
    
    
    CInstallSoftwarePath::CInstallSoftwarePath(void)
    {
    	m_cstrSoftwarePath=_T("");
    }
    
    CInstallSoftwarePath::~CInstallSoftwarePath(void)
    {
    }
    
    
    CString CInstallSoftwarePath::GetSoftwarePath(void)
    {
    	HKEY keyFirst = NULL, keySecond = NULL;	
    	TCHAR szSub[] = _T("SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"); 	
    	TCHAR szName[200]   = {0};
    	TCHAR szDisplay[200]  = {0};
    	TCHAR szShow[200]   = {0};
    	TCHAR szIcon[200] = {0};
    	DWORD   dwIclen = 200;
    	DWORD   dwIndex   = 0, dwNameSize = 200, dwShowLen = 200;
    	DWORD   m_attr=REG_BINARY | REG_DWORD | REG_EXPAND_SZ | REG_MULTI_SZ | REG_NONE | REG_SZ; 
    
    	if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSub, 0, KEY_ALL_ACCESS, &keyFirst))
    	{
    		while(ERROR_NO_MORE_ITEMS != RegEnumKeyEx(keyFirst, dwIndex, szName, &dwNameSize, 0, NULL, NULL, 0))
    		{
    			dwIndex++;
    			if (0 != _tcscmp(szName, _T("")))
    			{
    				_tcscpy(szDisplay, szSub);
    				_tcscat(szDisplay, _T("\"));
    				_tcscat(szDisplay, szName);
    				if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, szDisplay, 0, KEY_ALL_ACCESS, &keySecond))
    				{
    					memset(szName, 0, sizeof(szName));
    					memset(szShow, 0, sizeof(szShow));	
    					memset(szIcon, 0, sizeof(szIcon));
    					dwIclen=200;
    					dwNameSize = 200;
    					dwShowLen = 200;
    					RegQueryValueEx(keySecond, _T("DisplayName"), NULL, &m_attr, (LPBYTE)szName, &dwNameSize);
    					RegQueryValueEx(keySecond, _T("DisplayIcon"), NULL, &m_attr, (LPBYTE)szIcon, &dwIclen);
    
    					if(0 == _tcscmp(szName, g_szName))
    					{
    						if (keyFirst)
    						{
    							RegCloseKey(keyFirst);
    						}
    						if (keySecond)
    						{
    							RegCloseKey(keySecond);
    						}	
    						m_cstrSoftwarePath=szIcon;
    						m_cstrSoftwarePath.Remove('"');
    						return  m_cstrSoftwarePath;
    					}
    				}
    				memset(szName, 0, sizeof(szName));
    				memset(szShow, 0, sizeof(szShow));
    				memset(szDisplay, 0, sizeof(szDisplay));
    				memset(szIcon, 0, sizeof(szIcon));
    				dwIclen = 200;	
    				dwNameSize = 200;
    				dwShowLen = 200;
    			}		
    		}
    	}
    	if (keyFirst)
    	{
    		RegCloseKey(keyFirst);
    	}
    	if (keySecond)
    	{
    		RegCloseKey(keySecond);
    	}	
    	m_cstrSoftwarePath = _T("");
    	return m_cstrSoftwarePath;
    }
          GetSoftwarePath返回的就是应用程序g_szName的完整安装路径。


    3、对话框支持文件拖拽
    第一步、须要加入消息响应
    WM_DROPFILES
    1)、假设是MFC,操作例如以下:对话框上点击右键,选择Properties->Extended Styles。点选Accept files选项就可以。


    2)、假设不是MFC,如ATL、Win32、金山卫士开源码等,操作例如以下:

    LONG dwLong = GetWindowLong(GWL_EXSTYLE);
    SetWindowLong(GWL_EXSTYLE, dwLong|WS_EX_ACCEPTFILES);
    第二步、文件拖拽消息响应函数

    void CMainDlg::OnDropFiles(HDROP hDropInfo) 
    { 
    
    	UINT count;     
    	TCHAR strFilePath[MAX_PATH + 1]   ;   
    	count = DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0);           
    	if(count)            
    	{ 
    		for(UINT i=0; i<count; i++) 
                    //支持多个文件的拖拽操作                    
    		{ 
    		    int pathLen = DragQueryFile(hDropInfo, i, strFilePath, sizeof(strFilePath)); 
                       //strFilePath存储的是当前文件的完整路径+文件名称
                       //此处能够加入待处理的操作。完毕应用程序的功能
    		} 
    	} 
    	DragFinish(hDropInfo);  
            //CDialog::OnDropFiles(hDropInfo);//假设是MFC,最好加入此操作
    } 


    4、获取当前进程已载入模块的文件的完整路径,该模块必须由当前进程载入

     如以下的C:UsersjimjxuDesktop我的程序1.cpp源程序运行起来就是  "szPath = C:UsersjimjxuDesktop我的程序Debug1.exe"

    #include <windows.h>
    #include <stdio.h>
    
    BOOL GetExactFileName()
    {
        TCHAR szPath[MAX_PATH];
        if( !GetModuleFileName( NULL, szPath, MAX_PATH ) )
        {
            printf("GetModuleFileName failed (%d)
    ", GetLastError());
            return FALSE;
        }
    	printf("szPath = %s
    ", szPath);
    	return TRUE;
    }
    
    int main(int argc, TCHAR* argv[])
    {	
    	GetExactFileName();
    	return 0;
    }
    


    5、文件(夹)的操作,如复制、删除、移动等

         关于文件的操作。较为简单。能够直接调用CopyFile,其原型为:

    BOOL CopyFile( 
    LPCTSTR lpExistingFileName, // pointer to name of an existing file 
    LPCTSTR lpNewFileName,      // pointer to filename to copy to 
    BOOL bFailIfExists          // flag for operation if file exists 
    ); 
    当中各參数的意义: 
    LPCTSTR lpExistingFileName, // 你要拷贝的源文件名称 
    LPCTSTR lpNewFileName,      // 你要拷贝的目标文件名称 
    BOOL bFailIfExists // 假设目标已经存在,true:不拷贝并返回False; false:覆盖目标. 
       关于目录的操作。可能略微复杂一点。目录表现为一组文件的集合,本质上和文件没什么差别。

    关于目录的操作,大致有2种方法:

       第一种:递归复制单个文件注意处理。推断文件夹与文件。然后创建文件(夹)名称。递归拷贝文件。

       另外一种:调用Windows API处理。又分为MFC与Win32程序

          假设是MFC程序,能够直接用CFileFind处理。有点第一种方法的味道。详细操作例如以下:

    BOOL CopyDirectory(CString strSouDir, CString strDesDir)
    {
    	CFileFind finder;
    	CString str, strWildcard, strFilePath, strDesFilePath;	
    	BOOL bRetCode ;	
    	if(strDesDir.Right(1) != _T("\"))
    		strDesDir += _T("\");
    	if(strSouDir.Right(1) != _T("\"))
    		strSouDir += _T("\");
    	strWildcard = strSouDir + _T("*.*");
    	BOOL bContinue = finder.FindFile(strWildcard);	
    	while (bContinue)
    	{
    		bContinue = finder.FindNextFile();	
    		if(finder.IsDots())
    		{
    			continue;
    		}
    		str = finder.GetFileName();
    		if(finder.IsDirectory())
    		{
    			CString temstrSouDir = strSouDir + str;
    			CString temstrDesDir = strDesDir + str; 
    			CreateDirectory(temstrDesDir, NULL);
    			ret = CopyDirectory(temstrSouDir, temstrDesDir);
    		}
    		else
    		{
    			strFilePath = finder.GetFilePath();
    			strDesFilePath = strDesDir+str;
    			bRetCode = CopyFile(strFilePath, strDesFilePath, FALSE);
    			if(!bRetCode)
    				break;
    		}
    	}
    	finder.Close();
    	return bRetCode;
    }
    

        假设是Win32程序,能够直接调用int SHFileOperation(LPSHFILEOPSTRUCT lpFileOp)处理。当中LPSHFILEOPSTRUCT结果例如以下:1.FO_COPY:复制

    typedef struct _SHFILEOPSTRUCT {
     HWND hwnd;     //指向发送消息的窗体
     UINT wFunc;    //运行的操作
     LPCTSTR pFrom; //源文件名称
     LPCTSTR pTo   ;//目标文件名称
     FILEOP_FLAGS fFlags;        //操作与确认标识
     BOOL fAnyOperationsAborted; //操作是否终止
     LPVOID hNameMappings;       //文件映射
     LPCTSTR lpszProgressTitle;  //进度条标题
    } SHFILEOPSTRUCT, *LPSHFILEOPSTRUCT;

         详细运行文件的操作仅仅需设置对应的值就可以,关于其它成员变量的设置及说明,请点击说明例如以下:

      1.FO_COPY:复制
     2.FO_DELETE:删除
     3.FO_MOVE:移动
     4.FO_RENAME:重命名
        例如以下一段代码就可以完毕复制目录的操作:

    BOOL KWork::CopyDir(LPCTSTR lpszSrcDir, LPCTSTR lpszDstDir) 
    {
    	SHFILEOPSTRUCT sfo;
    	ZeroMemory(&sfo, sizeof(sfo));
    	sfo.wFunc = FO_COPY; 
    	sfo.pFrom = lpszSrcDir; 
    	sfo.pTo = lpszDstDir;
    	sfo.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR;
    	int ret = SHFileOperation(&sfo); 
    	if ( ret == 0 )
    		return TRUE;
    	else
    		return FALSE;
    }
          当然。对于不同的Windows程序,此处表现不同,是一大坑,详细说明点击说明


        本文章持续更新中…

        因为写博客时间有限,加之对VC不熟。难免有错误或不足的地方。欢迎斧正!







  • 相关阅读:
    使用密码解密TACACS+的报文
    C9K Stackwise Virtual(三)
    Webhook Configuration Example
    sup-bootflash和bootflash
    WLC5508 license没有500个?
    AAA Server Groups
    关于FlexConnect的Bug!
    Bug搬运工-CSCve57121--Cisco 2800, 3800 and 1560 series APs fail to pass traffic
    Bug搬运工-CSCvb29354-1810 OEAP cannot join vWLC
    阿里云云计算认证ACP模拟考试练习题第1套模拟题分享(共10套)
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5047073.html
Copyright © 2020-2023  润新知