본문 바로가기

Windows/Windows API

차일드 윈도우 (child)

#include <windows.h>

// 윈도우 프로시저
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
LRESULT CALLBACK ChildLeftProc(HWND,UINT,WPARAM,LPARAM);        // CHILD LEFT WINDOW
LRESULT CALLBACK ChildTopProc(HWND,UINT,WPARAM,LPARAM);            // CHILD RIGHT WINDOW
LRESULT CALLBACK ChildBottomProc(HWND,UINT,WPARAM,LPARAM);        // CHILD BOTTOM WINDOW

HINSTANCE g_hInst;

// 윈도우 핸들
HWND hWndMain, hC1, hC2, hC3;                                    // WINDOW HANDLE
LPSTR lpszClass="Childs";

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance
     ,LPSTR lpszCmdParam,int nCmdShow)
{
    HWND hWnd;
    MSG Message;
    WNDCLASS WndClass;
    g_hInst=hInstance;

    static HBRUSH hRedBrush, hBlueBrush, hGreenBrush;        // BRUSH HANDLE

    hRedBrush=CreateSolidBrush(RGB(255,0,0));                // 브러쉬 셋팅
    hBlueBrush=CreateSolidBrush(RGB(0,255,0));
    hGreenBrush=CreateSolidBrush(RGB(0,0,255));

    // 메인 윈도우 클래스
    WndClass.cbClsExtra=0;
    WndClass.cbWndExtra=0;
    WndClass.hbrBackground=(HBRUSH)GetStockObject(NULL_BRUSH);
    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    WndClass.hInstance=hInstance;
    WndClass.lpfnWndProc=(WNDPROC)WndProc;
    WndClass.lpszClassName=lpszClass;
    WndClass.lpszMenuName=NULL;
    WndClass.style=CS_HREDRAW | CS_VREDRAW;
    RegisterClass(&WndClass);

    // 왼쪽 차일드 클래스
    WndClass.hbrBackground=hRedBrush;
    WndClass.lpfnWndProc=(WNDPROC)ChildLeftProc;
    WndClass.lpszClassName="ChildLeft";
    RegisterClass(&WndClass);

    // 위쪽 차일드 클래스
    WndClass.hbrBackground=hBlueBrush;
    WndClass.lpfnWndProc=(WNDPROC)ChildTopProc;
    WndClass.lpszClassName="ChildTop";
    RegisterClass(&WndClass);

    // 아래쪽 차일드 클래스
    WndClass.hbrBackground=hGreenBrush;
    WndClass.lpfnWndProc=(WNDPROC)ChildBottomProc;
    WndClass.lpszClassName="ChildBottom";
    RegisterClass(&WndClass);

    // 메인 윈도우 생성
    hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
        NULL,(HMENU)NULL,hInstance,NULL);
    ShowWindow(hWnd,nCmdShow);
    hWndMain=hWnd;
    
    while(GetMessage(&Message,0,0,0)) {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }

    DeleteObject(hRedBrush);
    DeleteObject(hBlueBrush);
    DeleteObject(hGreenBrush);
    return Message.wParam;
}

// 메인 윈도우의 메시지 프로시저
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
    RECT crt;    //

    switch(iMessage) {
    case WM_CREATE:
        // 차일드 윈도우 생성하고
        hC1=CreateWindow("ChildLeft",NULL,WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN,
            0,0,0,0,hWnd,(HMENU)0,g_hInst,NULL);
        hC2=CreateWindow("ChildTop",NULL,WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN,
            0,0,0,0,hWnd,(HMENU)0,g_hInst,NULL);
        hC3=CreateWindow("ChildBottom",NULL,WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN,
            0,0,0,0,hWnd,(HMENU)0,g_hInst,NULL);
        return 0;
    case WM_SIZE:
        GetClientRect(hWnd,&crt);    // 작업 영역 크기를 재 조사해서 lParam으로 전달되어 사용 할 수 있다
        MoveWindow(hC1,0,0,300,crt.bottom,TRUE);        // 해당 위치로 윈도우 컨트롤을 이동
        MoveWindow(hC2,300,0,crt.right-300,150, TRUE);
        MoveWindow(hC3,300,150,crt.right-300,crt.bottom-150,TRUE);
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

// 왼쪽 차일드의 메시지 프로시저
LRESULT CALLBACK ChildLeftProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
    static HWND hList, hEdit;
    char str[256];

    switch(iMessage) {
    case WM_CREATE:
        
        // 리스트 박스
        hList=CreateWindow("listbox",NULL,WS_CHILD | WS_VISIBLE | WS_BORDER |
            LBS_NOTIFY | LBS_NOINTEGRALHEIGHT,0,0,0,0,hWnd,(HMENU)0,g_hInst,NULL);
        SendMessage(hList,LB_ADDSTRING,0,(LPARAM)"리스트 박스");    // 리스트 박스에 기본 문구 입력

        // 에디트
        hEdit=CreateWindow("edit",NULL,WS_CHILD | WS_VISIBLE | WS_BORDER |
            ES_AUTOHSCROLL,
            210,10,80,25,hWnd,(HMENU)1,g_hInst,NULL);

        // 버튼
        CreateWindow("button","Add",WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
            210,50,80,25,hWnd,(HMENU)2,g_hInst,NULL);
        return 0;
    case WM_SIZE:
        MoveWindow(hList,10,10,190,HIWORD(lParam)-20,TRUE);
        return 0;
    case WM_COMMAND:
        switch (LOWORD(wParam)) {
        case 2:
            GetWindowText(hEdit,str,256);                    // 에디트 안에 있는 TEXT를 가져온다.
            SendMessage(hList,LB_ADDSTRING,0,(LPARAM)str);    // 리스트 박스에 문구 입력
        }
        return 0;
    }
    return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

// 위쪽 차일드의 메시지 프로시저
LRESULT CALLBACK ChildTopProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    char Mes[]="이 윈도우는 차일드를 가지고 있지 않습니다";

    switch(iMessage) {
    case WM_PAINT:
        hdc=BeginPaint(hWnd, &ps);
        TextOut(hdc,10,50,Mes,strlen(Mes));
        EndPaint(hWnd, &ps);
        return 0;
    }
    return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

// 아래쪽 차일드의 메시지 프로시저
LRESULT CALLBACK ChildBottomProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
    static HWND hEdit;

    switch(iMessage) {
    case WM_CREATE:
        hEdit=CreateWindow("edit",NULL,WS_CHILD | WS_VISIBLE | WS_BORDER |
            ES_MULTILINE | WS_VSCROLL,
            0,0,0,0,hWnd,(HMENU)0,g_hInst,NULL);        // 멀티라인..
        SetWindowText(hEdit,"에디트 윈도우입니다");
        return 0;
    case WM_SIZE:
        MoveWindow(hEdit,50,50,LOWORD(lParam)-100,HIWORD(lParam)-100,TRUE);
        return 0;
    }
    return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}