OLEサーバの状態メッセージを取得


Excelが入力モードになっているとOLEサーバがBusy状態となり、処理を受け付けなくなります。
また、この状態になるとOLEサーバが

    [サーバー使用中]

のメッセージを出力し、動作に不都合が生じます。ここでは、[サーバー使用中]のメッセージを
出なくすると同時に、OLEサーバがBusy状態であることをチェックする方法を示します。

上記内容を実現するためには、COleMessageFilterを使います。

ここで、OLEサーバがBusy状態であることをチェックするために必要な処置を以下に示します。

【手順】

    @、COleMessageFilterを継承したクラスを作成します。

        サーバーの状態を示すメッセージを取得するためフレームワークが

           COleMessageFilter::OnMessagePending(const MSG* pMsg)

        を呼び出します。
        しかし、このメンバを使用するためには、COleMessageFilterを継承したクラスを
        作成し、オーバーライドする必要があります。

    A、AfxOleInit()を使用しOLEの初期化がされている場合は、登録されているメッセージフィルタを
    解除する。

    B、@で作成したクラスを使用して、新しいメッセージフィルタを作成

  C.Bで作成したメッセージフィルタを登録

    D.OnMessagePendingをオーバーライドする


【サンプル】


-------------------------------------------------------------------------------------------------
//メーセージフィルタのオーバーライド用クラス


#include <afxole.h>

class CMyOleMessageFilter : public COleMessageFilter
{
    //OnMessagePendingをオーバーライドする
virtual BOOL OnMessagePending(const MSG* pMsg); public: CMyOleMessageFilter(); virtual ~CMyOleMessageFilter(); }; CMyOleMessageFilter::CMyOleMessageFilter() { } CMyOleMessageFilter::~CMyOleMessageFilter() { } BOOL CMyOleMessageFilter::OnMessagePending(const MSG* pMsg) { //サーバがBusy状態(サーバ使用中)かどうかのチェック if(pMsg->wParam == 17){ AfxMessageBox("サーバがBusy状態です。入力モードになっている可能性があります。"); } return false; } --------------------------------------------------------------------------------------------------- //オーバライドしたクラスを使用して、メッセージフィルタを登録 #include "MyOleMessageFilter.h" //初期化 BOOL CSvBusyApp::InitInstance() { // OLE ライブラリの初期化 if (!AfxOleInit()) { AfxMessageBox(IDP_OLE_INIT_FAILED); return FALSE; } //----------------------------------------------↓ //オーバーライドしたメッセージフィルタの登録 CWinThread* pThread = AfxGetThread(); if (pThread != NULL) { //AfxOleInit()で登録されたメッセージフィルタを解除 delete pThread->m_pMessageFilter; pThread->m_pMessageFilter = NULL; //オーバーライド用のメッセージフィルタを作成 pThread->m_pMessageFilter = new CMyOleMessageFilter; ASSERT(AfxOleGetMessageFilter() != NULL); //メッセージフィルタを登録 AfxOleGetMessageFilter()->Register(); } //-------------------------------------------------------↑ AfxEnableControlContainer(); [省略] } ------------------------------------------------------------------------------------------------- //実行用コード #include "MyOleMessageFilter.h" //Excelを操作するためのタイプライブラリを読みこむ(Excel2002用)--注意:PCの環境によってタイプライブラリの存在ディレクトリは異なります。 #import "C:\Program Files\Common Files\Microsoft Shared\Office10\MSO.DLL" no_namespace rename("DocumentProperties", "DocumentPropertiesXL") #import "C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\Vbe6ext.olb" no_namespace #import "C:\Program Files\Microsoft Office\Office10\EXCEL.EXE" rename("DialogBox", "DialogBoxXL") rename("RGB", "RGBXL") rename("DocumentProperties", "DocumentPropertiesXL") no_dual_interfaces [省略] void CSvBusyDlg::OnButton1() { int i; char buffer[9]; COleVariant data,data1; using namespace Excel; _ApplicationPtr pXL; //Excelの起動 pXL.CreateInstance(L"Excel.Application"); pXL->Visible = TRUE; //「サーバ使用中」の警告メッセージを無効にする COleMessageFilter* pFilter = AfxOleGetMessageFilter(); pFilter->EnableBusyDialog(FALSE); pFilter->EnableNotRespondingDialog(FALSE); //WorkBookを追加する WorkbooksPtr pBooks = pXL->Workbooks; _WorkbookPtr pBook = pBooks->Add(); //アクティブ・シートを取得 _WorksheetPtr pSheet = pXL->ActiveSheet; AfxMessageBox("動作確認のために一時停止"); //---------------------------------------------------------------------------- //サーバ使用中の状態を取得するテストは、 //"動作確認のために一時停止"メッセージ出力中にCellへの入力モードにして下さい。 //その後で、"動作確認のために一時停止"メッセージのOKボタンを押すと //「サーバ使用中」となり動作テストが出来ます。 //------------------------------------------------------------------------------ //Cellsを使用したデータの出力 for(i = 1; i < 10; i++){ data = (short)i; data1 = (short)1; RangePtr pCells = pSheet->Cells->Item[data][data1]; itoa(i,buffer,10); pCells->Value2 = buffer; //Excel2002では、Value2を使用します。 } pXL->DisplayAlerts = false; pXL->Quit(); } ---------------------------------------------------------------------------------------------------- [サンプル・ソース]