質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

434閲覧

オブジェクト指向のクラスと組み方1

BeatStar

総合スコア4958

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2017/07/03 04:05

C/C++ ( Windows API 実装 ) でやっています。

趣味でやっていて、デフォルトで提供されている関数等を自分が使いやすいように
関数化したりクラス化して ライブラリ ( lib*.a ) にしています。

GUIウィンドウがないと使えないコントロールやその他のAPIを関数化, クラス化して libwindow.a とか。

オブジェクト指向の最低限の考え方は理解した "つもり" です。
( だって、ちゃんと教えてくれる人いないのに... 独自解釈するしかないじゃん? )

ですが、ちょっとどうすればいいか迷っていることがあります。

私は 常駐型プログラムも組めたらなぁということで、

調べてみると メニューバーみたいにするようですね。

で試しに使ってみると、

私のやり方が悪いのか、「これ、どうやってやるんだ?」となります。

普通に ボタンが複数並んでいるような状態であればそんなに問題ないです。

厄介なのが、階層が深い場合です。

例えば、

MENU -+- "C/C++" -+- "サンプル1" ! +- "サンプル2" ! +- "Java" -+- "サンプル1" ! +- "サンプル2" ! +- "Python" -+- "サンプル1" ! +- "サンプル2" ! +- "JavaScript" ...

という風に 子ノッドどころか孫ノッド? 以降もあるような場合です。

私は

C++

1// 必要なヘッダファイルはインクルード済みでリンクも済んでいるとする 2 3class WMenuBar{ 4 public: 5 static HMENU Create( void ); 6 7 static bool SetItem( HMENU hMenu, const std::string text, int nId, HMENU hSubMenu = NULL ); 8 9 static bool Register( HWND hWnd, HMENU hMenu ); 10}; 11 12 13/************************************************************** 14* 15* クラス名: WMenuBar 16* 17* 関 数 名: Create 18* 19* 目 的: メニューを作成する 20* 21* 引 数: 22* void 23* 24* 戻 り 値: 25* HMENU 26* 27* 使 用 例: 28* HMENU hMenu = WMenuBar::Create(); 29* 30* 参 ・ 引: 31* 32* 33* 備 考: 34* 35* 36**************************************************************/ 37 38HMENU WMenuBar::Create( void ){ 39 return CreateMenu(); 40} 41 42 43 44/************************************************************** 45* 46* クラス名: WMenuBar 47* 48* 関 数 名: SetItem 49* 50* 目 的: アイテムの設定 51* 52* 引 数: 53* HMENU hMenu := 親メニュー 54* const std::string ItemName := 表示する文字列. ""のとき SEPARATOR. 55* int nId := ID 56* HMENU hSubMenu := 子メニュー 57* 58* 戻 り 値: 59* bool 60* 61* 使 用 例: 62* bool result = WMenuBar::SetItem( 親メニュー, 表示する文字列, ID, 子メニュー ); 63* 64* 参 ・ 引: 65* 「EternalWindows」(http://eternalwindows.jp/) 66* ->「Windows基礎」 67* ->「メニュー」 68* ->「メニューの作成」&「ポップアップメニュー」 69* 70* 備 考: 71* 72* 73**************************************************************/ 74 75bool WMenuBar::SetItem( HMENU hMenu, const string text, int nId, HMENU hSubMenu ){ 76 MENUITEMINFO mii; 77 78 mii.cbSize = sizeof(MENUITEMINFO); 79 mii.fMask = MIIM_ID | MIIM_TYPE; 80 mii.wID = nId; 81 82 if( text.empty() != true ){ 83 mii.fType = MFT_STRING; 84 mii.dwTypeData = (char*)text.c_str(); 85 }else{ 86 mii.fType = MFT_SEPARATOR; 87 } 88 89 if( hSubMenu != NULL ){ 90 mii.fMask |= MIIM_SUBMENU; 91 mii.hSubMenu = hSubMenu; 92 } 93 94 if( InsertMenuItem( hMenu, nId, FALSE, &mii ) != 0 ){ 95 return true; 96 }else{ 97 return false; 98 } 99} 100 101 102 103/************************************************************** 104* 105* クラス名: WMenuBar 106* 107* 関 数 名: Register 108* 109* 目 的: メニューバーの登録 110* 111* 引 数: 112* HWND hWnd := 親ウィンドウハンドル 113* HMENU hMenu := 大本となる親メニュー 114* 115* 戻 り 値: 116* bool 117* 118* 使 用 例: 119* bool result = WMenuBar::Register( hWnd, 大本となる親メニュー ); 120* 121* 参 ・ 引: 122* 123* 124* 備 考: 125* 126* 127**************************************************************/ 128 129bool WMenuBar::Register( HWND hWnd, HMENU hMenu ){ 130 if( SetMenu( hWnd, hMenu ) == TRUE ){ 131 return true; 132 }else{ 133 return false; 134 } 135}

として、

C++

1HMENU Menu = WMenuBar::Create(); 2WMenuBar::SetItem( hMenu, "C/C++", 111 ); 3WMenuBar::SetItem( hMenu, "Java", 112 ); 4WMenuBar::Register( hWnd, hMenu );

という感覚でやっています。

このままだと namespace にしたほうがまだマシに見えます。

DestroyMenu関数を使うべきというのが ヘルプファイルにあったので、追加予定ですが。

私がしたいことは、

使うHMENU をメンバ変数とか ( 数が多くなるならvectorとか? ) で保持し、
後処理に追われることがないようにしたいのです。

こういうのってどうやって考えればいいのでしょうか?

Q2:
ちなみに 似た自作クラスとして WPopupMenu があり、このクラスのメンバも同じ感じです。
( 中の処理が微妙に違うぐらい? )
これと上記の WMenu を一緒にできたらいいのですが、これってありでしょうか?

例えば コンストラクタ の引数で bool bPopUp というのがあったとして、これを trueにすれば ポップアップ用, それ以外なら 通常のメニュー とか.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんにちは。

staticなメンバしか持っていないクラスって、namespaceに限りなく近いです。
namespaceは分割できるけど、クラスは分割できないが主な差と思います。
そのような構造をオフジェクト指向プログラミングと呼ぶ人は少ないでしょう。
非staticなメンバ変数を持たないクラスのインスタンス(オブジェクト)を生成する意味がほとんど無いからですね。

使うHMENU をメンバ変数とか ( 数が多くなるならvectorとか? ) で保持し、

後処理に追われることがないようにしたいのです。
こういうのってどうやって考えればいいのでしょうか?

「使うHMENU をメンバ変数とか ( 数が多くなるならvectorとか? ) で保持」で良いと思います。
HMENUを裸で管理するよりは、HMENUを使うWindows APIをラップするようなクラスを作ることも多いと思います。下手な設計をすると使いにくいクラスになりますので要注意ですけどね。

GUIライブラリの設計はノウハウの塊ですから、既にメジャーになっているGUI開発ツールのクラス設計を参考にすると良いかも知れません。
個人的には.NETのWindows Formsは好きです。WPFも良いものかも知れません。(使ったことないので知らないだけです。)言語が異なりますが、考え方は参考になると思います。

これと上記の WMenu を一緒にできたらいいのですが、これってありでしょうか?

メニューを触ったのはかなり昔なので記憶違いだったら申し訳ないのですが、どちらもMenuItemっぽい名前のクラスを使って、大差ないI/Fで実現してあった記憶があります。ルートのクラスのみPopupMenuとMainMenuで違っていただけのような。
この辺も既に成功しているGUI開発ツールを参考にされるのが良いと思いますよ。

投稿2017/07/03 08:24

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

BeatStar

2017/07/10 08:38

ご回答ありがとうございます! 帰宅して試したところ、うまくいきました! >> staticなメンバしか持っていないクラスってnamespaceに限りなく近い... 私もそう思っていますが、 どうやって複数のメニューを管理するかってことが気になって、 staticなメンバにして namespace内の関数みたいにしていました。 うまくいった方法として、 UML風に書くと, [ WMenuBar ] + CONSTRUCTOR() // CreateMenuで生成 + DESTRUCTOR() // hMenu の破棄 + PushItem( text : const std::string, nId : int, sub : const WMenuBar* ) : bool // 質問のやつだとSetItemのこと + Register( hWnd : HWND, menu : const WMenuBar* ) : bool [ static ] // staticなメンバ - hMenu : HMENU としたところ、うまくいきました。 なるほど。 Windows Form Application とかそういうライブラリを参考に...ですか。 確かにそういう手もありますね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問