#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 };
HWND hTabWnd, hStaticWnd;
FARPROC Org_StaticProc;
LRESULT CALLBACK StaticProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp){
PAINTSTRUCT ps;
HDC hdc;
static int nPage;
switch (msg) {
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
nPage = TabCtrl_GetCurSel(hTabWnd);
switch (nPage) {
case 0:
SetBkMode(hdc, TRANSPARENT);
TextOut(hdc, 10, 10, L"1ページです", 6);
break;
case 1:
SetBkMode(hdc, TRANSPARENT);
TextOut(hdc, 10, 10, L"2ページで~っす!!", 10);
break;
}
EndPaint(hWnd, &ps);
break;
case WM_COMMAND:
switch (LOWORD(wp)) {
case ID_TAB_E:
DestroyWindow(hTabWnd);
DestroyWindow(hStaticWnd);
break;
}
break;
default:
break;
}
return (CallWindowProc((WNDPROC)Org_StaticProc, hWnd, msg, wp, lp));
}
HWND MakeTabCtrl(HWND hWnd){
HINSTANCE hInst;
RECT rc;
TC_ITEM tcItem;
hInst = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE);
GetClientRect(hWnd, &rc);
hTabWnd = CreateWindowEx(
0, //拡張スタイルなし
WC_TABCONTROL, // クラスネーム
NULL, // ウィンドウネーム
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, // ウィンドウスタイル
0, 0, 4, 4, // 位置、大きさ(初期状態では極端に小さくしておく)
hWnd, // 親ウィンドウのハンドル
(HMENU)ID_TABCTRL, // 子供ウィンドウ識別子
hInst, // インスタンスハンドル
NULL); // WM_CREATEのパラメーターなし
hStaticWnd = CreateWindowEx(
0,
L"STATIC",
NULL,
WS_CHILD | WS_VISIBLE,
0, 0, 10, 10,
hWnd,
(HMENU)ID_STATICWND,
hInst,
NULL);
tcItem.mask = TCIF_TEXT;
tcItem.pszText = L"ページ1";
SendMessage(hTabWnd, TCM_INSERTITEM, (WPARAM)0, (LPARAM)&tcItem);
tcItem.mask = TCIF_TEXT;
tcItem.pszText = L"ページ2";
SendMessage(hTabWnd, TCM_INSERTITEM, (WPARAM)1, (LPARAM)&tcItem);
// 元々のスタティックウィンドウプロシージャの保存
Org_StaticProc = (FARPROC)GetWindowLong(hStaticWnd, GWL_WNDPROC);
// スタティックウィンドウのサブクラス化
SetWindowLong(hStaticWnd, GWL_WNDPROC, (LONG)StaticProc);
return hTabWnd;
}
//置き換えた後のプロシージャ
LRESULT CALLBACK WndProc2(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp){
int id=0;
static RECT rcDisp;
switch (msg) {
case WM_CREATE:
// コモンコントロールの初期化
InitCommonControls();
break;
case WM_COMMAND:
switch(LOWORD(wp)) {
case ID_EXIT:
PostQuitMessage(0);
break;
case ID_TAB_S:
if (IsWindow(hTabWnd) != 0) {
return 0;
}
MakeTabCtrl(hWnd);
// 強制的にWM_SIZEを送り出してサイズ調整
GetClientRect(hWnd, &rcDisp);
SendMessage(hWnd, WM_SIZE,
0, MAKELPARAM(rcDisp.right, rcDisp.bottom));
break;
case ID_TAB_E:
DestroyWindow(hTabWnd);
DestroyWindow(hStaticWnd);
break;
}
break;
case WM_SIZE:
GetClientRect(hWnd, &rcDisp);
TabCtrl_AdjustRect(hTabWnd, FALSE, &rcDisp);
RECT rcStatus;
SendMessage( hStatusbar, SB_GETRECT,(WPARAM)id,(LPARAM)&rcStatus);
MoveWindow(hTabWnd, 0, 0, LOWORD(lp), HIWORD(lp)-rcStatus.bottom, TRUE);
MoveWindow(hStaticWnd, rcDisp.left, rcDisp.top, rcDisp.right -
rcDisp.left, rcDisp.bottom - rcDisp.top, TRUE);
SendMessage( hStatusbar, WM_SIZE, wp, lp );
break;
case WM_NOTIFY:
switch (((NMHDR *)lp)->code) {
// 違うページが押された
case TCN_SELCHANGE:
InvalidateRect(hTabWnd, &rcDisp, TRUE);
InvalidateRect(hStaticWnd, NULL, TRUE);
break;
}
break;
case WM_DESTROY:
// サブクラス化の解除
if (IsWindow(hTabWnd) != 0) {
SetWindowLong(hTabWnd, GWL_WNDPROC, (LONG)Org_StaticProc);
}
exit(0);
break;
default:
if(WndProc){
return CallWindowProc(WndProc,hWnd , msg , wp , lp);
}else{
return DefWindowProc(hWnd,msg,wp,lp);
}
}
return 0;
}
//ウィンドウの検索
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;
}
// ステータスバーを作成
hStatusbar = CreateStatusWindowW(WS_CHILD | WS_VISIBLE | CCS_BOTTOM |
SBARS_SIZEGRIP,
L"ステータスバー",hWnd2,ID_STATUS);
glutDisplayFunc(display);
glutIdleFunc(idle);
Init();
glutMainLoop();
return true;
}
|