首页产品库评测行情新闻|手机数码笔记本台式机DIY硬件数字家庭数码相机办公外设|软件下载游戏开发|社区

更多

数码相机
MP4
LCD
机箱
音箱

软件资讯设计 工具 系统 开发 安全 办公 陶吧 IT教育 Vista频道 | 下载中心酷我音乐盒 腾讯QQ
天极网 > 开发频道>COM 组件设计与应用之简单调用组件

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

2005-07-06 14:43作者:杨老师出处:vckbase责任编辑:方舟

  示例程序

  示例一、由 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 的开发工作啦,您老人家准备好了吗?

关注此文的读者还看过:

返回开发频道首页

共2页。 上一页12

软件频道最新更新

热点推荐

IT嘉年华

编辑推荐

软件下载

热门
推荐

网友关注

软件
资料
游戏

装机推荐

文章排行

本周
本月
最新更新
天极服务|关于我们|About us|网站律师|RSS订阅|友情合作|加入我们|天极动态|网站地图|意见反馈|MSN/QQ上看天极
Copyright (C) 1999-2012 Yesky.com, All Rights Reserved 版权所有 天极网络