五、示例程序

示例一、由 CLSID 得到 ProgID。(程序以 word 为例子。如果运行不正确,嘿嘿,你没有安装 word 吧?)

    ::CoInitialize( NULL );HRESULT hr;// {000209FF-0000-0000-C000-000000000046} = word.application.9CLSID clsid = {0x209ff,0,0,{0xc0,0,0,0,0,0,0,0x46}};LPOLESTR lpwProgID = NULL;hr = ::ProgIDFromCLSID( clsid, &lpwProgID );if ( SUCCEEDED(hr) ){::MessageBoxW( NULL, lpwProgID, L"ProgID", MB_OK );IMalloc * pMalloc = NULL;hr = ::CoGetMalloc( 1, &pMalloc );  // 取得 IMallocif ( SUCCEEDED(hr) ){pMalloc->Free( lpwProgID );  // 释放ProgID内存pMalloc->Release();          // 释放IMalloc}}::CoUninitialize();

示例二、如何使用“浏览文件夹”选择对话窗。

CString BrowseFolder(HWND hWnd, LPCTSTR lpTitle)
{// 调用 SHBrowseForFolder 取得目录(文件夹)名称// 参数 hWnd: 父窗口句柄// 参数 lpTitle: 窗口标题char szPath[MAX_PATH]={0};BROWSEINFO m_bi;m_bi.ulFlags = BIF_RETURNONLYFSDIRS  | BIF_STATUSTEXT;m_bi.hwndOwner = hWnd;m_bi.pidlRoot = NULL;m_bi.lpszTitle = lpTitle;m_bi.lpfn = NULL;m_bi.lParam = NULL;m_bi.pszDisplayName = szPath;LPITEMIDLIST pidl = ::SHBrowseForFolder( &m_bi );if ( pidl ){if( !::SHGetPathFromIDList ( pidl, szPath ) )  szPath[0]=0;IMalloc * pMalloc = NULL;if ( SUCCEEDED ( ::SHGetMalloc( &pMalloc ) ) )  // 取得IMalloc分配器接口{pMalloc->Free( pidl );    // 释放内存pMalloc->Release();       // 释放接口}}return szPath;
}

示例三、在窗口中显示一幅 JPG 图象。

void CxxxView::OnDraw(CDC* pDC)
{::CoInitialize(NULL);  // COM 初始化HRESULT hr;CFile file;file.Open( "c:\\aa.jpg", CFile::modeRead | CFile::shareDenyNone );  // 读入文件内容DWORD dwSize = file.GetLength();HGLOBAL hMem = ::GlobalAlloc( GMEM_MOVEABLE, dwSize );LPVOID lpBuf = ::GlobalLock( hMem );file.ReadHuge( lpBuf, dwSize );file.Close();::GlobalUnlock( hMem );IStream * pStream = NULL;IPicture * pPicture = NULL;// 由 HGLOBAL 得到 IStream,参数 TRUE 表示释放 IStream 的同时,释放内存hr = ::CreateStreamOnHGlobal( hMem, TRUE, &pStream );ASSERT ( SUCCEEDED(hr) );hr = ::OleLoadPicture( pStream, dwSize, TRUE, IID_IPicture, ( LPVOID * )&pPicture );ASSERT(hr==S_OK);long nWidth,nHeight;  // 宽高,MM_HIMETRIC 模式,单位是0.01毫米pPicture->get_Width( &nWidth );    // 宽pPicture->get_Height( &nHeight );  // 高原大显示//CSize sz( nWidth, nHeight );pDC->HIMETRICtoDP( &sz );  // 转换 MM_HIMETRIC 模式单位为 MM_TEXT 像素单位pPicture->Render(pDC->m_hDC,0,0,sz.cx,sz.cy,0,nHeight,nWidth,-nHeight,NULL);按窗口尺寸显示
//  CRect rect; GetClientRect(&rect);
//  pPicture->Render(pDC->m_hDC,0,0,rect.Width(),rect.Height(),
//      0,nHeight,nWidth,-nHeight,NULL);if ( pPicture ) pPicture->Release();// 释放 IPicture 指针if ( pStream ) pStream->Release();  // 释放 IStream 指针,同时释放了 hMem::CoUninitialize();
}

示例四、在桌面建立快捷方式
    在阅读代码之前,先看一下关于“快捷方式”组件的结构示意图。


图二、快捷方式组件的接口结构示意图

  从结构图中可以看出,“快捷方式”组件(CLSID_ShellLink),有3个(其实不止)接口,每个接口完成一组相关功能的函数。IShellLink 接口(IID_IShellLink)提供快捷方式的参数读写功能(见图三),IPersistFile 接口(IID_IPersistFile)提供快捷方式持续性文件的读写功能。对象的持续性(注5),是一个非常常用,并且功能强大的接口家族。但今天,我们只要了解其中两函数,就可以了:IPersistFile::Save()和IPersistFile:Load()。(注6)


图三、快捷方式中的各种属性

#include < atlconv.h >
void CreateShortcut(LPCTSTR lpszExe, LPCTSTR lpszLnk)
{// 建立块捷方式// 参数 lpszExe: EXE 文件全路径名// 参数 lpszLnk: 快捷方式文件全路径名::CoInitialize( NULL );IShellLink * psl = NULL;IPersistFile * ppf = NULL;HRESULT hr = ::CoCreateInstance(  // 启动组件CLSID_ShellLink,      // 快捷方式 CLSIDNULL,                 // 聚合用(注4)CLSCTX_INPROC_SERVER, // 进程内(Shell32.dll)服务IID_IShellLink,       // IShellLink 的 IID(LPVOID *)&psl );     // 得到接口指针if ( SUCCEEDED(hr) ){psl->SetPath( lpszExe );  // 全路径程序名
//      psl->SetArguments();      // 命令行参数
//      psl->SetDescription();    // 备注
//      psl->SetHotkey();         // 快捷键
//      psl->SetIconLocation();   // 图标
//      psl->SetShowCmd();        // 窗口尺寸// 根据 EXE 的文件名,得到目录名TCHAR szWorkPath[ MAX_PATH ];::lstrcpy( szWorkPath, lpszExe );LPTSTR lp = szWorkPath;while( *lp )    lp++;while( ''\\'' != *lp )    lp--;*lp=0;// 设置 EXE 程序的默认工作目录psl->SetWorkingDirectory( szWorkPath );hr = psl->QueryInterface(  // 查找持续性文件接口指针IID_IPersistFile,      // 持续性接口 IID(LPVOID *)&ppf );      // 得到接口指针if ( SUCCEEDED(hr) ){USES_CONVERSION;       // 转换为 UNICODE 字符串ppf->Save( T2COLE( lpszLnk ), TRUE );  // 保存}}if ( ppf )   ppf->Release();if ( psl )    psl->Release();::CoUninitialize();
}void OnXXX()
{CreateShortcut(_T("c:\\winnt\\notepad.exe"),  // 记事本程序。注意,你的系统是否也是这个目录?_T("c:\\Documents and Settings\\Administrator\\桌面\\我的记事本.lnk"));// 桌面上建立快捷方式(lnk)文件的全路径名。注意,你的系统是否也是这个目录?// 如果用程序实现寻找桌面的路径,则可以查注册表// HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
}


七、小结

  本回介绍的内容比较实用。大家不要只抄袭代码,而一定要理解它。结合 MSDN 的说明去思索代码、理解其含义。好了,想方设法把代码忘掉!三天后(如过你还没有忘记,那就再过三天),你在不参考示例代码,但可以随便翻阅 MSDN 的情况下,自己能独立地再次完成这四个例程,那么恭喜你,你已经入门了:0) 从下回开始,我们要用 ATL 做 COM 的开发工作啦,您老人家准备好了吗?

作业,留作业啦......
  1、你已经学会如何建立快捷方式了,那么你知道怎么读取它的属性吗?(如果写不出这个程序,那么你就不用继续学习了。因为......动点脑筋呀!我还没有见过象你这么笨的学生呢!)
  2、示例程序三中使用了 IPicture 接口显示一个 JPG 图象。那么你现在去完成一个功能,把 JPG 文件转换为 BMP 文件。


注1:智能指针的概念和用法,后续介绍。
注2:IDL 文件,下回就要介绍啦。
注3:东北话,想干什么都可以,反正我不管啦。
注4:聚合,也许在第30回中介绍吧:-)
注5:持续性,IPersistXXXXXX是一个非常强大的接口家族,后续介绍。
注6:想知道 IShellLink、IPersistFile接口的所有函数吗?别愣着,快去看MSDN呀......
 
最新评论[发表评论][文章投稿] 查看所有评论推荐给好友打印

 // 设置 EXE 程序的默认工作目录
psl->SetWorkingDirectory( szWorkPath );
应该改为:
// 设置 EXE 程序的默认工作目录
psl->SetWorkingDirectory( lp );吧?否则上面的循环去除文件名就没意义了哦!~文章写的狠好!~顶一个
( angeltwb 发表于 2010-10-27 10:47:00)

 杨老师,太感激你了! :) ( xujin1117 发表于 2010-10-21 17:02:00)

 在这里既能学知识,又能学方言,舒服啊! ( clxye 发表于 2010-1-22 9:31:00)

 我在这里把我写的图像转码的代码贴在这里。BOOL CCOMTestDlg::ImageConvert(CFile& fileSrc, CFile& fileTar, CString strType)
{

SIZE_T nSrcSize = fileSrc.GetLength();
HGLOBAL hGlobal = ::GlobalAlloc(GPTR,nSrcSize);
LPVOID pSrcMem = ::GlobalLock(hGlobal);
fileSrc.Read(pSrcMem,nSrcSize);
::GlobalUnlock(hGlobal);
IStream *pStreamSrc,*pStreamTar;
HRESULT hr = ::CreateStreamOnHGlobal(hGlobal,TRUE,&pStreamSrc);
ASSERT(SUCCEEDED(hr));

Image *pImage;
pImage = Image::FromStream(pStreamSrc,FALSE);
CLSID TarImageClsid;
if(!GetEncoderClsid(strType,&TarImageClsid))
{
TRACE(_T("Get specific image clsid error!"));
return FALSE;
}
hGlobal = ::GlobalAlloc(GHND,0);

字符个数有要求,没办法只有分开传

( yg2362 发表于 2009-3-4 16:36:00)

 hr = ::CreateStreamOnHGlobal(hGlobal,TRUE,&pStreamTar);
ASSERT(SUCCEEDED(hr));
pImage->Save(pStreamTar,&TarImageClsid);
SIZE_T nTarMemSize = GlobalSize(hGlobal);
BYTE *pTarMem = (BYTE *)::GlobalLock(hGlobal);
ASSERT(pTarMem);
LARGE_INTEGER liBegin = {0};
//pStreamTar->Seek(liBegin, STREAM_SEEK_SET, NULL);
//fileTar.SeekToBegin();
fileTar.Write(pTarMem,nTarMemSize);
fileTar.Flush();
::GlobalUnlock(hGlobal);
return TRUE;
} ( yg2362 发表于 2009-3-4 16:36:00)

 好奇怪,我做了老师的作业,先用IPicture通过IStream对象去读一个jpg文件.然后再把这个IPicture通过一个IStream对象写到一个Buffer里,再通过这个Buffer写到一个bmp文件中。可是为什么原来那个JPG文件1.7M,可是写到bmp文件里还是1.7M?我感觉图像格式并没有变。 ( smallkey 发表于 2008-5-8 1:07:00)

示例程序 示例一、由 CLSID 得到 ProgID......相关推荐

  1. 【嵌入式】Libmodbus之TCP模式Slave端程序示例

    00. 目录 文章目录 00. 目录 01. 开发TCPSlave端程序流程 02. TCP Slave端程序示例 03. TCP Slave端程序说明 04. 预留 05. 附录 01. 开发TCP ...

  2. 【嵌入式】Libmodbus之TCP模式Master端程序示例

    00. 目录 文章目录 00. 目录 01. TCP模式Master开发流程 02. 读写单个线圈程序示例 03. 读写多个线圈程序示例 04. 读写单个保持寄存器程序示例 05. 读写多个保持寄存器 ...

  3. 【嵌入式】Libmodbus之RTU模式Slave端程序示例

    00. 目录 文章目录 00. 目录 01. 开发RTU Slave端程序流程 02. RTU Slave端程序示例 03. RTU Slave端程序说明 04. 预留 05. 附录 01. 开发RT ...

  4. 【嵌入式】Libmodbus之RTU模式Master端程序示例

    00. 目录 文章目录 00. 目录 01. 软件开发流程 02. 获取版本信息 03. 读写单个线圈程序示例 04. 读写多个线圈程序示例 05. 读写单个保持寄存器程序示例 06. 读写多个保持寄 ...

  5. EGE示例程序——花火闪烁的夜晚

    专栏:EGE专栏 专栏:EGE示例程序 示例程序下载 花火闪烁的夜晚 站点 链接 百度网盘 示例一 花火闪烁的夜晚 CSDN 示例一 花火闪烁的夜晚 (无需积分) 一.烟花   在做烟花特效前,先来看 ...

  6. ASP.NET AJAX示例程序:实现IDragSource和IDropTarget接口将商品拖放至购物车中

    本文来自<ASP.NET AJAX程序设计--第II卷:客户端Microsoft AJAX Library相关>第9章第3节. 9.3 示例程序:实现IDragSource和IDropTa ...

  7. MindSpore部署图像分割示例程序

    MindSpore部署图像分割示例程序 本端侧图像分割Android示例程序使用Java实现,Java层主要通过Android Camera 2 API实现摄像头获取图像帧,进行相应的图像处理,之后调 ...

  8. java聊天程序步骤解析_java网络之基于UDP的聊天程序示例解析

    基于UDP的Socket通信 UDP协议不是一种基于稳定连接的协议,是一种面向数据报包的通信协议,不需要通信双方建立稳定的连接,也没有所谓服务端和客户的概念,数据报包在传输的时候不保证一定及时到达,也 ...

  9. java web程序示例_想要建立一些有趣的东西吗? 这是示例Web应用程序创意的列表。...

    java web程序示例 Interested in learning JavaScript? Get my ebook at jshandbook.com 有兴趣学习JavaScript吗? 在js ...

最新文章

  1. 多重影分身:一套代码如何生成多个小程序?
  2. 如何高效的利用博客园?
  3. Istio所有模块、Service、Pod的功能介绍
  4. 第36-37 Tomcat SVN
  5. 【Redis学习】Redis实现分布式锁
  6. Rabbitmq如何设置优先级队列?如何限流?如何重试?如何处理幂等性?
  7. 使用kubeadm安装kubernetes高可用集群
  8. opengl启动过程
  9. 查看centos硬件配置
  10. CentOS linux系统将UTC时间修改为CST时间
  11. 一本教你如何编写高质量代码的图书:《设计模式之美》
  12. 什么是递归?递归的理解
  13. 什么是Subscript?
  14. 三菱FX5U连接MQTT
  15. 一个好用的软件定时器模块MultiTimer
  16. 天翼云,不要来,千万不要来!开始统计工时,安装监控软件,减少福利!
  17. jquery开发知识总结2
  18. 海量数据搜索、存储、查询、排序算法
  19. keras模型转TensorFlow模型-tensorrt UFF格式
  20. before和after怎么区分_before的用法和如何判断其时态,before和after区别

热门文章

  1. zeplin加载 不出图片_为什么Zeplin不能解决您的所有问题
  2. 模拟购物车页面全选单选的金额累加
  3. 快捷指令 python_不废话,学Python就是这条捷径
  4. 推荐一款好用的 office word 的markdown插件 - Writage
  5. 通过软链接mklink共享node_modules
  6. 多所“双非”跻身软科高校排名百强,特斯拉上海工厂复工在即,余承东嫌汽车芯片单价太贵,今日更多大新闻在此...
  7. Android快速开发之appBase——(4).详解com.snicesoft.Application和BaseActivity
  8. Redis Cluste部署
  9. 一张图看懂docker容器的所有状态
  10. Go语言基础入门(处理JSON)