![]()
前回はステータスバー関連処理を見直す前段階として「MainFrm.h」内の処理をコメントアウトした。今回はコメントアウトした処理を参考にしながらステータスバー関連処理を新しく作り直す。
#include "atlcoll.h"
//■CMainFrameから移動
//アイコンを管理
//アイコンをAddする関数などは未実装。今後追加
class CIconManager
{
protected:
CAtlArray<HICON> _ahIcon; //アイコンリスト
public:
CIconManager()
{
SetFixedIndexIcon(); //固定インデックスのアイコンを追加
}
~CIconManager()
{
Destroy();
}
enum ICON_INDEX
{
ICON_WARNING_SM = 0, //警告アイコン。スクリプトエラー時に利用
};
HICON GetIcon(UINT nIconIndex)
{
if(nIconIndex >= _ahIcon.GetCount())
return NULL;
return _ahIcon[nIconIndex];
}
protected:
//固定インデックスのアイコンを追加
//かならずICON_INDEXと同じ値になるようにする
bool SetFixedIndexIcon(void)
{
ATLASSERT(_ahIcon.GetCount() == 0); //すでに設定されてる?
if(_ahIcon.GetCount())
return false;
size_t nIndex;
HICON hIcon;
//警告アイコン
//LoadImageで32x32を読み込み、CopyImageで16x16に縮小。LoadImageのHICONはLR_SHAREDなのでDestroyIcon必要なし
hIcon = (HICON)::LoadImage(NULL,MAKEINTRESOURCE(OIC_WARNING),IMAGE_ICON,0,0,LR_DEFAULTSIZE | LR_SHARED);
hIcon = (HICON)::CopyImage(hIcon,IMAGE_ICON,::GetSystemMetrics(SM_CXSMICON),::GetSystemMetrics(SM_CYSMICON),LR_COPYFROMRESOURCE);
nIndex = _ahIcon.Add(hIcon);
ATLASSERT(nIndex == ICON_WARNING_SM);
return true;
}
//保持してるアイコンの破棄
void Destroy(void)
{
size_t i;
size_t nSize;
nSize = _ahIcon.GetCount();
for(i = 0; i < nSize; i++)
{
if(_ahIcon[i] == NULL)
continue;
::DestroyIcon(_ahIcon[i]);
}
_ahIcon.RemoveAll();
}
};
//■追加
class CIELikeStatusbar : public CWindowImpl<CIELikeStatusbar>
{
//■CMainFrameから移動
CIconManager _cIconList;
//■CMainFrameから移動
CProgressBarCtrl _wndProgressBar; //ステータスバーに配置するプログレスバーコントロール
CAtlString _strText;
//■CTabBrowser100Viewから移動
long _nLastProgress; //最後に受け取ったプログレス情報
long _nLastProgressMax; //最後に受け取ったプログレス最大値
//■CTabBrowser100Viewから移動
bool _bPageError; //現在のページでスクリプトエラーなどがあればtrue、通常はfalse
public:
CIELikeStatusbar()
{
_nLastProgress = -1;
_nLastProgressMax = -1;
_bPageError = false;
}
BEGIN_MSG_MAP(CIELikeStatusbar)
MESSAGE_HANDLER(WM_SIZE, OnSize) //■CMainFrameから移動
END_MSG_MAP()
//■CMainFrameから移動
LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
bHandled = FALSE;
if(_wndProgressBar.IsWindow())
RefreshProgressBar(); //プログレスバー表示更新
return 0;
}
//■CMainFrameから移動。m_hWndStatusBarをm_hWndに変更
//bVisible=falseならプログレスバーを消す
//nProgress < 0、nProgressMax < 0ならプログレス設定はしない
//nProgressMax < nProgressなら強制的に非表示にする
bool RefreshProgressBar(int nProgress=-1,int nProgressMax=-1,bool bVisible=true)
{
//■追加
if((nProgress >= 0 && nProgressMax >= 0) || (nProgressMax < nProgress))
{
//状態を保存しておく
_nLastProgress = nProgress;
_nLastProgressMax = nProgressMax;
}
if(::IsWindow(m_hWnd) == FALSE)
return false; //ステータスバー表示してない
int nProgressWidth = 100; //■プログレスバーの幅は100px固定とする
CRect rect;
CStatusBarCtrl wndStatusBar = m_hWnd;
if(_nLastProgressMax < _nLastProgress) //■変更
bVisible = false;
if(bVisible == false)
nProgressWidth = 0;
//ステータスバーのペインの作成/更新
{
int pnParts[2]; //2つペインを作成(1つはデフォルト、もう1つはプログレスバー用)
wndStatusBar.GetClientRect(&rect);
pnParts[0] = rect.Width() - nProgressWidth;
pnParts[1] = rect.Width();
wndStatusBar.SetParts(sizeof(pnParts) / sizeof(pnParts[0]),pnParts);
}
//プログレスバーの生成/更新
{
wndStatusBar.GetRect(1,&rect); //2つめのペインをプログレスバーに利用する
if(_wndProgressBar.IsWindow() == FALSE)
_wndProgressBar.Create(m_hWnd,rect,0,WS_CHILD); //プログレスバーを生成
else
_wndProgressBar.MoveWindow(&rect); //位置を移動
if(bVisible)
{
if(_wndProgressBar.IsWindowVisible() == FALSE)
_wndProgressBar.ShowWindow(SW_NORMAL); //可視に
}
else
{
if(_wndProgressBar.IsWindowVisible())
_wndProgressBar.ShowWindow(SW_HIDE); //不可視に
}
//■変更
//プログレスの設定
if(_nLastProgress >= 0)
_wndProgressBar.SetRange(0,_nLastProgressMax);
if(_nLastProgress >= 0)
_wndProgressBar.SetPos(_nLastProgress);
}
return true;
}
//ステータスバー表示更新
bool Refresh(bool bCapture)
{
if(bCapture == false)
{
if(_wndProgressBar.IsWindow())
{
if(_wndProgressBar.IsWindowVisible())
_wndProgressBar.ShowWindow(SW_HIDE); //不可視に
}
return true;
}
if(IsWindow() == FALSE)
return false;
//ステータスバーのテキスト変更
{
SetText(_strText);
}
//ステータスバーのエラーアイコン変更
{
CStatusBarCtrl wndStatusBar = m_hWnd;
if(_bPageError)
wndStatusBar.SetIcon(0,_cIconList.GetIcon(CIconManager::ICON_WARNING_SM));
else
wndStatusBar.SetIcon(0,NULL);
}
//プログレス変更
{
RefreshProgressBar(_nLastProgress,_nLastProgressMax);
}
return true;
}
bool SetText(LPCTSTR pszText)
{
_strText = pszText;
if(IsWindow() == FALSE)
return true;
SetWindowText(pszText);
return true;
}
bool SetPageError(bool bError)
{
_bPageError = bError; //エラーが発生したことを保持
if(IsWindow())
{
CStatusBarCtrl wndStatusBar = m_hWnd;
if(_bPageError)
wndStatusBar.SetIcon(0,_cIconList.GetIcon(CIconManager::ICON_WARNING_SM));
else
wndStatusBar.SetIcon(0,NULL);
}
return true;
}
};
//■処理内容変更
//ステータスバーのメッセージ変更
void ChangeStatusText(LPCTSTR pszText)
{
_strLastStatusText = pszText; //いつでも参照できるようにクラスのメンバーに保存しておく
GetLastStatusText(_strLastStatusText);
_wndStatusbar.SetText(_strLastStatusText);
}
void __stdcall OnStatusTextChange(BSTR bstrText)
{
ChangeStatusText((CAtlString)bstrText);
}
//■処理内容変更
//エラー発生/解消時に呼ぶ
//bError=trueならエラー発生
void SetErrorState(bool bError)
{
_bPageError = bError;
if(bError)
ChangeStatusText(NULL);
_wndStatusbar.SetPageError(bError);
}
//■削除
//bool IsPageError(void)
//{
// return _bPageError;
//}
LRESULT OnDnpScriptError(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
SetErrorState(true);
return 0;
}
//最後にIEコントロールから受け取ったステータスバー用メッセージを返す
void GetLastStatusText(CAtlString& strText)
{
strText = _strLastStatusText;
//表示する文字がないときで、現在ページにエラーがあればエラーメッセージを返す
if(_bPageError && strText == _T(""))
strText = _T("ページでエラーが発生しました。");
}
void __stdcall OnDownloadComplete()
{
}
void __stdcall OnCommandStateChange(long lCommand,VARIANT_BOOL vbEnable)
{
}
void __stdcall OnDownloadBegin(void)
{
SetErrorState(false); //エラー情報をリセット
}
//■削除
//long _nLastProgress; //最後に受け取ったプログレス情報
//long _nLastProgressMax; //最後に受け取ったプログレス最大値
//■処理内容変更
void __stdcall OnProgressChange(long lProgress,long lProgressMax)
{
if(lProgress < 0 || (lProgressMax == 0 && lProgress == 0)) //MSDNには記述がないが(0,0)で終わることが多いため(0,0)でも非表示
lProgressMax = lProgress - 1; //lProgressMax < lProgress にしておく -> 自動的にプログレスバーが消える
_wndStatusbar.RefreshProgressBar(lProgress,lProgressMax);
}
//■削除
////最後にIEコントロールから受け取ったプログレス情報を返す
//void GetLastProgress(long& nProgress,long& nProgressMax)
//{
// nProgress = _nLastProgress;
// nProgressMax = _nLastProgressMax;
//}
CTabBrowser100View(CTabView* pTabView,HWND hWndRebarIE)
{
_pTabView = pTabView;
// _nLastProgress = 0; //■削除
// _nLastProgressMax = -1; //■削除
_hWndRebarIE = hWndRebarIE;
_bPageError = false;
}
CIELikeStatusbar _wndStatusbar; //■追加
//■追加
//メインウインドウから呼ばれる
//bCapture=trueでこのビューがステータスバーを制御する
//bCapture=falseでこのビューがステータスバーを解放する
bool SetStatusBar(HWND hWnd,bool bCapture)
{
if(bCapture)
{
if(_wndStatusbar.IsWindow())
return false;
_wndStatusbar.SubclassWindow(hWnd);
_wndStatusbar.Refresh(true);
}
else
{
if(_wndStatusbar.IsWindow())
_wndStatusbar.UnsubclassWindow();
_wndStatusbar.Refresh(false);
}
return true;
}
//タブが選択されたときの処理
LRESULT OnTabPageActivated(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
{
if(pnmh == NULL)
return 0;
//全てのビューに対してタブ変更があったことを通知
{
int i;
int nCount;
CTabBrowser100View* pView;
nCount = m_view.GetPageCount();
for(i = 0; i < nCount; i++)
{
pView = GetPageView(i);
if(pView == NULL)
continue;
//■処理変更
if(pnmh->idFrom == i)
pView->OnTabPageChange(true);
else
{
pView->OnTabPageChange(false);
pView->SetStatusBar(m_hWndStatusBar,false); //ステータスバー解放
}
}
//■3行追加
pView = GetActivePageView();
if(pView)
pView->SetStatusBar(m_hWndStatusBar,true); //ステータスバーセット
}
bool ret;
CTabBrowser100View* pView;
pView = GetActivePageView(); //アクティブビュー取得
if(pView == NULL)
return 0;
//アドレスバーのURL変更
{
CAtlString strURL;
ret = pView->GetURL(strURL); //URL取得
if(ret)
_wndAddressBar.SetWindowText(strURL);
}
return 0;
}
![]()
これでビルド/実行すると再びステータスバーへの表示が行われるようになった。
しかしまだステータスバーのダブルクリックに関する処理を再実装していない。次回はそれを行う。
