タブコントロールを表示する

またまた同様にしてタブコントロールを表示してみます。
メニューの Option > タブ表示 でタブを表示して、
Option > タブ消去 でタブを消します。

resource.h

#define IDR_MENU1  100
#define ID_EXIT   101
#define ID_TAB_S 102
#define ID_TAB_E 103
#define ID_Help   107
#define ID_STATUS  108
#define IDM_END   114
#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(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;
}

 

 

 

 

 

 

最終更新:2014年05月16日 13:24
添付ファイル