#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
#pragma comment(lib, "comctl32.lib")
#include <windows.h>
#include <GL/freeglut/freeglut.h>
#include "resource.h"
#include <commctrl.h> //CreateStatusWindow()のために必要
//FreeGlutのウインドウプロシージャを置き換える為の変数
WNDPROC WndProc=NULL; //元のウィンドウプロシージャ
HWND hWnd2=NULL; //ウィンドウハンドル
HMENU hMenu=NULL; //メニュー
HWND hStatusbar; // ステータスバーのハンドル
HMENU hMenuFirst, hMenuDoc;
HMENU hMenuFirstWnd, hMenuDocWnd;
HINSTANCE hInst;
HWND hClient;
int doc_no;//ドキュメントの番号
wchar_t ChildDoc[] = L"document"; //ドキュメント
bool flag = false;
#define IDM_FIRSTCHILD 1000
#define WIDTH 640
#define HEIGHT 480
int width=0,height=0;
int pos_x=100,pos_y=100;
//回転用
float anglex = 0.0f;
//白
GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 };
LRESULT CALLBACK DocProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp){
static HWND hClient, hFrame;
HWND hEdit;
RECT rc;
switch (msg) {
case WM_CREATE:
hClient = GetParent(hWnd);
hFrame = GetParent(hClient);
GetClientRect(hWnd, &rc);
hEdit = CreateWindow(
L"EDIT", NULL,
WS_VISIBLE | WS_CHILD | ES_WANTRETURN | ES_MULTILINE |
ES_AUTOVSCROLL | WS_VSCROLL |
ES_AUTOHSCROLL | WS_HSCROLL,
rc.left, rc.top,
rc.right - rc.left,
rc.bottom - rc.top,
hWnd, NULL,
hInst, NULL);
return 0;
case WM_SIZE:
GetClientRect(hWnd, &rc);
hEdit = GetWindow(hWnd, GW_CHILD);
MoveWindow(hEdit, rc.left, rc.top, rc.right - rc.left, rc.bottom -
rc.top, TRUE);
break;
case WM_MDIACTIVATE:
if (lp == (LPARAM)hWnd)
SendMessage(hClient, WM_MDISETMENU, (WPARAM)hMenuDoc,
(LPARAM)hMenuDocWnd);
if (lp != (LPARAM)hWnd)
SendMessage(hClient, WM_MDISETMENU, (WPARAM)hMenuFirst,
(LPARAM)hMenuFirstWnd);
DrawMenuBar(hFrame);
return 0;
}
return (DefMDIChildProc(hWnd, msg, wp, lp));
}
BOOL CALLBACK CloseAllProc(HWND hWnd, LPARAM lp){
SendMessage(GetParent(hWnd), WM_MDIDESTROY, (WPARAM)hWnd, 0);
return TRUE;
}
int MyRegisterWC(WNDPROC lpfnWndProc, LPCWSTR lpszClassName, HBRUSH
hbrBack){
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = lpfnWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst; //インスタンス
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = hbrBack;
wc.lpszMenuName = NULL; //メニュー名
wc.lpszClassName = lpszClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
return(RegisterClassEx(&wc));
}
//置き換えた後のプロシージャ
LRESULT CALLBACK WndProc2(HWND hWnd , UINT msg , WPARAM wParam , LPARAM
lParam){
HWND hChild;
CLIENTCREATESTRUCT ccs;
MDICREATESTRUCT mdic;
wchar_t str[64], *str_org = L"No.%d";
RECT rc;
switch( msg ){
case WM_SIZE:
width=LOWORD(lParam);
height=HIWORD(lParam);
GetWindowRect(hStatusbar,&rc);
height=height-(rc.bottom-rc.top);
if(!flag){
ccs.hWindowMenu = hMenuFirstWnd;
ccs.idFirstChild = IDM_FIRSTCHILD;
hClient = CreateWindow(L"MDICLIENT", NULL, WS_CHILD | WS_VISIBLE |
WS_CLIPCHILDREN,
0, 0, width, height, hWnd, (HMENU)1, hInst,(LPVOID)&ccs);
flag=true;
}
SendMessage( hStatusbar, WM_SIZE, wParam, lParam );
return DefFrameProc(hWnd,hClient,msg,wParam,lParam);
case WM_COMMAND:
switch (LOWORD(wParam)){
case IDM_INVISIBLE:
MoveWindow(hClient,0,0,0,0,1);
return DefFrameProc(hWnd,hClient,msg,wParam,lParam);
case IDM_VISIBLE:
MoveWindow(hClient,0,0,width,height,1);
return DefFrameProc(hWnd,hClient,msg,wParam,lParam);
case IDM_NEW:
doc_no++;
wsprintf(str, str_org, doc_no);
mdic.szClass = ChildDoc;
mdic.szTitle = str;
mdic.hOwner = hInst;
mdic.x = CW_USEDEFAULT;
mdic.y = CW_USEDEFAULT;
mdic.cx = 240;
mdic.cy = 120;
mdic.style = 0;
mdic.lParam = 0;
MoveWindow(hClient,0,0,width,height,1);
hChild = (HWND)SendMessage(hClient, WM_MDICREATE,
0,(LPARAM)&mdic);
return DefFrameProc(hWnd,hClient,msg,wParam,lParam);
case IDM_CLOSE:
hChild = (HWND)SendMessage(hClient, WM_MDIGETACTIVE, 0, 0);
if (hChild)SendMessage(hClient, WM_MDIDESTROY, (WPARAM)hChild, 0);
return DefFrameProc(hWnd,hClient,msg,wParam,lParam);
case IDM_EXIT:
SendMessage(hWnd, WM_CLOSE, 0, 0);
return DefFrameProc(hWnd,hClient,msg,wParam,lParam);
case IDM_CLOSEALL:
EnumChildWindows(hClient, &CloseAllProc, 0);
doc_no=0;
return DefFrameProc(hWnd,hClient,msg,wParam,lParam);
case IDM_TILE:
MoveWindow(hClient,0,0,width,height,1);
SendMessage(hClient, WM_MDITILE, 0, 0);
return DefFrameProc(hWnd,hClient,msg,wParam,lParam);
case IDM_CASCADE:
MoveWindow(hClient,0,0,width,height,1);
SendMessage(hClient, WM_MDICASCADE, 0, 0);
return DefFrameProc(hWnd,hClient,msg,wParam,lParam);
case IDM_ARRANGE:
SendMessage(hClient, WM_MDIICONARRANGE, 0, 0);
return DefFrameProc(hWnd,hClient,msg,wParam,lParam);
default:
hChild = (HWND)SendMessage(hClient, WM_MDIGETACTIVE, 0, 0);
if (IsWindow(hChild))SendMessage(hChild, WM_COMMAND, wParam, lParam);
return DefFrameProc(hWnd,hClient,msg,wParam,lParam);
}
case WM_CLOSE:
SendMessage(hWnd, WM_COMMAND, IDM_CLOSEALL, 0);
if (GetWindow(hClient, GW_CHILD))return 0;
PostQuitMessage(0);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
if(WndProc){
return CallWindowProc(WndProc,hWnd , msg , wParam , lParam);
}else{
return DefFrameProc(hWnd,hClient,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);
}
bool main(int argc, char *argv[]){
glutInitWindowPosition(pos_x, pos_y);
glutInitWindowSize(WIDTH, HEIGHT);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutCreateWindow("MDI");
//FreeGlutのウインドウハンドルとウインドウプロシージャを置き換える
EnumWindows(enumWindowsProc,0);
hInst = (HINSTANCE)GetWindowLong(hWnd2, GWL_HINSTANCE);
if(!MyRegisterWC(WndProc2, L"test",(HBRUSH)(COLOR_APPWORKSPACE + 1)))return
FALSE;
if(!MyRegisterWC(DocProc, ChildDoc,
(HBRUSH)GetStockObject(WHITE_BRUSH)))return FALSE;
if(hWnd2){
WndProc=(WNDPROC)GetWindowLong(hWnd2,GWL_WNDPROC);
SetWindowLong(hWnd2,GWL_WNDPROC,(LONG)WndProc2);
}else{
return false;
}
hMenuFirst = LoadMenu(GetModuleHandle(NULL), L"OWNERMENU");
hMenuFirstWnd = GetSubMenu(hMenuFirst, 0);
hMenuDoc = LoadMenu(GetModuleHandle(NULL), L"DOCUMENT");
hMenuDocWnd = GetSubMenu(hMenuDoc, 1);
//メニューを作成
if(hMenuFirst){
SetMenu(hWnd2,hMenuFirst);
}else{
return false;
}
// コモンコントロール関係の初期化
InitCommonControls();
// ステータスバーを作成
hStatusbar = CreateStatusWindowW(WS_CHILD | WS_VISIBLE | CCS_BOTTOM |
SBARS_SIZEGRIP,
L"メニューの新規作成でウインドウを作成してください。",hWnd2,ID_STATUS);
MoveWindow(hWnd2,pos_x,pos_y,WIDTH,HEIGHT,1);
glutDisplayFunc(display);
glutIdleFunc(idle);
Init();
glutMainLoop();
return true;
}
|