![]()
ファイルコピー中などに表示される進行ダイアログはCOMインターフェースのIProgressDialogにより表示できる。このインターフェースはAVIファイルの指定によるアニメーション設定などきめ細かく設定できるので便利に使える。
ここでは楽に実装できるようにラッパークラスを作成し、Test2で利用している。
依存環境:ATL
#include "atlstr.h"
#include "shlobj.h"
class CDnpProgressDialog
{
IProgressDialog* _pIProgressDialog;
public:
CDnpProgressDialog()
{
_pIProgressDialog = NULL;
}
~CDnpProgressDialog()
{
Uninitialize();
}
//
// 解放処理
//
void Uninitialize(void)
{
if(_pIProgressDialog == NULL)
return;
_pIProgressDialog->StopProgressDialog();
_pIProgressDialog->Release();
_pIProgressDialog = NULL;
}
//
// プログレスダイアログの表示
//
bool ShowProgressDialog(HWND hParentWnd,LPCTSTR pszTitle,LPCTSTR pszCancelMsg,UINT nAVIResource=0)
{
HRESULT hr;
if(_pIProgressDialog)
return false;
hr = ::CoCreateInstance(CLSID_ProgressDialog,NULL,CLSCTX_INPROC_SERVER,IID_IProgressDialog,(void**)&_pIProgressDialog);
if(_pIProgressDialog == NULL)
return false;
if(SUCCEEDED(hr))
hr = _pIProgressDialog->SetTitle((CStringW)pszTitle);
if(SUCCEEDED(hr) && nAVIResource)
hr = _pIProgressDialog->SetAnimation(NULL,nAVIResource);
if(SUCCEEDED(hr))
hr = _pIProgressDialog->SetCancelMsg((CStringW)pszCancelMsg,NULL);
if(SUCCEEDED(hr))
hr = _pIProgressDialog->SetProgress(100,0);
if(FAILED(hr))
{
_pIProgressDialog->Release();
_pIProgressDialog = NULL;
return false;
}
hr = _pIProgressDialog->StartProgressDialog(hParentWnd,NULL,PROGDLG_NORMAL,NULL);
return SUCCEEDED(hr) ? true : false;
}
//
// プログレスバー位置の設定
//
bool SetProgress(DWORD dwCompleted,DWORD dwTotal)
{
HRESULT hr;
if(_pIProgressDialog == NULL)
return false;
hr = _pIProgressDialog->SetProgress(dwCompleted,dwTotal);
return SUCCEEDED(hr) ? true : false;
}
//
// メッセージの表示
//
//nLineは1~3の範囲で指定する
//
bool SetMessage(UINT nLine,LPCTSTR pszMessage)
{
HRESULT hr;
if(_pIProgressDialog == NULL)
return false;
hr = _pIProgressDialog->SetLine(nLine,(CStringW)pszMessage,FALSE,NULL);
return SUCCEEDED(hr) ? true : false;
}
//
// 処理を中止するかどうか
//
bool IsAbort(void)
{
if(_pIProgressDialog == NULL)
return true;
return _pIProgressDialog->HasUserCancelled() ? false : true;
}
};
bool Test2(void)
{
DWORD dwProgress;
CDnpProgressDialog dlg;
//プログレスダイアログの表示
dlg.ShowProgressDialog(NULL,_T("プログレスダイアログを使用した処理"),_T("処理をキャンセル中です。"));
//メッセージを表示
dlg.SetMessage(1,_T("ダミー処理中です。"));
dlg.SetMessage(3,_T("「キャンセル」ボタンを押すまで処理が続きます。"));
dwProgress = 0;
while(dlg.IsAbort())
{
//刻々変わるメッセージを表示
CAtlString strMessage;
strMessage.Format(_T("処理をしています(%d)"),::GetTickCount());
dlg.SetMessage(2,strMessage);
//プログレスバーの進行状態設定
//プログレスバーがいっぱいになったら元にもどす
dlg.SetProgress(dwProgress,100);
if(++dwProgress >= 100)
dwProgress = 0;
//////////////////////////////
//何かの処理を次の1行の代わりに置く
::Sleep(50);
}
dlg.Uninitialize();
return true;
}
bool Test(void)
{
::CoInitialize(NULL);
Test2();
::CoUninitialize();
return true;
}
