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