プログラム上でコンボボックスのスタイルを
ドロップダウン⇔ドロップダウンリストと変更することは
出来るのでしょうか?
どなたかご存知でしたらご教授御願い致しますm(__)m
書き忘れました。
開発環境は
Windows2000 VC++6.0
MFC ダイアログベース
です。
> プログラム上でコンボボックスのスタイルを
> ドロップダウン⇔ドロップダウンリストと変更することは
> 出来るのでしょうか?
# 何故に変更したいのか・・・分からん。
ドロップダウン → ドロップダウンリストに変更
ドロップダウンリスト → ドロップダウンに変更
の二つを行いたいと言う事でしょうか?
また、どのタイミングで変更したいのでしょうか?
>ドロップダウン → ドロップダウンリストに変更
>ドロップダウンリスト → ドロップダウンに変更
>の二つを行いたいと言う事でしょうか?
これはどちらかが出来ればOKです。
タイミングとしては、ウィンドウを表示するときにやりたいと
思っています。
何か方法はありますでしょか。
> ドロップダウン⇔ドロップダウンリストと変更することは
これはやってみたことがないですが...
一般的に、コントロールのスタイルを変更しようという場合は次のいずれかになると思
います。
1.SetWindowLong で変更(MFCならModifyStyleでも同等)
2.特別なスタイル変更のために用意されたメッセージをコントロールに送信する
(例:EM_SETPASSWORDCHAR)
1や2がだめなら、
3.スタイルの異なるコントロールを2つ作っておいて一方だけを可視にする
4.元のコントロールと同じ場所に別のスタイルのコントロールを Create し、
元のコントロールは Destroy してしまう
といったところです。
(他にもあるかもしれませんが、特殊な処理になると思います)
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の位置を取得すれば同じ所に
表示できると思います。
補足情報。
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 が効かないケースかどうかについては試してません。
#試した人がいたら、教えてね。いや、まぁ、試してみりゃわかるんだけど σ(^^;
>vさんの4番目の方法です。
rさんの4番目の方法です。
#すいません。年のせいか目が。。(言い訳)
> #今回のが 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で、情報を確認したワケではないので断言は出来ませんが。
こんなんどうですか?
(微妙に手直しが必要かも)
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(中身);
}
ごめんなさい。
間違って解決チェック入れてしまいました。
(外し方ないのね...とほほ...)
>(微妙に手直しが必要かも)
ほんとにごめんなさい。
微妙どころかいっぱい手直し必要ですね...(汗
こんなんでいかがでしょうか?
(少しは手を入れる必要があるかな…)
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);
みなさんありがとうございます!!
勉強もかねて、色々な方法を試してみたいと思います!!
完成したら、またご報告いたしますねm(__)m