左键获取当前鼠标选中的文件的路径

C++语言 专栏收录该内容
22 篇文章 0 订阅

右键获取文件名的程序 的方式请百度:Windows Shell扩展编程完全指南.chm  的demo1;

没废话,直接代码~

// ExplorerFileName.cpp : 定义应用程序的入口点。
//
//
//
// 功能:实时获取打开的资源管理器中鼠标左键选中的文件路径及文件名
//
//

#include "stdafx.h"
#include "ExplorerFileName.h"

//包含头文件
#include <windows.h>
#include <shlwapi.h>
#include <shlobj.h>
#include <ExDisp.h>
#pragma comment(lib, "shlwapi.lib")


// 全局变量:
#define MAX_LOADSTRING 100

HINSTANCE hInst;				// 当前实例
TCHAR szTitle[MAX_LOADSTRING];			// 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING];		// 主窗口类名

//定时器
#define MAKETIME 216
//定时器到点执行回调的函数
void CALLBACK RecalcText(HWND hwnd, UINT, UINT_PTR, DWORD);

//窗口宽度,高度
const int g_WndWidth  = 600;
const int g_WndHeight = 400;
//取得的文件路径和文件名
TCHAR g_szPath[MAX_PATH];
TCHAR g_szItem[MAX_PATH];

BOOL    ILIsFile(LPCITEMIDLIST pidl)
{
	BOOL bRet=FALSE;
	LPCITEMIDLIST  pidlChild=NULL;
	IShellFolder* psf=NULL;
	HRESULT    hr = SHBindToParent(pidl, IID_IShellFolder, (LPVOID*)&psf, &pidlChild);
	if (SUCCEEDED(hr) && psf)
	{
		SFGAOF rgfInOut=SFGAO_FOLDER|SFGAO_FILESYSTEM ;
		hr=psf->GetAttributesOf(1,&pidlChild,&rgfInOut);
		if (SUCCEEDED(hr))
		{
			//in file system, but is not a folder
			if( (~rgfInOut & SFGAO_FOLDER) && (rgfInOut&SFGAO_FILESYSTEM) )
			{
				bRet=TRUE;    
			}
		}
		psf->Release();
	}
	return bRet;
}

//定时器
void CALLBACK RecalcText(HWND hWnd, UINT, UINT_PTR, DWORD)
{
	//变量初始化
	BOOL bResult = FALSE;
	BOOL lb_isExplorer = FALSE;
	TCHAR szBuff[256]; 
	BOOL bFile = 0;		 //当前选中项类型 ( 1/2/3 表示:文件/文件夹/当前选择了多项 )
	g_szPath[0] = TEXT('\0');	//选中文件的路径
	g_szItem[0] = TEXT('\0');	//选中文件的文件名

	//获取最前端窗口的句柄
	HWND hExplorer = GetForegroundWindow();
	GetClassName(hExplorer,szBuff,sizeof(szBuff)/sizeof(TCHAR));

	//本机三个操作系统上的explorer.exe窗口类型都是CabinetWClass/ExploreWClass,不知道其他系统是不是,待验证
	if (_tcscmp(szBuff,_T("CabinetWClass")) == 0 || _tcscmp(szBuff,_T("ExploreWClass")) == 0)  
	{
		lb_isExplorer = TRUE;
	}
	if (!lb_isExplorer)
	{
		return;
	}

	IShellWindows *psw = NULL; 
	HRESULT hr = CoCreateInstance(CLSID_ShellWindows,NULL,CLSCTX_ALL,IID_IShellWindows,(void**)&psw);
	if (SUCCEEDED(hr)) 
	{
		//SWC_EXPLORER 指出获取explorer打开的窗口,如果没有打开任何窗口则会调用失败  
		//VISTA及以后的版本可以用SWC_DESKTOP,此时获取的是桌面窗口,即使没有其他shell 窗口,该调用也不会失败.  
		VARIANT v;
		V_VT(&v) = VT_I4;//其含义是,对于指针X,取其指向的对象的vt成员。即 vpidl.vt = VT_I4;  
		v.ulVal = SWC_EXPLORER;//V_VT(&v)如果是VT_I, 或VT_I4子类型,其值将被解释为Shell windows collection 的索引。
		BOOL fFound = FALSE; 
		long count = -1;
		IDispatch  *pdisp; 

		// 获取打开的shell窗口个数.获取数目可能会出错,判断if (pdisp == NULL)即可
		if (SUCCEEDED(psw->get_Count(&count)))  
		{
			//#define V_I4(X)   V_UNION(X, lVal) 
			//#define V_UNION(X, Y)   ((X)->Y)
			for (V_I4(&v) = 0; !fFound && (V_I4(&v) < count); V_I4(&v)++)//V_I4(&v) == v->lVal
			{
				if (SUCCEEDED(psw->Item(v, &pdisp)))
				{
					//如果获取输出错误,一定是获取多了,只有存在的explorer才会有pdisp,其他窗口为空,那就获取下一个!别去查询接口!
					if (pdisp == NULL)	
					{
						continue;
					}
					IWebBrowserApp *pwba;// 这个接口是一个控件接口
					if (SUCCEEDED(pdisp->QueryInterface(IID_IWebBrowserApp, (void**)&pwba))) 
					{
						HWND l_hwnd;
						if (SUCCEEDED(pwba->get_HWND((LONG_PTR*)&l_hwnd)) && l_hwnd == hExplorer) 
						{
							fFound = TRUE;
							IServiceProvider *psp;// 接口类工厂,用于创建另外一些接口对象
							if (SUCCEEDED(pwba->QueryInterface(IID_IServiceProvider, (void**)&psp))) 
							{
								// SID_STopLevelBrowser指出获取最顶层的那个shell窗口.  
								//可以调用该接口的GetControlWindow成员函数,然后再用sp++查看一下,就知道是哪个窗口了。
								IShellBrowser *psb; //Shell浏览器
								if (SUCCEEDED(psp->QueryService(SID_STopLevelBrowser,IID_IShellBrowser, (void**)&psb))) 
								{
									IShellView *psv; //Shell视图
									if (SUCCEEDED(psb->QueryActiveShellView(&psv))) 
									{
										IFolderView *pfv;//文件夹视图
										if (SUCCEEDED(psv->QueryInterface(IID_IFolderView,(void**)&pfv))) 
										{
											//										
											IPersistFolder2 *ppf2;
											if (SUCCEEDED(pfv->GetFolder(IID_IPersistFolder2,(void**)&ppf2))) {
												LPITEMIDLIST pidlFolder;
												if (SUCCEEDED(ppf2->GetCurFolder(&pidlFolder))) {
													//SHGetPathFromIDList 功能是把项目标志符列表转换为文档系统路径
													//pidlFolder--相对 namespace 的根指定一个文档或目录地点的一张项目标识符表的地址 ( 桌面 ) ;
													if (!SHGetPathFromIDList(pidlFolder, g_szPath)) {   //获取文件夹路径
														lstrcpyn(g_szPath, TEXT("<not a directory>"), MAX_PATH);
													}
													bResult = TRUE;
													int iFocus;
													int selectedNmu = 0;

													if (SUCCEEDED(pfv->GetFocusedItem(&iFocus))) 
													{
														if (SUCCEEDED(pfv->ItemCount(SVGIO_SELECTION,&selectedNmu)))
														{
															if (selectedNmu == 1)
															{
																LPITEMIDLIST pidlItem;
																if (SUCCEEDED(pfv->Item(iFocus, &pidlItem))) 
																{
																	IShellFolder *psf;
																	if (SUCCEEDED(ppf2->QueryInterface(IID_IShellFolder,(void**)&psf))) 
																	{
																		STRRET str;
																		if (SUCCEEDED(psf->GetDisplayNameOf(pidlItem,SHGDN_INFOLDER,&str))) 
																		{
																			StrRetToBuf(&str, pidlItem, g_szItem, MAX_PATH);   //获取文件名 
																			bFile = ILIsFile(pidlItem);
																		}//SVSI_SELECT
																		psf->Release();
																	}
																	CoTaskMemFree(pidlItem);  //此函数用于释放被分配的内存块。															
																} 
															}else 
																bFile = 3;
														}																								
													}
													CoTaskMemFree(pidlFolder);
												}
												ppf2->Release();
											}
											pfv->Release(); 
										}
										psv->Release();
									}
									psb->Release();
								}
								psp->Release();
							}
						}
						pwba->Release();
					}
					pdisp->Release();
				}
			}
		}
		psw->Release();
	}
	if (bResult)
	{
		HDC		hdc;
		RECT	rect ;
		HBRUSH hBrush ;

		hdc = GetDC(hWnd);  
		GetClientRect (hWnd, &rect) ;
		hBrush = CreateSolidBrush(RGB(0,0,0));
		FillRect (hdc, &rect, hBrush);
		InvertRect (hdc, &rect) ;

		TextOut(hdc,rect.left, rect.top, g_szPath, lstrlen(g_szPath));
		TextOut(hdc,rect.left, rect.top+20, g_szItem, lstrlen(g_szItem));

		DeleteObject (hBrush) ;
		ReleaseDC(hWnd,hdc);  
	}
}


参考: http://blogs.msdn.com/b/oldnewthing/archive/2004/07/20/188696.aspx

什么?运行不了?我了个艹,当然运行不了,不过主函数都在这了!

VS08完整代码:http://download.csdn.net/download/tpnndhqc/8188545

没错!传资源是就是为了骗分的!友情提示,回复一下分就回来了。别打我,我已经被打过了!啦啦啦啦啦啦~

  • 0
    点赞
  • 4
    评论
  • 3
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:编程工作室 设计师:CSDN官方博客 返回首页

打赏作者

Sping

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值