総集編:Lunaインターフェース

総集編という事で、Windows XP の Luna インターフェースで表示してみます。
.manifest ファイルを作成する方法もありますがプログラムに直接、コードを
追加する方法を紹介しておきます。

 #pragma comment(linker,"/manifestdependency:\"type='win32' \
  name='Microsoft.Windows.Common-Controls' \
  version='6.0.0.0' \
  processorArchitecture='x86' \
  publicKeyToken='6595b64144ccf1df' \
  language='*'\"")

上記のコードをプログラムに追加すると簡単にビジュアルスタイルに変更できます。
Windows Vista からは aero というスタイルもあるみたいですが
Windows 8 から aero は削除される予定らしいので当サイトでは紹介しません。

resource.h

#define IDR_MENU1  100
#define ID_EXIT   101
#define ID_TAB_S 102
#define ID_TAB_E 103
#define ID_GROUP  104
#define ID_RADIO1 105
#define ID_RADIO2 106
#define ID_RADIO3 107
#define ID_Help   108
#define ID_STATUS  109
#define ID_TRACK 110
#define ID_BUTTON 111
#define IDM_END   112
#define ID_TABCTRL 2000
#define ID_STATICWND 2001

menu.rc

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

IDR_MENU1 MENU
BEGIN
    POPUP "File"
    BEGIN
        MENUITEM "Exit",                    ID_EXIT
    END
    POPUP "Option"
    BEGIN
        MENUITEM "タブ表示",                ID_TAB_S
        MENUITEM "タブ消去",    ID_TAB_E
    END
    MENUITEM "ヘルプ",      ID_Help
END

main.cpp

#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
#pragma comment(linker,"/manifestdependency:\"type='win32' \
  name='Microsoft.Windows.Common-Controls' \
  version='6.0.0.0' \
  processorArchitecture='x86' \
  publicKeyToken='6595b64144ccf1df' \
  language='*'\"")
#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;    //インスタンスハンドル


#define WIDTH 320
#define HEIGHT 240

#define SCR_MAX 100
#define SCR_MIN 0

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

HWND hTabWnd, hStaticWnd;
HWND hButton;
HWND hTrack;//トラックバーのハンドル
HWND ud;//アップダウンコントロール用
HWND ud_t;//アップダウンのテキストボックス用
HWND hGroup,hRadio1,hRadio2,hRadio3;
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:
                    TextOut(hdc, 10, 10, L"岸辺露伴は動かない", 9);
                    break;
                case 1:
                    TextOut(hdc, 10, 10, L"万華鏡写輪眼", 6);
                    break;
            }
            EndPaint(hWnd, &ps);
            break;
        case WM_COMMAND:
            switch (LOWORD(wp)) {
                case ID_TAB_E:
                    DestroyWindow(hTabWnd);
                    DestroyWindow(hStaticWnd);
                    DestroyWindow(hButton);
                    DestroyWindow(hTrack);
                    DestroyWindow(ud_t);
                    DestroyWindow(ud);
                    DestroyWindow(hGroup);
                    DestroyWindow(hRadio1);
                    DestroyWindow(hRadio1);
                    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"うちはマダラ";
    SendMessage(hTabWnd, TCM_INSERTITEM, (WPARAM)0, (LPARAM)&tcItem);
    tcItem.mask = TCIF_TEXT;
    tcItem.pszText = L"うちはオビト";
    SendMessage(hTabWnd, TCM_INSERTITEM, (WPARAM)1, (LPARAM)&tcItem);
    hButton = CreateWindow( L"BUTTON", L"…何……だと…?",
        WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
        10, 100, 140, 30,  hStaticWnd, (HMENU)ID_BUTTON, hInst, NULL);
    hTrack = CreateWindowEx(0,TRACKBAR_CLASS, L"",
        WS_CHILD | WS_VISIBLE |TBS_AUTOTICKS | TBS_ENABLESELRANGE,//ウィンドウスタイル
        10, 50, 150, 30,//位置、大きさ
        hStaticWnd,(HMENU)ID_TRACK,hInst,NULL);
    //トラックバーの範囲設定
    SendMessage(hTrack, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELPARAM(0, 10));

    //アップダウンコントロール
    ud_t=CreateWindowEx(0,L"EDIT",L"",WS_CHILD| WS_BORDER,200, 10,64, 24,
        hStaticWnd,NULL,hInst,NULL);
    ShowWindow(ud_t,SW_SHOW);
    //アップダウンコントロール作成用API関数
    ud= CreateUpDownControl(WS_CHILD |WS_VISIBLE |UDS_ALIGNRIGHT |UDS_SETBUDDYINT,
        0, 0, 0, 0, hStaticWnd,NULL,hInst,
        ud_t,//テキストボックスと兄弟Windowにする
        SCR_MAX,SCR_MIN,//範囲指定
        0);//初期値指定
    ShowWindow(ud,SW_SHOW);

    hGroup = CreateWindow(L"BUTTON",L"漫画",WS_CHILD|WS_VISIBLE|WS_GROUP|BS_GROUPBOX,
                 170,50,130,110,hStaticWnd,(HMENU)ID_GROUP,hInst,NULL);
    hRadio1 = CreateWindow(L"BUTTON",L"NARUTO",WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
                 175,70,100,30,hStaticWnd,(HMENU)ID_RADIO1,hInst,NULL);
    hRadio2 = CreateWindow(L"BUTTON",L"クレイモア",WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
                 175,95,100,30,hStaticWnd,(HMENU)ID_RADIO2,hInst,NULL);
    hRadio3 = CreateWindow(L"BUTTON",L"GANTZ",WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
                 175,120,100,30,hStaticWnd,(HMENU)ID_RADIO3,hInst,NULL);
    SendDlgItemMessage(hStaticWnd,ID_RADIO1,BM_SETCHECK,BST_CHECKED,0);//選択肢1にセット

    // 元々のスタティックウィンドウプロシージャの保存
    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[]){
 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;
 }
 // ステータスバーを作成
 hStatusbar = CreateStatusWindowW(WS_CHILD | WS_VISIBLE | CCS_BOTTOM | SBARS_SIZEGRIP,
   L"ステータスバー",hWnd2,ID_STATUS);
 glutDisplayFunc(display);
 glutIdleFunc(idle);
 Init();
 glutMainLoop();
 return true;
}

 

 

 

 

 

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