AutoCAD 3DMAX C语言 Pro/E UG JAVA编程 PHP编程 Maya动画 Matlab应用 Android
Photoshop Word Excel flash VB编程 VC编程 Coreldraw SolidWorks A Designer Unity3D
 首页 > VC编程

COM 组件设计与应用之简单调用组件

51自学网 2015-08-30 http://www.wanshiok.com

  示例程序

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

 ::CoInitialize( NULL );  HRESULT hr;  // {000209FF-0000-0000-C000-000000000046} = word.application.9  CLSID 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 );  // 取得 IMalloc   if ( 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()。



 
图三、快捷方式中的各种属性
#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,      // 快捷方式 CLSID   NULL,                 // 聚合用(注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 的开发工作啦,您老人家准备好了吗?

 
 
说明
:本教程来源互联网或网友上传或出版商,仅为学习研究或媒体推广,wanshiok.com不保证资料的完整性。

上一篇:用VC++在工具栏上添加平面组合框控件  下一篇:VC++删除浮动工具条中“关闭”按钮