More servicesWindows Live
HomeHotmailSpacesOneCare
 
MSN
Sign in
 
 
Spaces home  蒋晟(JIANG,Sheng), a Micro...PhotosProfileFriendsBlog Tools Explore the Spaces community

Blog

    • View next 20 entriesView last 20 entries
    October 05

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

    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" />

    September 08

    When Microsoft Office Live Meets Google Chrome

    To use Microsoft Office Live, your computer must meet one of the following requirements:

    Microsoft Internet Explorer 6 or 7, running on Microsoft Windows XP, Windows Server 2003 or Windows Vista. You can download Internet Explorer from the Windows Internet Explorer page.
    Mozilla Firefox running on Windows XP, Windows Server 2003, Windows Vista, or Mac OS X 10.2.x and later. You can download Firefox from the Firefox download page.

    April 07

    MFC Feature Pack发布

    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。

    March 24

    Detect if a MSI component is installed

    A C# program for those who don't know MSI SDK or C++. C++ programmers can find the API inside the msi.h  file in Windows SDK.

    class Program
    {
        static int Main(string[] args)
        {
            uint pathSize = 0;
            try
            {
                foreach (string componentId in args)
                {
                    MsiInstallState state = MsiLocateComponent(
                        componentId, null, ref pathSize);
                    if (state != MsiInstallState.Local)
                    {
                        return ERROR_UNKNOWN_COMPONENT;
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
                return ERROR_MOD_NOT_FOUND;
            }
            return 0;
        }
        [DllImport("msi.dll", CharSet = CharSet.Auto)]
        extern static internal MsiInstallState MsiLocateComponent(string component, string path, ref uint pathSize);
        /// <summary>Enumeration of MSI install states.</summary>
        internal enum MsiInstallState : int
        {
            Local = 3
        }
        const int ERROR_MOD_NOT_FOUND = 126;
        const int ERROR_UNKNOWN_COMPONENT = 1607;
    }

    March 17

    Hard Drive broke

    The first 3 Dell support technicians tried to persuade me to clean the temp files, to remove unnecessary startup programs and to reinstall Windows. It does not help if the computer complains an error during self test. I keep saying a self test error can not be solved by twisting the OS, but they won't listen. After educating the representatives for a week I finally got one that has better experience (and better English) to examine my computer. A full system test shows bad sectors on the hard drive, and totally toasted the hard drive. Luckily I just bought the computer for 6 months so I asked for a replacement. Dell sent me one in 2 days and I sent back the broken one.

    Now my back up hard drive started to fail ... Time to call Seagate.

    January 09

    Smart harddrive error

    In case anyone is googling this message
    Hard Drive SELF MONITOR SYSTEM has reported that a parameter has exceed its normal operating range
    Dell recommends that you back up your data regularly
    Press F1 to continue, Press F2 to enter setup
     
    Run event log and look for warning messages. I have several messages looked like this
    C:\Program Files\Microsoft Windows OneCare Live\Database\WinSS_st.edb (3612) C:\Program Files\Microsoft Windows OneCare Live\Database\WinSS_st.edb: A request to read from the file "C:\Program Files\Microsoft Windows OneCare Live\Database\WinSS_st.edb" at offset 180224 (0x000000000002c000) for 4096 (0x00001000) bytes succeeded, but took an abnormally long time (60 seconds) to be serviced by the OS. In addition, 0 other I/O requests to this file have also taken an abnormally long time to be serviced since the last message regarding this problem was posted 0 seconds ago. This problem is likely due to faulty hardware. Please contact your hardware vendor for further assistance diagnosing the problem.
     
    msnmsgr (2980) \\.\C:\Users\jiangsheng\AppData\Local\Microsoft\Messenger\<windows live id>\SharingMetadata\Working\database_8E6C_5899_6C58_7E41\dfsr.db: A request to write to the file "\\.\C:\Users\jiangsheng\AppData\Local\Microsoft\Messenger\<windows live id>\SharingMetadata\Working\database_8E6C_5899_6C58_7E41\fsr.log" at offset 19456 (0x0000000000004c00) for 512 (0x00000200) bytes succeeded, but took an abnormally long time (75 seconds) to be serviced by the OS. This problem is likely due to faulty hardware. Please contact your hardware vendor for further assistance diagnosing the problem.
     
    The reaction is obvious: contact Dell Customer Support.
     
    thankfully, I have dialy incremental backup and weekly full system backup, but my dialy backup has been failing. So I will lose a week's data, not a big deal.
    January 07

    MFC更新Beta版

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

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

    September 18

    科学,我的信仰?

    花が咲き そして散る
    Flowers open out and then they fade
    花开,然后花落
    星が輝き やがていつかは消える
    Stars shine and later or sooner they go off
    星光闪耀,不知何时熄灭
    この地球も 太陽も 銀河系 大いなる宇宙も いつか死するときがくる
    Both this Earth, the Sun, the Milky Way, and even for the big Universe which is growing, later or sooner the time to die will come
    这个地球,太阳,银河系,甚至整个宇宙也总会有消失的时候
    人間の一生などそれらに比べれば瞬きほどの僅かなものであろう
    And compared to these things, human life is insignificant.
    人的生命和那些相比只不过是一瞬间吧
    その僅かなひとときに 人は生まれ
    In that little moment, a man is born
    在那一瞬间中,人诞生
    笑い 涙し 戦い 傷つき 喜び 悲しみ 誰かを憎み 誰かを愛し
    Laughs, cries, fights, is injured, feels joy and feels sadness, loves someone, hates someone
    微笑,哭泣,战斗,伤害,喜悦,悲伤,憎恨谁,喜欢谁
    全ては刹那の邂逅
    Everything is random and in a instant
    所有的一切都是刹那间的邂逅
    そして誰しもが死という永遠の眠りに包まれる
    And, in the end, covered by an eternal sleep called Death.
    谁都不能逃脱死亡的长眠
    ——沙加在沙罗双树涅磐时的遗言,引自《圣斗士·冥王篇·沙罗双树下之卷》
    昨天有位朋友问我,你到底信仰什么,我当时的回答是科学;我不信仰一切把自然科学解释不了的现象归类于一个超自然的存在的宗教。我当时的逻辑是超自然是无法被定义的。这是因为你可以定义一个东西是什么,但是你不能定义一个东西为不是什么,因为定义是确定的,而定义的反面(不是什么)的范围是无法确定的。后来想想,我自己对我的信仰下的定义也不是很准确,因为科学是在不断发展的。
    毕达哥拉斯曾认为万物之源是数,但是他对数的定义仅限制于有理数。当他的学生希帕索斯用毕达哥拉斯定理发现当两个直角边长度都是1时斜边的长度是不是一个有理数的时候,这个发现震撼了整个毕达哥拉斯学派的根基。在传说中,希帕索斯被愤怒的毕达哥拉斯学派的人沉到海中淹死了。现在我们知道除了无理数之外还存在复数,在高维空间内我们还有超复数。人的信仰,即使是一个数学伟人的信仰,也阻挡不了数学发展的脚步。
    再举一个例子。几何学是基于一系列假设(数学上叫做公理)的。在欧几里得的《几何原本》中,被称为平行公理的第五条公理(或者其等价命题)表述如下:
        通过一个不在直线上的点,有且仅有一条不与该直线相交的直线。 
    这个定理只在证明第二十九个命题中才用到,以后再也没有用到。也就是说,看起来欧几里得几何中此定理的地位可有可无。关于第五公理的地位争论了两千多年,终于在十九世纪二十年代得到解决。俄国数学家罗巴切夫斯基试图用反证法证明这个命题。他用一个和第五公理冲突的公理替代了第五公理,然后试图推导出一个自相矛盾的理论体系。和他的预期相反,他推导出了一门新的几何学,在后来被称为罗巴切夫斯基几何。如果认为空间的曲率是可以变化的,那么第五公里就可以被去掉,而欧几里德几何和罗巴切夫斯基几何成为鲍耶提出的绝对几何在常曲率空间的特例。
    我们上学的时候都学过,太阳系有九大行星。然而在2006年,国际天文家联合会将冥王星从行星中除名,太阳系只剩下八大行星。如果客观真理可以这样更改的话,究竟什么才是科学?建立在科学方法上的主流意见就是科学么?我们都知道哥白尼这个反例了。另外,科学真的可以用科学手段来验证么?像恒星的演化这样的课题,短命的人类永远只能用理论来解释观测到的现象,没有人能有足够的寿命来验证恒星演化论的真伪。科学,不过是人类对有限的世界的解读而已。
    我对这个问题没有答案。我对那个朋友的回答可能需要更改一下,我可能信仰客观唯心主义。我认为物质的存在不能用客观的方式来证明,而只能用主观的理论来表述。我认为科学是建立在一系列假设上的,也只能描述基于这些假设的世界。科学越发展,可以描述的现象就越多,但是——引用一下哥德尔第二条定理——任何相容的形式体系不能用于证明它本身的相容性,科学是不能用科学方法来验证的。
    August 05

    AutoComplete with DataSource

    Download the code for this article (22KB)

    .Net 2.0 introduced autocompletion in TextBox and ComboBox. It is obvious that autocomplete is not very useful when the number of options is small. However, when your option becomes too many, pre-filling of all options to an AutoCompleteStringCollection becomes impractical, especially when your data comes from a remote computer. An alternative is to replace the AutoCompleteCustomSource in a TextChanged event, however, users are getting random AccessViolationException when trying to replace it.  In this article I will demonstrate another alternative, using a BindingSource as the data source of options and bypassing the .Net framework and call the underline Windows API directly.

    The first thing I need to do is to port the APIs to managed code. The autocompletion API is exposed as a COM object, so I need to write managed version of its interfaces:

        [ComImport]
        [InterfaceType(ComInterfaceType::InterfaceIsIUnknown)]
        [Guid("EAC04BC0-3791-11D2-BB95-0060977B464C")]
        [SuppressUnmanagedCodeSecurity]
        interface  class IAutoComplete2
        {
                 [PreserveSig] int Init(
                HandleRef hwndEdit,
                IEnumString^ punkACL,
                 String^ pwszRegKeyPath,           
                String^ pwszQuickComplete
            );
            void Enable( [MarshalAs(UnmanagedType::Bool)] bool value);

            int SetOptions(int dwFlag);

            void GetOptions([Out]IntPtr pdwFlag);
        };
    Second, I need to create the autocomplete object and query the IAutoComplete2 interface:

           Type^ autoCompleteType = Type::GetTypeFromCLSID(CLSID_AutoComplete);
            try{
                autoComplete2 =(IAutoComplete2^)(Activator::CreateInstance(autoCompleteType));
            }
            catch(Exception^ e)
            {
                Marshal::ReleaseComObject(autoComplete2);
                autoComplete2 = nullptr;
            }

    Third, I need to bind it to an TextBox control:

        bool AutocompleteBindingSource::Bind()
        {
            if (nullptr==this->autoComplete2)
                return false;
            try
            {
                this->autoComplete2->SetOptions((int)ControlToBind->AutoCompleteMode);
                this->autoComplete2->Init(
                    HandleRef(ControlToBind,ControlToBind->Handle),
                    this,
                    String::Empty
                    ,String::Empty);
                return true;
            }
            catch(Exception^e)
            {
                return false;
            }

        }

    Finally, I need to implement IEnumString to provide a list of options. Luckily, .Net has declared this interface, so I don't need to port it to managed code, however, I still need to write my binding code in my implementation of IEnumString.

        void AutocompleteBindingSource::Reset()
        {
            this->current = 0;
            if(BindingSource!=nullptr)
                this->size=BindingSource->Count;
        }

            int AutocompleteBindingSource::Next(
            int celt, [Out, MarshalAs(UnmanagedType::LPArray, ArraySubType=UnmanagedType::LPWStr, SizeParamIndex=0)] array<String^>^ rgelt, IntPtr pceltFetched)
        {
            if (celt < 0)        {
                return E_INVALIDARG;
            }
            int index = 0;
            while ((this->current < this->size) && (celt > 0))
            {
                Object^ item=this->BindingSource->default[this->current];

                bool useDisplayMember=false;

                if(!String::IsNullOrEmpty(DisplayMember))
                {
                    ICustomTypeDescriptor^ customTypeDescriptor=dynamic_cast<ICustomTypeDescriptor^>(item);
                    if(customTypeDescriptor!=nullptr)
                    {
                        PropertyDescriptorCollection^ propertyDescriptorCollection=
                            customTypeDescriptor->GetProperties();
                        if(propertyDescriptorCollection!=nullptr)
                        {
                            PropertyDescriptor^ propertyDescriptor=propertyDescriptorCollection->default[DisplayMember];
                            if(propertyDescriptor!=nullptr)
                            {
                                rgelt[index] = propertyDescriptor->GetValue(item)->ToString();
                                useDisplayMember=true;
                            }
                        }
                    }
                }

                if(!useDisplayMember)
                {
                    if(item!=nullptr)
                    {
                        rgelt[index] = item->ToString();
                    }
                }
                this->current++;
                index++;
                celt--;
            }
            if ((pceltFetched != IntPtr::Zero))
            {
                Marshal::WriteInt32(pceltFetched, index);
            }
            if ((celt != 0))
            {
                return 1;
            }
            return 0;

        }

    Here the DisplayMember property is the name of the property in the data source to be displayed. If the property specified by the value of the DataMember property does not exist, I use ToString to get a text representation of the current item in the data source.

    You may want to ask, where is the filtering code? Well, that is implemented by BindingSource class.

           System::Void FormTest::textBoxDemo_TextChanged(System::Object^  sender, System::EventArgs^  e)
        {
            static bool inThisFunction=false;
            if(!inThisFunction)
            {
                inThisFunction=true;
                if(String::IsNullOrEmpty(textBoxDemo->Text))
                    bindingSourceAutoComplete->Filter=nullptr;
                else
                {
                    System::String^ addText=textBoxDemo->Text+"og/NextElement";
                    dataSetDemo->Tables[0]->DefaultView->Sort="Text";
                    if(dataSetDemo->Tables[0]->DefaultView->FindRows(addText)->Length==0)
                    {
                        System::Data::DataRow^ row=dataSetDemo->Tables[0]->NewRow();
                        row->default[0]=addText;
                        dataSetDemo->Tables[0]->Rows->Add(row);
                    }
                    bindingSourceAutoComplete->Filter=
                        String::Format("{0} LIKE '{1}%'"
                        ,dataSetDemo->Tables[0]->Columns[0]->Caption
                        ,textBoxDemo->Text);
                }
                if(textBoxDemo->SelectionStart>0)
                {
                    autocompleteBindingSource1->Reset();
                    autocompleteBindingSource1->Bind();
                    String^ text=textBoxDemo->Text;
                    int selectionStart=textBoxDemo->SelectionStart;
                    int selectionLength=textBoxDemo->SelectionLength;
                    textBoxDemo->SelectionStart=0;
                    textBoxDemo->SelectionLength=0;
                    textBoxDemo->SelectAll();            
                    System::Windows::Forms::SendKeys::SendWait("{BACKSPACE}");
                    textBoxDemo->Text=text;
                    textBoxDemo->SelectionStart=selectionStart-1;
                    textBoxDemo->SelectionLength=selectionLength+1;
                    System::Windows::Forms::SendKeys::SendWait(textBoxDemo->SelectedText);
                }
                inThisFunction=false;
            }
        }

    Somehow Windows caches the result. If I don't clear the text, my IEnumString implementation won't be asked again for candidate strings (pointed out by Andy Gilman). 

    The BindingSource class checks the data source to see if they support the IBindingListView. If IBindingListView is supported, the BindingSource class delegates sorting and filtering to the data source.  In this sample, the data source of the BindingSource object is a DataSet, and the DataMember of BindingSource object is the name of the first table , so BindingSource creates a DataView as its data source. The DataView class implements IBindingListView and filters its data using expressions parsed from the filter string. In reality, the data source could be a business object that implements IBindingListView and supports filtering and sorting with stored procedures.

    This sample does not consider compound autocomplete object support. If you want to get your options from multiple sources, you need to use IObjMgr to add sources to the autocomplete object.

    Reference

    July 29

    Visual C++ 2008 Beta2 里面的Class Designer

    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++项目组在做下一个版本的市场调查,有兴趣的可以去提提要求。

     

     

    July 03

    Handle NewWindow3 and ShowModalDialog in CHtmlView

    CHTMLView does not support NewWindow3 as of MFC 9.0. It is relatively easy to add this support, given the event sink code in atlmfc\src\viewhtml.cpp

    Add the following into the declaration of the derived CHtmlView class (named CHtmlViewTestView in this example)

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

    DECLARE_EVENTSINK_MAP()

    Add the following to the implementation file of the CHtmlViewTestView class

    #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();
    }

    Handling ShowHtmlDialog in CHtmlView needs some extension the browser control site, however, the MFC implementation is not reusable. Heck, for some reason the two MFC HTML Classes, namely CHtmlView and CDHtmlDialog, are NOT reusing their own extension inside the same class library. They use two almost identical extension control sites to redirect IDocHostUIHandler methods. The one used CHtmlView, CHtmlControlSite, is not even in MFC header file, while the one used by CDHtmlDialog, CBrowserControlSite, is in afxdhtml.h, leaving some room to extend it by exposing GetInterfaceHook.

    Now back to CHtmlView. To create a control site extension, you need to override CWnd::CreateControlSite, which is added in MFC 7.0 specifically for extending the web browser control ,  but is used in MFC 8.0 for embedding .Net Windows Forms controls.

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

    Actually, pContainer->m_pWnd is this (CHtmlViewTestView), so I can emit a parameter here and cast the window pointer to CHtmlViewTestView, but this is not obvious to me when I wrote this class.

    The control site extension needs to extend COleControlSite, an internal class in MFC 6.0 but is documented in MFC 7.0, again, to support class level customization of the control site. Previously, you can only replace the global control container by calling 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)
    {
    }

    Here m_pView is saved to delegate INewWindowManager calls to the CHtmlViewTestView class.

    Now it is the fun part. The web browser control does not actually query the INewWindowManager interface from the control site, instead, it calls the control site's implementation of IServiceProvider::QueryService, so I need to implement IServiceProvider first, then answer the service query call with my INewWindowManager implementation.

        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);
    }

    Actually, I can implementation INewWindowManager in another class and return another object in QueryService, but since INewWindowManager is used exclusively for web browser customization, this INewWindowManager implementation is not going to be reusable anyway.

    Finally, to make CHtmlView's IDocHostUIHandler implementation happy, I have to redirect IDocHostUIHandler method calls to it:

    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();
    }

    That's it, you can handle ShowModalDialog now

    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
    }

    Well, here you can add as many policies as you like , people can never be creative enough on making policies.

    This should be enough for adding your web browser customization. If you want to add more interfaces, such as IDocHostUIHandler2, IInternetSecurityManager, IDocHostShowUI, IOleCommandTarget or IAuthenticate, to of the customized control site, simply add more interface parts and answer QueryService calls if necessary.

    About the author

    Sheng Jiang has been a Microsoft MVP in Visual C++ since 2004. He is a student in Austin Community College in Austin, Texas, USA.

    April 11

    STL/CLR, Compiler and Marshaling

    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)的竞争下已经不再有必要维护一个单独的条件表达式标准了
    March 29

    McDonald's, Yum! Alleged To Break Chinese Wage Laws

    Source

    McDonald's and Yum! Brands, the owner of KFC and Pizza Hut were the targets of an undercover investigation made by New Express Daily reporters.

    The report pointed out several violations of labor laws:

    • Minimum wage. McDonald's, KFC and Pizza Hut were paying part-time employees as much as 40 percent less than the local minimum wage for part-time employees.
    • Contract. The stores refused to give the contract text to some employees.
    • Part time probation. Part time probation is still in their contracts text after being outlawed for 4 years.
    • Long hours. Have part time employee working full time hours (up to 10 hours a day), thus deny them full time benefits.

    A spokesman of KFC argued that their student workers are exempt from the local minimum wage law because they are neither full-time nor part time workers. Legal experts say there is no other alternative-time worker type exists.

    Update:

    Another report says the Pizza Hut contract states "this contract is not governed by labor law", while the labor law says it covers any paid labor between business and natural person.

    The report also says the majority of McDonald's and KFC employees can not get their contract back after they signed it. Legal experts say this is to destroy the evidence.  McDonald's contract also includes the part time employees discipline, which is changed unilaterally.

    Facts:

    McDonald's has 670 branches and over 50,000 employees in China.

    Yum! Brands has more than 1,500 branches and over 100,000 employees in China.

    Local minimum wages and Pizza Hut Salary (RMB/hour)

    Shanghai: Local minimum wage 6.5, Pizza Hut 5.8

    Shijiazhuang: Local minimum wage 6.6, Pizza Hut 5.4

    Shenyang: Local minimum wage 5.5, Pizza Hut 4.1

    Ian: Local minimum wage 6, Pizza Hut 5.5

    Shijiazhuang: Local minimum wage 6.6, Pizza Hut 5.4

    January 01

    MIcrosoft MVP again

     
    祝贺您!我们非常高兴向您授予 2007 Microsoft® MVP 大奖!
     
    您为世界各地的社区做出了巨大贡献,我们通过 Microsoft MVP 大奖对您表示感谢、敬意和鼓励。作为 Microsoft“最有价值专家”(Most Valuable Professional) 奖的得主,您成为全球技术社区领导者精英群体中的一员,该群体与用户和 Microsoft 积极分享实际工作的专业技能,促进了知识的自由、客观交流。Microsoft 向所有不断努力促进社区发展、提升人们生活质量和促进行业成功的 MVP 们表示崇高的敬意。要了解有关 MVP 计划的更多信息,请访问:www.microsoft.com/mvp

    非常感谢您在过去一年中为 Visual Developer - Visual C++ 技术社区所做的杰出贡献。
     
    November 11

    Visual Studio 2005 Untrusted by IE7

    Today I upgraded one of my development machine to IE7. Everything looks fine, except I have to change the FileDownload event handler to make my code compile.

    However, suddenly I found Visual Studio 2005 is complaining:

    Conclusion:

    • Visual Studio is based on WebBrowser control (Is this news story?)
    • Upgrade to IE7 may break some applications (Again, is this a news story?)

    Everything else works fine so far...

    October 23

    Error: Unable to cast COM object of type 'mshtml.HTMLDocumentClass' to interface type 'ICustomDoc'

    This operation failed because the QueryInterface call on the COM component for the interface with IID '{3050F3F0-98B5-11CF-BB82-00AA00BDCE0B}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

    My first reaction was:"What the hell? HTMLDocumentClass is the managed wrapper of MSHTML, and MSHTML is supposed to support the ICustomDoc interface!"

    Now I started wondering why the interfaces don't work I created a sandbox project and tried to cast interface there, but it works smoothly. I played with strong name and found no luck. Finally, I found out that it is the frame document that does not support this interface.

    October 17

    CSDN statistics

    基本信息:
    UserID:7298
    CSDN帐号:jiangsheng
    注册时间:2000-4-29 0:09:00
    最后一次登录时间:2006-10-16 21:27:00
    社区昵称:蒋晟.Net[MVP]
    个人简述:http://bloglines.com/public/jiangsheng
    https://mvp.support.microsoft.com/profile=53E2CF19-EA8C-48B1-8941-A7AB174DA98A
    http://www.codeproject.com/script/profile/whos_who.asp?vt=arts&id=65456
    目前是:.NET技术 VC.NET 小斑竹
    目前是:VC/MFC 大斑竹
    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    截至目前,得分在100分以上的大板块依次是:
    Web 开发 得专家分 2143
    专题开发/技术/项目 得专家分 3586
    硬件/嵌入开发 得专家分 140
    Windows专区 得专家分 1197
    硬件使用 得专家分 115
    扩充话题 得专家分 6075
    其他开发语言 得专家分 2702
    VC/MFC 得专家分 184291
    VB 得专家分 8330
    .NET技术 得专家分 17050
    Delphi 得专家分 8935
    Java 得专家分 1578
    C++ Builder 得专家分 5252
    C/C++ 得专家分 3017
    MS-SQL  Server 得专家分 133
    PowerBuilder 得专家分 255
    Oracle 得专家分 405
    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    ==================================================================
    微软技术社区每月发帖量统计
    2001年07月 1
    2001年09月 1
    2002年01月 4
    2002年04月 1
    2002年05月 1
    2002年06月 3
    2002年10月 1
    2002年11月 1
    2003年12月 1
    2004年04月 2
    2004年06月 1
    2004年07月 1
    2005年04月 1
    2005年08月 1
    2005年10月 1
    2006年04月 1
    微软技术社区每月回复量统计
    2000年04月 3
    2000年05月 4
    2000年06月 15
    2000年07月 4
    2000年08月 27
    2000年09月 13
    2000年12月 1
    2001年03月 7
    2001年05月 3
    2001年07月 4
    2001年08月 1144
    2001年09月 848
    2001年10月 296
    2001年11月 273
    2001年12月 127
    2002