■Visual C++6.0によるマクロ(AddIn)■

日本ローパー及び、ローパーサイエンティフィック社では、C++言語でのマクロ(Automation)の公式なサポートは行っていません。C++で制御したい方は市販のCOMプログラミングに関する書籍をご覧下さい。ここでは、簡単な例だけを示しておきます。(C++でのプログラミングに関するご質問には回答できません)

下のプログラム例をコンパイルするために、VC++6.0のプロジェクトウィザードからWin32 Console Applicationを作成してください。C++言語では、COMインターフェースの情報をタイプライブラリと呼ばれるファイルから取得します。このために、

#import "C:\Program Files\Princeton Instruments\WinSpec32\WinSpec.exe"

のようにインポートディレクティブを使用します。例として白色光吸収スペクトルを測定するプログラム(ポンプ-プローブ)を示します。Visual Basicでの例より少し凝っています。TTLポートの1番と2番に外部シャッターを接続し、1番のシャッターでプローブ光(白色光)を、2番のシャッターでポンプ光をコントロールし、ダークも自動的に測定します。さらに、CCD素子のビニング(グルーピング)がしてあるとして(もしくはDual PDAを使用して)、上の領域に試料を通過するスペクトルを、下の領域でサンプルを通過しない参照スペクトルを取得して、白色光の揺らぎを抑える事が出来るように作成してあります。2番のシャッターでポンプ光を遮断した時のスペクトルと開いた時のスペクトルの除算(透過率)を表示するプログラムです(ちと長いです)。

#include "stdafx.h"

#include "stdio.h"



#import "C:\Program Files\Princeton Instruments\WinSpec32\WinSpec.exe"



WINX32Lib::IDocFilePtr pMeasureSub(_variant_t Filename, int nCount)

{

    WINX32Lib::IExpSetupPtr pExp( __uuidof(WINX32Lib::ExpSetup) );

    static WINX32Lib::IDocFilePtr pDoc( __uuidof( WINX32Lib::DocFile ));

    long framecount=0;

    long count;     

    short running;

    _variant_t  var;

    short response;



    //  Backgroundを使わない

    var=(long)FALSE;

    pExp->SetParam( WINX32Lib::EXP_BBACKSUBTRACT, &var );



    //  data-typeをLongに固定

    var=(long)WINX32Lib::X_LONG;

    pExp->SetParam( WINX32Lib::EXP_DATATYPE, &var );





    //  Overwriteでいく

    var=(long)WINX32Lib::EXPFA_OVERWRITE;

    pExp->SetParam( WINX32Lib::EXP_FILEACCESS, &var );



    /*  overwrite confirmを消す */

    var=(long)FALSE;

    pExp->SetParam( WINX32Lib::EXP_OVERWRITECONFIRM, &var );



    //  Auto-saveを設定

    var=(long)WINX32Lib::EXPAS_AUTO;

    pExp->SetParam( WINX32Lib::EXP_AUTOSAVE, &var );



    //  ファイル名を設定する

    var=Filename;

    pExp->SetParam( WINX32Lib::EXP_DATFILENAME, &var );



    //  Frame数を設定

    var=(long)nCount;

    pExp->SetParam( WINX32Lib::EXP_SEQUENTS, &var );



    //  測定スタート

    pExp->Start(&pDoc);



    running = TRUE;

    count=1;

    framecount=0;



    /* loop until all frames acquired */

    do

    {

        while (( framecount < count ) && (running))

        {

            /* While Experiment is running */

            var = pDoc->GetParam( WINX32Lib::DM_LASTFRAMERDY, &response );

            framecount = (long) var;                

            running = pExp->GetParam(WINX32Lib::EXP_RUNNING, &response);

        }

        if ( running )

            count++;

    } while (( count <= nCount ) && (running));



    var = pDoc->GetParam( WINX32Lib::DM_LASTFRAMERDY, &response );

    framecount = (long) var;



    /*  ABORT */

    if ( framecount < nCount )

    {

        return  NULL;

    } /* END ABORT */





    return pDoc;



}



int main(int argc, char* argv[])

{

    CoInitialize( NULL );   //  必須



    WINX32Lib::IExpSetupPtr pExp( __uuidof(WINX32Lib::ExpSetup) );

    WINX32Lib::IDocFilePtr pDoc( __uuidof( WINX32Lib::DocFile ));

    WINX32Lib::IDocFilePtr pDocNew( __uuidof( WINX32Lib::DocFile ));

    _variant_t vData, vData2;  // make an empty variant for the data

    SAFEARRAY *pSA, *pSA2;

    LONG    *pDataLong;         //  2

    double  *pDataDouble;       //  4

    long frames;

    short response;

    _variant_t  var;

    int j, k;

    int status = 1;

    _variant_t ttl((long)0x00);

    double *dBkg1, *dBkg2, *dRef, *dTrans;

    double dTmp1, dTmp2;

    int *nAvr;

    variant_t Filename, FilenameOrg;

    long xdim, ydim, zdim;



    xdim = (long) pExp->GetParam( WINX32Lib::EXP_XDIM, &response );

    ydim = (long) pExp->GetParam( WINX32Lib::EXP_YDIM, &response );



    if (ydim!=2){

        //  ROIが2つ設定されていないと動作しない

        CoUninitialize();       //  必須

        return -1;

    }



    dBkg1=new double[xdim];

    dBkg2=new double[xdim];

    dRef=new double[xdim];

    dTrans=new double[xdim];

    nAvr=new int[xdim];



    /* Get the number of frames that we are getting */

    frames=(long)pExp->GetParam( WINX32Lib::EXP_SEQUENTS, &response );



    // new doc xdim X ydim X zdim as float type

    var=pExp->GetParam( WINX32Lib::EXP_DATFILENAME, &response );

    FilenameOrg = var.bstrVal;



    //  まずバックグラウンドを取得

    //  シャッターをクローズ

    ttl = (long)0x0c;

    pExp->SetParam( WINX32Lib::EXP_TTL_LINES, &ttl );

    Filename="PumpPrb_Bkg";

    pDoc=pMeasureSub(Filename, 1);

    if (pDoc==NULL){

        return 0;

    }

    zdim = (long) pDoc->GetParam( WINX32Lib::DM_FRAMECOUNT, &response );



    for (k = 0; k < (long)xdim; k++){

        dBkg1[k]=0.0;

        dBkg2[k]=0.0;

    }



    for ( j=0; j < zdim;j++){

        pDoc->GetFrame(j+1, &vData); // get the data

        pSA =   V_ARRAY(&vData);

        if (S_OK ==(long)SafeArrayAccessData(pSA, (void **)&pDataLong)){

            for (k = 0; k < (long)xdim; k++){

                dBkg1[k]+=(double)pDataLong[k];

                dBkg2[k]+=(double)pDataLong[k+xdim];

            }

            SafeArrayUnaccessData(pSA); // unlock the array

        }

    }

    for (k = 0; k < (long)xdim; k++){

        dBkg1[k]/=(double)zdim;

        dBkg2[k]/=(double)zdim;

    }



    pDoc->Close();



    /*  透過率用のデータを開く  */

    pDocNew->Open("", xdim, 1L, 1L, (long)WINX32Lib::X_DOUBLE, 

        "Trans");  



    WINX32Lib::IDocWindowPtr pWin=pDocNew->GetWindow();



    var=(long)FALSE;

    pWin->SetParam(WINX32Lib::DI_BINITAUTOSCALE, &var);

    var=(double)0.0;

    pWin->SetParam(WINX32Lib::DI_DATAINTENLO, &var);

    var=(double)1.2;

    pWin->SetParam(WINX32Lib::DI_DATAINTENHI, &var);





    //  次にIoを取得

    //  LSBをHighにしてシャッターをオープン

    ttl = (long)0x0d;

    pExp->SetParam( WINX32Lib::EXP_TTL_LINES, &ttl );



    for (int nCount=0;nCount<2; nCount++){

        Filename="PumpPrb_Io";

        pDoc=pMeasureSub(Filename, 1);

        if (pDoc==NULL){

            break;

        }

        zdim = (long) pDoc->GetParam( WINX32Lib::DM_FRAMECOUNT, &response );



        for (k = 0; k < (long)xdim; k++){

            dTrans[k]=0.0;

            nAvr[k]=0;

        }



        for ( j=0; j < zdim;j++){

            pDoc->GetFrame(j+1, &vData); // get the data

            pSA =   V_ARRAY(&vData);

            if (S_OK ==(long)SafeArrayAccessData(pSA, (void **)&pDataLong)){

                for (k = 0; k < (long)xdim; k++){

                    dTmp1=(double)pDataLong[k]-dBkg1[k];

                    dTmp2=(double)pDataLong[k+xdim]-dBkg2[k];

                    if (dTmp2>0.0){

                        dTrans[k]+=dTmp1/dTmp2;

                        nAvr[k]++;

                    }

                }

                SafeArrayUnaccessData(pSA); // unlock the array

            }

        }

        for (k = 0; k < (long)xdim; k++){

            if (nAvr[k]>0)   dTrans[k]/=(double)nAvr[k];

            else            dTrans[k]=0.0;

        }



        pDoc->Close();



        if (nCount==1){

            for (k = 0; k < (long)xdim; k++){

                if (dRef[k]>0.0) dTrans[k]/=dRef[k];

                else            dTrans[k]=0.0;

            }



            for (k = 0; k < (long)xdim; k++)

                dRef[k]=dTrans[k];





            pDocNew->GetFrame(1, &vData2); // get the data

            pSA2 =  V_ARRAY(&vData2);



            if (S_OK == (long)SafeArrayAccessData(pSA2, (void **)&pDataDouble)){

                for (k = 0; k < (long)xdim; k++){

                    pDataDouble[k]=dTrans[k];

                }

                SafeArrayUnaccessData(pSA2); // unlock the array

                pDocNew->PutFrame(1, &vData2);  // stuff the data back into the doc

                pDocNew->Update();

            }

        }



    }



    delete[] dBkg1;

    delete[] dBkg2;

    delete[] dRef;

    delete[] dTrans;

    delete[] nAvr;



    //  シャッターをクローズ

    ttl = (long)0x0c;

    pExp->SetParam( WINX32Lib::EXP_TTL_LINES, &ttl );





    //  ファイル名を戻す

    var=FilenameOrg;

    pExp->SetParam( WINX32Lib::EXP_DATFILENAME, &var );



    //  データタイプを戻す

    var=(long)WINX32Lib::X_UNKNOWN;

    pExp->SetParam( WINX32Lib::EXP_DATATYPE, &var );



    CoUninitialize();       //  必須



    return 0;

}