トップページ > 過去ログ > 記事閲覧
メニュー動作
名前:ライブラリ使用者 日時: 2008/10/17 23:50

以下サンプルコード #include <windows.h> #include "DxLib.h" #pragma warning(disable : 4996) HMENU hSubmenu; HMENU hSub1; HMENU hSub2; int CreateMenuDX(); int DestoryMenuDX(); LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp); int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { char Buf[256];//キーボード入力状態保持用 char buf[20]; BOOL cb_MouseRFlg = FALSE; int count = 0; // ウインドウモードに変更 ChangeWindowMode( TRUE ); //プロシージャをフック SetHookWinProc(WndProc); if( DxLib_Init() == -1 ) // DXライブラリ初期化処理 { return -1 ; // エラーが起きたら直ちに終了 } //ウインドウがアクティブではない状態でも処理を続行する SetAlwaysRunFlag(TRUE); //メニュー作成 CreateMenuDX(); while(1) { if(count > 1000000) { count = 0; } else { count++; } // メッセージループに代わる処理をする if( ProcessMessage() == -1 ) { break ; // エラーが起きたらループを抜ける } //キーボード入力があれば処理する if(CheckHitKeyAll(DX_CHECKINPUT_KEY) != 0) { //キーボード入力状態を取得 GetHitKeyStateAll(&Buf[0]); //ESCチェック if(Buf[KEY_INPUT_ESCAPE]) { break; } } //左マウス押下処理 if((GetMouseInput() & MOUSE_INPUT_RIGHT) != 0) { //LBUTTONDOWN時の場合のみ処理する if(cb_MouseRFlg == FALSE) { ::MessageBoxA(NULL,"左マウス押下","Sample",MB_OK); } } else { //マウスクリック判定(LBUTTON押下検知後、押し続け処理させない) if(cb_MouseRFlg == TRUE) { cb_MouseRFlg = FALSE; } } sprintf(buf,"count:%d",count); DrawBox( 0 , 0 , 640 , 480 , GetColor(0,0,200) , TRUE) ; DrawString(100,300,buf,GetColor(200,0,0),GetColor(0,200,0)); ScreenFlip(); } //メニュー破棄 DestoryMenuDX(); DxLib_End() ; // DXライブラリ使用の終了処理 return 0 ; // ソフトの終了 } int CreateMenuDX() { //サブメニュー作成 //HMENU hmenu = ::CreateMenu(); hSubmenu = ::CreatePopupMenu(); hSub1 = ::CreatePopupMenu(); hSub2 = ::CreatePopupMenu(); MENUITEMINFO mii; mii.cbSize = sizeof(MENUITEMINFO); /* //ショートカットメニュー作成 mii.fMask = MIIM_TYPE | MIIM_SUBMENU; mii.fType = MFT_STRING; mii.hSubMenu = hSubmenu; mii.dwTypeData = TEXT("未表示"); ::InsertMenuItem(hmenu,0,TRUE,&mii); */ //ショートカット登録 mii.fMask = MIIM_TYPE | MIIM_SUBMENU; mii.fType = MFT_STRING; mii.hSubMenu = hSub1; mii.dwTypeData = TEXT("ショートカット1"); ::InsertMenuItem(hSubmenu,0,TRUE,&mii); mii.hSubMenu = hSub2; mii.dwTypeData = TEXT("ショートカット2"); ::InsertMenuItem(hSubmenu,1,TRUE,&mii); //サブメニュー登録(識別子付き) mii.fMask = MIIM_ID | MIIM_TYPE; mii.fType = MFT_STRING; mii.wID = 100; mii.dwTypeData = TEXT("サブメニュー1-1"); ::InsertMenuItem(hSub1,100,FALSE,&mii); mii.wID = 110; mii.dwTypeData = TEXT("サブメニュー1-2"); ::InsertMenuItem(hSub1,110,FALSE,&mii); mii.wID = 200; mii.dwTypeData = TEXT("サブメニュー2-1"); ::InsertMenuItem(hSub2,200,FALSE,&mii); mii.wID = 210; mii.dwTypeData = TEXT("サブメニュー2-1"); ::InsertMenuItem(hSub2,210,FALSE,&mii); return 0; } int DestoryMenuDX() { ::DestroyMenu(hSub2); ::DestroyMenu(hSub1); ::DestroyMenu(hSubmenu); //::DestroyMenu(hmenu); return 0; } LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { static HMENU hMenu, hSubMenu; POINT pos; switch( msg ) { case WM_COMMAND: // 項目が選択されたとき switch( LOWORD( wp ) ) { case 100: ::MessageBoxA(NULL,"サブメニュー1-1","Sample",MB_OK); break; case 110: ::MessageBoxA(NULL,"サブメニュー1-2","Sample",MB_OK); break; case 200: ::MessageBoxA(NULL,"サブメニュー2-1","Sample",MB_OK); break; case 210: ::MessageBoxA(NULL,"サブメニュー2-2","Sample",MB_OK); break; } return 0; case WM_RBUTTONDOWN: // マウスの右ボタンが離されたとき // カーソルの位置を取得する pos.x = LOWORD( lp ); pos.y = HIWORD( lp ); // 取得したカーソル位置を、スクリーン座標に変換する ClientToScreen( GetMainWindowHandle(), &pos ); // ポップアップメニューを表示する //TrackPopupMenu( hSubMenu, TPM_LEFTALIGN, pos.x, pos.y, 0, hWnd, NULL ); ::TrackPopupMenu(hSubmenu, TPM_LEFTALIGN, pos.x, pos.y, 0, GetMainWindowHandle(), NULL); ::DrawMenuBar(GetMainWindowHandle()); break; //これで返すと、DXライブラリで情報取得できない return 0; case WM_CLOSE: // ウィンドウが閉じられるとき // メニューリソースを破棄する //DestroyMenu( hMenu ); //hMenu = NULL; break; // ウィンドウを閉じる処理はDefWindowProc()に任せる case WM_DESTROY: // ウィンドウが破棄されるとき PostQuitMessage( 0 ); return 0; } return DefWindowProc( hWnd, msg, wp, lp ); }

Page: 1 |

Re: メニュー動作 ( No.1 )
名前:ライブラリ使用者 日時:2008/10/17 23:59

何点か質問したい点があります。上から解答が欲しい順です。 1.ポップアップメニューを出している間、メインのループが停止してしまっています。 count表示部分で確認。SetAlwaysRunFlag(TRUE)を立ててみましたが変わらず。 どうにかループは廻し続けたいのですが、手はないのでしょうか? 2.SetHookWinProc()した場合ですが、マウスクリックなどを処理したい場合に、プロシージャ→ループ内の順に処理が動いてるようなのですが、両方きちんと動かない場合がありますが重複しているとおかしくなっているのでしょうか?(もしくはソースに変な部分がある?) プロシージャ、ループ内でそれぞれマウス右クリック動作処理を記載し確認。 3.DXライブラリにもメニュー作成関数がありますが、上記をそれらを使うとどうなるでしょうか? AddMenuItem( int AddType /* MENUITEM_ADD_CHILD等 */ , const char *ItemName, int ItemID, int SeparatorFlag, const char *NewItemName = NULL , int NewItemID = -1 ) ; // メニューに項目を追加する というのがありますが、変数としてどんな値を与えればよいのかが分かりません
Re: メニュー動作 ( No.2 )
名前:管理人 日時:2008/10/25 17:16

1. 申し訳ありません、現在のライブラリでは手はありません 詳しくはこちらのスレッド http://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=view&no=1020 の No.5 の私の書き込みをご覧下さい。 ポップアップメニューを出している間もウインドウ移動中と同じ状態で DXライブラリで言うところの ProcessMessage 関数で処理が止まっている (システムから処理が返ってこない)状態になっています 2. ソースに問題が無いかは掲載していただいた部分だけでは判断できませんが 重複しても問題は無いと思います 3. AddMenuItem はポップアップメニューではなく普通のメニューを扱うための ものですが、とりあえずサンプルを・・・ #include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int x, add; // メニューの追加 AddMenuItem_Name( NULL, "list1" ) ; AddMenuItem_Name( "list1", "item1" ) ; AddMenuItem_Name( "list1", "item2" ) ; AddMenuItem_Name( "list1", "item3" ) ; AddKeyAccel_Name( "item1", KEY_INPUT_L, FALSE, FALSE, FALSE ) ; ChangeWindowMode( TRUE ) ; if( DxLib_Init() == -1 ) return -1 ; SetDrawScreen( DX_SCREEN_BACK ) ; // item1 が選択されるまでループ x = 0; add = 1; while( ProcessMessage() == 0 && CheckMenuItemSelect_Name( "item1" ) == 0 ) { x += add; if( x > 640 || x < 0 ) add = -add; ClearDrawScreen() ; DrawBox( x, 100, x + 3, 103, GetColor( 255,255,255 ), FALSE ); ScreenFlip() ; } DxLib_End() ; return 0 ; } AddMenuItem は引数が複雑なので、普通は以下の関数を使います // メニューに選択項目を追加する int AddMenuItem_Name( const char *ParentItemName, const char *NewItemName ) ; // メニューのリストに区切り線を追加する int AddMenuLine_Name( const char *ParentItemName ) ; // 指定の項目と、指定の項目の一つ上の項目との間に新しい項目を追加する int InsertMenuItem_Name( const char *ItemName, const char *NewItemName ) ; // 指定の項目と、指定の項目の一つ上の項目との間に区切り線を追加する int InsertMenuLine_Name( const char *ItemName ) ; // メニューから選択項目を削除する int DeleteMenuItem_Name( const char *ItemName ) ; // メニューが選択されたかどうかを取得する( 0:選択されていない 1:選択された ) int CheckMenuItemSelect_Name( const char *ItemName ) ; // メニューの項目を選択出来るかどうかを設定する( 1:選択できる 0:選択できない ) int SetMenuItemEnable_Name( const char *ItemName, int EnableFlag ) ; // メニューの項目にチェックマークやラジオボタンを表示するかどうかを設定する int SetMenuItemMark_Name( const char *ItemName, int Mark ) ; メニューの指定を全部文字列で行うので、同じ名前を使うことが できないという欠点がありますが・・・

Page: 1 |