スポンサーリンク

Win32APIでメニュー生成する自作クラス

ツリー構造を作っていた時にできた副産物です。改善の余地はありますが楽です。

結果


使い方

case WM_CREATE:
  {

    menu_t::SetDefaultMII();

    MyMenu m;

    m.root().set( L"Menu",0);//メニューのルート。表示されない
    m.root().push(L"File",100);// push(タイトル, ID)の順に記述
    m.root().latest().push(L"Load"  ,110);//latestはこの階層で最後にpushされたアイテム
    m.root().latest().push(L"Save"  ,120);
    m.root().latest().push(L"Export",130);
    m.root().latest().push(L"Import",140);
    m.root().latest().push(L"Recent",150);
    m.root().latest().latest().push(L"file1",151);
    m.root().latest().latest().push(L"file2",152);
    m.root().latest().latest().push(L"file3",153);
    m.root().push(L"Edit",200);
    m.root().latest().push(L"Add"   ,210);
    m.root().latest().push(L"Delete",220);
    m.root().latest().push(L"Select",230);
    m.root().push(L"View",300);
    m.root().latest().push(L"Vertical" ,310);
    m.root().latest().push(L"Horizonal",320);

    m.winSetMenu(hwnd);

  }
  return 0;
case WM_COMMAND://メニューがクリックされた時の処理
  switch (LOWORD(wp)) {
  case 110:
    MessageBox(hwnd,L"Load",0,0);
    break;
  case 120:
    MessageBox(hwnd,L"Save",0,0);
    break;
  }
  break;

コード本体

nuWinMenu.h

#include <vector>
#include<windows.h>

struct menu_t{

  static MENUITEMINFO defaultMII;

  MENUITEMINFO mii;
  std::vector< menu_t > m_submenues;
  HMENU hmenu_this;

  menu_t(){}
  menu_t(wchar_t* title,UINT id,MENUITEMINFO _mii = defaultMII);

 //このメニュー項目を設定 void set( wchar_t* title,UINT id,MENUITEMINFO _mii = defaultMII);
//このメニュー項目にサブメニューの項目を追加
void push(wchar_t* title,UINT id,MENUITEMINFO _mii = defaultMII);
//このメニュー項目のサブメニューの末尾を取得
menu_t& latest(); static void SetDefaultMII(); }; //メニュー管理クラス class MyMenu{ menu_t m_root; HMENU hMenuTop;
//メニュー登録のエントリポイント。内部でSetMenuesを呼び出す HMENU defineMenu();

//登録作業の本体。InsertMenuItemを呼び出している void SetMenues(HMENU hmenu , menu_t& menu); public: menu_t& root(); MyMenu();

//Win32apiのSetMenuを呼び出し、実際にメニューを登録する
BOOL winSetMenu(HWND hwnd); };

nuWinMenu.cpp

#include "nuWinMenu.h"


MENUITEMINFO menu_t::defaultMII;

menu_t::menu_t(wchar_t* title,UINT id,MENUITEMINFO _mii){
  set(title,id,_mii);
}

void menu_t::set( wchar_t* title,UINT id,MENUITEMINFO _mii){
//このメニュー項目のタイトルとIDを設定 mii = _mii; mii.fMask = MIIM_ID | MIIM_STRING; mii.wID = id; mii.dwTypeData = title; } void menu_t::push(wchar_t* title,UINT id,MENUITEMINFO _mii){
//このメニュー項目のサブメニューにアイテムを追加
m_submenues.emplace_back(title,id,_mii); } menu_t& menu_t::latest(){
//このメニュー項目に最後に追加されたサブメニュー項目を取得
return m_submenues.back(); } void menu_t::SetDefaultMII(){ memset(&defaultMII, 0, sizeof(MENUITEMINFO)); defaultMII.cbSize = sizeof(MENUITEMINFO); defaultMII.fMask = MIIM_ID | MIIM_STRING; } ///////////////////////////////////////////////////////// HMENU MyMenu::defineMenu(){ hMenuTop = CreateMenu();//メニュー作成 for(size_t i = 0; i < m_root.m_submenues.size();i++){
//トップレベルのメニュー項目を登録する
SetMenues(hMenuTop,m_root.m_submenues[i]); } m_root.hmenu_this = hMenuTop; return hMenuTop; } void MyMenu::SetMenues(HMENU hmenu , menu_t& menu){ if(menu.m_submenues.size()!=0){ HMENU submenu = CreatePopupMenu();//ポップアップメニュー作成 menu.mii.hSubMenu = submenu; menu.mii.fMask |= MIIM_SUBMENU;//この項目にサブメニューがあることを指示 InsertMenuItem(hmenu, menu.mii.wID, FALSE, &menu.mii);
//サブメニューの各項目を登録 for(size_t i = 0; i < menu.m_submenues.size();i++){ SetMenues(submenu,menu.m_submenues[i]); } } else{ InsertMenuItem(hmenu, menu.mii.wID, FALSE, &menu.mii); } menu.hmenu_this = hmenu; } menu_t& MyMenu::root(){ return m_root; } MyMenu::MyMenu(){ hMenuTop = 0; } BOOL MyMenu::winSetMenu(HWND hwnd){ return SetMenu( hwnd,defineMenu() ); }


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: