VC札记

VC笔记
VC++(MFC)读取共享文件夹下子目录信息,并显示在listctrl控件中 
     为了实现文件传输功能,特整理了一下有关读取指定文件下其子目录信息的读取方法,及添加双击事件循环读取下一层信息的功能。
一、变量的定义:
#define MAX_COUNT   1024  
#define MAX_PATH       256
struct   OLDPATH
{
   char m_oldpath[MAX_PATH];
};


OLDPATH   oldpath[10];   //记录上一层文件读取的路径
char          m_flpath[MAX_PATH];   //记录当前文件读取的路径


CButton    m_FileBack;//声明返回上一层控件对象
CListCtrl    m_filelist;    //声明listctrl控件对象
int           m_count[MAX_COUNT]; //用来记录共享文件夹下子文件夹在listctrl控件中显示的行号
int          layernum; //用来记录查询的是第几层
二、具体实现:
1、初始化:
for (int i=0;i<MAX_COUNT;i++) //如果listctrl中第i行为文件夹则m_count[i]=i,否则仍为-1
{
   m_count[i]=-1;
}
layernum=0;
//初始化listctrl控件
m_filelist.InsertColumn(0,"名称");
m_filelist.InsertColumn(1,"大小");
CRect   rect;
m_filelist.GetClientRect(&rect);
m_filelist.SetColumnWidth(0,rect.Width()/3);
m_filelist.SetColumnWidth(1,rect.Width()/3);
//获取当前目录的路径
char* des;
des=new char[256];
memset(des,0,256);
GetCurrentDirectory(256,des);
strcat(des,"\\共享文件夹");     //des存储的是你需要读取的文件夹的路径,根据自己的要求进行修改
2、定义查询函数find(char* lpPath)
void CFileScan::find(char *lpPath)

       int i=0;
        m_filelist.DeleteAllItems(); //每次查询前清除上次查询显示在listctrl中的结果
       char szFind[MAX_PATH];
      WIN32_FIND_DATA FindFileData;


      strcpy(szFind,lpPath);
       strcpy(oldpath[layernum].m_oldpath,szFind); 用oldpath记录第几(layernum)层的文件夹的路径
      strcpy(m_flpath,szFind); //用m_flpath记录当前文件夹的路径
      strcat(szFind,"\\*.*");
    HANDLE hFind=::FindFirstFile(szFind,&FindFileData);
    if(INVALID_HANDLE_VALUE == hFind)    return;
    
    while(TRUE)
    {
        if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
            if(FindFileData.cFileName[0]!='.')//查询出的子文件夹信息
            {
                    CString fileName;
                  fileName=FindFileData.cFileName;
                  m_filelist.InsertItem(i,fileName) ;
                   m_count[i]=i;    //记录是listctrl中的第几行
                    i++;
            }
        }
        else //查询出的子文件信息
        {
              CString fileName,fileSizeh,fileSizelow,str,fileSize;
             DWORD HfileSize,LfileSize;
              HfileSize=FindFileData.nFileSizeHigh; //记录文件大小的高32位
               LfileSize=FindFileData.nFileSizeLow;   //记录文件大小的低32位
             fileSizeh.Format("%d",HfileSize);
              fileSizelow.Format("%d",LfileSize);
             str=fileSizeh;
              str+=fileSizelow;
              fileSize.Format("%db",atoi(str));    //文件大小****b
                // AfxMessageBox(fileSize);
           //将文件名和大小显示在listctrl控件中
            fileName=FindFileData.cFileName;
            m_filelist.InsertItem(i,fileName);
             m_filelist.SetItemText(i,1,fileSize);
               i++;
        }
        if(!FindNextFile(hFind,&FindFileData))    break;
    }
           FindClose(hFind);
            layernum++;   //记录查询的是第几层
}
3、定义listctrl控件下的左键双击消息:
afx_msg void OnDblclkList1(NMHDR* pNMHDR, LRESULT* pResult); //消息
ON_NOTIFY(NM_DBLCLK, IDC_LIST1, OnDblclkList1)
实现:
void CFileScan::OnDblclkList1(NMHDR* pNMHDR, LRESULT* pResult) 
{
// TODO: Add your control notification handler code here
POSITION pos=m_filelist.GetFirstSelectedItemPosition();
int nItem=m_filelist.GetNextSelectedItem(pos);    //获取双击的行号,从0开始计算
CString listname;
listname=m_filelist.GetItemText(nItem,0);   //得到选中行的文件名
char szFile[MAX_PATH];
strcpy(szFile,m_flpath);


strcat(szFile,"\\");
strcat(szFile,listname);               //得到新的查询路径


if(m_count[nItem]==nItem)           //判断选中行是否为文件夹
{
     for(int i=0;i<MAX_COUNT;i++) //将用来标志子文件夹所在行号信息重新置为-1
             m_count[i]= -1;
     find(szFile);                             //查询当前文件夹的子目录
}
else
{
// CFile file;
  
}

*pResult = 0;
}
4、返回上一层的实现:
void CFileScan::OnFileback() 
{
// TODO: Add your control notification handler code here
        if(layernum>1)   //在进入第二层的查询后才会有返回上一层的操作
       {
                layernum - =2; /*切记是当前层次号减去2,从第二层返回第一层需要的是第0层的路径来进行查询*/
                find(oldpath[layernum].m_oldpath); 
         }
}
1. 1 CString,int,string,char*之间的转换  
2. string 转 CString  
3. CString.format("%s", string.c_str());  
4.  
5. char 转 CString  
6. CString.format("%s", char*);  
7.  
8. char 转 string  
9. string s(char *);  
10.  
11. string 转 char *  
12. char *p = string.c_str();  
13.  
14. //  CString转std::string 
15. CString str = dlg.GetPathName(); 
16. setlocale(LC_ALL, "chs"); 
17. char *p = new char[256]; 
18. wcstombs( p, str, 256 ); 
19. m_fileName = p; 
20.  
21. 1,string -> CString  
22. CString.format("%s", string.c_str());  
23. 用c_str()确实比data()要好.  
24. 2,char -> string  
25. string s(char *);  
26. 你的只能初始化,在不是初始化的地方最好还是用assign().  
27. 3,CString -> string  
28. string s(CString.GetBuffer());  
29. GetBuffer()后一定要ReleaseBuffer(),否则就没有释放缓冲区所占的空间.  
30.  
31.  
32. 《C++标准函数库》中说的  
33. 有三个函数可以将字符串的内容转换为字符数组和C—string  
34. 1.data(),返回没有”\0“的字符串数组  
35. 2,c_str(),返回有”\0“的字符串数组  
36. 3,copy()  
37.  
38.  
39. CString互转int  
40.  
41. 将字符转换为整数,可以使用atoi、_atoi64或atol。  
42. 而将数字转换为CString变量,可以使用CString的Format函数。如  
43. CString s;  
44. int i = 64;  
45. s.Format("%d", i)  
46. Format函数的功能很强,值得你研究一下。  
47.  
48. void CStrDlg::OnButton1()  
49. {  
50. // TODO: Add your control notification handler code here  
51. CString  
52. ss="1212.12";  
53. int temp=atoi(ss);  
54. CString aa;  
55. aa.Format("%d",temp);  
56. AfxMessageBox("var is " + aa);  
57. }  
58.  
59. sart.Format("%s",buf);  
60.  
61. CString互转char*  
62.  
63. ///char * TO cstring  
64. CString strtest;  
65. char * charpoint;  
66. charpoint="give string a value";  
67. strtest=charpoint;  
68.  
69.  
70. ///cstring TO char *  
71. charpoint=strtest.GetBuffer(strtest.GetLength());  
72.  
73. 标准C里没有string,char *==char []==string  
74.  
75. 可以用CString.Format("%s",char *)这个方法来将char *转成CString。要把CString转成char *,用操作符(LPCSTR)CString就可以了。  
76.  
77.  
78. CString转换 char[100]  
79.  
80. char a[100];  
81. CString str("aaaaaa");  
82. strncpy(a,(LPCTSTR)str,sizeof(a));  
83. 2 CString类型的转换成int  
84. CString类型的转换成int  
85. 将字符转换为整数,可以使用atoi、_atoi64或atol。  
86.  
87. //CString aaa = "16" ; 
88. //int int_chage = atoi((lpcstr)aaa) ;  
89.  
90.  
91. 而将数字转换为CString变量,可以使用CString的Format函数。如  
92. CString s;  
93. int i = 64;  
94. s.Format("%d", i)  
95. Format函数的功能很强,值得你研究一下。  
96. 如果是使用char数组,也可以使用sprintf函数。 
97.  
98. //CString ss="1212.12";  
99. //int temp=atoi(ss);  
100. //CString aa;  
101. //aa.Format("%d",temp);  
102.  
103.  
104. 数字->字符串除了用CString::Format,还有FormatV、sprintf和不需要借助于Afx的itoa  
105.  
106. 3 char* 在装int  
107. #include <stdlib.h> 
108.  
109. int atoi(const char *nptr); 
110. long atol(const char *nptr); 
111. long long atoll(const char *nptr); 
112. long long atoq(const char *nptr);  
113.  
114. 4 CString,int,string,char*之间的转换  
115. string aa("aaa"); 
116. char *c=aa.c_str(); 
117.  
118.  
119. cannot convert from 'const char *' to 'char *' 
120. const char *c=aa.c_str();  
121.  
122. 5 CString,int,string,char*之间的转换  
123. string.c_str()只能转换成const char *, 
124. 要转成char *这样写: 
125.  
126. string mngName; 
127. char t[200]; memset(t,0,200); strcpy(t,mngName.c_str());



1..图片操作
此代码放入Onpaint
//编辑图片


//CDialog::OnPaint();//要禁止这个调用   
          CPaintDC   dc(this);   
          CRect   rect;   
          GetClientRect(&rect);                                                                                                                                                                          
          CDC   dcMem;   
          dcMem.CreateCompatibleDC(&dc);                                                                                                            
          CBitmap   bmpBackground;   
          bmpBackground.LoadBitmap(IDB_BITMAP);   
                  //IDB_BITMAP是你自己的图对应的ID   
          BITMAP   bitmap;   
          bmpBackground.GetBitmap(&bitmap);   
          CBitmap   *pbmpOld=dcMem.SelectObject(&bmpBackground);   
          dc.StretchBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,   
         bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);   



2.文件操作


(1)//放在OnInitDialog()中
m_list.InsertColumn(0,"文件名", LVCFMT_LEFT, 100, -1);   //插入列
//m_list.InsertColumn(1,"大小", LVCFMT_LEFT, 100, -1);
m_list.InsertColumn(2,"路径",LVCFMT_LEFT,200,-1);

void CLOVEDlg::OnAddFile() 
{
// TODO: Add your control notification handler code here
//复制文件并记录时间
/*CFileDialog fileDlg(TRUE);
fileDlg.m_ofn.lpstrTitle="添加文件";
fileDlg.m_ofn.lpstrFilter="All Files(*.*)\0*.*\0\0";
int result=fileDlg.DoModal();
if(result==IDOK)
{
CString newpath=path+CString("\\")+fileDlg.GetFileName();
CopyFile(fileDlg.GetPathName(),newpath,FALSE); //拷贝文件
//记录上传
CFile mFile;
mFile.Open(path+CString("\\file.txt"),CFile::modeNoTruncate|CFile::modeWrite);
mFile.SeekToEnd();//移至文件末端输入
//获取当前时间
CTime time=CTime::GetCurrentTime();
CString strTime = time.Format(" %Y-%m-%d %H:%M:%S");
mFile.Write(strTime,strlen(strTime));
mFile.Write("将",2);
mFile.Write(fileDlg.GetPathName(),strlen(fileDlg.GetFileName()));
mFile.Write("上传至共享目录",14);
mFile.Write("\r\n",2);
mFile.Close();
}*/


//打开共享文件
CFileDialog filedlg(TRUE);
if(filedlg.DoModal()==IDOK)
{
CFile file;
//CString strFileSize;
CString path = filedlg.GetPathName();
CString name = filedlg.GetFileName();
//long FileLength = file.GetLength();//文件大小
//strFileSize.Format("%0.1fk", ((float)FileLength)/1024);
LVFINDINFO FindText;
FindText.flags=LVFI_STRING | LVFI_PARTIAL;
FindText.psz = name; 
int index=m_list.FindItem(&FindText,-1);
if(index!=-1)
{
MessageBox("文件已经共享!");
}
else
{
int iCount=GetPrivateProfileInt("Cont","count",0,"d:\\program\\本地共享文件.ini");
iCount++;//将记录写入ini中
CString max;
max.Format("%d",iCount);
::WritePrivateProfileString("cont","count",max,"d:\\program\\本地共享文件.ini");
max="file"+max;
::WritePrivateProfileString(max,"filename",name,"d:\\program\\本地共享文件.ini");
//::WritePrivateProfileString(max,"filepath",strFileSize,"d:\\program\\地共享文件.ini");
::WritePrivateProfileString(max,"filepath",path,"d:\\program\\本地共享文件.ini");
m_list.InsertItem(iCount - 1, name);
//m_list.SetItemText(iCount - 1,1,strFileSize);
m_list.SetItemText(iCount - 1,1,path);
}
}
}
//再打开本地共享文件之前添加一个list control的消息响应函数这样路径才会显示出来
void CLOVEDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CLOVEDlg)
DDX_Control(pDX, IDC_LIST1, m_list);
//}}AFX_DATA_MAP
m_list.InsertColumn(0,"文件名", LVCFMT_LEFT, 100, -1);
m_list.InsertColumn(1,"文件大小", LVCFMT_LEFT, 100, -1);
m_list.InsertColumn(2,"文件路径", LVCFMT_LEFT, 200, -1);


int iCount = GetPrivateProfileInt("Cont","count",0,"d:\\program\\本地共享文件.ini");
CString File;
char name[20];
char size[20];
char path[50];
memset(name, 0, 20);
memset(size, 0, 20);
memset(path, 0, 50);
for(int i = 1; i <= iCount; i++)
{
File.Empty();
File.Format("%d", i);
File = "file" + File;
::GetPrivateProfileString(File,"filename","error",name,20,"d:\\program\\本地共享文件.ini");
::GetPrivateProfileString(File,"filesize","error",size, 20,"d:\\program\\本地共享文件.ini");
::GetPrivateProfileString(File,"filepath","error",path, 50,"d:\\program\\本地共享文件.ini");

m_list.InsertItem(i - 1, name);
m_list.SetItemText(i - 1,1, size);
m_list.SetItemText(i - 1,1, path);
}
}



//删除文件
void CLOVEDlg::OnDelete() 
{
// TODO: Add your control notification handler code here
/*CFileDialog fileDlg(TRUE);
fileDlg.m_ofn.lpstrTitle="删除文件";
fileDlg.m_ofn.lpstrFilter="All Files(*.*)\0*.*\0\0";
fileDlg.m_ofn.lpstrInitialDir=path;//打开共享目录
int result=fileDlg.DoModal();
if(result==IDOK)
{
CString newpath=path+CString("\\")+fileDlg.GetFileName();
DeleteFile(newpath); 
//CFile::Remove( newpath );
//记录删除
CFile mFile;
mFile.Open(path+CString("\\file.txt"),CFile::modeNoTruncate|CFile::modeWrite);
mFile.SeekToEnd();//移至文件末端输入
//获取当前时间
CTime time=CTime::GetCurrentTime();
CString strTime = time.Format("%Y-%m-%d %H:%M:%S");
mFile.Write(strTime,strlen(strTime));
mFile.Write("将",2);
mFile.Write(fileDlg.GetPathName(),strlen(fileDlg.GetPathName()));
mFile.Write("从共享目录中删除",16);
mFile.Write("\r\n",2);
mFile.Close();
}
*/

//将文件从列表中删除
Int clickItem;
CFile file;
//CString strFileSize;
CString max;
CString section;
//long FileLength = file.GetLength();
// strFileSize.Format("%0.2fk", ((float)FileLength)/1024);
m_list.DeleteItem(clickItem);
int iCount = GetPrivateProfileInt("Cont","count",0,"d:\\program\\本地共享文件.ini");
max.Format("%d", iCount - 1);
::WritePrivateProfileString("Cont","count",max,"d:\\program\\本地共享文件.ini");
char name[20];
char path[50];
for(int i = clickItem + 2; i <= iCount; i++)
{
section.Format("%d",i);
section = "file" + section;

::GetPrivateProfileString(section,"filename","error",name,20,"d:\\program\\本地共享文件.ini");
::GetPrivateProfileString(section,"filepath","error",path, 50,"d:\\program\\本地共享文件.ini");
section.Format("%d",i - 1);
section = "file" + section;
::WritePrivateProfileString(section,NULL,NULL,"d:\\program\\本地共享文件.ini");
::WritePrivateProfileString(section,"filename",name,"d:\\program\\本地共享文件.ini");
//::WritePrivateProfileString(section,"filesize",strFileSize,"d:\\program\\本地共享文件.ini");
::WritePrivateProfileString(section,"filepath",path,"d:\\program\\本地共享文件.ini");
}
section.Format("%d",iCount);
section = "file" + section;
::WritePrivateProfileString(section,NULL,NULL,"d:\\program\\本地共享文件.ini");


}


//添加文件,将文件写入TXT文件中
void CLOVEDlg::OnAdd() 
{
// TODO: Add your control notification handler code here
CFileDialog fileDlg(TRUE);//TRUE为OPEN对话框,FALSE为SAVE   AS对话框 
BROWSEINFO bInfo;
ZeroMemory(&bInfo, sizeof(bInfo));
bInfo.hwndOwner=GetSafeHwnd();
bInfo.lpszTitle=_T("请选择共享文件夹的路径:");
bInfo.ulFlags=BIF_RETURNONLYFSDIRS; 
LPITEMIDLIST lpDlist; //用来保存返回信息的IDList
lpDlist=SHBrowseForFolder(&bInfo); //显示选择对话框
if(lpDlist!=NULL) //用户按了确定按钮
{
TCHAR chPath[MAX_PATH]; //用来存储路径的字符串
SHGetPathFromIDList(lpDlist, chPath);//把项目标识列表转化成字符串
CString m_strPath = chPath; //将TCHAR类型的字符串转换为CString类型的字符串
CString prepath=path;
strncpy(path,(LPCTSTR)m_strPath,sizeof(path));
CString newpath1=path+CString("\\file.txt");
CopyFile(prepath+CString("\\file.txt"),newpath1,FALSE);
CString m_flpath=path+CString("\\")+fileDlg.GetFileName();
CString m_flname=fileDlg.GetFileName(); 

CFileDialog   dlg(TRUE);//TRUE为OPEN对话框,FALSE为SAVE   AS对话框 
if   (dlg.DoModal()   ==   IDOK) 
m_flpath=dlg.GetPathName(); 
CFile   file("file.txt",CFile::modeCreate | CFile::modeWrite); 
CString   str1(m_flpath); 
CString   str2(m_flname);
file.Write(str1,strlen(m_flpath));
file.Write(str2,strlen(m_flname));
file.Close();
}
}


(2)//添加文件并显示到List Control
void CFileTransferClientDlg::OnAddFile() //添加文件
{
CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY|OFN_ALLOWMULTISELECT, "All Files(*.*)|*.*||", this);
if(dlg.DoModal() == IDOK)
{
POSITION pos = dlg.GetStartPosition();
int nItem;
while(pos != NULL)
{
CString strPathName = dlg.GetNextPathName(pos);
CFile file;
BOOL bResult = file.Open(strPathName, CFile::modeRead|CFile::shareDenyNone, NULL);
if(!bResult)
continue;
CString strFileName = file.GetFileName();
long lFileLength = file.GetLength();
file.Close();

CString strFileSize;
strFileSize.Format("%0.2fk", ((float)lFileLength)/1024);

nItem = m_SendFileList.InsertItem(0,strFileName);
m_SendFileList.SetItemText(nItem,1,strFileSize);
m_SendFileList.SetItemText(nItem,2,strPathName);

}
}
}



3.窗口操作
//窗口转换
void CLOVEDlg::OnExchenge() 
{
// TODO: Add your control notification handler code here
//CTestDlg DLG;
//DLG.DoModal();
CTestDlg *pDlg = new CTestDlg;
pDlg->Create(IDD_DIALOG1);//要转换的窗口的ID
pDlg->ShowWindow(SW_NORMAL); 
}

//打开窗口
CFileDialog fileDlg(TRUE);
fileDlg.m_ofn .lpstrTitle=TEXT("我的文件打开对话框");
fileDlg.m_ofn .lpstrFilter=TEXT("Text Files(*.txt)\0*.txt\0All Files(*.*)\0*.*\0\0");
    fileDlg.DoModal() ;*


CFileDialog dlg(TRUE);//TRUE为OPEN对话框,FALSE为SAVE对话框
dlg.DoModal();
//消息处理
AfxMessageBox("连接服务器成功!");在vs2005中为AfxMessageBox(L"连接服务器成功!");
if (AfxMessageBox("无法连接服务器!\n重试?",MB_YESNO)==IDNO)
{
AfxMessageBox("连接服务器成功!");
return ;
}

//画对话框背景
BOOL CFileTransferClientDlg::OnEraseBkgnd(CDC* pDC) //画对话框背景

CRect rc;
GetClientRect(&rc);
CBrush brush, *pOldbrush;
brush.CreateSolidBrush(RGB(200, 150, 250));
pOldbrush=pDC->SelectObject(&brush);
pDC->FillRect(&rc, &brush);
pDC->SelectObject(pOldbrush);
return true;
}