|
Windows 7 新功能、新发现 - 超强的Windows Search
Windows 7 强化了Windows Search功能,方便使用者在电脑中检索所有的东西,只要按Windows Button在Search Program and File按入你想要的东西就可找尋到相關的Programs, Folder, Documents等在用戶的电脑中。
Windows Search,一个小型的繁忙的后台Windows服务,每个Window用户对它既爱又恨。 Windows Search占用你宝贵的CPU周期并翻来覆去地搜索你的硬盘,用户对它的态度也是爱恨交加,但是它很少得到应有的重视。
就有利方面而言,Windows Search使得查找隐藏文件、数据---以Vista为例---功能、设置等几乎非常容易。你只需要在任何Explorer窗口的搜索框中输入你要搜索的内容,那么你想要的目标几乎可以立刻就能出现。虽然这一功能在Windows XP操作系统中集成地不太好(例如,你不能组织搜索结果或搜索特定的Windows对象),而免费下载的Windows桌面搜索工具(Windows Desktop Search)提供了一个非常不错的集中接口,使得你可以在以数据为中心的数字世界里任意驰骋。
Windows Search for windows7,可以帮助用户轻松找到PC上的文件、Email消息或附件、日程、照片等等任何东西,甚至还可以快速找到其他PC共享文件,或邮件服务器上的内容。
Windows Search for windows7提高了搜索速度和可靠性,并能够同Windows操作系统无缝整合。其他新特性包括:
·支持索引在线邮件,即使没有将邮件下载到本地也可随时搜索其内容,减轻Exchange Server服务器负担。
·支持加密文件系统(EFS)搜索。
·支持远程搜索其他PC上的共享文件。
·支持组策略设置。
我们来亲自体验下基于VS2010与windows 7sdk开发Window Search应用,查询文件夹结构,
代码在windows7上用VS2010调试通过,
详情请见代码
#include #include #include #include #include #pragma comment(lib, "propsys.lib")#pragma comment(lib, "shlwapi.lib")// 一个条件操作返回一个结果。非任意结果。#define MAP_ENTRY(x) {L#x, x}PCWSTR GetOperationLabel(CONDITION_OPERATION op){PCWSTR pszLabel = NULL;static struct { PCWSTR pszLabel; CONDITION_OPERATION op; } const c_rgOperationLabels[] ={MAP_ENTRY(COP_IMPLICIT),MAP_ENTRY(COP_EQUAL),MAP_ENTRY(COP_NOTEQUAL),MAP_ENTRY(COP_LESSTHAN),MAP_ENTRY(COP_GREATERTHAN),MAP_ENTRY(COP_LESSTHANOREQUAL),MAP_ENTRY(COP_GREATERTHANOREQUAL),MAP_ENTRY(COP_VALUE_STARTSWITH),MAP_ENTRY(COP_VALUE_ENDSWITH),MAP_ENTRY(COP_VALUE_CONTAINS),MAP_ENTRY(COP_VALUE_NOTCONTAINS),MAP_ENTRY(COP_DOSWILDCARDS),MAP_ENTRY(COP_WORD_EQUAL),MAP_ENTRY(COP_WORD_STARTSWITH),MAP_ENTRY(COP_APPLICATION_SPECIFIC),};for (ULONG i = 0 ; !pszLabel && i < ARRAYSIZE(c_rgOperationLabels) ; ++i){if (c_rgOperationLabels.op == op){pszLabel = c_rgOperationLabels.pszLabel;}}if (!pszLabel){pszLabel = L"???";}return pszLabel;}//显示在标准输出上一个条件与缩进树。//代码只针对Windows 7和更高版本可以利用ICondition2和IObjectArray优势。//代码为Windows早期版本的搜索也应该使用ICondition和IEnumUnknown。//请注意,这两个函数显示,没有留下明确原因使用搜索条件有所不同#if _WIN32_WINNT >= _WIN32_WINNT_WIN7HRESULT DisplayQuery(ICondition2* pc, int cIndentation){CONDITION_TYPE ct;HRESULT hr = pc->GetConditionType(&ct);if (SUCCEEDED(hr)){switch (ct){case CT_AND_CONDITION:case CT_OR_CONDITION:{wprintf(L"%*s%s/n", 2 * cIndentation, L"", (ct == CT_AND_CONDITION ? L"AND" : L"OR"));IObjectArray* poaSubs;hr = pc->GetSubConditions(IID_PPV_ARGS(&poaSubs));if (SUCCEEDED(hr)){UINT cSubs;hr = poaSubs->GetCount(&cSubs);for (UINT i = 0 ; SUCCEEDED(hr) && i < cSubs ; ++i){ICondition2* pcSub;hr = poaSubs->GetAt(i, IID_PPV_ARGS(&pcSub));if (SUCCEEDED(hr)){DisplayQuery(pcSub, cIndentation + 1);pcSub->Release();}}poaSubs->Release();}}break;case CT_NOT_CONDITION:{wprintf(L"%*s%s/n", 2 * cIndentation, L"", L"NOT");// ICondition::GetSubConditions返回一个检索的结果ICondition2* pcSub;hr = pc->GetSubConditions(IID_PPV_ARGS(&pcSub));if (SUCCEEDED(hr)){DisplayQuery(pcSub, cIndentation + 1);pcSub->Release();}}break;case CT_LEAF_CONDITION:{PROPERTYKEY propkey;CONDITION_OPERATION op;PROPVARIANT propvar;hr = pc->GetLeafConditionInfo(&propkey, &op, &propvar);if (SUCCEEDED(hr)){IPropertyDescription* ppd;hr = PSGetPropertyDescription(propkey, IID_PPV_ARGS(&ppd));if (SUCCEEDED(hr)){PWSTR pszPropertyName;hr = ppd->GetCanonicalName(&pszPropertyName);if (SUCCEEDED(hr)){PROPVARIANT propvarString;hr = PropVariantChangeType(&propvarString, propvar, PVCHF_ALPHABOOL, VT_LPWSTR); // 实际应用中应选择PSFormatForDisplay,但我们希望有更多的“原始”的数据。if (SUCCEEDED(hr)){PWSTR pszSemanticType;hr = pc->GetValueType(&pszSemanticType);if (SUCCEEDED(hr)){//语义类型可以是NULL;若有,不显示它。if (!pszSemanticType){hr = SHStrDup(L"", &pszSemanticType);}if (SUCCEEDED(hr)){wprintf(L"%*sLEAF %s %s %s %s/n", 2 * cIndentation, L"", pszPropertyName, GetOperationLabel(op), propvarString.pwszVal, pszSemanticType);}CoTaskMemFree(pszSemanticType);}PropVariantClear(&propvarString);}CoTaskMemFree(pszPropertyName);}ppd->Release();}PropVariantClear(&propvar);}}break;}}return hr;}#else // _WIN32_WINNT >= _WIN32_WINNT_WIN7HRESULT DisplayQuery(ICondition* pc, int cIndentation){CONDITION_TYPE ct;HRESULT hr = pc->GetConditionType(&ct);if (SUCCEEDED(hr)){switch (ct){case CT_AND_CONDITION:case CT_OR_CONDITION:{wprintf(L"%*s%s/n", 2 * cIndentation, L"", (ct == CT_AND_CONDITION ? L"AND" : L"OR"));IEnumUnknown* peuSubs;hr = pc->GetSubConditions(IID_PPV_ARGS(&peuSubs));if (SUCCEEDED(hr)){IUnknown* punk;while ((hr = peuSubs->Next(1, &punk, NULL)) == S_OK){ICondition* pcSub;hr = punk->QueryInterface(IID_PPV_ARGS(&pcSub));if (SUCCEEDED(hr)){DisplayQuery(pcSub, cIndentation + 1);pcSub->Release();}punk->Release();}peuSubs->Release();}}break;case CT_NOT_CONDITION:{wprintf(L"%*s%s/n", 2 * cIndentation, L"", L"NOT");// ICondition::GetSubConditions 返回一个检索的结果ICondition* pcSub;hr = pc->GetSubConditions(IID_PPV_ARGS(&pcSub));if (SUCCEEDED(hr)){DisplayQuery(pcSub, cIndentation + 1);pcSub->Release();}}break;case CT_LEAF_CONDITION:{PWSTR pszPropertyName;CONDITION_OPERATION op;PROPVARIANT propvar;hr = pc->GetComparisonInfo(&pszPropertyName, &op, &propvar);if (SUCCEEDED(hr)){// The property name may be NULL or "*"; if NULL, display it as such.if (!pszPropertyName){hr = SHStrDup(L"(NULL)", &pszPropertyName);}PROPVARIANT propvarString;hr = PropVariantChangeType(&propvarString, propvar, PVCHF_ALPHABOOL, VT_LPWSTR); // 实际应用中应选择PSFormatForDisplay,但我们希望有更多的“原始”的数据。if (SUCCEEDED(hr)){PWSTR pszSemanticType;hr = pc->GetValueType(&pszSemanticType);if (SUCCEEDED(hr)){// 语义类型可以是NULL;若有,不显示它。if (!pszSemanticType){hr = SHStrDup(L"", &pszSemanticType);}if (SUCCEEDED(hr)){wprintf(L"%*sLEAF %s %s %s %s/n", 2 * cIndentation, L"", pszPropertyName, GetOperationLabel(op), propvarString.pwszVal, pszSemanticType);}CoTaskMemFree(pszSemanticType);}PropVariantClear(&propvarString);}CoTaskMemFree(pszPropertyName);PropVariantClear(&propvar);}}break;}}return hr;}#endif // _WIN32_WINNT >= _WIN32_WINNT_WIN7int wmain(int /* argc */, wchar_t* /* argv */ []){wprintf(L"文件夹机构查询范例/n");wprintf(L"请输入一个在高级查询语法(AQS),或一个空行查询退出/n");wprintf(L"该程序。该项目将解析查询,解决由此产生的条件n");wprintf(L"尝试树的形式显示它:/n");wprintf(L"from:bill modified:last week subject:(cats OR dogs)/n");wprintf(L"name:(bubble NOT bath) author:~~george taken:=0.125 received:5/25/2006 .. 7/17/2007/n");wprintf(L"请注意,这些问题是英语语言的界面。如果您的界面语言/n");wprintf(L"不同的,你可以使用该语言的关键字。需要注意的是/n");wprintf(L"System.IsShared:=否则是一个查询的例子/"canonical syntax/", which/n");wprintf(L"适用于任何用户界面语言,应在使用旧AQS./n");wprintf(L"MSDN on AQS: http://msdn.microsoft.com/en-us/library/aa965711(VS.85).aspx)/n");wprintf(L"还要注意,在任何时间条件下的树结构在星期六,而不是本地时间./n");HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);if (SUCCEEDED(hr)){//这是可能的CoCreateInstance的查询分析器直接使用__uuidof(QueryParser的),但由于使用QueryParserManager,我们可以从查询分析器某用户界面语言和目录编制。IQueryParserManager* pqpm;hr = CoCreateInstance(__uuidof(QueryParserManager), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pqpm));if (SUCCEEDED(hr)){//给IQueryParserManager的语言::CreateLoadedParser应该是用户界面语言应用程序,它通常是作为操作系统的默认界面此用户的语言相同。它用于决定什么语言时使用的解释的关键字IQueryParser* pqp;hr = pqpm->CreateLoadedParser(L"SystemIndex", GetUserDefaultUILanguage(), IID_PPV_ARGS(&pqp));if (SUCCEEDED(hr)){//此示例关闭“自然查询语法”,这是更为宽松和人类的语言一样搜索符号,也使自动搜索的词用了什么的开始位置指定的(这样的投入“的:法案”将搜索来自任何人的名字开头“规则”。hr = pqpm->InitializeOptions(FALSE, TRUE, pqp);WCHAR szLine[1024];while (SUCCEEDED(hr) && fgetws(szLine, ARRAYSIZE(szLine), stdin)[0] != L'/n'){//在解析查询字符串的实际工作都是在这里完成IQuerySolution* pqs;hr = pqp->Parse(szLine, NULL, &pqs);if (SUCCEEDED(hr)){//在这个示例,我们也懒得各方的解析错误,但我们可以区分。请注意,将有一个解决办法,即使有解析错误,它只是可能不用户意图IEnumUnknown* peu;hr = pqs->GetErrors(IID_PPV_ARGS(&peu));if (SUCCEEDED(hr)){if (peu->Skip(1) == S_OK){wprintf(L"Some part of the query string could not be parsed./n");}ICondition* pc;hr = pqs->GetQuery(&pc, NULL);if (SUCCEEDED(hr)){//IQueryCondition::Resolve and IConditionFactory2::ResolveCondition 转任何日期/时间引用(相对,如“今天”,绝对的,如“2009年5月7日”)为绝对日期/时间引用(在星期二的时区),并简化了各种方式的结果。//请注意,电脑是不变的,可以解决对其他日期/时间。代码只针对Windows 7和更高版本可以利用IConditionFactory2::ResolveCondition优势。代码为目标的Windows和Windows早期版本的搜索也应使用IQueryCondition::Resolve。SYSTEMTIME st;GetLocalTime(&st);#if (_WIN32_WINNT >= _WIN32_WINNT_WIN7)IConditionFactory2* pcf;hr = pqs->QueryInterface(IID_PPV_ARGS(&pcf));if (SUCCEEDED(hr)){ICondition2* pcResolved;hr = pcf->ResolveCondition(pc, SQRO_DEFAULT, &st, IID_PPV_ARGS(&pcResolved));if (SUCCEEDED(hr)){hr = DisplayQuery(pcResolved, 0);pcResolved->Release();}pcf->Release();}#else // _WIN32_WINNT >= _WIN32_WINNT_WIN7ICondition* pcResolved;//由于IConditionFactory::Resolve ,我们必须使用SQRO_DONT_SPLIT_WORDS表现得像IConditionFactory2::ResolveCondition,我们希望保持自然短语间断。hr = pqs->Resolve(pc, SQRO_DONT_SPLIT_WORDS, &st, &pcResolved);if (SUCCEEDED(hr)){hr = DisplayQuery(pcResolved, 0);pcResolved->Release();}#endif // _WIN32_WINNT >= _WIN32_WINNT_WIN7pc->Release();}peu->Release();}pqs->Release();}}pqp->Release();}pqpm->Release();}CoUninitialize();}return SUCCEEDED(hr) ? EXIT_SUCCESS : EXIT_FAILURE;}
欢迎技术交流!
本文作者专著《Visual C++2010开发权威指南》即将推出,敬请关注,Visual C++2010最近技术,Windows7开发最新技术! |
|