Articles of ATL

我如何在Linux中使用COM ATL项目?

我有一个小的C ++库,在Visual Studio中作为ATL项目。 我想把它从crossplatfrom。 它将用于Windows和Linux。 它将被包含在我的项目中,该项目使用Qt 4.x. 我怎样才能轻松地转换图书馆?

为TypeLib注册调用CComModule.RegisterServer,_AtlComModule.RegisterServer和LoadTypeLibEx有什么区别?

在我的COM dll的DllRegisterServer方法中,我以前有调用LoadTypeLibEx(module,REGKIND_REGISTER,&pTypeLib)来注册我的COM类和它们相应的TypeLib的代码。 我的COM DLL是一个64位的。 我注意到,在我的64位Vista系统下,在HKCR:\\ TypeLib \ {myguid} \ 1.0 \ 0我find一个win32子项,位置为我的COM DLL。 我也有一些独立的COM DLL中的其他代码,我支持使用较旧的,现在不推荐使用的CComModule.RegisterServer(TRUE)调用。 此代码创build一个64位DLL的0键下的win64子项和一个32位DLL的0键下的win32子项。 我正在使用正确的位版本regsvr32在所有情况下进行注册(将regsvr32位与DLL位的匹配)。 为什么LoadTypeLibEx和_AtlComModule.RegisterServer都不为包含我的TypeLib的64位dll创buildwin64密钥,而较早的CComModule.RegisterServer创build正确的密钥?

分解成Win32函数的ATL类

我想从一个ATL类(我需要指定一个不同的第一个hWnd,ATL通常处理)调用SetWindowPos的Win32版本,但是我不能'爆发'的ATL类,并得到以下错误: error C2661: 'ATL::CWindow::SetWindowPos' : no overloaded function takes 7 arguments 我怎么告诉它我不想在我的基类中使用那个?

什么时候注册types库是必要的?

例如,如果编写一个shell扩展,是否有必要注册与CComModule::RegisterServer (即,我想知道如果调用它与FALSE会导致一些问题)。

如何处理ATLMFC包含文件中的指针截断?

在将我当前的32位应用程序移植到64位的过程中,我添加了编译器选项/ we4302(参考SO 问题说明:移植32位到64位以及Hans Passant的build议答案),我遇到了ATLMFC包含文件似乎有指针截断。 c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\ATLMFC\INCLUDE\afxtempl.h (163) : error C4302: 'type cast' : truncation from 'CControlBar *' to 'long' c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\ATLMFC\INCLUDE\afxtempl.h (163) : error C4302: 'type cast' : truncation from 'HMENU ' to 'long' 我打算将编译器标志永久添加到我们的构build系统,但是如果我们在MFC包含中存在问题,这将是一个坏主意。 所以我的问题是 报告的问题是否是虚假警告? 如果这确实会导致指针截断,那么build议的解决scheme是什么? 在编译系统中添加编译器选项/ we4302是不是一个好主意?

Windows消息循环混淆

我在WTL中有一个GUI窗口,它在CMessageLoop实例中的一个线程内运行,该实例已经添加到应用程序实例并运行。 现在,在主GUI中的一个button处理程序中,我创build一个新窗口。 一旦我点击该button并创build窗口,并尝试将退出消息发布到主GUI循环。 代码: 主窗口,有自己的线程: CMessageLoop theLoop; _MyppModule.AddMessageLoop(&theLoop); if(m_pMyDlg == NULL) { m_pMyDlg = new CMyDlg(); if(!IsWindow(*m_pMyDlg)) { m_pMyDlg->Create(NULL); m_pMyDlg->ShowWindow(SW_SHOW); nRet = theLoop.Run(); _MyppModule.RemoveMessageLoop(); } } button处理程序和子窗​​口创build: LRESULT CMyDlg::OnButtonClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { ChildWindowDlg childDlg; childDlg.Create(m_hWnd); childDlg.ShowWindow(SW_SHOW); CMessageLoop _loop; ); _loop.Run(); ::DestroyWindow(childDlg); return S_OK; } 现在,如果我点击我的MyDlg窗口中的closuresbutton,button的处理程序将被调用,在它内部我::PostQuitMessage但从来没有达到从第一个代码片段theLoop messageloop。 这是在我退出第二个循环后发生的,所以_loop被销毁,子对话被销毁。 这里发生了什么?

删除和replaceCAtlArray中间的对象指针

我有一个CAtlArray保存定义像对象指针 CAtlArray<MyClass*> objPtrArray; 有条件需要更新对象,而不是复制成员,我宁愿只更新指针。 基本上,这在更新中发生: objPtryArray.SetAt( i, newObj ); 我的第一个问题是,我是否需要删除曾经住在我的指针(是的,它被分配了新的)? 我的直觉说是的,但是当我试图做到这个程序崩溃。 我已经尝试了以下的许多变化: delete objPtrArray[i]; objPtrArray.SetAt( i, newObj ); 另一个尝试是: MyClass *tmpObj; tmpObj = objPtrArray[i]; objPtrArray.SetAt( i, newObj ); delete tmpObj; 有任何想法吗? 提前致谢! 编辑:我应该澄清。 在更换指针时程序实际上不会崩溃。 如果我不删除旧的指针,它是好的,对象更新。 但是,如果我删除旧的指针,我会得到奇怪的行为。 例如,对象的一个​​成员char数组可能会从“Hello”变成一个奇怪的字符,如“Ä”。 该程序往往会在几分钟后崩溃。 此外,实际上有多个相同对象指针的CAtlArray – 一个是主数据数组,另一个用于虚拟列表视图。 我也使用SetAt更新虚拟列表数组。 更新: 好的,这个问题与CAtlArray无关。 我试图更新的其中一个指针实际上是指向不同数组中的旧指针(用于pipe理虚拟列表视图),所以这是问题的根源。 因此,删除旧的指针实际上也会删除新的指针。 愚蠢的错误在我的一部分。

什么是WTL CIdleHandler的正确使用?

我正在学习WTL / Win32编程,而且我不太了解CIdleHandler mixin类的devise。 对于WTL 9.1,CMessageLoop代码如下(来自atlapp.h): for(;;) { while(bDoIdle && !::PeekMessage(&m_msg, NULL, 0, 0, PM_NOREMOVE)) { if(!OnIdle(nIdleCount++)) bDoIdle = FALSE; } bRet = ::GetMessage(&m_msg, NULL, 0, 0); if(bRet == -1) { ATLTRACE2(atlTraceUI, 0, _T("::GetMessage returned -1 (error)\n")); continue; // error, don't process } else if(!bRet) { ATLTRACE2(atlTraceUI, 0, _T("CMessageLoop::Run – exiting\n")); break; // WM_QUIT, exit […]

Atl服务不注册

我正在尝试使用注册一个atl服务 ExeName.exe /服务 如下所述: http : //msdn.microsoft.com/en-us/library/74y2334x(VS.80).aspx 这样做后,它不会出现在我的服务控制面板(我通过在Vista上的启动框中键入服务)。 我试图挖掘通过ATL代码,看看它处理/服务开关,但找不到它,虽然我可以find代码来处理/ RegServer和/ UnregServer 这曾经工作,我以前设法注册这项服务。 但是,现在我已经移动了它的位置,不能再次注册。 当我运行ExeName.exe /服务时,如果我首先执行一个/ RegServer,它会作为本地服务器启动,但是我希望它作为服务来安装。 我错过了什么,你知道/服务开关的处理在哪里吗?

将dword的void *表示转换为wstring

我周一有哑巴,所以我发表这样一个新手般的问题,我的道歉。 我正在使用CRegKey.QueryValue从registry中返回一个双字值。 QueryValue将值写入void* pData并将其长度写入ULONG* pnBytes 。 现在有一种方法可以通过stringstream将它从pData转换为wstring。 我来到的最接近的结果是一个hexstring。 我正打算把hex表示法转换成双字节,然后从那里转换成一个string,当我决定只是笨手笨脚地问这里,而不是在这个问题上浪费我一个小时的时间。