none
カスタムのツールバーをメインフォームの画面トップに配置できない RRS feed

  • 質問

  • VisualStudio2010 VC++MFCでメインフォームにツールバーを画面トップに配置できず何時も画面のボトムに配置される
    通常のボタンのみのツールバーの場合は問題ないのですが、コンボボックス等のコントロールを配置するために新たにクラス定義で作成したものは
    何故か画面のトップに配置できないというトラブルが発生しています。
    手動でTOPに移動はできますが、再起動した場合またそのツールバーだけがBOTTOMに配置されてしまいます。

    プログラムは以下のようにしています。

    ◆MainFrm.h
    CEditBar    m_wndEditBar;

    ◆MainFrm.cpp
    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
        if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
          return -1;

       WINDOWPLACEMENT wp;
       if (ReadWindowPlacement(&wp))
          SetWindowPlacement(&wp);

       m_bColor = (AfxGetApp()->GetProfileInt(_T("General"),_T("Color"),1)!=0);
       m_bToolTips = (AfxGetApp()->GetProfileInt(_T("General"),_T("ToolTips"),1)!=0);

       if (!m_wndEditBar.Init(this,m_bColor,m_bToolTips))
       {
          TRACE0("Failed to create editbar\n");
          return -1;      // fail to create
       }

       m_wndEditBar.SetWindowText(_T("系統"));
       m_wndEditBar.EnableDocking(CBRS_ALIGN_ANY);
       EnableDocking(CBRS_ALIGN_ANY);
       DockControlBar(&m_wndEditBar,AFX_IDW_DOCKBAR_TOP);
     .
     .
     他のツールバーの配置etc
     .
     .
       LoadBarState(_T("General"));

       return 0;
    }

    ◆editbar.h
    class CEditBar : public CToolBar
    {
    public:
       BOOL m_bColor;
       CEditBar();
       BOOL Init(CWnd* pParentWnd, BOOL bColor, BOOL bToolTips);
       BOOL SetColor(BOOL bColor);
       BOOL SetHorizontal();
       BOOL SetVertical();
     //-----------------------------------
       CComboBox m_combo1;
       CComboBox m_combo2;
       CComboBox m_combo3;
       CComboBox m_combo4;
       CComboBox m_combo5;
       CComboBox m_combo6;
       CButton m_button1;
       CEdit m_edit1;
       CEdit m_edit2;
       CEdit m_edit3;


    // Attributes
    public:

    // Operations
    public:

    // Overrides
     // ClassWizard generated virtual function overrides
     //{{AFX_VIRTUAL(CEditBar)
     //}}AFX_VIRTUAL

    // Implementation
    public:
       BOOL m_bVertical;

       virtual ~CEditBar();
       virtual CSize CalcDynamicLayout(int nLength, DWORD dwMode);
       virtual BOOL PreTranslateMessage(MSG* pMsg);

     // Generated message map functions
    protected:
     //{{AFX_MSG(CEditBar)
       afx_msg void OnCombo1();
       afx_msg void OnCombo2();
       afx_msg void OnCombo3();
       afx_msg void OnCombo4();
       afx_msg void OnCombo5();
       afx_msg void OnCombo6();
       afx_msg void OnChangeEdit1();
       afx_msg void OnChangeEdit2();
       afx_msg void OnChangeEdit3();
     //}}AFX_MSG
       DECLARE_MESSAGE_MAP()
    };

    ◆editbar.cpp
    BOOL CEditBar::Init(CWnd* pParentWnd, BOOL bColor, BOOL bToolTips)
    {
       CString str;
       CStringA strA;
       m_bColor = bColor;
       m_bVertical = FALSE;

     // start out with no borders
       DWORD dwStyle = CBRS_TOOLTIPS | WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_SIZE_DYNAMIC;
       if (bToolTips)
        dwStyle |= (CBRS_TOOLTIPS | CBRS_FLYBY);
       if (!Create(pParentWnd, dwStyle, IDW_EDIT_BAR))
       {
          return FALSE;
       }

       if (!SetColor(m_bColor))
          return FALSE;

       if(!SetButtons(EditButtons, sizeof(EditButtons)/sizeof(UINT)))
          return FALSE;

       CRect rect(-COMBOBOX_WIDTH, -COMBOBOX_HEIGHT, 0, 0);
       if (!m_combo1.Create(WS_CHILD | CBS_DROPDOWN |
          CBS_AUTOHSCROLL | WS_VSCROLL | CBS_HASSTRINGS, rect, this,
          ID_EDIT_KEITOU))
       {
          return FALSE;
       }
       if (!m_combo2.Create(WS_CHILD | CBS_DROPDOWN |
          CBS_AUTOHSCROLL | WS_VSCROLL | CBS_HASSTRINGS, rect, this,
          ID_EDIT_DUCTPIPE))
       {
          return FALSE;
       }

       if (!m_combo3.Create(WS_CHILD | CBS_DROPDOWN |
          CBS_AUTOHSCROLL | WS_VSCROLL | CBS_HASSTRINGS, rect, this,
          ID_EDIT_SIZEPAI))
       {
          return FALSE;
       }
       if (!m_combo4.Create(WS_CHILD | CBS_DROPDOWN |
          CBS_AUTOHSCROLL | WS_VSCROLL | CBS_HASSTRINGS, rect, this,
          ID_EDIT_SIZEA))
       {
          return FALSE;
       }
       if (!m_combo5.Create(WS_CHILD | CBS_DROPDOWN |
          CBS_AUTOHSCROLL | WS_VSCROLL | CBS_HASSTRINGS, rect, this,
         ID_EDIT_SHUBETU))
       {
          return FALSE;
       }
       if (!m_combo6.Create(WS_CHILD | CBS_DROPDOWN |
          CBS_AUTOHSCROLL | WS_VSCROLL | CBS_HASSTRINGS, rect, this,
          ID_EDIT_KANZAI))
       {
          return FALSE;
       }
        HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
       if (hFont == NULL)
          hFont = (HFONT)GetStockObject(ANSI_VAR_FONT);

       m_combo1.SendMessage(WM_SETFONT, (WPARAM)hFont);
       m_combo2.SendMessage(WM_SETFONT, (WPARAM)hFont);
       m_combo3.SendMessage(WM_SETFONT, (WPARAM)hFont);
       m_combo4.SendMessage(WM_SETFONT, (WPARAM)hFont);
       m_combo5.SendMessage(WM_SETFONT, (WPARAM)hFont);
       m_combo6.SendMessage(WM_SETFONT, (WPARAM)hFont);
       //エディットBOX
       SetButtonInfo(3, ID_EDIT_SIZEW, TBBS_SEPARATOR, 60);
       GetItemRect(3, &rect);
       rect.left = 220;//tuika
       rect.right=280;
       rect.top = 2;
       rect.bottom = 20;// henkou 99/9/6
       if (!m_edit1.Create(
           WS_VISIBLE|WS_CHILD|WS_TABSTOP,
           rect, this, ID_EDIT_SIZEW))
       {
          TRACE0("Failed to create edit1\n");
          return FALSE;
       }
       strA.Format("%.f",GL_KaniW1);
       CString str5(strA);//
       m_edit1.SetWindowText(str5);
       m_edit1.SendMessage(WM_SETFONT, (WPARAM)hFont);

     //------------------------------------------------
       SetButtonInfo(4, ID_EDIT_SIZEH, TBBS_SEPARATOR, 60);
       GetItemRect(4, &rect);
       rect.left = 280;//tuika
       rect.right=340;
       rect.top = 2;
       rect.bottom = 20;// henkou 99/9/6
       if (!m_edit2.Create(
         WS_VISIBLE|WS_CHILD|WS_TABSTOP,
         rect, this, ID_EDIT_SIZEH))
       {
          TRACE0("Failed to create edit1\n");
          return FALSE;
       }
       strA.Format("%.0f",GL_KaniW1);
       CString str6(strA);
       m_edit2.SetWindowText(str6);
       m_edit2.SendMessage(WM_SETFONT, (WPARAM)hFont);
       //------------------------------------------------
       SetButtonInfo(7, ID_EDIT_TAKASA, TBBS_SEPARATOR, 60);
       GetItemRect(7, &rect);
       rect.left = 280+60+100+100;
       rect.right=340+60+100+100;
       rect.top = 2;
       rect.bottom = 20;
       if (!m_edit3.Create(
         WS_VISIBLE|WS_CHILD|WS_TABSTOP,
         rect, this, ID_EDIT_TAKASA))
       {
          TRACE0("Failed to create edit1\n");
          return FALSE;
       }
       strA.Format("%.0f",GL_KaniZZ);
       CString str7(strA);//
       m_edit3.SetWindowText(str7);
       m_edit3.SendMessage(WM_SETFONT, (WPARAM)hFont);

       if(!SetHorizontal())
          return FALSE;
       m_combo1.SetDroppedWidth(220);
       m_combo4.SetDroppedWidth(180);
       m_combo6.SetDroppedWidth(220);

       m_combo2.AddString(_T("a"));
       m_combo2.AddString(_T("b"));
       m_combo2.AddString(_T("c"));
       m_combo2.AddString(_T("d"));
       m_combo2.AddString(_T("e"));
       m_combo2.AddString(_T("f"));
       CStringA strA2;
       int i;
       for( i = 0 ;i < 25;i++){
          strA2.Format("%sφ",sizemoji[0][i]);
          CString strTmp(strA2);
          m_combo3.AddString(strTmp);
       }
       for( i = 0;i < 54;i++){
          strA.Format("%s:%s-%s", sizemoji[1][i],sizemoji[3][i],sizemoji[50][i]);
          CString strTmp(strA);
          m_combo4.AddString(strTmp);
       }
       for(i=0;i < 142;i++){
          CString strTmp(tugitemoji[i]);
          m_combo6.AddString(strTmp);
       }
       return TRUE;
    }

    BOOL CEditBar::SetHorizontal()
    {
       m_bVertical = FALSE;

       SetBarStyle((GetBarStyle() & ~CBRS_ALIGN_ANY) | CBRS_ALIGN_TOP);

       SetButtonInfo(COMBOBOX_INDEX_KEITOU, ID_EDIT_KEITOU, TBBS_SEPARATOR, COMBOBOX_WIDTH);
       SetButtonInfo(COMBOBOX_INDEX_DUCTPIPE, ID_EDIT_KEITOU, TBBS_SEPARATOR, COMBOBOX_WIDTH);

       SetButtonInfo(COMBOBOX_INDEX_SIZEPAI, ID_EDIT_SIZEPAI, TBBS_SEPARATOR, COMBOBOX_WIDTH);

       SetButtonInfo(COMBOBOX_INDEX_SIZEA, ID_EDIT_SIZEA, TBBS_SEPARATOR, COMBOBOX_WIDTH);
       SetButtonInfo(COMBOBOX_INDEX_SHUBETU, ID_EDIT_SHUBETU, TBBS_SEPARATOR, COMBOBOX_WIDTH);
       SetButtonInfo(COMBOBOX_INDEX_KANZAI, ID_EDIT_KANZAI, TBBS_SEPARATOR, COMBOBOX_WIDTH);

       if (m_combo1.m_hWnd != NULL)
       {
          CRect rect;
          GetItemRect(COMBOBOX_INDEX_KEITOU, rect);

          m_combo1.SetWindowPos(NULL, rect.left, rect.top, 0,0,      SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOCOPYBITS);
          m_combo1.ShowWindow(SW_SHOW);

          m_combo2.SetWindowPos(NULL, rect.left+100, rect.top, 0, 0,   SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOCOPYBITS);
          m_combo2.ShowWindow(SW_SHOW);
          m_combo3.SetWindowPos(NULL, rect.left+100+100+20+60+60, rect.top, 0, 0, SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOCOPYBITS);
          m_combo3.ShowWindow(SW_SHOW);
          m_combo4.SetWindowPos(NULL, rect.left+100+100+20+60+60+100, rect.top, 0, 0, SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOCOPYBITS);
          m_combo4.ShowWindow(SW_SHOW);
          m_combo5.SetWindowPos(NULL, rect.left+100+100+20+60+60+100+100+60, rect.top, 0, 0, SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOCOPYBITS);
          m_combo5.ShowWindow(SW_SHOW);
          m_combo6.SetWindowPos(NULL, rect.left+100+100+20+60+60+100+100+60+100, rect.top, 0, 0, SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOCOPYBITS);
          m_combo6.ShowWindow(SW_SHOW);
       }

       return TRUE;
    }

    2013年6月21日 2:32

回答

  • ざっと見ただけですが、気になる点を以下に示します。

    1.LoadToolBar()が見あたらないようですが、IDの設定などはどのようにしてますか。
    2.CToolBarの派生クラスであることはわかりますが、CMainFrameは(Ex)なしの
     クラスになってますでしょうか、フレームワークが異なると動作しません。
     つまりCMDIFrameWndExの場合はCMFCToolBarなどを使用すべきです。
    3.文中の「ボトム」や「トップ」とはZオーダーですか、それともY/X軸ですか。
    4.DockControlBarLeftOf()で位置調整していないようですけど、どのように
     配置を調整してますでしょうか。
    5.VC6の頃のコードっぽいやや古臭い余計なコードがあります。
     これらは外した方が良いかもしれません。

    あと、配置を確かめるだけの、もうちょっと簡単なコードで
    試してみたほうが良いかもしれません。

    • 編集済み 仲澤@失業者 2013年6月21日 5:45 やや追加と修正
    • 回答の候補に設定 星 睦美 2013年6月25日 2:04
    • 回答としてマーク 星 睦美 2013年6月26日 7:33
    2013年6月21日 5:40

すべての返信

  • ざっと見ただけですが、気になる点を以下に示します。

    1.LoadToolBar()が見あたらないようですが、IDの設定などはどのようにしてますか。
    2.CToolBarの派生クラスであることはわかりますが、CMainFrameは(Ex)なしの
     クラスになってますでしょうか、フレームワークが異なると動作しません。
     つまりCMDIFrameWndExの場合はCMFCToolBarなどを使用すべきです。
    3.文中の「ボトム」や「トップ」とはZオーダーですか、それともY/X軸ですか。
    4.DockControlBarLeftOf()で位置調整していないようですけど、どのように
     配置を調整してますでしょうか。
    5.VC6の頃のコードっぽいやや古臭い余計なコードがあります。
     これらは外した方が良いかもしれません。

    あと、配置を確かめるだけの、もうちょっと簡単なコードで
    試してみたほうが良いかもしれません。

    • 編集済み 仲澤@失業者 2013年6月21日 5:45 やや追加と修正
    • 回答の候補に設定 星 睦美 2013年6月25日 2:04
    • 回答としてマーク 星 睦美 2013年6月26日 7:33
    2013年6月21日 5:40
  • 鋭く見抜かれたみたいです
    [5.VC6の頃のコードっぽいやや古臭い余計なコードがあります。]
    まさしくコードはVC6の頃に作成したソフトをVisual studio2010に移植したものです。

    [2.CToolBarの派生クラスであることはわかりますが、CMainFrameは(Ex)なしの
     クラスになってますでしょうか、フレームワークが異なると動作しません。
     つまりCMDIFrameWndExの場合はCMFCToolBarなどを使用すべきです。]

    当初CMFCToolBarを使用して作成すべきだとは考えたのですが、知識とサンプルコードが乏しく
    その方向は断念しましたところ、VisualStudio2010 でカスタムツールバーを作成しているサンプルを
    見つけそれに習って作成しました。
    [1.LoadToolBar()が見あたらないようですが、IDの設定などはどのようにしてますか。]
    VC6のコードにはそれがあったのですが見つけたサンプルには特にそれがなく、buttonsetting[]で
    ボタンの順番を設定しているだけのようでしたのでそのようにしました
    [3.文中の「ボトム」や「トップ」とはZオーダーですか、それともY/X軸ですか。]
    Y軸です
    [4.DockControlBarLeftOf()で位置調整していないようですけど]
    この部分はサンプルコードにもありそのようにしていましたが
    動作しないようなので途中外して試した状態で、問い合わせしてしまいました

    やはり、CMFCToolBarを使用し作り直さなければならない可能性が高そうですね。
    しかし、CMFCToolBarを使用したサンプルをどこかで見つけないとプログラムできそうにありません。
    どこか良いサイトまたは書籍をご存知ないでしょうか

     

    2013年6月21日 7:21
  • LoadToolBar()はツールバービットマップをロードするためのものと
    思われていますが、それだけでなく、ツールバービットマップのIDを
    ツールバー(ウインドウ)のウインドウIDにしているようです。
    ウインドウプレイスメントはこのIDを頼りにしているようです。
    同じく、メインフレームのフレームワークもツールバー等の子ウインドウを
    IDで管理してる部分があります。

    一般に、ウインドウIDが設定されない場合は0になってしまいますが、
    フレームワークはID=0の子ウインドウを無視する可能性が否定できません。

    ウインドウIDはSetWindowLongPtr()でも設定できますが、
    やはり、空のツールバーをリソースにエントリして、
    LoadToolBar()するのが近道だと考えられます。

    コストも少なくてすむので、まず、これを試してみては、どうでしょう。

    ダメだった場合は、メインフレームをCMDIFrameWndEx等にした上、
    CMFCToolBarにするわけですが、これは

    「CMFCToolBar」by「CMFCBaseToolBar」by「CPane」by「CBasePane」by「CWnd」

    と継承されていてCToolBarとは、まったく無関係なので、
    いままでのコードがそのままでは使えません。
    ただし、手順や原理は相似なので、考え方自体は近いものがあります。
    一度覚えてしまえば、なんということはありません。
    かつ、新しいフレームワーク(CMFC系)の便利さを教授できます。

    ただし、軽微な修正で済むと思ってはいけません。
    メインフレームのOnCreate()、及び基本クラスを変更した
    ツールバーなどの初期化系のコードは全面的な書き換えに
    なるものと考えてください。

    2013年6月21日 8:12
  • ご返信ありがとうございました。
    LoadToolBar()を使用してみたのですが、結果は変わりませんでした、
    やはりCMFCToolBar()を考えないよならないようです。
    ただ、どこかで同じような処理をしているソースを参照できなければ
    こちらの技量では現状無理ですのでおりを見てまた探してみます。
    2013年6月21日 11:55