ポップアップメニューを表示する

右クリックでポップアップメニューを表示します。

resource.h

#define IDR_MENU1  100
#define ID_EXIT   101
#define ID_Dialog  102
#define ID_A   103
#define ID_B   104
#define ID_Menu   105
#define ID_Whats  106
#define ID_Help   107
#define ID_STATUS  108
#define ID_TEXT   109
#define ID_1   110
#define ID_2   111
#define ID_3   112
#define ID_popup  113
#define IDM_END   114

menu.rc

#include "windows.h"
#include "resource.h"

IDR_MENU1 MENU
BEGIN
    POPUP "File"
    BEGIN
        MENUITEM "Exit",    ID_EXIT
    END
    POPUP "Dialog"
    BEGIN
        MENUITEM "ダイアログ",    ID_Dialog
    END
    POPUP "Option"
    BEGIN
        MENUITEM "A",     ID_A
        MENUITEM "B",     ID_B
        MENUITEM "めにゅ~",   ID_Menu
        MENUITEM "whats?",    ID_Whats
    END
    MENUITEM "ヘルプ",     ID_Help
END

OPTDLG DIALOG DISCARDABLE  0, 0, 121, 69
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "オプション"
FONT 9, "MS Pゴシック"
BEGIN
    DEFPUSHBUTTON   "OK",IDOK,7,38,50,14
    PUSHBUTTON      "キャンセル",IDCANCEL,61,37,50,14
    LTEXT           "ダイアログです。",ID_TEXT,36,19,48,8
END

POPUP MENU DISCARDABLE
BEGIN
    POPUP "ダミー"
    BEGIN
        MENUITEM "終了",      IDM_END
        POPUP "オプション"
        BEGIN
            MENUITEM "1番目",                  ID_1
            MENUITEM "2番目",                  ID_2
            MENUITEM "3番目",       ID_3
            MENUITEM "popup",                  ID_popup
        END
    END
END

main.cpp

#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
#pragma comment(lib, "comctl32.lib")
#include <GL/freeglut/freeglut.h>
#include "resource.h"
#include <commctrl.h> //CreateStatusWindow()のために必要


//FreeGlutのウインドウプロシージャを置き換える為の変数
WNDPROC WndProc=NULL; //元のウィンドウプロシージャ
HWND hWnd2=NULL; //ウィンドウハンドル
HMENU hMenu=NULL; //メニュー
HWND hStatusbar;     // ステータスバーのハンドル
HINSTANCE hInstance;    //インスタンスハンドル


//Windowのサイズ
int width = 320;
int height = 240;

//回転用
float anglex = 0.0f;
//白
GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 };

LRESULT CALLBACK DlgProc(HWND hDlgWnd, UINT msg, WPARAM wp, LPARAM lp){
    switch (msg) {
        case WM_INITDIALOG:
            return FALSE;
        case WM_COMMAND:
            switch (LOWORD(wp)) {
                case IDOK:
                    EndDialog(hDlgWnd, IDOK);
                    break;
                case IDCANCEL:
                    EndDialog(hDlgWnd, IDCANCEL);
                    break;
                default:
                    return FALSE;
            }
        default:
            return FALSE;
    }
    return TRUE;
}


//置き換えた後のプロシージャ
LRESULT CALLBACK WndProc2(HWND hWnd , UINT msg , WPARAM wp , LPARAM lp){
 POINT pt;
 HMENU hmenu,hSubmenu;
 switch( msg ){
 case WM_RBUTTONDOWN:
  pt.x = LOWORD(lp);
  pt.y = HIWORD(lp);
  hmenu = LoadMenu((HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), L"POPUP");
  hSubmenu = GetSubMenu(hmenu, 0);
  ClientToScreen(hWnd, &pt);
  TrackPopupMenu(hSubmenu, TPM_LEFTALIGN, pt.x, pt.y, 0, hWnd, NULL);
  DestroyMenu(hmenu);
  return 0;
 case WM_SIZE:
  SendMessage( hStatusbar, WM_SIZE, wp, lp );
  return 0;
 case WM_COMMAND:
  switch (LOWORD(wp)){
  case ID_Dialog:
   DialogBox(hInstance, L"OPTDLG", hWnd, (DLGPROC)DlgProc);
   break;
  case ID_EXIT:
   PostQuitMessage(0);
   break;
  }
  return 0;
 case WM_DESTROY:
  exit(0);
  break;
 default:
  if(WndProc){
   return CallWindowProc(WndProc,hWnd , msg , wp , lp);
  }else{
   return DefWindowProc(hWnd,msg,wp,lp);
  }
 }
}

//ウィンドウの検索
BOOL CALLBACK enumWindowsProc(HWND hWnd,LPARAM lParam){
 HANDLE hModule=(HANDLE)GetWindowLong(hWnd,GWL_HINSTANCE);
 if(GetModuleHandle(NULL)==hModule){
  wchar_t ClassName[256];
  GetClassNameW(hWnd,ClassName,sizeof(ClassName)/sizeof(ClassName[0]));
  if(wcsncmp(ClassName,L"FREEGLUT",wcslen(ClassName))==0){
   hWnd2=hWnd;
   return FALSE;
  }
 }
 return TRUE;
}

void display(void){
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 glViewport(0, 0, width, height);
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();

 gluPerspective(30.0, (double)width / (double)height, 1.0, 1000.0);
 glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

 gluLookAt(150.0,150.0,-150.0,
      0.0,0.0,0.0,
     0.0,1.0,0.0);

 glMaterialfv(GL_FRONT, GL_DIFFUSE, white);
 //回転
 glRotatef(anglex,1.0f,0.0f,0.0f);//X軸を回転
 glutSolidSphere(40.0,16,16);

 glutSwapBuffers();
}
void idle(void){
 anglex+=2.0f;
 Sleep(1);
 glutPostRedisplay();
}
void Init(){
 glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
 glEnable(GL_DEPTH_TEST);
 //ワイヤーフレーム
 glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
}
bool main(int argc, char *argv[]){
 glutInit(&argc, argv);
 glutInitWindowPosition(100, 100);
 glutInitWindowSize(width, height);
 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
 glutCreateWindow("ポップアップメニュー");
 //FreeGlutのウインドウハンドルとウインドウプロシージャを置き換える
 EnumWindows(enumWindowsProc,0);
 if(hWnd2){
  WndProc=(WNDPROC)GetWindowLong(hWnd2,GWL_WNDPROC);
  SetWindowLong(hWnd2,GWL_WNDPROC,(LONG)WndProc2);
 }else{
  return false;
 }
 //メニューを作成
 hMenu=LoadMenu(GetModuleHandle(NULL),MAKEINTRESOURCE(IDR_MENU1));
 if(hMenu){
  SetMenu(hWnd2,hMenu);
 }else{
  return false;
 }
 // コモンコントロール関係の初期化
 InitCommonControls();
 // ステータスバーを作成
 hStatusbar = CreateStatusWindowW(WS_CHILD | WS_VISIBLE | CCS_BOTTOM | SBARS_SIZEGRIP,
   L"ステータスバー",hWnd2,ID_STATUS);
 glutDisplayFunc(display);
 glutIdleFunc(idle);
 Init();
 glutMainLoop();
 return true;
}

 

最終更新:2014年05月16日 13:18
添付ファイル