티스토리 뷰

프로그래밍/API

쓰레드 내 메시지루프

에어버스 2017. 3. 18. 23:28

쓰레드는 윈도우(UI), 메시지큐, 스택만 소유한다.

프로세스는 4GB메모리공간, 파일, 메모리, 스레드 등의 객체를 소유하며, 프로세스가 종료될때 프로세스가 소유한 모든 자원은 OS에 의해 파괴된다.

프로세스는 최소한 한개 이상의 스레드를 가진다. 프로세스와 동시에 만들어지는 스레드를 주 스레드(Primary Thread)라 한다. 하나의 프로세스는 여러개의 스레드를 가질 수 있어 멀티스레드라고 한다.

객체간의 소유 관계 : 프로세스 > 스레드 > 윈도우

- 여기서는 스레드의 메시지큐를 살펴본다.

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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
...
TCHAR Cap[256];
HWND hWndMain;
HINSTANCE g_hInstance;
DWORD WINAPI ThreadFunc(LPVOID);
LRESULT CALLBACK DeCompProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam);
...
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
...
while (GetMessage(&msg, nullptr, 00))
    {
        if (msg.message == WM_USER + 1)
        {
            MessageBox(hWndMain, L"주스레드 : 사용자 정의 메시지 얻음."NULLNULL);
        }
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
 
    return (int) msg.wParam;
}
 
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW wcex;
...
wcex.lpfnWndProc = DeCompProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = g_hInstance;
    wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = L"DeCompWnd";
    wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
 
    return RegisterClassExW(&wcex);
}
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
...
  switch (message)
    {
    case WM_USER+1:
        MessageBox(hWndMain, L"주스레드 메시지 처리함수 : 사용자 정의 메시지 얻음."NULLNULL);
        break;
    ...
    }
    return 0;
}
 
DWORD WINAPI ThreadFunc(LPVOID temp)
{
    HWND hWnd;
 
    hWnd = CreateWindow(L"DeCompWnd", L"0", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 400150, hWndMain, (HMENU)NULL, g_hInstance, NULL);
    ShowWindow(hWnd, SW_SHOW);
 
    MSG msg;
    while (GetMessage(&msg, nullptr, 00))
    {
        if(msg.message == WM_USER+1)
        {
            MessageBox(hWnd, L"스레드 : 사용자 정의 메시지 얻음."NULLNULL);
        }
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return (int)msg.wParam;
}
 
LRESULT CALLBACK DeCompProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
    
    int Value;
 
    switch (iMsg)
    {
    case WM_USER+1:
        MessageBox(hWnd, L"스레드 메시지 처리함수 : 사용자 정의 메시지 함수 호출됨"NULLNULL);
        break;
    case WM_CREATE:
        CreateWindow(L"button", L"시작", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 50809025, hWnd, (HMENU)0, g_hInstance, NULL);
        CreateWindow(L"button", L"닫기", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 250809025, hWnd, (HMENU)1, g_hInstance, NULL);
        Value = 0;
        SetProp(hWnd, L"VALUE", (HANDLE)Value);
        return 0;
    case WM_TIMER:
        Value = (int)GetProp(hWnd, L"VALUE");
        Value++;
        wsprintf(Cap, L"%d", Value);
        SetWindowText(hWnd, Cap);
        SetProp(hWnd, L"VALUE", (HANDLE)Value);
        if (Value == 0)
        {
            SetWindowText(hWnd, L"0");
            KillTimer(hWnd, 1);
            EnableWindow(GetDlgItem(hWnd, 0), FALSE);
        }
        return 0;
    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case 0:
            GetDlgItemText(hWnd, 0, Cap, 256);
            if (lstrcmp(Cap, L"시작"== 0)
            {
                SetDlgItemText(hWnd, 0, L"중지");
                SetTimer(hWnd, 1200NULL);
                PostMessage(hWnd, WM_USER + 1034567);
            }
            else
            {
                SetDlgItemText(hWnd, 0, L"시작");
                KillTimer(hWnd, 1);
            }
            
            break;
        case 1:
            DestroyWindow(hWnd);
            break;
        }
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return (DefWindowProc(hWnd, iMsg, wParam, lParam));
}
cs

 

프로그램 실행하고 메인 윈도우에서 마우스 우측버튼을 클릭하면 스레드가 생성되고 스레드에서 새 윈도우를 만든다. 스레드에서 만든 윈도우에서 시작 버튼을 누르면 사용자정의메시지(WM_USER+1)는 메인 윈도우 메시지 루프로 전달되지 않고 스레드의 메시지 큐로 전달됨을 알 수 있다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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