シェブロンを表示する

シェブロンデース

 
レバーコントロールで隠されてしまったコントロールを
ポップアップメニューで表示します。

resource.h

#define IDR_MENU1  100
#define ID_EXIT   101
#define ID_TEST   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_TOOLBAR    109
 
#define IDM_NEW    1010
#define IDM_OPEN    1020
#define IDM_SAVE    1030
#define IDM_COPY    1040
#define IDM_PASTE   1050
#define IDM_DELETE  1060
#define IDM_CUT     1070
#define IDM_FIND  1080
#define IDM_HELP  1090
#define IDM_PRINT  1110
#define IDM_REDOW  1120
#define IDM_REPLACE 1130
#define ID_REBAR 1140
#define ID_TOOL1 1150
#define ID_TOOL2 1160

menu.rc

#include "resource.h"

IDR_MENU1 MENU
BEGIN
    POPUP "File"
    BEGIN
        MENUITEM "Exit",    ID_EXIT
    END
    POPUP "Test"
    BEGIN
        MENUITEM "てすつ",    ID_TEST
    END
    POPUP "Option"
    BEGIN
        MENUITEM "A",     ID_A
        MENUITEM "B",     ID_B
        MENUITEM "めにゅ~",   ID_Menu
        MENUITEM "whats?",    ID_Whats
    END
    MENUITEM "ヘルプ",     ID_Help
END

FILE MENU DISCARDABLE
BEGIN
    POPUP "ダミー"
    BEGIN
        MENUITEM "新規作成",                    IDM_NEW
        MENUITEM "開く",                        IDM_OPEN
        MENUITEM "上書き保存",                  IDM_SAVE
        MENUITEM "コピー",                      IDM_COPY
        MENUITEM "切り取り",                    IDM_CUT
        MENUITEM "削除",                        IDM_DELETE
    END
END

EDIT MENU DISCARDABLE
BEGIN
    POPUP "ダミー"
    BEGIN
        MENUITEM "検索",                      IDM_FIND
        MENUITEM "ヘルプ",                    IDM_HELP
        MENUITEM "貼り付け",                    IDM_PASTE
        MENUITEM "印刷",                        IDM_PRINT
        MENUITEM "元に戻す",                    IDM_REDOW
        MENUITEM "置き換え",                    IDM_REPLACE
    END
END

main.cpp

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

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

HWND hTool1, hTool2, hRebar;

TBBUTTON tbButton1[] = {
 {STD_FILENEW, IDM_NEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
    {STD_FILEOPEN, IDM_OPEN, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
    {STD_FILESAVE, IDM_SAVE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
    {STD_COPY, IDM_COPY, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
    {STD_CUT, IDM_CUT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
    {STD_DELETE, IDM_DELETE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0}
};

TBBUTTON tbButton2[] = {
    {STD_FIND, IDM_FIND, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
    {STD_HELP, IDM_HELP, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
    {STD_PASTE, IDM_PASTE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
    {STD_PRINT, IDM_PRINT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
    {STD_REDOW, IDM_REDOW, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
    {STD_REPLACE, IDM_REPLACE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0}
};
 
#define WIDTH 320
#define HEIGHT 240
 
//回転用
float anglex = 0.0f;
//白
GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 };
 
//置き換えた後のプロシージャ
LRESULT CALLBACK WndProc2(HWND hWnd , UINT msg , WPARAM wParam , LPARAM lParam){
 LPNMHDR lpnmhdr;
 NMREBARCHEVRON *lpnmchevron;
 RECT rc1, rc2;
 POINT pt;
 RECT rc1_scr, rc2_scr, rc3_scr;
 REBARBANDINFO rbinfo;
 int nBtn, i;
 int nHideBtn = 0;
 wchar_t szResourceName[32];
 HMENU hPopMenu, hSubMenu;
 switch( msg ){
  case WM_SETCURSOR:
    return DefWindowProc(hWnd,msg,wParam,lParam);
  case WM_SIZE:
    SendMessage(hRebar, WM_SIZE, wParam, lParam);
    SendMessage( hStatusbar, WM_SIZE, wParam, lParam );
    return 0;
  case WM_COMMAND:
    switch (LOWORD(wParam)){
       case IDM_NEW:
             MessageBox(hWnd, L"変更を保存しますか", L"注意",  MB_YESNO | MB_ICONQUESTION);
         break;
       case IDM_SAVE:
             MessageBox(hWnd, L"上書きしてもよろしいですか", L"上書き保存", MB_YESNO | MB_ICONQUESTION);
         break;
      /* 他省略 */
       case ID_EXIT:
        PostQuitMessage(0);
       }
       return 0;
  case WM_DESTROY:
    exit(0);
    break;
   case WM_NOTIFY:
    lpnmhdr = (LPNMHDR)lParam;
    if (lpnmhdr->code == TTN_POP) {
       return 0;
    }
    switch (wParam) {
     case ID_REBAR:
           switch (lpnmhdr->code) {
            case RBN_CHEVRONPUSHED:
               lpnmchevron = (NMREBARCHEVRON *)lParam;
               if (SendMessage(hRebar, RB_GETRECT, (WPARAM)lpnmchevron->uBand, (LPARAM)&rc1) == 0) {
                     MessageBox(hWnd, L"RB_GETRECT ERROR", L"OK", MB_OK);
                      return FALSE;
                  }
                  pt.x = rc1.left;
                  pt.y = rc1.top;
                  ClientToScreen(hRebar, &pt);
                        
                  rc1_scr.left = pt.x;
                  rc1_scr.top = pt.y;
                  pt.x = rc1.right;
                  pt.y = rc1.bottom;
                  ClientToScreen(hRebar, &pt);
                  rc1_scr.right = pt.x;
                  rc1_scr.bottom = pt.y;
                  memset(&rbinfo, 0, sizeof(REBARBANDINFO));
                  rbinfo.cbSize = sizeof(REBARBANDINFO);
                  rbinfo.fMask = RBBIM_CHILD;
                         
                  if (SendMessage(hRebar, RB_GETBANDINFO, (WPARAM)lpnmchevron->uBand, (LPARAM)&rbinfo) == 0)
                      MessageBox(hWnd, L"Error RB_GETBANDINFO", L"Error", MB_OK);
                  nBtn = SendMessage(rbinfo.hwndChild, TB_BUTTONCOUNT, 0, 0);
                         
                  for (i = 0; i < nBtn; i++) {
                      SendMessage(rbinfo.hwndChild, TB_GETITEMRECT, (WPARAM)i, (LPARAM)&rc2);
                      pt.x = rc2.left;
                      pt.y = rc2.top;
                      ClientToScreen(rbinfo.hwndChild, &pt);
                      rc2_scr.left = pt.x;
                      rc2_scr.top = pt.y;
                      pt.x = rc2.right;
                      pt.y = rc2.bottom;
                      ClientToScreen(rbinfo.hwndChild, &pt);
                      rc2_scr.right = pt.x;
                      rc2_scr.bottom = pt.y;
                      IntersectRect(&rc3_scr, &rc2_scr, &rc1_scr);
                      if (!EqualRect(&rc2_scr, &rc3_scr)) {
                          nHideBtn = nBtn - i;
                          break;
                      }
                   }
                           
                   if (rbinfo.hwndChild == hTool1) {
                       wcscpy(szResourceName, L"FILE");
                   } else if (rbinfo.hwndChild == hTool2) {
                       wcscpy(szResourceName, L"EDIT");
                   } else {
                       MessageBox(hWnd, L"Error", L"Error", MB_OK);
                       return FALSE;
                   }
                          
                   hPopMenu = LoadMenu((HINSTANCE)GetWindowLong(hWnd2, GWL_HINSTANCE), szResourceName);
                   if (hPopMenu == NULL) {
                       MessageBox(hWnd, L"LoadMenu Error", L"Error", MB_OK);
                       break;
                   }
                   hSubMenu = GetSubMenu(hPopMenu, 0);
                   if (nHideBtn == 0)
                       nHideBtn = 1;
                   for (i = 0; i < nBtn - nHideBtn; i++) {
                      if (DeleteMenu(hSubMenu, 0, MF_BYPOSITION) == 0) {
                           MessageBox(hWnd, L"DeleteMenu Error", L"Error", MB_OK);
                           return 0;
                      }
                   }
                   TrackPopupMenu(hSubMenu, TPM_LEFTALIGN, rc1_scr.right-10, rc1_scr.bottom, 0, hWnd, NULL);
                   DestroyMenu(hPopMenu);
                   break;
            default:
                return DefWindowProc(hWnd, msg, wParam, lParam);
            }
            break;
    }
   default:
    if(WndProc){
     return CallWindowProc(WndProc,hWnd , msg , wParam , lParam);
    }else{
     return DefWindowProc(hWnd,msg,wParam,lParam);
  }
 }
}
 
//ウィンドウの検索
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);
}

HWND MakeToolbar(HWND hWnd, int n, TBBUTTON *tbButton, int id){
    HWND hTool;
    TBADDBITMAP tbab;
    int stdid, i;

    hTool = CreateToolbarEx(hWnd, WS_VISIBLE | WS_CHILD| CCS_NODIVIDER | CCS_NORESIZE | TBSTYLE_FLAT, id ,
        0, NULL, NULL, tbButton, 0, 0, 0, 0, 0, sizeof(TBBUTTON));
    tbab.hInst = HINST_COMMCTRL;
    tbab.nID = IDB_STD_SMALL_COLOR;

    stdid = SendMessage(hTool, TB_ADDBITMAP, n, (LPARAM)&tbab);
    for (i = 0; i < n; i++)tbButton[i].iBitmap += stdid;

    SendMessage(hTool, TB_ADDBUTTONS, n, (LONG)tbButton);
    SendMessage(hTool, TB_AUTOSIZE, 0, 0);

    return hTool;
}

bool main(int argc, char *argv[]){
 glutInitWindowPosition(100, 100);
 glutInitWindowSize(WIDTH, HEIGHT);
 glutInit(&argc, argv);
 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;
 }
 // コモンコントロール関係の初期化
 INITCOMMONCONTROLSEX ic;
 ic.dwSize = sizeof(INITCOMMONCONTROLSEX);
 ic.dwICC = ICC_BAR_CLASSES | ICC_COOL_CLASSES | ICC_PAGESCROLLER_CLASS;
 InitCommonControlsEx(&ic);
 // ステータスバーを作成
 hStatusbar = CreateStatusWindowW(WS_CHILD | WS_VISIBLE | CCS_BOTTOM | SBARS_SIZEGRIP,
   L"ステータスバー",hWnd2,ID_STATUS);

 hRebar = CreateWindowEx(WS_EX_TOOLWINDOW, REBARCLASSNAME, NULL,
              WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
              RBS_BANDBORDERS | RBS_VARHEIGHT,
              0, 0, 0, 0, hWnd2, (HMENU)ID_REBAR, (HINSTANCE)GetWindowLong(hWnd2, GWL_HINSTANCE), NULL);
           
  hTool1 = MakeToolbar(hRebar, 6, tbButton1, ID_TOOL1);
  hTool2 = MakeToolbar(hRebar, 6, tbButton2, ID_TOOL2);
  REBARBANDINFO rbinfo;
 RECT rc;
 memset(&rbinfo, 0, sizeof(REBARBANDINFO));
 rbinfo.cbSize = sizeof(REBARBANDINFO);
 rbinfo.fMask = /*RBBIM_TEXT |*/ RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE |
     RBBIM_SIZE | RBBIM_IDEALSIZE;
 rbinfo.fStyle = RBBS_CHILDEDGE | RBBS_USECHEVRON;
 rbinfo.hwndChild = hTool1;
 rbinfo.cxMinChild = 0;
 rbinfo.cyMinChild = 25;
 rbinfo.cxIdeal = 144;
 rbinfo.cx = 160;
 SendMessage(hRebar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbinfo);

 GetWindowRect(hRebar, &rc);
 rbinfo.hwndChild = hTool2;
 rbinfo.cxMinChild = 0;
 rbinfo.cyMinChild = 25;
 rbinfo.cxIdeal = 176;
 rbinfo.cx = 192;
 SendMessage(hRebar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbinfo);

 glutDisplayFunc(display);
 glutIdleFunc(idle);
 Init();
 glutMainLoop();
 return 0;
}

最終更新:2014年06月14日 15:15
添付ファイル