コンボボックスのスタイル変更

[戻る]
TOMO 2004/04/21(水) 21:14:34
プログラム上でコンボボックスのスタイルを
ドロップダウン⇔ドロップダウンリストと変更することは
出来るのでしょうか?
どなたかご存知でしたらご教授御願い致しますm(__)m

TOMO 2004/04/21(水) 21:20:35
書き忘れました。

開発環境は
Windows2000 VC++6.0 
MFC ダイアログベース
です。

blackwind 2004/04/21(水) 21:29:53
> プログラム上でコンボボックスのスタイルを
> ドロップダウン⇔ドロップダウンリストと変更することは
> 出来るのでしょうか?

# 何故に変更したいのか・・・分からん。

ドロップダウン → ドロップダウンリストに変更
ドロップダウンリスト → ドロップダウンに変更
の二つを行いたいと言う事でしょうか?

また、どのタイミングで変更したいのでしょうか?

TOMO 2004/04/21(水) 21:35:31
>ドロップダウン → ドロップダウンリストに変更
>ドロップダウンリスト → ドロップダウンに変更
>の二つを行いたいと言う事でしょうか?

これはどちらかが出来ればOKです。

タイミングとしては、ウィンドウを表示するときにやりたいと
思っています。

何か方法はありますでしょか。

r 2004/04/21(水) 23:15:21
> ドロップダウン⇔ドロップダウンリストと変更することは

これはやってみたことがないですが...
一般的に、コントロールのスタイルを変更しようという場合は次のいずれかになると思
います。

1.SetWindowLong で変更(MFCならModifyStyleでも同等)
2.特別なスタイル変更のために用意されたメッセージをコントロールに送信する
   (例:EM_SETPASSWORDCHAR)

1や2がだめなら、

3.スタイルの異なるコントロールを2つ作っておいて一方だけを可視にする
4.元のコントロールと同じ場所に別のスタイルのコントロールを Create し、
    元のコントロールは Destroy してしまう

といったところです。
(他にもあるかもしれませんが、特殊な処理になると思います)

... 2004/04/22(木) 00:25:09
vさんの4番目の方法です。

CComboBox m_cbo;

BOOL CxxxDlg::OnInitDialog()
{
  RECT rect;
  rect.top =10;
  rect.bottom  =200;
  rect.left =10;
  rect.right =200;

//  m_cbo.Create(CBS_DROPDOWN  | WS_VSCROLL ,rect,this,IDC_COMBO1);
    m_cbo.Create(CBS_DROPDOWNLIST | WS_VSCROLL ,rect,this,IDC_COMBO1);

  m_cbo.AddString("AAA");
  m_cbo.AddString("BBB");

  m_cbo.ShowWindow(TRUE);
}

位置はあえて直指定していますが、IDC_COMBO1の位置を取得すれば同じ所に
表示できると思います。

r 2004/04/22(木) 01:28:46
補足情報。

http://support.microsoft.com/default.aspx?
scid=http://support.microsoft.com:80/support/kb/articles/Q84/9/78.asp&NoWebCont
ent=1

SetWindowLong では、ある種のスタイル変更がうまくいかない場合があること、
その場合は3か4を使用したらいい、というようなことが書かれています。

#今回のが SetWindowLong が効かないケースかどうかについては試してません。
#試した人がいたら、教えてね。いや、まぁ、試してみりゃわかるんだけど σ(^^;

... 2004/04/22(木) 01:44:49
>vさんの4番目の方法です。
rさんの4番目の方法です。

#すいません。年のせいか目が。。(言い訳)

瀬戸っぷ [E-Mail] 2004/04/22(木) 10:23:54
> #今回のが SetWindowLong が効かないケースかどうかについては試してません。
> #試した人がいたら、教えてね。いや、まぁ、試してみりゃわかるんだけど σ(^^;

というワケでちょっと試してみました。
(Windows98SE/VC++6SP6/PlatformSDK February 2003)
ドロップダウンリスト→ドロップダウンへの変更で。

    DWORD dwErr;
    HWND hCombo = GetDlgItem(hdwnd, IDC_STYLE);
    DWORD dwStyle = GetWindowLong(hCombo, GWL_STYLE);
    dwStyle &= ~CBS_DROPDOWNLIST;
    dwStyle |= CBS_DROPDOWN;
    SetLastError(0);
    dwErr = SetWindowLong(hCombo, GWL_STYLE, dwStyle);
    if(dwErr == 0) {
        dwErr = GetLastError();
    }
    SetWindowPos(hCombo, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | 
SWP_NOZORDER | SWP_FRAMECHANGED);

こんな感じでやってみましたが…無理でした。

ドロップダウンの時はコンボボックスにエディットボックスの子ウィンドウが生成されますが、
ドロップダウンリストの時にはありませんから…その辺りの問題かと思われます。
CB_GETCOMBOBOXINFOで、情報を確認したワケではないので断言は出来ませんが。

sugar 2004/04/22(木) 12:47:51
こんな方法もあるみたいです。

http://niigata.cool.ne.jp/minamix/winctrl/combo/switchcombo.htm

Jojy 2004/04/22(木) 14:17:25
[[解決]]
こんなんどうですか?
(微妙に手直しが必要かも)

CComboBox    *pCbx = (CComboBox *)GetDlgItem( IDC_COMBO1 );
if( pCbx != NULL )
{
    CRect    rect,rect2;
    DWORD    dwStyle;
    CFont    *pFont;
    pCbx->GetDroppedControlRect(rect);
    pCbx->GetClientRect(rect2);
    rect2.right = rect2.left = 0;
    rect += rect2;
    ScreenToClient(rect);
    dwStyle = pCbx->GetStyle();
    pFont = pCbx->GetFont();
    pCbx->DestroyWindow();
    if( (dwStyle & 0x3) == CBS_DROPDOWNLIST )
    {
        //ドロップダウンリスト->ドロップダウン
        dwStyle = dwStyle & (~CBS_DROPDOWNLIST) | CBS_DROPDOWN;
    }
    else
    {
        //ドロップダウン->ドロップダウンリスト
        dwStyle = dwStyle & (~CBS_DROPDOWN) | CBS_DROPDOWNLIST;
    }
    pCbx->Create(dwStyle,rect,this,IDC_COMBO1);
    pCbx->SetFont(pFont);
    pCbx->ShowWindow(SW_SHOW);
    //中身をセット
    //pCbx->AddString("中身");
}

Jojy 2004/04/22(木) 14:18:25
ごめんなさい。
間違って解決チェック入れてしまいました。
(外し方ないのね...とほほ...)

Jojy 2004/04/22(木) 14:40:22
>(微妙に手直しが必要かも)
ほんとにごめんなさい。
微妙どころかいっぱい手直し必要ですね...(汗

Jojy 2004/04/22(木) 15:39:49
こんなんでいかがでしょうか?
(少しは手を入れる必要があるかな…)

void CXXXDlg::ChangeListStyle( int nID, DWORD dwType, DWORD dwHeight )
{
    CComboBox    *pCbx = (CComboBox *)GetDlgItem( nID );
    if( pCbx != NULL )
    {
        CRect    rect;
        DWORD    dwStyle;
        CFont    *pFont;
        pCbx->GetDroppedControlRect(rect);
        ScreenToClient(rect);
        rect.bottom = rect.top + dwHeight;
        dwStyle = pCbx->GetStyle();
        pFont = pCbx->GetFont();
        pCbx->DestroyWindow();
        dwStyle = dwStyle & (~0x3) | dwType;
        pCbx->Create(dwStyle,rect,this,nID);
        pCbx->SetFont(pFont);
        pCbx->ShowWindow(SW_SHOW);
    }
}

以下のような感じでいつでも変更できます。(多分)
ChangeListStyle(IDC_COMBO1,CBS_SIMPLE,86);
ChangeListStyle(IDC_COMBO1,CBS_DROPDOWN,86);
ChangeListStyle(IDC_COMBO1,CBS_DROPDOWNLIST,86);

TOMO 2004/04/22(木) 19:48:01
[[解決]]
みなさんありがとうございます!!
勉強もかねて、色々な方法を試してみたいと思います!!
完成したら、またご報告いたしますねm(__)m

古いスレッドには追加発言できません。