こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

CTabCtrl:TABインデックス単位のEnableWindow(false)について

TABインデックス単位でEnableWindow(false)を行うとTABに置いたコントールすべてが入力不可(VBでいうとLOCK(TRUE))となりますが非活性になりません。
さらに、TAB自体選択可能です。

VBではTABインデックス単位で非活性・選択不可にできるのですが、VC++では無理なのでしょうか?

-環境-
・VC++ 6.0
・MFC
・ダイアログベース

-参考-
TC_ITEM item;
::memset(&item, 0, sizeof(TC_ITEM));
item.mask = TCIF_TEXT;

item.pszText = "XXX";
m_Tab.InsertItem(0, &item);
m_OptionTab1.Create(IDD_OPTION_TAB1, &m_Tab);

  ある条件で
m_OptionTab1.EnableWindow(false);

投稿日時 - 2010-04-14 17:58:38

QNo.5825906

困ってます

このQ&Aは役に立ちましたか?

13人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.4

No.3です。
サンプルですが、以下のような感じで良いと思います。色づけ部分だけですが…。

class CTabCtrlEx : public CTabCtrl
{
: // 途中省略
public:
BOOL IsTabEnabled(int nTab); // Tab Indexが使用可能か
BOOL SubclassDlgItem(UINT nID, CWnd* pParent); // SubClassのOverride

protected:
void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
void OnDrawText(CDC& dc, CRect rc, CString sText, BOOL bDisabled);
};

// CTabCtrlEx
void CTabCtrlEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
DRAWITEMSTRUCT& ds = *lpDrawItemStruct;

int iItem = ds.itemID;

// Tab 情報
char cText[128];
TCITEM tcItem;
tcItem.mask = TCIF_TEXT;
tcItem.pszText = cText;
tcItem.cchTextMax = sizeof(cText);
GetItem(iItem, &tcItem);

// DrawItem
CDC dc;
dc.Attach(ds.hDC);

// Rect Angle と色の設定
CRect rc = ds.rcItem;
rc += CPoint(1, 4);// 適当に…

// テキスト描画
OnDrawText(dc, rc, cText, !IsTabEnabled(iItem));

dc.Detach();
}

BOOL CTabCtrlEx::IsTabEnabled(int nTab)
{
// 例えばTab2番目ならば使用不能。それ以外は使用可能
if (nTab != 2) return TRUE;

return FALSE;
}

void CTabCtrlEx::OnDrawText(CDC& dc, CRect rc, CString sText, BOOL bDisabled)
{
dc.SetTextColor(GetSysColor(bDisabled ? COLOR_3DHILIGHT : COLOR_BTNTEXT));
dc.DrawText(sText, &rc, DT_CENTER|DT_VCENTER);

if (bDisabled) {
rc += CPoint(-1,-1);
dc.SetTextColor(GetSysColor(COLOR_GRAYTEXT));
dc.DrawText(sText, &rc, DT_CENTER|DT_VCENTER);
}
}

BOOL CTabCtrlEx::SubclassDlgItem(UINT nID, CWnd* pParent)
{
if (!CTabCtrl::SubclassDlgItem(nID, pParent)) return FALSE;

ModifyStyle(0, TCS_OWNERDRAWFIXED);

return TRUE;
}


// 実装クラス
BOOL CHogeDlg::OnInitDialog()
{
CDialog::OnInitDialog();
: // 途中省略
m_ctlTabCtrl.SubclassDlgItem(IDC_TAB1, this); // サブクラス化
m_ctlTabCtrl.InsertItem(0, _T("Hoge1")); // Index追加
m_ctlTabCtrl.InsertItem(1, _T("Hoge2"));
m_ctlTabCtrl.InsertItem(2, _T("Hoge3"));
m_ctlTabCtrl.InsertItem(3, _T("Hoge4"));

return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}

上記以外にキーボード押下による処理とか、IsTabEnabledでFALSEが返ってきたIndexはtab押下を拒否するとか追加してあげれば良いと思います。

投稿日時 - 2010-04-29 01:21:20

お礼

ありがとうございます

TABインデックスの選択不可はOnSelchangeTabOptionメソッドでうまくできました
あとは、TABインデックスの文字を非活性に見せるということで、サンプルを参考にさせていただきます

投稿日時 - 2010-05-10 15:26:20

ANo.3

>VBではTABインデックス単位で非活性・選択不可にできるのですが、VC++では無理なのでしょうか?
基本的にWindowsアプリに関して(難易度は別にして)VC++で出来ない事はありません。

さて、インデックス単位でEnable/Disableですが、残念ながら標準的には関数として用意されてはいません。
ですのでサブクラス化し、カスタムドローを用いて描画してあげれば良いと思います。

投稿日時 - 2010-04-24 23:43:49

補足

ありがとうございます

>VC++で出来ない事はありません。
サンプルを探しても見つからなかったので、「できないの?」と思ったのですが、サブクラス化で可能なんですね
サンプルがあると助かるのですが...

VB暦の方が長いので、VC++の画面制御に色々苦戦しています
(VB感覚で考えてしまうので)
(C自体はVBより長いです)

投稿日時 - 2010-04-26 10:02:40

ANo.2

#1 訂正 標準コントロールじゃなくて
他から探してきたTABコントロール使ってました
ぜんぜん話が違うので忘れてください

投稿日時 - 2010-04-14 19:21:58

ANo.1

EnableWindow関数では無くてEnableTabという関数があるはずです

やってますし

投稿日時 - 2010-04-14 19:18:49

あなたにオススメの質問