• Visual C++的STL和CComPtr的一个问题

    发表于 2009年05月28日 魏 拾俊 没有评论

    今天在编写IFilter插件的时候,发现一个STL和CComPtr问题(Visual C++ / Visual Studio 2008):

    我定义了一个数组:

    std::vector<CComPtr<ICANode> > arrayNodes;

    当我对这个数组排序的时候:

    std::sort(arrayNodes.begin(), arrayNodes.end(), CompareNodeByID);

    出现了一个断言失败,位于atlcomcli.h第149行,如下:

        //The assert on operator& usually indicates a bug. If this is really
        //what is needed, however, take the address of the p member explicitly.
        T** operator&() throw()
        {
            ATLASSERT(p==NULL);
            return &p;
        }

    在这个函数之前,这里有一个说明,ATL的作者认为通常来说,对于一个CComPtr对象获得地址,一般是用来给这个对象赋予一个新的值,就像QueryInterface那样。所以,在这个时候,p本身的值,应该是空。

    然后经过跟踪,发现是std::sort这里在调用&操作符(<utility>文件):

    template<class _Ty> inline
        void swap(_Ty& _Left, _Ty& _Right)
        {    // exchange values stored at _Left and _Right
        if (&_Left != &_Right)
            {    // different, worth swapping
            _Ty _Tmp = _Left;
            _Left = _Right;
            _Right = _Tmp;
            }
        }

    排序的时候要交换元素得值,这里先比较两个元素的地址,是否相同。如果相同,认为是同一个元素,就不交换了。在这里调用&操作符,用于比较元素的地址。这里的元素,就是CComPtr对象。而在这里,对象本身的值,当然不为空,结果就出现了断言失败。

    目前没有找到好的解决办法。好在Release版本,不会出现问题。

  • ToolBar的一个奇怪现象

    发表于 2009年05月13日 魏 拾俊 没有评论

    ToolBar的一个奇怪现象

    将CyberArticle Express工具栏修改成标准的Windows工具栏(使用CToolBarCtrl),结果发现一个奇怪的现象:

    如果工具栏按钮包含下拉按钮BTNS_DROPDOWN,而且工具栏具有TBSTYLE_EX_DRAWDDARROWS和TBSTYLE_FLAT风格,则工具栏按钮在某些情况下,会变得很大(例如更改Theme,或者某些系统下面,锁定计算机,然后再恢复)。

    经过检查,原来这是COMCTL32的一个问题:在MFC的CToolBar这个类里面,修复了这个问题,但是CToolBarCtrl没有修复这个问题。

    下面是bartool.cpp里面的一段说明

    //  In comctl32 version 6.00 when using XP Look combined with TBSTYLE_EX_DRAWDDARROWS
    // style minimal sizing policy was changed to be
    //   button.height >= image.height + 13
    //   button.width >= image.width + 16
    // this force buttons to be bigger then usual
    // To override this behavior we should remove TBSTYLE_EX_DRAWDDARROWS prior to sizing operations
    //

    在CToolBarCtrl派生类里面,增加消息处理。下面的代码,是从bartool.cpp里面找到的。

    ON_MESSAGE(WM_SETTINGCHANGE, OnPreserveZeroBorderHelper)
    ON_MESSAGE(WM_SETFONT, OnPreserveZeroBorderHelper)
     
    LRESULT CWizToolBarCtrlEx::OnPreserveZeroBorderHelper(WPARAM, LPARAM)
    {
        int _afxComCtlVersion = _AfxGetComCtlVersion();
        //
        BOOL bModify = FALSE;
        ASSERT(_afxComCtlVersion != -1);
        DWORD dwStyle = 0;
        DWORD dwStyleEx = 0;
        if (_afxComCtlVersion >= VERSION_IE4)
        {
            dwStyle = GetStyle();
            bModify = ModifyStyle(0, TBSTYLE_TRANSPARENT|TBSTYLE_FLAT);
            if ((_afxComCtlVersion >= VERSION_6) && ::IsWindow(m_hWnd))
            {
                dwStyleEx = SetExtendedStyle(GetExtendedStyle() &~ TBSTYLE_EX_DRAWDDARROWS);
            }
        }
        LRESULT lResult = Default();
        if (bModify)
        {
            SetWindowLong(m_hWnd, GWL_STYLE, dwStyle);
        }
        if (dwStyleEx & TBSTYLE_EX_DRAWDDARROWS)
        {
            SetExtendedStyle(dwStyleEx);
        }
        return lResult;
    }
     
    处理后可以解决这个问题
  • Visual Studio 2008使用体验

    发表于 2009年05月9日 魏 拾俊 没有评论

    Visual Studio 2008使用体验

    为了是程序具有Vista界面,尤其是一些通用对话框,例如打开/保存文件对话框,安装Visual Stuido 2008进行升级(未安装VS2008Sp1)。

    安装后,遇到以下问题

    1:VS2008里面的ATL,少了一些文件,缺少的这些文件,被当成ATL Server作为开源软件发布了。下载ATL Server源代码可以解决。

    2:VS2008不再使用/wp64参数,编译的时候。会出现很多警告。用VS2008打开所有的vcproj文件(作为XML文件打开),全部替换里面的Detect64BitPortabilityProblems=”true”为空,保存文件。

    3:其他一些比较简单的兼容问题,例如某些类型重复定义,很容易解决。

    4:编译工程的时候,出现了很多编译器错误问题。

    下载

    http://connect.microsoft.com/VisualStudio/Downloads/DownloadDetails.aspx?DownloadID=11399

    http://code.msdn.microsoft.com/KB946040/Release/ProjectReleases.aspx?ReleaseId=921

    安装这两个补丁后,解决编译出错问题。

    目前未发现其他问题。