分割ウインドウ

二つのエディットコントロールを使ってウインドウを分割したように
見せます。
この類の処理はSDKを使うとサイズ変更などの度に再描画が発生し
チラついてしまいますのでGUIを自作するのが良いかもしれません。

resource.h

#define IDR_MENU1  100
#define ID_EXIT   101
#define ID_ERASE   102
#define ID_SHOW   103
#define ID_STATUS  104
#define IDC_EDIT1 105
#define IDC_EDIT2 106

menu.rc

#include "resource.h"

IDR_MENU1 MENU
BEGIN
    POPUP "File"
    BEGIN
        MENUITEM "Exit",    ID_EXIT
    END
    POPUP "ウインドウ"
    BEGIN
        MENUITEM "クライアント領域を消す",    ID_ERASE
  MENUITEM "クライアント領域を表示",    ID_SHOW
    END
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;     // ステータスバーのハンドル

HWND hEdit1;
HWND hEdit2;
int width = 155;       // 分割ウインドウ(左)の幅
#define SPLIT_WIDTH 1
#define SPLIT_MIN 5
bool flag=false;
bool flg=true;

#define WIDTH 320
#define HEIGHT 240

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

int MaxMinPoint(LPARAM lParam,RECT rc){
    POINTS pts;

    pts = MAKEPOINTS(lParam);
    width = pts.x;
    if(width < SPLIT_MIN){
        width = SPLIT_MIN;
    }else if(width > (rc.right - rc.left - SPLIT_MIN -10)){
        width = rc.right - rc.left - SPLIT_MIN -10;
    }else{
        ;
    }
    return width;
}

//置き換えた後のプロシージャ
LRESULT CALLBACK WndProc2(HWND hWnd , UINT msg , WPARAM wParam , LPARAM lParam){
 RECT rc;
 static BOOL push = FALSE;
 switch( msg ){
 case WM_SIZE:
  if(flag){
   MoveWindow(hEdit1, 0, 0, 0, 0, TRUE);
      MoveWindow(hEdit2, 0, 0, 0, 0, TRUE);
   SendMessage( hStatusbar, WM_SIZE, wParam, lParam );
  }else{
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   glutSwapBuffers();
   MoveWindow(hEdit1, 0, 0, width - SPLIT_WIDTH, HIWORD(lParam), TRUE);
   MoveWindow(hEdit2, width + SPLIT_WIDTH, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
   SendMessage( hStatusbar, WM_SIZE, wParam, lParam );
  }
  return 0;
 case WM_LBUTTONDOWN:  // マウスの左ボタンが押されたとき
    // マウスキャプチャを開始する
    SetCapture(hWnd);
    SetCursor(LoadCursor(NULL, IDC_SIZEWE));
    push = TRUE;        // 左ボタンが押された
    return 0;
 case WM_LBUTTONUP:   // マウスの左ボタンが離されたとき
    GetWindowRect(hWnd, &rc);
    // マウスカーソルの位置を取得して、終点として保存しておく
    width = MaxMinPoint(lParam, rc);
    push = FALSE;      // 左ボタンが押されてない
    // マウスキャプチャを終了する
    ReleaseCapture();
    SendMessage(hWnd, WM_SIZE, SIZE_RESTORED,
    ((rc.bottom-rc.top)<<16) | (rc.right-rc.left));
    MoveWindow(hStatusbar ,0,0,0,0,true);
    return 0;
 case WM_MOUSEMOVE:      // マウスカーソルが移動したとき
    if(push == TRUE){
       GetWindowRect(hWnd, &rc);
       // マウスカーソルの位置を取得して、終点として保存しておく
       width = MaxMinPoint(lParam, rc);
       SendMessage(hWnd, WM_SIZE, SIZE_RESTORED,
       ((rc.bottom-rc.top)<<16) | (rc.right-rc.left));
    }else if((width <= (LOWORD(lParam) + SPLIT_WIDTH))&& (width >= (LOWORD(lParam) - SPLIT_WIDTH))){
        if(!flag)SetCursor(LoadCursor(NULL, IDC_SIZEWE));
        }else{
         SetCursor(LoadCursor(NULL, IDC_ARROW));
        }
        return 0;
 case WM_COMMAND:
  switch (LOWORD(wParam)){
 case ID_ERASE:
  flag=true;
  return 0;
 case ID_SHOW:
  flag=false;
  flg=true;
  GetWindowRect(hWnd, &rc);
  SendMessage(hWnd, WM_SIZE, SIZE_RESTORED,
         ((rc.bottom-rc.top)<<16) | (rc.right-rc.left));
  MoveWindow(hStatusbar ,0,0,0,0,true);
  return 0;
  case ID_EXIT:
   PostQuitMessage(0);
  }
  return 0;
 case WM_DESTROY:
  exit(0);
  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){
 if(flag){
  if(flg){
   MoveWindow(hEdit1, 0, 0, 0, 0, TRUE);
   MoveWindow(hEdit2, 0, 0, 0, 0, TRUE);
   flg=false;
  }
  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;
 }
 // コモンコントロール関係の初期化
 InitCommonControls();
 // ステータスバーを作成
 hStatusbar = CreateStatusWindowW(WS_CHILD | WS_VISIBLE | CCS_BOTTOM | SBARS_SIZEGRIP,
   L"ステータスバー",hWnd2,ID_STATUS);

 hEdit1 = CreateWindowEx(WS_EX_CLIENTEDGE,  TEXT("EDIT"), TEXT("ウインドウ1"),
                WS_CHILD | WS_VISIBLE | ES_MULTILINE,
                0, 0, 155, 240, hWnd2, (HMENU)IDC_EDIT1,
    (HINSTANCE)GetWindowLong(hWnd2, GWL_HINSTANCE), NULL);

 hEdit2 = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), TEXT("ウインドウ2"),
                WS_CHILD | WS_VISIBLE | ES_MULTILINE,
                157, 0, 320, 240, hWnd2, (HMENU)IDC_EDIT2,
    (HINSTANCE)GetWindowLong(hWnd2, GWL_HINSTANCE), NULL);

 glutDisplayFunc(display);
 glutIdleFunc(idle);
 Init();
 glutMainLoop();
 return true;
}

 

 

 

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