윈도우스에서 사각형을 출력하는 것은 항상 말하는 사각형을 표현하는 방식에서 정의가 된다.


 여기서는 2가지 점의 정보. 정확하게는 x1, x2, y1, y2인 총 가지 정보가 필요하다.


 사각형 함수.
 Rectangle(

HDC hdc, // DC의 핸들

int nLeftRect, // 좌측 x 좌표.

int nTopRect, // 상단 y 좌표.

int nRightRect, // 우측 x 좌표.

int nBottomRect); // 하단 y 좌표.


 예제

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <stdlib.h>
 
#include <tchar.h>
#include <windows.h>
 
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
 
WNDCLASS WndClass;
 
int WINAPI WinMain(HINSTANCE hInstance,
            HINSTANCE hPrevInstance,
            LPSTR lpszCmdParam,
            int nCmdShow)
{
    HWND hWnd;
    MSG Message;
    g_hInst = hInstance;
    
    //윈도우 클래스 초기화
    WndClass.cbClsExtra=0;
    WndClass.cbWndExtra=0;
    WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    WndClass.hInstance=hInstance;
    WndClass.lpfnWndProc=(WNDPROC)WndProc;
    WndClass.lpszClassName="ApiBase";
    WndClass.lpszMenuName=NULL;
    WndClass.style=CS_HREDRAW|CS_VREDRAW;
 
    //윈도우 클래스 생성.
    RegisterClass(&WndClass);
    
    //윈도우 객체 생성.
    hWnd = CreateWindow("ApiBase",
                        "Test",
                        WS_OVERLAPPEDWINDOW,
                        10,// X
                        100,// Y
                        400,// Width
                        400,// Height
                        NULL,
                        (HMENU)NULL,
                        hInstance,
                        NULL);
    
    //윈도우 창 띄우기.
    ShowWindow(hWnd,nCmdShow);
    
    while(GetMessage(&Message,0,0,0))
    {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }
    
    return Message.wParam;
}
 
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    long dwStyle;
    
    switch(iMessage)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        case WM_LBUTTONDOWN:
            hdc = GetDC(hWnd);
            Rectangle(hdc, 100100300300);
            ReleaseDC(hWnd, hdc);
            break;
        case WM_PAINT:
            hdc = GetDC(hWnd);
            TextOut(hdc, 10050"Hello World",11);
            ReleaseDC(hWnd, hdc);
            break;
    }
    return DefWindowProc(hWnd,iMessage,wParam, lParam);
}
 
cs



 윈도우스에서는 사각형만 처리할 수 있는게 아니다.

 라운드 사각형이라는 것을 할 수 있다.

 사각형을 이용해서 라운드 사각형이 될 수 있는 것은 사각형에서 각 꼭지점에서 원을 표현 하는 것이다.


 여기서, 원을 표현 하는 방식은 미분 기하학에서 나오는 매개 함수로 표현이 가능하다.

 매개 함수를 이용하는 방법이란, 원래의 함수를 이용해서 처리 하는 것이 아니다.


 더 자세한 것은 미분 기하학을 이용한 원을 표현법을 한 번 보는 것이 좋을 것이다.


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <stdlib.h>
 
#include <tchar.h>
#include <windows.h>
 
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
 
WNDCLASS WndClass;
 
int WINAPI WinMain(HINSTANCE hInstance,
            HINSTANCE hPrevInstance,
            LPSTR lpszCmdParam,
            int nCmdShow)
{
    HWND hWnd;
    MSG Message;
    g_hInst = hInstance;
    
    //윈도우 클래스 초기화
    WndClass.cbClsExtra=0;
    WndClass.cbWndExtra=0;
    WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    WndClass.hInstance=hInstance;
    WndClass.lpfnWndProc=(WNDPROC)WndProc;
    WndClass.lpszClassName="ApiBase";
    WndClass.lpszMenuName=NULL;
    WndClass.style=CS_HREDRAW|CS_VREDRAW;
 
    //윈도우 클래스 생성.
    RegisterClass(&WndClass);
    
    //윈도우 객체 생성.
    hWnd = CreateWindow("ApiBase",
                        "Test",
                        WS_OVERLAPPEDWINDOW,
                        10,// X
                        100,// Y
                        400,// Width
                        400,// Height
                        NULL,
                        (HMENU)NULL,
                        hInstance,
                        NULL);
    
    //윈도우 창 띄우기.
    ShowWindow(hWnd,nCmdShow);
    
    while(GetMessage(&Message,0,0,0))
    {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }
    
    return Message.wParam;
}
 
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    long dwStyle;
    
    switch(iMessage)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        case WM_LBUTTONDOWN:
            hdc = GetDC(hWnd);
            RoundRect(hdc, 1001003003001020);
            ReleaseDC(hWnd, hdc);
            break;
        case WM_PAINT:
            hdc = GetDC(hWnd);
            TextOut(hdc, 10050"Hello World",11);
            ReleaseDC(hWnd, hdc);
            break;
    }
    return DefWindowProc(hWnd,iMessage,wParam, lParam);
}
 
cs


Posted by JunkMam
,

 Windows에서 선을 그려주는 작업을 하는 함수가 있다.


 여기서 선이란, 선분을 뜻한다.


 시작 점과 끝점을 알고 있었을 경우. 그어진 선을 선분이라고 한다.


 수학에서 직선, 반직선, 선분으로 나뉘어 지는걸 생각하면, 여기서 말하는 선은 직선이된다.


 직선을 표현하는 방법은 선형 대수학에서 말하는 함수의 값과 x와 y의 값에 따른 차로 점들을 이어간다면, 선이 된다. 이것을 만들어 주는 작업은 Windows 함수에 지원이 되어있지만, 만약에 구현을 하기 원한다면, 직선은 점들의 모임이라는 것을 이해 하면 도움이 될 것이다.


  Windows 에서 지원되어 있는 직선을 긋는 함수는 다음과 같다.


  MoveToEx(

HDC hdc, // DC의 핸들

int X, // 새로운 지점의 x 좌표.

int y, // 새로운 지점의 y 좌표.

LPPOINT lpPoint); // 이전 위치 좌표.


 LineTo(

HDC hdc, // DC의 핸들

int nXEnd, // 그리는 마지막 지점의 X 좌표

int nYEnd); // 그리는 마지막 지점의 Y 좌표.


 이렇게 사용한다. 그렇지만, 이전 지점 포인트라는 것이 있는데, 여기서 MoveToEx에 lpPoint 라는 값에는 NULL이 들어가게 된다.



 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <stdlib.h>
 
#include <tchar.h>
#include <windows.h>
 
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
 
WNDCLASS WndClass;
 
int WINAPI WinMain(HINSTANCE hInstance,
            HINSTANCE hPrevInstance,
            LPSTR lpszCmdParam,
            int nCmdShow)
{
    HWND hWnd;
    MSG Message;
    g_hInst = hInstance;
    
    //윈도우 클래스 초기화
    WndClass.cbClsExtra=0;
    WndClass.cbWndExtra=0;
    WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    WndClass.hInstance=hInstance;
    WndClass.lpfnWndProc=(WNDPROC)WndProc;
    WndClass.lpszClassName="ApiBase";
    WndClass.lpszMenuName=NULL;
    WndClass.style=CS_HREDRAW|CS_VREDRAW;
 
    //윈도우 클래스 생성.
    RegisterClass(&WndClass);
    
    //윈도우 객체 생성.
    hWnd = CreateWindow("ApiBase",
                        "Test",
                        WS_OVERLAPPEDWINDOW,
                        10,// X
                        100,// Y
                        400,// Width
                        400,// Height
                        NULL,
                        (HMENU)NULL,
                        hInstance,
                        NULL);
    
    //윈도우 창 띄우기.
    ShowWindow(hWnd,nCmdShow);
    
    while(GetMessage(&Message,0,0,0))
    {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }
    
    return Message.wParam;
}
 
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    long dwStyle;
    
    switch(iMessage)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        case WM_LBUTTONDOWN:
            hdc = GetDC(hWnd);
            MoveToEx(hdc, 4040NULL);
            LineTo(hdc, 8040);
            ReleaseDC(hWnd, hdc);
            break;
        case WM_PAINT:
            hdc = GetDC(hWnd);
            TextOut(hdc, 10050"Hello World",11);
            ReleaseDC(hWnd, hdc);
            break;
    }
    return DefWindowProc(hWnd,iMessage,wParam, lParam);
}
 
cs


Posted by JunkMam
,

 도형 출력.

 윈도우에서 사용하는 것은 사용자에게 GUI을 제공하기 위한 것으로, 기본적으로 도형을 출력할 수 있는 점이 있다.


 도형은 점, 선, 면이 있다. 2차원에서는 최대 면까지 표현할 수 있다.

 만약에 3D를 표현하고 싶다면, 복잡한 도형을 생각해야 된다. 그래서 OpenGL을 이용해서 표현을 하는게 좋다. 그리고 GDI에서는 3D를 지원해주는 형태가 아니다.


 참조 : https://msdn.microsoft.com/en-us/library/windows/desktop/dd183385(v=vs.85).aspx


 그래픽 출력의 기본으로는 점, 선, 도형으로 나뉘어 진다.


 점은 다음 과 같은 함수를 사용한다.

 SetPixel()[각주:1]


 SetPixel(

HDC hdc, // hdc의 핸들.

int X, // 출력할 픽셀의 x좌표.

int Y, // 출력할 픽셀의 y좌표.

COLORREF crColor); // 픽셀의 색깔.


 색상인 COLORREF는 32bit형태로 되어있는거랑 비슷하다고 보면된다.


 역으로 Pixel 단위로 데이터를 얻는 방법이 있다.

 GetPixel()[각주:2]


 GetPixel(

HDC hdc,

int X,

int Y);


 이렇게해서 해당 컬러 데이터를 얻을 수 있다.


 COLORREF의 데이터를 만들기 위해서는 함수를 사용한다.

 RGB 라는 형식으로 컬러를 생성하는 함수를 얻을 수 있다.


 이렇게해서 이미지를 생성하는 방법으로 SetPixel을 사용하면, 문제가 생긴다.

 이유는 SetPixel함수를 작동할때마다 HDC에서 받아들여지는 BMP의 정보를 받아들여 데이터를 변환한다. 해당 값을 변환 한 후에 끊는다. 그래서 SetPixel()이 많이 작동하게 되면, HDC을 연결하고 끊는 작업이 반복되서 문제가 생기게 된다.


 그래서 그림을 출력하는 것은 SetPixel()을 사용하지 않는게 좋다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <stdlib.h>
 
#include <tchar.h>
#include <windows.h>
 
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
 
WNDCLASS WndClass;
 
int WINAPI WinMain(HINSTANCE hInstance,
            HINSTANCE hPrevInstance,
            LPSTR lpszCmdParam,
            int nCmdShow)
{
    HWND hWnd;
    MSG Message;
    g_hInst = hInstance;
    
    //윈도우 클래스 초기화
    WndClass.cbClsExtra=0;
    WndClass.cbWndExtra=0;
    WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    WndClass.hInstance=hInstance;
    WndClass.lpfnWndProc=(WNDPROC)WndProc;
    WndClass.lpszClassName="ApiBase";
    WndClass.lpszMenuName=NULL;
    WndClass.style=CS_HREDRAW|CS_VREDRAW;
 
    //윈도우 클래스 생성.
    RegisterClass(&WndClass);
    
    //윈도우 객체 생성.
    hWnd = CreateWindow("ApiBase",
                        "Test",
                        WS_OVERLAPPEDWINDOW,
                        10,// X
                        100,// Y
                        400,// Width
                        400,// Height
                        NULL,
                        (HMENU)NULL,
                        hInstance,
                        NULL);
    
    //윈도우 창 띄우기.
    ShowWindow(hWnd,nCmdShow);
    
    while(GetMessage(&Message,0,0,0))
    {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }
    
    return Message.wParam;
}
 
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    long dwStyle;
    
    switch(iMessage)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        case WM_LBUTTONDOWN:
            hdc = GetDC(hWnd);
            SetPixel(hdc, 10030, RGB(255,0,0));
            ReleaseDC(hWnd, hdc);
            break;
        case WM_PAINT:
            hdc = GetDC(hWnd);
            TextOut(hdc, 10050"Hello World",11);
            ReleaseDC(hWnd, hdc);
            break;
    }
    return DefWindowProc(hWnd,iMessage,wParam, lParam);
}
 
cs


  1. https://msdn.microsoft.com/en-us/library/windows/desktop/dd145078(v=vs.85).aspx(2016-06-22) [본문으로]
  2. https://msdn.microsoft.com/en-us/library/windows/desktop/dd144909(v=vs.85).aspx(2016-06-22) [본문으로]
Posted by JunkMam
,

 윈도우에서는 텍스트를 출력하는 방법이 2가지로 나뉜다.


 한 줄을 출력하는 TextOut()을 이용한다.


 TextOut(HDC hdc, // DC의 핸들.

int nXStart, // 문자열의 x축 시작점.

int nYStart, // 문자열의 y축 시작점.

LPCTSTR lpString, // 출력할 문자열.

int cbString); // 문자열 길이.



 전에 사용한 WM_LBUTTONDWN: 라는 이벤트에서 문자열을 출력하기 위해서 사용한 것이다.


 HDC는 GDI을 컨트롤 하기 위해서 사용하는 핸들 정보이고, XStart와 YStart는 윈도우스에 출력되는 위치 정보를 지정한다.


 출력할 문자열 lpString은 문자열(문자 배열)을 받아 들여서 윈도우상에 출력하는 것이고, cbString은 출력하고자하는 문자열의 길이를 받아 들인다.


 그래서 주로 char arr[]="Test"; strlen(arr); 이런식의 정보를 넣는게 많을 것이다.


 사각 영역에 문자열을 출력하는 경우도 있다.

 메모장의 자동 줄 바꿈 형태라고 이해하면, 빠를 것 같다.


 사각 영역을 설정하기 위해서 우리는 사각형 영역을 정하는 구조체를 봐야한다.


 전에 윈도우 출력하는 부분에서 평면에 2가지 방식이 있다. 라고 했다.


 1. 좌상단과 우하단의 점 위치 정보를 가지고 있어야 되는 것.

 2. 좌상단의 점 위치를 알고, 넓이와 높이를 알고 있어야 되는 것.


 여기서 윈도우 생성하는 CreateWindow의 함수에는 2번째를 사용한다. 라고 했다.


 RECT의 정보는 그와는 다르게 1의 방식을 사용한다.


 RECT 구조체 정의


 struct _RECT{

LONG left; // 왼쪽 좌표.

LONG top; // 상단 좌표.

LONG right; // 오른쪽 좌표.

LONG bottom; // 하단 좌표.

 };

 _RECT라는 구조체는 사각형을 받는 구조체이다. POINT 구조체를 이용하는 것은 복잡한 구조가 되기 때문에, 변수 4개가 되어 있다.


 사각형 영역에 문자열을 출력하는 함수

 DrawText는 다음과 같은 원형을 갖는다.


 int DrawText(

HDC hdc, // DC의 핸들

LPCTSTR lpString, // 출력할 문자열

int nCount, // 문자열 길이

LPRECT lpRect, // 문자열의 출력될 사각 영역의 구조체 포인터

UINT uFormat); // 문자열을 어떤 형태로 출력할 지 설정하는 옵션.


 uFormat은 문자열의 형태(워드에서 좌측 정렬 우측 정렬 같은 형태를 뜻한다.)를 뜻한다.

 이것도 BitData로 저장시키는 것이기 떄문에 OR 연산이 가능하다.(속성을 중복 처리가 가능하다. 라는 뜻이다.)


 예제


 (소스)


 다음과 같은 형태로 윈도우의 값이 나오게 된다.

Posted by JunkMam
,

 WM_PAINT란, Windows Massage Event 중에 Paint(다시 그림을 그리는 이벤트)가 발생할 경우. 해당 값을 출력하는 이벤트이다.



 WIndows 10에서는 문제 없이 작동이 되는걸 확인 되었다.


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <stdlib.h>
 
#include <tchar.h>
#include <windows.h>
 
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
 
int WINAPI WinMain(HINSTANCE hInstance,
            HINSTANCE hPrevInstance,
            LPSTR lpszCmdParam,
            int nCmdShow)
{
    HWND hWnd;
    MSG Message;
    WNDCLASS WndClass;
    g_hInst = hInstance;
    
    //윈도우 클래스 초기화
    WndClass.cbClsExtra=0;
    WndClass.cbWndExtra=0;
    WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    WndClass.hInstance=hInstance;
    WndClass.lpfnWndProc=(WNDPROC)WndProc;
    WndClass.lpszClassName="ApiBase";
    WndClass.lpszMenuName=NULL;
    WndClass.style=CS_HREDRAW|CS_VREDRAW;
 
    //윈도우 클래스 생성.
    RegisterClass(&WndClass);
    
    //윈도우 객체 생성.
    hWnd = CreateWindow("ApiBase",
                        "Test",
                        WS_OVERLAPPEDWINDOW,
                        10,// X
                        100,// Y
                        400,// Width
                        400,// Height
                        NULL,
                        (HMENU)NULL,
                        hInstance,
                        NULL);
    
    //윈도우 창 띄우기.
    ShowWindow(hWnd,nCmdShow);
    
    while(GetMessage(&Message,0,0,0))
    {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }
    
    return Message.wParam;
}
 
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    long dwStyle;
    
    switch(iMessage)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        case WM_LBUTTONDOWN:
            hdc = GetDC(hWnd);
            TextOut(hdc, 10050"Hello World",11);
            ReleaseDC(hWnd, hdc);
            break;
        case WM_PAINT:
            break;
    }
    return DefWindowProc(hWnd,iMessage,wParam, lParam);
}
 
cs


 이렇게 사용해도 상관 없으며,


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <stdlib.h>
 
#include <tchar.h>
#include <windows.h>
 
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
 
int WINAPI WinMain(HINSTANCE hInstance,
            HINSTANCE hPrevInstance,
            LPSTR lpszCmdParam,
            int nCmdShow)
{
    HWND hWnd;
    MSG Message;
    WNDCLASS WndClass;
    g_hInst = hInstance;
    
    //윈도우 클래스 초기화
    WndClass.cbClsExtra=0;
    WndClass.cbWndExtra=0;
    WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    WndClass.hInstance=hInstance;
    WndClass.lpfnWndProc=(WNDPROC)WndProc;
    WndClass.lpszClassName="ApiBase";
    WndClass.lpszMenuName=NULL;
    WndClass.style=CS_HREDRAW|CS_VREDRAW;
 
    //윈도우 클래스 생성.
    RegisterClass(&WndClass);
    
    //윈도우 객체 생성.
    hWnd = CreateWindow("ApiBase",
                        "Test",
                        WS_OVERLAPPEDWINDOW,
                        10,// X
                        100,// Y
                        400,// Width
                        400,// Height
                        NULL,
                        (HMENU)NULL,
                        hInstance,
                        NULL);
    
    //윈도우 창 띄우기.
    ShowWindow(hWnd,nCmdShow);
    
    while(GetMessage(&Message,0,0,0))
    {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }
    
    return Message.wParam;
}
 
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    long dwStyle;
    
    switch(iMessage)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        case WM_LBUTTONDOWN:
            break;
        case WM_PAINT:
            hdc = GetDC(hWnd);
            TextOut(hdc, 10050"Hello World",11);
            ReleaseDC(hWnd, hdc);
            break;
    }
    return DefWindowProc(hWnd,iMessage,wParam, lParam);
}
 
cs


 이렇게 해도 된다.

Posted by JunkMam
,

 GDI란, Graphic Device Interface의 약어이다.

 그래픽 장치로 사용자에게 그래픽 형태의 인터페이스를 제공하는 장치가 GDI이다.

 GUI를 만들기 위해서 디바이스에게 적용하는 것이 GDI라고 이해하는게 편할 것 같다.(그래서 GDI32 Library을 사용하는 것이다.)


 옛날에는 그래픽처리 방법으로 출력되는 것이 아닌, 텍스트처리로 출력되었다.

 이것은 TUI형태로 볼 수 있으며, 텍스트는 점자 프린트등으로 출력하였다.


 TUI로 구성된 프로그램이나 Shell을 사용해보면 알겠지만, 사용자가 해당 프로그램을 사용하기 어렵다.


 대표적으로 CMD, DOS을 보면 알 수 있다. 요즘에 CMD를 사용하는 사람이 별로 없을 것이다. 이유는 '귀찮아서' 일 것이다. '어려워서'라고 생각할 것 같지만, 사실 기본적인 명령어가 그렇게 많지 않다.(약 50개 이내) 하지만, 사람들은 50개 이내에 있는 또 다른 명령어들을 공부하기 귀찮아서 쓰지 않는다.


 DOS일때는 책을 펼치면서 이것 저것 작성을 해야되고, 대충 처리하고 싶은 일 또한 복잡한 작업을 해야된다.


 그래서 그것을 편하게 만들기 위해서 나온 OS. 그것이 윈도우/맥/리눅스 들이였다.(GUI가 적용된 OS들이다. GUI 형태의 OS는 먼저 리눅스에서 나왔고, 그것이 업그레이드 되서 맥, 윈도우 순으로 나왔다.)


 GDI을 사용하기 위해서는 DC(Device Context)에 대해서 가지고 와야한다.

 DC란, 디바이스에서 윈도우를 띄우기 위해서 사용하는 모든 정보를 가지고 있는 구조체이다.

 DC를 변경해서 특정 정보, 윈도우의 속성, 윈도우의 그림을 그리는 등을 할 수 있다.


 DC의 핸들러를 얻는 방법은 다음과 같다.

 hdc = BeginPaint(hWnd, &ps);

 EndPaint(hWnd, &ps);


 여기서 BeginPaint는 DC 핸들을 얻는데 사용한다. ps는 PAINTSTRUCT의 구조체로 그리기 위한 정보를 가지고 있는 구조체로 선의 굵기, 선의 색상등을 설정해서 사용할 수 도 있다.


 EndPaint라는 것은 hdc를 사용하는 것을 종료시키는 것이다.

Posted by JunkMam
,

 윈도우에서 처리하는 클라이언트의 색깔을 설정하고, 수정할 수 있다.


 처음 설정하는 것에서 본다면, 다음과 같은 방법으로 설정을 하게 된다.

 

1
    WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
cs


 이렇게 GetStockObject라는 것을 이용해서 BRUSH 핸들을 가지고오게 만들어서 값을 변경 시킨다.


 GetStockObject 함수는 그래픽 객체 함수로 펜, 브러시, 폰트, 팔렛트 등의 객체 핸들을 얻는 함수이다.

 

 참조 : https://msdn.microsoft.com/ko-kr/library/windows/desktop/dd144925(v=vs.85).aspx


 해당 함수의 값을 이용해서 글꼴등을 설정할 수 있다.


 CreateHatchBrush는 브러시 객체를 만들어 낸다.


 참조 : https://msdn.microsoft.com/ko-kr/library/windows/desktop/dd183504(v=vs.85).aspx


 검은색 브러쉬 예제로 작성한다.


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <stdlib.h>
 
#include <tchar.h>
#include <windows.h>
 
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
 
WNDCLASS WndClass;
 
int WINAPI WinMain(HINSTANCE hInstance,
            HINSTANCE hPrevInstance,
            LPSTR lpszCmdParam,
            int nCmdShow)
{
    HWND hWnd;
    MSG Message;
    g_hInst = hInstance;
    
    //윈도우 클래스 초기화
    WndClass.cbClsExtra=0;
    WndClass.cbWndExtra=0;
    WndClass.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    WndClass.hInstance=hInstance;
    WndClass.lpfnWndProc=(WNDPROC)WndProc;
    WndClass.lpszClassName="ApiBase";
    WndClass.lpszMenuName=NULL;
    WndClass.style=CS_HREDRAW|CS_VREDRAW;
 
    //윈도우 클래스 생성.
    RegisterClass(&WndClass);
    
    //윈도우 객체 생성.
    hWnd = CreateWindow("ApiBase",
                        "Test",
                        WS_OVERLAPPEDWINDOW,
                        10,// X
                        100,// Y
                        400,// Width
                        400,// Height
                        NULL,
                        (HMENU)NULL,
                        hInstance,
                        NULL);
    
    //윈도우 창 띄우기.
    ShowWindow(hWnd,nCmdShow);
    
    while(GetMessage(&Message,0,0,0))
    {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }
    
    return Message.wParam;
}
 
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    long dwStyle;
    
    switch(iMessage)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        case WM_LBUTTONDOWN:
            break;
        case WM_PAINT:
            hdc = GetDC(hWnd);
            TextOut(hdc, 10050"Hello World",11);
            ReleaseDC(hWnd, hdc);
            break;
    }
    return DefWindowProc(hWnd,iMessage,wParam, lParam);
}
 
cs


Posted by JunkMam
,

 윈도우 창에 있는 타이틀 처리 방법..


 생성시 타이틀 설정.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <stdlib.h>
 
#include <tchar.h>
#include <windows.h>
 
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
 
int WINAPI WinMain(HINSTANCE hInstance,
            HINSTANCE hPrevInstance,
            LPSTR lpszCmdParam,
            int nCmdShow)
{
    HWND hWnd;
    MSG Message;
    WNDCLASS WndClass;
    g_hInst = hInstance;
    
    //윈도우 클래스 초기화
    WndClass.cbClsExtra=0;
    WndClass.cbWndExtra=0;
    WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    WndClass.hInstance=hInstance;
    WndClass.lpfnWndProc=(WNDPROC)WndProc;
    WndClass.lpszClassName="ApiBase";
    WndClass.lpszMenuName=NULL;
    WndClass.style=CS_HREDRAW|CS_VREDRAW;
 
    //윈도우 클래스 생성.
    RegisterClass(&WndClass);
    
    //윈도우 객체 생성.
    hWnd = CreateWindow("ApiBase",
                        "Test",
                        WS_OVERLAPPEDWINDOW,
                        10,// X
                        100,// Y
                        400,// Width
                        400,// Height
                        NULL,
                        (HMENU)NULL,
                        hInstance,
                        NULL);
    
    //윈도우 창 띄우기.
    ShowWindow(hWnd,nCmdShow);
    
    while(GetMessage(&Message,0,0,0))
    {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }
    
    return Message.wParam;
}
 
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    long dwStyle;
    
    switch(iMessage)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        case WM_LBUTTONDOWN:
            
            MoveWindow(hWnd, LOWORD(lParam),HIWORD(lParam), 5005001);
            
            break;
    }
    return DefWindowProc(hWnd,iMessage,wParam, lParam);
}
 
cs


 왼쪽 버튼을 클릭하면, 타이틀을 변경하길 원한다면, 다음 같이 한다.


 참조 : https://msdn.microsoft.com/en-us/library/windows/desktop/ms633546(v=vs.85).aspx


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <stdlib.h>
 
#include <tchar.h>
#include <windows.h>
 
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
 
int WINAPI WinMain(HINSTANCE hInstance,
            HINSTANCE hPrevInstance,
            LPSTR lpszCmdParam,
            int nCmdShow)
{
    HWND hWnd;
    MSG Message;
    WNDCLASS WndClass;
    g_hInst = hInstance;
    
    //윈도우 클래스 초기화
    WndClass.cbClsExtra=0;
    WndClass.cbWndExtra=0;
    WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    WndClass.hInstance=hInstance;
    WndClass.lpfnWndProc=(WNDPROC)WndProc;
    WndClass.lpszClassName="ApiBase";
    WndClass.lpszMenuName=NULL;
    WndClass.style=CS_HREDRAW|CS_VREDRAW;
 
    //윈도우 클래스 생성.
    RegisterClass(&WndClass);
    
    //윈도우 객체 생성.
    hWnd = CreateWindow("ApiBase",
                        "Test",
                        WS_OVERLAPPEDWINDOW,
                        10,// X
                        100,// Y
                        400,// Width
                        400,// Height
                        NULL,
                        (HMENU)NULL,
                        hInstance,
                        NULL);
    
    //윈도우 창 띄우기.
    ShowWindow(hWnd,nCmdShow);
    
    while(GetMessage(&Message,0,0,0))
    {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }
    
    return Message.wParam;
}
 
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    long dwStyle;
    
    switch(iMessage)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        case WM_LBUTTONDOWN:
            SetWindowText(hWnd, "WWW");
            break;
    }
    return DefWindowProc(hWnd,iMessage,wParam, lParam);
}
 
cs



 타이틀의 변경을 할 수 있게 된다.

Posted by JunkMam
,

 윈도우가 출력하는 사이즈 및 위치를 정의 할 수 있다.

 프로그램은 사각형을 만드는 방법을 총 2가지 방법이 있다.


 1. 두점을 알고 있을 경우.

 2. 한 점을 알고, 크기를 알고 있을 경우.


 1.은 사각형의 점으로 왼측 상단의 점과 우측 하단의 점 두개의 점을 알고 있다면, 쉽게 사각형을 만들 수 있다. (사각형을 그리는 프로그래밍을 할때, 사용한다.)


 2.는 기준이 되는 사각형의 점 1개를 만들고, 나머지는 넓이와 높이를 가지는 값을 가진다.


 1이든 2이든 모든 값은 4개씩 필요하다.(평면의 독립변수는 {x, y}로 2개이다.)


 윈도우 출력은 2.을 기준으로 작업한다.


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <stdlib.h>
 
#include <tchar.h>
#include <windows.h>
 
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
 
int WINAPI WinMain(HINSTANCE hInstance,
            HINSTANCE hPrevInstance,
            LPSTR lpszCmdParam,
            int nCmdShow)
{
    HWND hWnd;
    MSG Message;
    WNDCLASS WndClass;
    g_hInst = hInstance;
    
    //윈도우 클래스 초기화
    WndClass.cbClsExtra=0;
    WndClass.cbWndExtra=0;
    WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    WndClass.hInstance=hInstance;
    WndClass.lpfnWndProc=(WNDPROC)WndProc;
    WndClass.lpszClassName="ApiBase";
    WndClass.lpszMenuName=NULL;
    WndClass.style=CS_HREDRAW|CS_VREDRAW;
 
    //윈도우 클래스 생성.
    RegisterClass(&WndClass);
    
    //윈도우 객체 생성.
    hWnd = CreateWindow("ApiBase",
                        "ApiBase",
                        WS_OVERLAPPEDWINDOW,
                        10,// X
                        100,// Y
                        400,// Width
                        400,// Height
                        NULL,
                        (HMENU)NULL,
                        hInstance,
                        NULL);
    
    //윈도우 창 띄우기.
    ShowWindow(hWnd,nCmdShow);
    
    while(GetMessage(&Message,0,0,0))
    {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }
    
    return Message.wParam;
}
 
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    long dwStyle;
    
    switch(iMessage)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        case WM_LBUTTONDOWN:
            dwStyle = GetWindowLong(hWnd, GWL_STYLE);//현재 윈도우 스타일 받아들이기.
            dwStyle = dwStyle | WS_HSCROLL;
            SetWindowLong(hWnd, GWL_STYLE, dwStyle);
            break;
    }
    return DefWindowProc(hWnd,iMessage,wParam, lParam);
}
 
cs



 전과 다른 점은 기존 값을 가지고 처리하는 것이 아니라, 값을 정의해서 처리하는 것이다.


 X,Y, Width, Height로 나뉘고, 위치와 크기를 조절 할 수 있다.


 유동적으로 크기를 조절하는 경우는 다음과 같은 소스로 고치면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <stdlib.h>
 
#include <tchar.h>
#include <windows.h>
 
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
 
int WINAPI WinMain(HINSTANCE hInstance,
            HINSTANCE hPrevInstance,
            LPSTR lpszCmdParam,
            int nCmdShow)
{
    HWND hWnd;
    MSG Message;
    WNDCLASS WndClass;
    g_hInst = hInstance;
    
    //윈도우 클래스 초기화
    WndClass.cbClsExtra=0;
    WndClass.cbWndExtra=0;
    WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    WndClass.hInstance=hInstance;
    WndClass.lpfnWndProc=(WNDPROC)WndProc;
    WndClass.lpszClassName="ApiBase";
    WndClass.lpszMenuName=NULL;
    WndClass.style=CS_HREDRAW|CS_VREDRAW;
 
    //윈도우 클래스 생성.
    RegisterClass(&WndClass);
    
    //윈도우 객체 생성.
    hWnd = CreateWindow("ApiBase",
                        "ApiBase",
                        WS_OVERLAPPEDWINDOW,
                        10,// X
                        100,// Y
                        400,// Width
                        400,// Height
                        NULL,
                        (HMENU)NULL,
                        hInstance,
                        NULL);
    
    //윈도우 창 띄우기.
    ShowWindow(hWnd,nCmdShow);
    
    while(GetMessage(&Message,0,0,0))
    {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }
    
    return Message.wParam;
}
 
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    long dwStyle;
    
    switch(iMessage)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        case WM_LBUTTONDOWN:
            
            MoveWindow(hWnd, LOWORD(lParam),HIWORD(lParam), 5005001);
            
            break;
    }
    return DefWindowProc(hWnd,iMessage,wParam, lParam);
}
 
cs



 다음과 같이 하면, 클릭시 크기가 변하면서 이동할 것이다.


 lParam에서 마우스 클릭한 위치를 저장하고 있기 때문에, X와 Y가 들어가 있다.

 X, Y에 맞춰서 이동되기 때문에 클릭시 이동하는 현상이 있다.


 이 이동이 없길 원한다면, GetWindowRect()이라는 걸 이용해서 X, Y을 찾아 줘야한다.


 참조 : https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms633519.aspx


 Client(내부 윈도우)는 GetClientRect()을 이용해서 사용한다.

Posted by JunkMam
,

 Windows에서 Frame이 화면에 띄워지는 형태를 다양하게 정할 수 있다.


 이것을 Window Style이라고 하고, Style의 종류는 다음을 참조하면 알 수 있다.


 참조 : https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms632600(v=vs.85).aspx


 Windows의 스타일은 2가지로 개발 할 수 있는데, 첫번째로 Window 객체를 만들때 정의를 내릴 수 있다.


 객체를 만들때는 CreateWindow라는 함수를 사용하는데. 여기서 스타일을 적용할때, 저잘하는 방식을 bitdata형태로 저장한다.


 쉽게 말해서 이진법으로 되어있는 데이터들로 처리한다는 것이다.


 예을 들어서 이진수 4자리는 0000이 된다.

 여기서 첫번째 자리는 세로 스크롤바. 두번째 자리는 가로 스크롤바. 세번째 자리는 최소화 버튼 활성화. 네번째 자리는 타이틀바 존재 유무.


 이런식으로 각 자리에 대한 뜻이 존재하고, 0은 off/ 1은 on 이라는 식으로 관리하게 된다.


 이렇게 할 경우에 or 연산을 붙이게 되면 원하는 속성을 정할 수 있게 되기 때문에 개발의 편의성이 존재한다.


 맨 처음 글에서 사용되느 소스를 보면 알 수 가 있다.


1
2
3
4
5
6
7
8
9
10
11
    hWnd = CreateWindow("ApiBase",
                        "ApiBase",
                        WS_OVERLAPPEDWINDOW | WS_HSCROLL,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        NULL,
                        (HMENU)NULL,
                        hInstance,
                        NULL);
cs


 여기서 WS_OVERLAPPDWINDOW 것과 WS_HSCROLL이라는 스타일을 정할 수 있다.

 이렇게 해서 HSCROLL(수평 스크롤)을 정할 수 있게 되는 것으며, 결과로 스크롤 바가 나오는 것을 알 수 있다.


 하지만, 이 방법은 윈도우 객체가 만들어질때 사용하는 방법이다.


 그러면, 중간에 윈도우 스타일을 바꾸고 싶어지면, 어떻게 해야될까?


 Windows에서는 다음과 같은 함수를 지원해 준다.


 GetWindowLong(), SetWindowLong()


 이 두 함수는 WIndow에 대한 정보를 받아들이고/수정하는 용도로 사용하는 함수이다. 즉, 스타일만 수정하는 함수가 아니다.


 참조 :

 GetWindowLong -> https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms633584(v=vs.85).aspx


 SetWindowLong -> https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms633591(v=vs.85).aspx



 여기서 GWL_EXSTYLE라는 것을 SetWindowLong에 사용하게 되면, 스타일에 관련된 정보를 수정할 수 있게 된다.


 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <stdlib.h>
 
#include <tchar.h>
#include <windows.h>
 
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
 
int WINAPI WinMain(HINSTANCE hInstance,
            HINSTANCE hPrevInstance,
            LPSTR lpszCmdParam,
            int nCmdShow)
{
    HWND hWnd;
    MSG Message;
    WNDCLASS WndClass;
    g_hInst = hInstance;
    
    //윈도우 클래스 초기화
    WndClass.cbClsExtra=0;
    WndClass.cbWndExtra=0;
    WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    WndClass.hInstance=hInstance;
    WndClass.lpfnWndProc=(WNDPROC)WndProc;
    WndClass.lpszClassName="ApiBase";
    WndClass.lpszMenuName=NULL;
    WndClass.style=CS_HREDRAW|CS_VREDRAW;
 
    //윈도우 클래스 생성.
    RegisterClass(&WndClass);
    
    //윈도우 객체 생성.
    hWnd = CreateWindow("ApiBase",
                        "ApiBase",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        NULL,
                        (HMENU)NULL,
                        hInstance,
                        NULL);
    
    //윈도우 창 띄우기.
    ShowWindow(hWnd,nCmdShow);
    
    while(GetMessage(&Message,0,0,0))
    {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }
    
    return Message.wParam;
}
 
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    long dwStyle;
    
    switch(iMessage)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        case WM_LBUTTONDOWN:
            dwStyle = GetWindowLong(hWnd, GWL_STYLE);//현재 윈도우 스타일 받아들이기.
            dwStyle = dwStyle | WS_HSCROLL;
            SetWindowLong(hWnd, GWL_STYLE, dwStyle);
            break;
    }
    return DefWindowProc(hWnd,iMessage,wParam, lParam);
}
 
cs


이렇게 하면, 좌 클릭시 수평 스크롤이 완성되는걸 알 수 있다.

Posted by JunkMam
,