#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;
}
|