Articles of ATL

复制另一个HBITMAP的位图

我想写一个类来包装位图function在我的程序中。 一个有用的function是从另一个位图句柄复制位图。 我有点卡住了: void operator=( MyBitmapType & bmp ) { HDC dcMem; HDC dcSource; if( m_hBitmap != bmp.Handle() ) { if( m_hBitmap ) this->DisposeOf(); // copy the bitmap header from the source bitmap GetObject( bmp.Handle(), sizeof(BITMAP), (LPVOID)&m_bmpHeader ); // Create a compatible bitmap dcMem = CreateCompatibleDC( NULL ); m_hBitmap = CreateCompatibleBitmap( dcMem, m_bmpHeader.bmWidth, m_bmpHeader.bmHeight ); […]

如何扩展CAxHostWindow?

ATL用于COM ActiveX托pipe的标准类CAxHostWindow不支持接口IDocHostUIHandler2。 我如何扩展CAxHostWindow类为IDocHostUIHandler2支持?

shell扩展不能在Windows-Explorer中工作,但在其他程序中工作?

我使用ATL“由书”做了shell扩展(实现IContextMenu , IShellExtInit , IExtractIcon和IPersistFile )。 有趣的是,在“Total Commander”和“Free Commander”等文件pipe理器中,所有的function都很好,但在Windows资源pipe理器中完全失败: 当我在TC(“Total Commander”)中右键点击我注册的文件(例如*.000 )时,扩展名工作:我在我的日志和上下文菜单中看到它:带有图标的条目出现。 但是如果我使用Win-Explorer,没有任何反应! 没有日志条目出现 ,在上下文菜单没有证据 – 什么都没有! 即使一台完整的电脑重新启动也没有帮助 我当然注册了ShellEx\MyX\ContextMenuHandlers和ShellEx\IconHandler键,以及资源pipe理器的…\Shell Extensions\Approved\ ,他们都指向我的CLSID 。 我使用Windows 7。 我在这里错过什么?

以编程方式创buildWindows Media Player的基本播放

我试图通过COM “快速集成” Windows Media Player来播放本地文件系统或HTTP源中的单个文件 – 但是由于稀疏的文档和在线资源的使用,当没有embedded某种types的Ole容器时,我无法得到所谓的微不足道的用例。 初始化等工作正常,但实际上播放一些文件总是失败。 示例代码,从初始化开始(剥离的error handling,基本上从MSDN上的C#示例转换,在主线程上执行): CComPtr<IWMPPlayer> player; player.CoCreateInstance(__uuidof(WindowsMediaPlayer), 0, CLSCTX_INPROC_SERVER); CComQIPtr<IWMPCore3> core(player); CComPtr<IWMPControls> controls; core->get_controls(&controls); CComPtr<IWMPPlaylist> playlist; core->get_currentPlaylist(&playlist); CComBSTR path("c:\\bar.mp3"); // alternatively http://foo/bar.mp3 玩的第一种方法是“命令不可用” : core->put_url(path); // … waiting after that for WMP to load doesn't make a difference controls->play(); // returns 0x000D1105 – NS_S_WMPCORE_COMMAND_NOT_AVAILABLE 第二种方法只产生S_OK s,但实际上没有任何东西被发挥: CComPtr<IWMPMedia> media; core->newMedia(path, […]

为连接点客户端提供IDispatch实现

我用一个简单的COM对象写了一个简单的COM DLL inproc服务器。 COM对象实现一个连接点。 我知道如何创build一个从IDispEventImpl派生的ATL客户端,并使用汇地图来简化这个过程。 但是,为了演示的目的,我想创build一个win32控制台应用程序,该应用程序使用调用我的简单COM对象的类,然后充当连接点接收器。 我不知道如何提供一个IDispatch的实现 – 有人可以推荐文档,因为我找不到任何(我有ATL内部,但这似乎并不包括我需要)。 这是我已经得到的课程: #pragma once #include <iostream> using namespace std; // Because we're implementing a connection points sink (_IPogFarmEvents) // in a non-ATL class, we must provide implementations for IUnknown and IDispatch. class KidWithAPogFarm : public _IPogFarmEvents { private: DWORD m_dwRefCount; LONG m_lNumPogs; public: KidWithAPogFarm() : m_dwRefCount (0), […]

如何最好地将CString转换为BSTR将其作为“in”parameter passing给COM方法?

我需要将CString实例转换为正确分配的BSTR ,并将该BSTR传递给COM方法。 要使编译和ANSI和Unicode统一工作的代码我使用CString::AllocSysString()将任何格式的CString转换为Unicode BSTR。 由于没有人拥有返回的BSTR,所以我需要照顾它,并在调用完成之后以最安全的方式进行释放,并尽可能使用尽可能less的代码。 目前我使用ATL::CComBSTR进行终身pipe理: ATL::CComBSTR converted; converted.Attach( sourceString.AllocSysString() ); //simply attaches to BSTR, doesn't reallocate it interface->CallMethod( converted ); 我不喜欢这里是我需要两个单独的语句只是构造绑定到转换结果的ATL::CComBSTR 。 有没有更好的方法来完成相同的任务?

为COM接口启用编组需要什么?

我有一个没有types库的32位ATL COM组件。 它有一个给定的类的类工厂,实现了几个接口。 当我使用它作为进程内服务器时,一切正常 – 客户端调用CoCreateInstance(),对象被实例化,QueryInterface()检索指向所请求的接口的指针。 但是,当我把组件到COM +中,我不再可以实例化类 – CoCreateInstance()现在返回E_NOINTERFACE。 我相信问题是COM +不能执行编组,因为没有types库 – 它不知道该怎么做。 我是否需要生成并注册一个types库来解决这个问题,或者还有其他方法吗?

我如何configurationDCOM将我的DLL加载到一个单独的进程?

我试图强制一个现有的本地C + + ATL in-proc COM服务器到一个单独的进程。 我希望DCOM可以做到这一点,而无需更改COM服务器。 我开始使用通常的registry设置 – 我有一个HKCR \ CLSID {classId}条目和一个InProcServer32键指定.dll文件的path。 我生成了一个应用程序ID(GUID)并将其添加到这里和那里。 具体来说,我在HKCR \ CLSID {classId}下添加了一个等同于应用程序ID的string值“AppId”。 我还添加了一个HKCR \ AppId {applicationId}键和一个string值“DllSurrogate”等于一个空string。 我认为这足以迫使我的COM服务器进入一个默认的系统提供的代理。 DCOM应用程序出现在DCOMconfiguration控制台中。 但是,当我调用CoCreateInstance()或CoGetClassObject()并提供类ID和CLSCTX_LOCAL_SERVER它返回“类未注册”。 我究竟做错了什么? UPD:解决。 所采取的步骤足以使其工作,除了我编辑registry的错误的类ID由于某种原因在InProcServer32键下有相同的path – 也许这是一个COM地狱问题。

如何在closures应用程序时禁止“此应用程序中仍有活动的COM对象”错误?

我已经写了几个ATL COM对象,用于在我的C ++ Builder应用程序中进行拖放操作。 由于我无法控制的原因,当用户尝试closures它时,我的应用程序仍然有活动的COM对象。 这是因为使用我的对象的其他COM客户端似乎caching我的COM对象,并不释放它们 – 因此,当用户单击“X”closures我的程序时,我的COM对象仍然有一个大于零的引用计数。 这导致用户得到如下不友好的消息: 我想我的应用程序默默终止,而不是问用户这个烦人的问题。 我如何压制这个信息?

永远不要用ATL CWindowImpl结束WM_PAINT循环

我有一个非常简单的使用CAtlExeModuleT的Win32应用程序。 该模块只需创build一个从CWindowImpl派生的类CTestWindow。 它只有一个WM_PAINT消息处理程序。 在我创build窗口并显示它之后,OnPaint方法(WM_PAINT消息)被无限调用,并由此消耗100%的CPU。 创build窗口的代码非常简单: m_pMainWnd = new CTestWindow(); if(NULL == m_pMainWnd->Create(NULL, CWindow::rcDefault, _T("Test Window"), WS_OVERLAPPEDWINDOW, 0, hMenu)){ DWORD dwErr = GetLastError(); return E_FAIL; } m_pMainWnd->ShowWindow(nShowCmd); OnPaint消息处理程序也很简单(它什么也不做): LRESULT CTestWindow::OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { // TODO: Add your message handler code here and/or call default return 0; }