Eric's profileMastersPhotosBlogListsMore Tools Help

Blog


    April 21

    电脑看长了,看看这张图片,包治脖子酸痛....



    现在的人真有想法。。。
    并由此突发奇想,注备做个小工具,图片的内容可以由RSS提供,换种方式看新闻挺不错;)
    April 15

    Outlook Watchdog - prevent your outlook from being closed... ;)

    People in our office usually feel disappointed that they usually close outlook by accident and complain about why Microsoft does not provide such kind of an option. It's just a small piece of cake, isn't it? If that does exist, I would like to hear that from you; ) Then I started to look for something that might help from the web today... But unluckily, many people are complaining but few of them get a good solution for that? By googling, googling, ... I finally found one called AddsForOutlookInst.exe, but it's not free and costs 70$ or so. Then, I was considering to make one myself. It's just a job regarding how to prevent a window from being closed. First of all, I took a look at the Visual Studio Tools for Office and would like to develop an Outlook addin. Unluckily once again, the Outlook application does not provide any facilities to prevent its main window from being closed. So I give up that choice immediately and just planned to use windows hook techniques to achieve the purposes. Windows hook is an amazing technique if are properly used. A good example is the cursor transation in morden dictionary tools, such as KingSoft or YouDao, etc. Actually windows hook is more or less used in every windows applications to manage complicated user scenarios. The solution, I called "Outlook Watchdog", is shown as below:

    HHOOK hOutlookWatchdogHook = NULL;

    BOOL OUTLOOKWATCHDOGHOOKAPI OutlookWatchdog_SetHooks()
    {
        HMODULE hMod = GetModuleHandle( _T("OutlookWatchdogHook.dll") );
        if (!hMod) return FALSE;
        hOutlookWatchdogHook = SetWindowsHookEx(
            WH_CBT,
            OutlookWatchdogHookProc,
            hMod,
            0
            );
        return NULL != hOutlookWatchdogHook;
    }

    LRESULT CALLBACK OutlookWatchdogHookProc( int nCode, WPARAM wParam, LPARAM lParam )
    {
        if (nCode == HCBT_SYSCOMMAND && wParam == SC_CLOSE)
        {
            HWND hWnd = FindWindow( _T("rctrl_renwnd32"), NULL );
            if (hWnd == GetActiveWindow())
            {
                static TCHAR wndText[80];
                ZeroMemory( wndText, sizeof(wndText) );
                GetWindowText(hWnd, wndText, 80);
                if (_tcsstr( wndText, _T("- Microsoft Outlook") )) // hard code here for testing outlook main window.
                {
                    if (IDNO == MessageBox( hWnd, _T("Exiting outlook is not a good idea for now;) Do you want to continue? "), _T("Exit Outlook"), MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON2 ))
                    {
                        ShowWindow( hWnd, SW_SHOWMINIMIZED );
                        return 1;
                    }
                }
            }
        }
        return 0;
    }

    void OUTLOOKWATCHDOGHOOKAPI OutlookWatchdog_KillHooks()
    {
        if (hOutlookWatchdogHook)
        {
            UnhookWindowsHookEx( hOutlookWatchdogHook );
            hOutlookWatchdogHook = NULL;
        }
    }


    It's trivial to use windows hook techniques. Just one thing I want to remind of here that you'd better use "WH_CBT" windows hook type. I have tried other types, for example, WH_CALLWNDPROC, WH_GETMESSAGE. However, you could not modify the message for WH_CALLWNDPROC, and modifying the message for WH_GETMESSAGE does not work. I just don't know why... maybe someone could help point out that.

    Finally, if someone needs the executable file from me, just go ahead, it's free. ;)

    Thanks
    Eric

    April 14

    mshtml deployment for your .NET applications

    One of the component we have recently delivered depends upon the mshtml a little bit. However, mshtml might not be installed properly in some environment. (For us, it worked well in our pre-production environment, however did work in the production environment. ) Basically, if your operating system has installed all the updates, basically it works. In other cases, you could deploy the mshtml manually. Mshtml.dll exposes its functionalities via COM interfaces, and generally you could locate the COM server and type library at %systemroot%\system32\mshtml.dll/tlb. On the other hand, .NET applications call mshtml via COM Interop service, so that we need the COM Interop assemblies installed property. The following shows two ways to simply deploy the mshtml so that your application that directly or indirectly depends on it could work as expected.

    1. Download the Primary Interop Assemblies redistribution packages for Office system from Microsoft. Use the links below for Office 2003 and 2007  respectively. http://www.microsoft.com/downloads/details.aspx?familyid=3c9a983a-ac14-4125-8ba0-d36d67e0f4ad&displaylang=en and http://www.microsoft.com/downloads/details.aspx?FamilyID=59daebaa-bed4-4282-a28c-b864d8bfa513&displaylang=en. Extract the files from the downloaded exe, and run the *.msi (e.g., o2007pia.msi) to installed it. After that, the COM Interop assemblies will be installed and registered.

    2. If you're using Visual Studio 2005+, you could find the Microsoft.msthml.dll assembly from %Program Files%\Microsoft.NET\Primary Interop Assemblies. Then, copy the dll (Microsoft.mshtml.dll) to the target machine, run the following command to install it to the GAC.

        gacutil.exe /i %path%Microsoft.mshtml.dll

    Note: if you take a look at the list when you add a .NET assembly reference, you will notice other loactions where Microsoft.mshtml.dll could be present as well, for example, C:\Program Files\Microsoft Visual Studio 9.0\Visual Studio Tools for Office\PIA\Office11 or C:\Program Files\Microsoft Visual Studio 9.0\Visual Studio Tools for Office\PIA\Office12. Don't use them, because gacutil requires the assembly to be strong name signed in order to install it to the GAC and the assemblies you found in other locations are delay signed or test signed and cannot be used for deployment.

    #Q.E.D