RSS 2.0 Feed

Monday, October 06, 2008

In Visual C# 2005 SP1, I added an object data source to a web page that uses my business class as the select method. The method has one parameter of type Guid. The data source wizard generates code like this

<asp:Parameter DbType="Guid" Name="rowId" />

Although the web server has .Net 2.0 SP1 installed (I checked the registry), it still throws an error

Type 'System.Web.UI.WebControls.Parameter' does not have a public property named 'DbType'

The walk around is easy:

<asp:Parameter Type="Object" Name="rowId" />

posted @ | Feedback (0) |

Tuesday, April 08, 2008

Visual C++项目组今天发布了Visual C++ 2008 Feature Pack。这个Feature Pack包含了一些以前需要付费给BCG Soft才可以使用的控件,例如BCG著名的窗口布局和风格自定义功能,不过也有一些有用的控件,例如文件夹列表文件夹树属性窗格等等。

这个Feature Pack也包含从Dinkumware获得授权的一些对STL的扩展,实现了TR1草案。这包含新的随机算法、集合类和正则表达式支持。关于TR1的更多信息,可以参考Dinkumware的网站

安装了这个Feature Pack之后,生成的应用程序在发布时需要同时发布新版本的MFC和CRT组件。预计对这个Feature Pack的技术支持策略会和VC6中从Dinkumware获得授权的STL库会是一个级别,也就是说,BCG Soft、Dinkumware和微软都会提供技术支持。如果在安装了这个Feature Pack之后需要安装Windows SDK 6.1,那么在安装完SDK之后需要修复Visual Studio 2008以保持文件是最新的。

目前发布的这个补丁只支持英文版的Visual Studio 2008 标准版或更高版本,其他语言版的Visual Studio 2008 要获得这些新的功能的话,需要等到Visual Studio 2008 SP1发布。Visual Studio 2008会包含这个Feature Pack。

posted @ | Feedback (0) |

Monday, January 07, 2008

一个面向Visual C++ 2008的MFC更新测试版已经发布,同时也提供了文档的下载。这个版本包含新的界面的特性,例如Office Ribbon、2003和XP风格,Visual Studio风格和MDI标签。另外,这个版本也包含部分TR1的实现,例如正则表达式、更加丰富的集合和智能指针。

另外,在下载页面居然说这个版本还不支持Visual Studio 2008 Service Pack 1的Beta版,正式版才出来几天SP1的测试版就出来了?

posted @ | Feedback (1) |

Thursday, December 20, 2007

在未安装Visual C++ 2005 的计算机上运行使用 Visual C++ 2005开发的应用程序,必须先安装Visual C++ 2005 运行时刻库组件。Visual C++ 2005 SP1更新了这个组件,所以使用Visual C++ 2005 SP1 开发的应用程序必须随程序发布Visual C++ 2005 SP1运行时刻库组件。但是Visual C++ 2005 SP1的一个BUG造成使用安装和部署项目进行部署的时候,安装程序可能安装原版的Visual C++ 2005 运行时刻库组件,而不是SP1版本,造成使用Visual C++ 2005 SP1 开发的应用程序启动失败。这个问题的原因是%Program Files%Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages\vcredist_x86下面的product.xml中的产品代码在安装Visual C++ 2005 SP1的过程中没有更新。要修正这个问题,可以打开这个文件,修改如下两行

<MsiProductCheck Property="VCRedistInstalled" Product="{A49F249F-0C91-497F-86DF-B2585E8E76B7}"/>

<BypassIf Property="VCRedistInstalled" Compare="ValueGreaterThanOrEqualTo" Value="3"/>

<MsiProductCheck Property="VCRedistInstalled" Product="{7299052b-02a4-4627-81f2-1818da5d550d}"/>

<BypassIf Property="VCRedistInstalled" Compare="ValueGreaterThanOrEqualTo" Value="5"/>

另外,Visual C++ 2005 SP1版本的可以用最新的Visual C++ 2005 SP1运行时刻库组件来替换%Program Files%Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages\vcredist_x86下面的vcredist_x86.exe,这样安装和部署项目产生的安装程序中会包含最新版的组件。

posted @ | Feedback (2) | Filed Under [ 集成开发环境(IDE) ]

Monday, November 19, 2007

今天一个项目进行到测试阶段,把开发用的数据库结构导出到测试用的数据库,之后移动数据库关系图,正想着没问题的时候,程序报错,一个存储过程没找到。先以为是导出出了问题,但是重新创建存储过程的时候SQL Server却报告对象已存在,不能创建同名对象。上网搜索错误消息之后找到一个解决方案,执行http://support.microsoft.com/kb/827448这里的存储过程就可以解决问题。回想起来,原因可能是部分存储过程导出失败,之后导入数据库关系图的时候把这些存储过程的属性也导入了,但是没有导入sysobjects表里面对应的记录。2005版本的数据库关系图存在sysdiagrams表里面,倒起来容易多了。

P.S. 重命名存储过程之后要记得更新存储过程的SQL脚本里面的过程名称。

posted @ | Feedback (1) |

Monday, November 12, 2007

Visual C++类库组的Ale Contenti在欧洲TechEd上宣布MFC将会有新的界面支持。这些风格将会包含微软的旗舰产品使用的界面风格,

wizard1

例如Visual Studio

VS2005 Docking (edit)

和Office。

Wizard Generated with accelerator tips

根据Channel9对Pat Brenner的采访,这个更新是微软从BCGSoft获得授权的(更新:BCGSoft的官方声明在此)。预计的测试版本发布日期是明年第一季度,正式发布日期在明年上半年。CodeJock对这个消息肯定不会高兴,个人认为他们的MFC扩展库比BCGSoft要强,但是他们的价格也比BCGSoft要贵。微软和BCGSoft的合作肯定会改进BCG类库的文档质量,或许也会改进性能和代码质量。微软加入这两家的竞争之后或许会逼得CodeJock降低其产品价格。这样经常写界面的程序员的工作会变得容易,这个更新对那些想给老MFC程序换上新的漂亮界面的项目应该很有用。

微软负责开发工具的副总裁Somasegar也同时宣布Visual C++对TR1的支持。由于VC更新的滞后,很多程序员都使用其它开发工具来编写界面,而使用Visual C++来写底层,所以MFC的更新对VC程序员的影响还不如可以由编译器决定类型的关键字对于C++会更加有用。想跟踪C++新标准的进度的程序员可以去C++标准化委员会的网页去看看。

posted @ | Feedback (10) |

Saturday, August 11, 2007

在Biztalk项目中想作分层,把一些代码搬到类库项目以便于单元测试,但是加了引用之后Biztalk的Schema Mapper在打开Biztalk Transform Map (btm)的时候IDE报错,找不到schema。现在想到的解决办法是再分几层,现在项目结构大概是这样

Database Layer Schema Layer Custom Decoder Component
Business Layer Map Layer Custom Pipeline
Orchestration Port

这样map项目只引用Schema项目,就不会抱错误了。但是遗留的一个问题是,这样数据库层的Schema就不能直接在map里面用了,要自己定义一个schema,用xsd.exe生成一个xml schema相同的类加入到business layer,然后在Orchestration这一层做Serialize。

posted @ | Feedback (1) |

Sunday, July 29, 2007

image

Visual Studio 2008 Beta2中的Class Designer终于支持C++了,上面是一个MFC程序的类图,可以看到已经支持扩展MFC的宏了,可惜只能看不能重构代码。尽管Class Designer这功能相当不错,但是设计师们可能还是更习惯IBM 的Rational Rose Developer for Visual Studio和UML。我用Class Designer的C#支持的时候也就是加加注释而已,重构我更习惯用DevExpress提供的工具Refactor来做,类则用XSD.exe生成,因为Class Designer生成的属性只会扔NotImplementedException异常。

Visual C++项目组在做下一个版本的市场调查,有兴趣的可以去提提要求。

posted @ | Feedback (4) |

Tuesday, July 03, 2007

截至MFC 9.0(Visual Studio 2008)Beta1版本为止CHtmlView还不支持Windows XP SP2中IE新增的NewWindow3事件,但是在atlmfc\src\viewhtml.cpp源代码里面已经有了其他事件的处理代码,要加上NewWindow3的支持也很简单。

添加下面几行到你对CHtmlView的派生类的声明内 (在此示例中姑且名为CHtmlViewTestView)

void NewWindow3(     
        IDispatch **ppDisp,
        VARIANT_BOOL *Cancel,
        DWORD dwFlags,
        BSTR bstrUrlContext,
        BSTR bstrUrl
    );

DECLARE_EVENTSINK_MAP()

添加下面几行到你对CHtmlViewTestView的实现源文件

#include <exdisp.h> //For IWebBrowser2* and others
#include <exdispid.h>
#include <Mshtml.h>
#include <Mshtmdid.h>
#include <shobjidl.h>

BEGIN_EVENTSINK_MAP(CHtmlViewTestView, CHtmlView)
    ON_EVENT(CHtmlViewTestView, AFX_IDW_PANE_FIRST,DISPID_NEWWINDOW3,NewWindow3,VTS_PDISPATCH VTS_PBOOL VTS_I4 VTS_BSTR VTS_BSTR)
END_EVENTSINK_MAP()

void CHtmlViewTestView::NewWindow3(     
    IDispatch **ppDisp,
    VARIANT_BOOL *Cancel,
    DWORD dwFlags,
    BSTR bstrUrlContext,
    BSTR bstrUrl
)
{
    CDocTemplate* pDocTemplate=GetDocument()->GetDocTemplate();
    CDocument* pDocument=pDocTemplate->OpenDocumentFile(NULL);
    POSITION pos= pDocument->GetFirstViewPosition();
    CHtmlViewTestView* pNewView=(CHtmlViewTestView*)pDocument->GetNextView(pos);
    pNewView->SetRegisterAsBrowser(TRUE);
    *ppDisp=pNewView->GetApplication();
}

在CHtmlView派生类里面处理ShowHtmlDialog比较麻烦一点,需要扩展控件站点,但是MFC对控件站点的扩展是不可复用的。MFC里面的两个浏览器控件封装类 CHtmlView和CDHtmlDialog甚至没有共享任何代码,而是使用几乎相同的代码来做完全一样的事情:重定向IDocHostUIHandler 的方法。CHtmlView用的扩展叫做 CHtmlControlSite,甚至都不在MFC头文件里面,而CDHtmlDialog用的 CBrowserControlSite在afxdhtml.h这个文件里面,暴露了GetInterfaceHook,留下了一点扩展的空间。

现在回到CHtmlView。要创建一个控件站点的扩展,你需要重载CWnd::CreateControlSite。这个函数是在MFC 7.0里面为扩展浏览器空间量身定做的,但是在MFC 8.0里面也被用于嵌入.Net里面的Windows Forms控件。

BOOL CHtmlViewTestView::CreateControlSite(COleControlContainer* pContainer,
   COleControlSite** ppSite, UINT /* nID */, REFCLSID /* clsid */)
{
    ASSERT(ppSite != NULL);
    *ppSite = new CExtendedHtmlControlSite(pContainer,this);
    return TRUE;
}

实际上,pContainer->m_pWnd 就是第二个参数this (CHtmlViewTestView),,所以我应该可以省下一个参数,把pContainer->m_pWnd 转换成CHtmlViewTestView;但是在我写这个类的时候还不知道这一点。

控件站点的扩展需要扩展COleControlSite,一个在MFC 6.0里面未公开的类,但是在MFC 7.0里面被公开了,用来支持类级别的控件站点扩展。在这之前,你只能够调用AfxEnableControlContainer来替换全局的控件容器工厂。

class CExtendedHtmlControlSite :
    public COleControlSite
{
public:
    CExtendedHtmlControlSite(COleControlContainer* pContainer,CHtmlViewTestView* pView);
    virtual ~CExtendedHtmlControlSite(void);
protected:
    CHtmlViewTestView* m_pView;
}

CExtendedHtmlControlSite::CExtendedHtmlControlSite(COleControlContainer* pContainer,CHtmlViewTestView* pView)
:COleControlSite(pContainer),m_pView(pView)
{
}

CExtendedHtmlControlSite::~CExtendedHtmlControlSite(void)
{
}

这里m_pView被存下来用于重定向INewWindowManager的方法到CHtmlViewTestView类.。

现在说到有趣的部分了。实际上,浏览器控件并不查询控件站点扩展的INewWindowManager接口,而是调用控件站点扩展对IServiceProvider::QueryService的实现。所以我需要先实现IServiceProvider,在浏览器控件进行服务查询时返回我自己的INewWindowManager。

    BEGIN_INTERFACE_PART(ServiceProvider, IServiceProvider)
        STDMETHOD(QueryService)(REFGUID,REFIID,void**);
    END_INTERFACE_PART(ServiceProvider)

    BEGIN_INTERFACE_PART(NewWindowManager, INewWindowManager)       
        STDMETHOD(EvaluateNewWindow)(
            LPCWSTR pszUrl,
            LPCWSTR pszName,
            LPCWSTR pszUrlContext,
            LPCWSTR pszFeatures,
            BOOL fReplace,
            DWORD dwFlags,
            DWORD dwUserActionTime);
    END_INTERFACE_PART(NewWindowManager);

ULONG FAR EXPORT CExtendedHtmlControlSite::XServiceProvider::AddRef()
{
    METHOD_PROLOGUE(CExtendedHtmlControlSite, ServiceProvider)
    return pThis->ExternalAddRef();
}

ULONG FAR EXPORT CExtendedHtmlControlSite::XServiceProvider::Release()
{                           
    METHOD_PROLOGUE(CExtendedHtmlControlSite, ServiceProvider)
    return pThis->ExternalRelease();
}

HRESULT FAR EXPORT CExtendedHtmlControlSite::XServiceProvider::QueryInterface(REFIID riid,
    void** ppvObj)
{
    METHOD_PROLOGUE(CExtendedHtmlControlSite, ServiceProvider)
    HRESULT hr = (HRESULT)pThis->ExternalQueryInterface(&riid, ppvObj);
    return hr;
}
STDMETHODIMP CExtendedHtmlControlSite::XServiceProvider::QueryService(REFGUID guidService, 
    REFIID riid,
    void** ppvObject)
{
    if (riid == IID_INewWindowManager)
    {
        METHOD_PROLOGUE(CExtendedHtmlControlSite, ServiceProvider);
        HRESULT hr = (HRESULT)pThis->ExternalQueryInterface(&riid, ppvObject);
        return hr;
    }
    else
    {
        *ppvObject = NULL;

    }
    return E_NOINTERFACE;
}

ULONG CExtendedHtmlControlSite::XNewWindowManager::AddRef()
{
    METHOD_PROLOGUE(CExtendedHtmlControlSite, NewWindowManager);

    return pThis->ExternalAddRef();
}

ULONG CExtendedHtmlControlSite::XNewWindowManager::Release()
{
    METHOD_PROLOGUE(CExtendedHtmlControlSite, NewWindowManager);

    return pThis->ExternalRelease();
}

HRESULT CExtendedHtmlControlSite::XNewWindowManager::QueryInterface(REFIID riid, void ** ppvObj)
{
    METHOD_PROLOGUE(CExtendedHtmlControlSite, NewWindowManager);

    return pThis->ExternalQueryInterface( &riid, ppvObj );
}

HRESULT CExtendedHtmlControlSite::XNewWindowManager::EvaluateNewWindow(
LPCWSTR pszUrl,
LPCWSTR pszName,
LPCWSTR pszUrlContext,
LPCWSTR pszFeatures,
BOOL fReplace,
DWORD dwFlags,
DWORD dwUserActionTime
)
{
    METHOD_PROLOGUE(CExtendedHtmlControlSite, NewWindowManager);

    return pThis->m_pView->EvaluateNewWindow(
        pszUrl,
        pszName,
        pszUrlContext,
        pszFeatures,
        fReplace,
        dwFlags,
        dwUserActionTime);
}

实际上,我可以在另外一个类中实现INewWindowManager,然后在服务查询中返回该类的一个对象,但是由于INewWindowManager只被用来扩展浏览器控件的控件站点,这个单独的INewWindowManager实现并不能被重用。

最后,为了让CHtmlView的IDocHostUIHandler方法继续工作,我需要重定向IDocHostUIHandler的方法:

DECLARE_INTERFACE_MAP()

    BEGIN_INTERFACE_PART(DocHostUIHandler, IDocHostUIHandler)
        STDMETHOD(ShowContextMenu)(DWORD, LPPOINT, LPUNKNOWN, LPDISPATCH);
        STDMETHOD(GetHostInfo)(DOCHOSTUIINFO*);
        STDMETHOD(ShowUI)(DWORD, LPOLEINPLACEACTIVEOBJECT,
            LPOLECOMMANDTARGET, LPOLEINPLACEFRAME, LPOLEINPLACEUIWINDOW);
        STDMETHOD(HideUI)(void);
        STDMETHOD(UpdateUI)(void);
        STDMETHOD(EnableModeless)(BOOL);
        STDMETHOD(OnDocWindowActivate)(BOOL);
        STDMETHOD(OnFrameWindowActivate)(BOOL);
        STDMETHOD(ResizeBorder)(LPCRECT, LPOLEINPLACEUIWINDOW, BOOL);
        STDMETHOD(TranslateAccelerator)(LPMSG, const GUID*, DWORD);
        STDMETHOD(GetOptionKeyPath)(OLECHAR **, DWORD);
        STDMETHOD(GetDropTarget)(LPDROPTARGET, LPDROPTARGET*);
        STDMETHOD(GetExternal)(LPDISPATCH*);
        STDMETHOD(TranslateUrl)(DWORD, OLECHAR*, OLECHAR **);
        STDMETHOD(FilterDataObject)(LPDATAOBJECT , LPDATAOBJECT*);
    END_INTERFACE_PART(DocHostUIHandler)

 

STDMETHODIMP CExtendedHtmlControlSite::XDocHostUIHandler::GetExternal(LPDISPATCH *lppDispatch)
{
    METHOD_PROLOGUE_EX_(CExtendedHtmlControlSite, DocHostUIHandler)
    return pThis->m_pView->OnGetExternal(lppDispatch);
}STDMETHODIMP CExtendedHtmlControlSite::XDocHostUIHandler::ShowContextMenu(
    DWORD dwID, LPPOINT ppt, LPUNKNOWN pcmdtReserved, LPDISPATCH pdispReserved)
{
    METHOD_PROLOGUE_EX_(CExtendedHtmlControlSite, DocHostUIHandler)
    return pThis->m_pView->OnShowContextMenu(dwID, ppt, pcmdtReserved, pdispReserved);
}STDMETHODIMP CExtendedHtmlControlSite::XDocHostUIHandler::GetHostInfo(
    DOCHOSTUIINFO *pInfo)
{
    METHOD_PROLOGUE_EX_(CExtendedHtmlControlSite, DocHostUIHandler)
    return pThis->m_pView->OnGetHostInfo(pInfo);
}STDMETHODIMP CExtendedHtmlControlSite::XDocHostUIHandler::ShowUI(
    DWORD dwID, LPOLEINPLACEACTIVEOBJECT pActiveObject,
    LPOLECOMMANDTARGET pCommandTarget, LPOLEINPLACEFRAME pFrame,
    LPOLEINPLACEUIWINDOW pDoc)
{
    METHOD_PROLOGUE_EX_(CExtendedHtmlControlSite, DocHostUIHandler)
    return pThis->m_pView->OnShowUI(dwID, pActiveObject, pCommandTarget, pFrame, pDoc);
}STDMETHODIMP CExtendedHtmlControlSite::XDocHostUIHandler::HideUI(void)
{
    METHOD_PROLOGUE_EX_(CExtendedHtmlControlSite, DocHostUIHandler)

    return pThis->m_pView->OnHideUI();
}
STDMETHODIMP CExtendedHtmlControlSite::XDocHostUIHandler::EnableModeless(BOOL fEnable)
{
    METHOD_PROLOGUE_EX_(CExtendedHtmlControlSite, DocHostUIHandler)
    return pThis->m_pView->OnEnableModeless(fEnable);
}STDMETHODIMP CExtendedHtmlControlSite::XDocHostUIHandler::OnDocWindowActivate(BOOL fActivate)
{
    METHOD_PROLOGUE_EX_(CExtendedHtmlControlSite, DocHostUIHandler)
    return pThis->m_pView->OnDocWindowActivate(fActivate);
}STDMETHODIMP CExtendedHtmlControlSite::XDocHostUIHandler::OnFrameWindowActivate(
    BOOL fActivate)
{
    METHOD_PROLOGUE_EX_(CExtendedHtmlControlSite, DocHostUIHandler)
    return pThis->m_pView->OnFrameWindowActivate(fActivate);
}

STDMETHODIMP CExtendedHtmlControlSite::XDocHostUIHandler::ResizeBorder(
    LPCRECT prcBorder, LPOLEINPLACEUIWINDOW pUIWindow, BOOL fFrameWindow)
{
    METHOD_PROLOGUE_EX_(CExtendedHtmlControlSite, DocHostUIHandler)
    return pThis->m_pView->OnResizeBorder(prcBorder, pUIWindow, fFrameWindow);
}
STDMETHODIMP CExtendedHtmlControlSite::XDocHostUIHandler::TranslateAccelerator(
    LPMSG lpMsg, const GUID* pguidCmdGroup, DWORD nCmdID)
{
    METHOD_PROLOGUE_EX_(CExtendedHtmlControlSite, DocHostUIHandler)
    return pThis->m_pView->OnTranslateAccelerator(lpMsg, pguidCmdGroup, nCmdID);
}
STDMETHODIMP CExtendedHtmlControlSite::XDocHostUIHandler::GetOptionKeyPath(
    LPOLESTR* pchKey, DWORD dwReserved)
{
    METHOD_PROLOGUE_EX_(CExtendedHtmlControlSite, DocHostUIHandler)
    return pThis->m_pView->OnGetOptionKeyPath(pchKey, dwReserved);
}STDMETHODIMP CExtendedHtmlControlSite::XDocHostUIHandler::GetDropTarget(
    LPDROPTARGET pDropTarget, LPDROPTARGET* ppDropTarget)
{
    METHOD_PROLOGUE_EX_(CExtendedHtmlControlSite, DocHostUIHandler)
    return pThis->m_pView->OnGetDropTarget(pDropTarget, ppDropTarget);
}

STDMETHODIMP CExtendedHtmlControlSite::XDocHostUIHandler::TranslateUrl(
    DWORD dwTranslate, OLECHAR* pchURLIn, OLECHAR** ppchURLOut)
{
    METHOD_PROLOGUE_EX_(CExtendedHtmlControlSite, DocHostUIHandler)
    return pThis->m_pView->OnTranslateUrl(dwTranslate, pchURLIn, ppchURLOut);
}STDMETHODIMP CExtendedHtmlControlSite::XDocHostUIHandler::FilterDataObject(
    LPDATAOBJECT pDataObject, LPDATAOBJECT* ppDataObject)
{
    METHOD_PROLOGUE_EX_(CExtendedHtmlControlSite, DocHostUIHandler)
    return pThis->m_pView->OnFilterDataObject(pDataObject, ppDataObject);
}
STDMETHODIMP_(ULONG) CExtendedHtmlControlSite::XDocHostUIHandler::AddRef()
{
    METHOD_PROLOGUE_EX_(CExtendedHtmlControlSite, DocHostUIHandler)
    return pThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG) CExtendedHtmlControlSite::XDocHostUIHandler::Release()
{
    METHOD_PROLOGUE_EX_(CExtendedHtmlControlSite, DocHostUIHandler)
    return pThis->ExternalRelease();
}

STDMETHODIMP CExtendedHtmlControlSite::XDocHostUIHandler::QueryInterface(
          REFIID iid, LPVOID far* ppvObj)    
{
    METHOD_PROLOGUE_EX_(CExtendedHtmlControlSite, DocHostUIHandler)
    return pThis->ExternalQueryInterface(&iid, ppvObj);
}STDMETHODIMP CExtendedHtmlControlSite::XDocHostUIHandler::UpdateUI(void)
{
    METHOD_PROLOGUE_EX_(CExtendedHtmlControlSite, DocHostUIHandler)

    return pThis->m_pView->OnUpdateUI();
}

终于干完了,现在你可以捕获ShowModalDialog了

HRESULT CHtmlViewTestView::EvaluateNewWindow(
    LPCWSTR pszUrl,
    LPCWSTR pszName,
    LPCWSTR pszUrlContext,
    LPCWSTR pszFeatures,
    BOOL fReplace,
    DWORD dwFlags,
    DWORD dwUserActionTime
)
{
    CString url(pszUrl);
    if(url.MakeLower().Find(_T("showdialogtest.htm"))!=-1)
    {
        return S_FALSE;//block the new window
    }
    return E_FAIL;//default
}

你可以在这里任意加入你喜欢的策略。

这篇文章应该足够作为浏览器控件扩展基础。如果你需要加入更多的扩展,例如IDocHostUIHandler2、 IInternetSecurityManager、 IDocHostShowUI、 IOleCommandTarget或者IAuthenticate,像文章里面添加接口组件,如果有必要的话,在浏览器控件进行服务查询时返回扩展的接口就可以了。

posted @ | Feedback (6) |

Thursday, April 12, 2007

MSDN第9频道又采访了Visual C++类库组的项目经理Nikola DudarSarita Bafna,以及质量控制组的Marina Polishchuk尽管Visual C++项目组已经转移了工作重点,但是很少人注意到这一点。或许这些采访可以帮助你了解Visual C++项目组的工作。

为什么C++仍旧重要?

  • 非托管的应用程序有很大的代码积累,而这些程序的升级工作仍旧在进行
  • 性能是选择C++的重要因素。举例来说,游戏和杀毒程序更适合用非托管代码来编写。
  • 多平台支持。虽然.Net号称是跨平台的,但是如果要编写真正的跨平台程序,开发的时候遵循C++标准还是很有必要的。

为什么C++程序员仍旧重要?

  • C++程序员理解整个机器的运作,他们知道怎么写垃圾收集机制,甚至可以写机器代码
  • C++程序员可以很容易的学会其他语言——C++已经是最难学的语言之一了
  • C++程序员并不只使用一种语言。如果有必要的话,他们会选择汇编、C#或者Perl这样更适合特定任务的语言。

为什么Visual C++项目组转移了工作重点?

  • C++程序员对于转到C#没有抵触心理,所以Visual C++项目组不认为有必要尽快实现Visual C#支持的所有特性,比如LINQ和WPF设计器
  • C++程序员对于让他们的非托管程序调用其他语言的托管代码比用C++来写托管代码更有兴趣
  • 核心模块,例如IE和Windows外壳会更加频繁地更新,而会有更多的非托管代码需要调用这些新的特性,为了这些特性,有必要在MFC中引入新的封装类来节省C++程序员的时间

Orcas中Visual C++的新特性:

  • 托管代码互操作库。可扩展的托管数据类型和非托管数据类型的转换支持
  • STL/CLR。使得托管代码可以利用旧的STL编写的算法
  • Vista支持。对Vista中新的通用控件和文件对话框等界面元素的MFC封装。
  • DevExpess重构引擎——将包含DevExpess的Refactor!? for C++

Orcas之后的考虑

  • 更新界面。有些Visual C++的代码是针对20年之前的硬件环境设计的,已经不适合现在的需要。新的Phoenix编译引擎使得重写前台变得更加容易。
  • 太多现有的代码需要重构。新的Phoenix编译引擎使得代码分析变得更加容易。
  • C++标准。新的C++标准TR1可能会在Orcas下一版本开发时成为正式标准。
  • 多核支持。需要编写可以充分利用多CPU的代码。第一个尝试是LINQ。

结论

  • MFC和非托管代码回来了
  • 性能和多平台支持的重要性越来越低,托管代码仍旧具有很大的市场。

Visual C++项目组的其他动作

  • ATL Server发布到了源代码共享站点CodePlex。这包含CAtlRegExp,在.Net和第三方类库(boost,TR1)的竞争下已经不再有必要维护一个单独的条件表达式标准了

posted @ | Feedback (3) |