![]()
今回は新しいページをバックグラウンドのタブで開けるようにする。
現状では「ファイルメニュー」の「新規作成」でも、リンクを右クリックして現れるメニューから「新しいウインドウで開く」を選択したときも、新しく開いたタブにフォーカスがあたり、それまで開いていたタブから新しいタブに切り替わってしまう。
それを
・「ファイルメニュー」の「新規作成」で開いたタブはアクティブで
・リンクを右クリックして現れるメニューから「新しいウインドウで開く」から開いたタブはバックグラウンドで
開くようにする。
//■追加
class CTabViewEx : public CTabView
{
public:
//WTLのCTabView::InsertPageからソースをコピー&改変
//
//bOpenInBackground=trueなら新しいタブにフォーカスを与えない(バックグラウンドで開く)
//
bool AddPage(HWND hWndView, LPCTSTR lpstrTitle, int nImage = -1, LPVOID pData = NULL,bool bOpenInBackground=false)
{
return InsertPage(GetPageCount(), hWndView, lpstrTitle, nImage, pData, bOpenInBackground);
}
//WTLのCTabView::InsertPageからソースをコピー&改変
//
//bOpenInBackground=trueなら新しいタブにフォーカスを与えない(バックグラウンドで開く)
//
bool InsertPage(int nPage, HWND hWndView, LPCTSTR lpstrTitle, int nImage = -1, LPVOID pData = NULL,bool bOpenInBackground=false)
{
ATLASSERT(::IsWindow(m_hWnd));
ATLASSERT(nPage == GetPageCount() || IsValidPageIndex(nPage));
CTabViewEx* pT = static_cast<CTabViewEx*>(this); //■変更 CTabViewExでキャスト
int cchBuff = lstrlen(lpstrTitle) + 1;
LPTSTR lpstrBuff = NULL;
ATLTRY(lpstrBuff = new TCHAR[cchBuff]);
if(lpstrBuff == NULL)
return false;
SecureHelper::strcpy_x(lpstrBuff, cchBuff, lpstrTitle);
CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
LPTSTR lpstrTabText = buff.Allocate(m_cchTabTextLength + 1);
if(lpstrTabText == NULL)
return false;
pT->ShortenTitle(lpstrTitle, lpstrTabText, m_cchTabTextLength + 1);
SetRedraw(FALSE);
TCITEMEXTRA tcix = { 0 };
tcix.tciheader.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM;
tcix.tciheader.pszText = lpstrTabText;
tcix.tciheader.iImage = nImage;
tcix.tvpage.hWnd = hWndView;
tcix.tvpage.lpstrTitle = lpstrBuff;
tcix.tvpage.pData = pData;
int nItem = m_tab.InsertItem(nPage, tcix);
if(nItem == -1)
{
delete [] lpstrBuff;
SetRedraw(TRUE);
return false;
}
if(bOpenInBackground == false || GetPageCount() == 1) //■条件を追加
{
//新しいタブをアクティブにする
SetActivePage(nItem);
pT->OnPageActivated(m_nActivePage);
}
if(GetPageCount() == 1)
pT->ShowTabControl(true);
pT->UpdateLayout();
SetRedraw(TRUE);
RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN);
return true;
}
};
class CMainFrame : public CFrameWindowImpl<CMainFrame>, public CUpdateUI<CMainFrame>,
public CMessageFilter, public CIdleHandler
,protected CIShellMenuPopup //「お気に入り」メニュー用クラス。publicの必要なし
,protected CIEToolbarManager //IEツールバー管理クラス。publicの必要なし
{
CAddressBarCtrl _wndAddressBar; // アドレスバー用コンボボックス
CTabViewEx m_view; //■変更
CCommandBarCtrl2 m_CmdBar;
public:
//■変更(bOpenInBackgroundへの対応)
//タブの新規作成
//nPosはタブを追加する場所。nPos<0(もしくはnPos=m_view.GetPageCount())で一番後ろ、
//そのほかの数値はCTabView::InsertPageにそのまま渡す
//
//戻ったポインタは自動削除されるため、deleteの必要なし
//
//bOpenInBackground=trueならバックグラウンドでタブを開く
//
CTabBrowser100View* CreateNewTab(LPCTSTR pszURL,LPCTSTR pszTitle,int nPos=-1,int nImage=-1,bool bOpenInBackground=false)
{
bool ret;
CTabBrowser100View* pView;
//■追加
//bOpenInBackgroundが指定されていても現在タブが1つもない状態ならbOpenInBackgroundをfalseに強制設定する
if(bOpenInBackground && m_view.GetPageCount() == 0)
bOpenInBackground = false;
pView = new CTabBrowser100View(&m_view); //タブビューのポインタを渡す
if(pView == NULL)
return NULL;
//ビューウインドウ生成
if(pszURL == NULL || *pszURL == NULL)
pView->Create(m_view, rcDefault, _T("about:blank"), WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_HSCROLL | WS_VSCROLL, 0);
else
pView->Create(m_view, rcDefault, pszURL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_HSCROLL | WS_VSCROLL, 0);
if(pView->IsWindow() == FALSE)
{
delete pView;
return NULL; //ビューウインドウ生成失敗
}
//タブにビューを割り当てる
if(nPos < 0)
nPos = m_view.GetPageCount();
if(pszTitle)
ret = m_view.InsertPage(nPos,pView->m_hWnd,pszTitle,nImage,pView,bOpenInBackground); //■変更
else
ret = m_view.InsertPage(nPos,pView->m_hWnd,_T(""),nImage,pView,bOpenInBackground); //■変更
if(ret == false)
{
delete pView;
return NULL; //タブへの追加失敗
}
//IEツールバーの生成
{
size_t i;
size_t nSize;
nSize = _acAvailableIEToolbar.GetCount();
for(i = 0; i < nSize; i++)
{
if(_acAvailableIEToolbar[i].pwndDummy)
pView->AddIEToolbar(*_acAvailableIEToolbar[i].pwndDummy,bOpenInBackground); //IEツールバー生成
}
}
return pView;
}
#pragma once
class CTabBrowser100View;
// CMainFrame::nDnpCreateNewTab() 用の情報クラス
class CDnpCreateNewTabInfo
{
public:
CAtlString strURL;
CAtlString strTitle;
int nImage;
int nPos;
bool bOpenInBackground; //■追加
CTabBrowser100View* pView;
CDnpCreateNewTabInfo()
{
strURL = _T("about:blank");
pView = NULL;
nImage = -1;
nPos = -1;
bOpenInBackground = false; //■追加
}
};
//WM_DNP_CREATENEWTABによりタブの作成
//WPARAMはCDnpCreateNewTabInfoへのポインタを渡す
LRESULT OnDnpCreateNewTab(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
CDnpCreateNewTabInfo* pInfo = (CDnpCreateNewTabInfo*)wParam;
if(pInfo == NULL)
return 0;
//■変更 pInfo->bOpenInBackgroundを追加
pInfo->pView = CreateNewTab(pInfo->strURL,pInfo->strTitle,pInfo->nPos,pInfo->nImage,pInfo->bOpenInBackground);
return 0;
}
//新しいウインドウで開く前に呼ばれる処理
//新しいタブで開く
void __stdcall OnNewWindow2(IDispatch **ppDisp,VARIANT_BOOL *Cancel)
{
CDnpCreateNewTabInfo cInfo;
cInfo.bOpenInBackground = true; //■追加 リンクを新しいタブで開くときはバックグラウンドで開く
//新しいタブを作る
GetTopLevelWindow().SendMessage(WM_DNP_CREATENEWTAB,(WPARAM)&cInfo);
if(cInfo.pView == NULL || cInfo.pView->_pIWebBrowser2 == NULL)
return;
//新しいタブで開くようにIEコントロールにポインタを渡す
cInfo.pView->_pIWebBrowser2->put_RegisterAsBrowser(VARIANT_TRUE); //これしなくても開くようになっているのはなぜ?IE8から?一応実行しておく
cInfo.pView->_pIWebBrowser2->get_Application(ppDisp);
}
しかし今回の修正によりリンクを新しいタブで開いたときに「Googleツールバー」の下端が欠けてしまい、きちんと表示されなくなった。次回はその問題を修正する。
