标签:des style blog http color os io strong
***********************************************声明*************************************************************************************
原创作品,出自 “晓风残月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:\Users\jimjxu\Desktop\我的程序\1.cpp源程序执行起来就是 "szPath = C:\Users\jimjxu\Desktop\我的程序\Debug\1.exe"
#include <windows.h>
#include <stdio.h>
BOOL GetExactFileName()
{
TCHAR szPath[MAX_PATH];
if( !GetModuleFileName( NULL, szPath, MAX_PATH ) )
{
printf("GetModuleFileName failed (%d)\n", GetLastError());
return FALSE;
}
printf("szPath = %s\n", 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;
}
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不熟,难免有错误或不足的地方,欢迎斧正!
VC中文件(夹)目录与路径操作原理与代码实现,布布扣,bubuko.com
标签:des style blog http color os io strong
原文地址:http://blog.csdn.net/xiaofengcanyuexj/article/details/38467591