MFC记住上次路径---遇到的一些问题

    今天完成一个需求,就是记住用户选择的文件路径,先是熟悉代码,然后在网上找解决方法,一开始感觉没什么,网上的方法差不多,应该很容易做出来,结果真是卡了一半天,到晚上自己才慢慢的搞清楚了。

遇到的问题真不少,记录一下好多细节,真是不写不知道。

2016-08-18 21:35:36补充:

MFC选择文件夹的对话框

VC++------------MFC选择文件夹和文件对话框

1.基本方法

http://blog.csdn.net/shuilan0066/article/details/7302904

http://www.cnblogs.com/Hisin/archive/2012/02/27/2370614.html

这两篇是比较清楚的。

先认识了

SHBrowseForFolder打开文件夹时,每次都是从根目录打开。要记住上次的路径或者设置默认路径,需要写个回掉函数。

CFileDialog会自动记住上次路径

int CALLBACK BrowseCallBackFun(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)  
{  
    switch(uMsg)  
    {  
    case BFFM_INITIALIZED:  //选择文件夹对话框初始化  
     //设置默认路径为lpData即'D:\'  
        ::SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData);  
        //在STATUSTEXT区域显示当前路径  
        ::SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, lpData);  
        //设置选择文件夹对话框的标题  
        ::SetWindowText(hwnd, TEXT("请先设置个工作目录"));   
        break;  
    case BFFM_SELCHANGED:   //选择文件夹变更时  
        {  
            TCHAR pszPath[MAX_PATH];  
            //获取当前选择路径  
            SHGetPathFromIDList((LPCITEMIDLIST)lParam, pszPath);  
            //在STATUSTEXT区域显示当前路径  
            ::SendMessage(hwnd, BFFM_SETSTATUSTEXT, TRUE, (LPARAM)pszPath);  
        }  
        break;  
    }  
    return 0;  
}  
  

回掉函数首先搞清楚参数的意义

2.SHBrowseForFolder函数

 

     打开文件目录对话框,我找到的方法就是使用SHBrowseForFolder函数,这个函数的原型是LPITEMIDLIST SHBrowseForFolder(LPBROWSEINFO lpbi)。函数很简单,就一个返回值和一个参数。参数简单罗列如下

 

typedef struct _browseinfo {

 

     HWND hwndOwner;            // 父窗口句柄

 

     LPCITEMIDLIST pidlRoot;    // 要显示的文件目录对话框的根(Root)

 

     LPTSTR pszDisplayName;     // 保存被选取的文件夹路径的缓冲区

 

     LPCTSTR lpszTitle;         // 显示位于对话框左上部的标题

 

     UINT ulFlags;              // 指定对话框的外观和功能的标志

 

     BFFCALLBACK lpfn;          // 处理事件的回调函数

 

     LPARAM lParam;             // 应用程序传给回调函数的参数

 

     int iImage;                // 文件夹对话框的图片索引

 

} BROWSEINFO, *PBROWSEINFO, *LPBROWSEINFO

 

     一般而言父窗口句柄(hwndOwner)和根(pidlRoot)设置为Null就可以了,pszDisplayName设定一块MAX_PATH大小的缓冲区,跟显示相关的参数就是对话框提示标题(lpszTitle)、对话框样式(ulFlags)、设定对话框的缺省路径的操作(lpfn和lParam)以及对话框任务栏上显示的图标(iImage)。

 

     由于返回值LPITEMIDLIST是一个指向ITEMIDLIST的指针,这个ITEMIDLIST涉及到Windows Shell中关于管理诸如文件、网络上的计算机、控制面板程序、回收站等等对象的知识点,Windows Shell为了识别具体的每一个对象,就使用了ITEMID来唯一识别和区分,而ITEMIDLIST就是一个完整的对象路径。显然这个函数可以用来浏览非文件对象,比如局域网内的电脑等等,在这里这个LPITEMIDLIST返回的对象路径是一个文件夹的路径,Windows提供了一个函数BOOL SHGetPathFromIDList(LPCITEMIDLIST pidl, LPSTR pszPath)来实现从对象路径转化为文件夹路径。

弄清楚每个参数的意义,然后才能按需求设定初值。先太盲目了,只知道套别人的,根本就没有理解。

                LPCITEMIDLIST pidl = NULL;
                BROWSEINFO bi;
                bi.hwndOwner = AfxGetMainWnd()->GetSafeHwnd();
                bi.pidlRoot = NULL;
                bi.pszDisplayName = folderName;
                bi.lpszTitle = _T("请选择用于保存的文件夹");
                bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;;
                bi.lpfn = BrowseCallbackProc;    //回调函数  
                bi.iImage = 0;
                bi.lParam = long(&szPath);  //设置默认路径,传给回掉函数的参数

                pidl = SHBrowseForFolder(&bi);
                if (pidl)
                {        
                    SHGetPathFromIDList(pidl, szPath);
                 }

3.回掉函数

     先看别人说设置全局的静态变量,然后设置静态变量和静态函数,开始编译通不过,要搞清楚类里面怎么写这种特殊的静态变量和函数。

      静态变量初始化,在cpp中,回掉函数的定义.h中static,cpp不需要了。

     感觉回掉函数只是发送了一些消息,根本就没有什么其他的用处,然后有人用lpData设置初始化路径,每次将选中的路径赋值给IpData也可以完成功能。

 

4.记住路径

     在软件开启的时候,设置全局变量,每个更新默认的路径即可,但是重新开启软件的时候,采用先写入注册表中,然后再读注册表的路径,这样就解决了问题。也可以写到ini文件中。

 

 

5.CString与TCHAR数组 相互转换

 TCHAR数组转到CString很简单:使用CString的Format就行。

    TCHAR m_buf[100] = _T("Hello");

    CString str;

    str.Format(L"%s",m_buf);

     现在就来CString转为TCHAR数组,这个就有点麻烦了。因为网上有很多的解决方案,但是都不怎么理想。我们使用_tcscpy()宏。

CString str = L"sssssss";

TCHAR m_buf[20];

_tcscpy(m_buf, str);  //类型之间的转换真麻烦,知道定义这个宏的好处了。

自己找了半天,这个方法很有效!用memcpy,strcpy都不行。。。

TCHAR szDefaultDir[MAX_PATH];
                CString strDef(_T("E:\\"));
                memcpy(szDefaultDir, strDef.GetBuffer(strDef.GetLength() * 2), strDef.GetLength() * 2);
                strDef.ReleaseBuffer();
                szDefaultDir[strDef.GetLength()] = 0;

这样也是一种方法吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值