티스토리 뷰

190702-4
 
교육을 받으면서 노트필기 했던 내용을 날것 그대로 업로드합니다.

 
worker 쓰레드
UI 쓰레드
#include <windows.h>
#include <TCHAR.H>
 
DWORD __stdcall DrawThread(LPVOID pParam);
DWORD __stdcall UIThread(LPVOID pParam);
 
 
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg,
    WPARAM wParam, LPARAM lParam);
 
LRESULT CALLBACK ChildProc(HWND hwnd, UINT iMsg,
    WPARAM wParam, LPARAM lParam);
 
HINSTANCE g_hInst;
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpszCmdLine, int nCmdShow)
{
    g_hInst = hInstance;
 
    HWND hwnd;
    MSG      msg;
    WNDCLASS WndClass;
    WndClass.style = CS_HREDRAW | CS_VREDRAW;
    WndClass.lpfnWndProc = WndProc;
    WndClass.cbClsExtra = 0;
    WndClass.cbWndExtra = 0;
    WndClass.hInstance = hInstance;
    WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClass.lpszMenuName = NULL;
    WndClass.lpszClassName = _T("Window Class Name");
    RegisterClass(&WndClass);
 
    WndClass.lpfnWndProc = ChildProc;
    WndClass.lpszClassName = _T("ChildWindow");
    RegisterClass(&WndClass);
 
    hwnd = CreateWindow(_T("Window Class Name"),
        _T("Window Title Name"),
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL
    );
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return (int)msg.wParam;
}
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg,
    WPARAM wParam, LPARAM lParam)
{
    static HANDLE hThread;
    static DWORD threadID;
    switch (iMsg)
    {
    case WM_CREATE:
        hThread = CreateThread(NULL, 0, DrawThread, hwnd, 0, &threadID);
 
        break;
    case WM_LBUTTONDOWN:
        CloseHandle(CreateThread(NULL, 0, UIThread, hwnd, 0, &threadID));
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        CloseHandle(hThread);
        break;
    }
    return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
DWORD __stdcall DrawThread(LPVOID pParam) { // Worker 쓰레드 라고한다.
    HWND hwnd = (HWND)pParam;
    HDC hdc = GetDC(hwnd);
 
    for (int i = 0; i < 100; i++)
    {
        Rectangle(hdc, 100 + i, 100, 200 + i, 200);
        Sleep(20);
    }
 
    ReleaseDC(hwnd, hdc);
 
    return 0;
}
LRESULT CALLBACK ChildProc(HWND hwnd, UINT iMsg,
    WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    switch (iMsg)
    {
    case WM_LBUTTONDOWN:
        hdc = GetDC(hwnd);
        Rectangle(hdc, LOWORD(lParam), HIWORD(lParam), LOWORD(lParam) + 50, HIWORD(lParam) + 50);
        ReleaseDC(hwnd, hdc);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }
    return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
DWORD __stdcall UIThread(LPVOID pParam) { // UI 쓰레드 라고 한다.
 
    HWND hwndParent=(HWND)pParam;
    HWND hwndChild;
    MSG      msg;
 
 
    hwndChild = CreateWindow(_T("ChildWindow"),
        _T("Child Window !!"),
        WS_OVERLAPPEDWINDOW|WS_CHILD,
        100,
        100,
        300,
        300,
        hwndParent,
        (HMENU)1,
        g_hInst,
        NULL
    );
    ShowWindow(hwndChild, SW_SHOW);
    //UpdateWindow(hwndChild);
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return (int)msg.wParam;
 
    return 0;
}
 
#include <windows.h>
#include <TCHAR.H>
#include <vector>
using namespace std;
 
struct TP { // 쓰레드 파라미터
    HWND hwnd;
    POINT pt; // 클릭한 좌표
};
 
DWORD __stdcall DrawThread(LPVOID pParam);
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg,
    WPARAM wParam, LPARAM lParam);
 
HINSTANCE g_hInst;
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpszCmdLine, int nCmdShow)
{
    g_hInst = hInstance;
 
    HWND hwnd;
    MSG      msg;
    WNDCLASS WndClass;
    WndClass.style = CS_HREDRAW | CS_VREDRAW;
    WndClass.lpfnWndProc = WndProc;
    WndClass.cbClsExtra = 0;
    WndClass.cbWndExtra = 0;
    WndClass.hInstance = hInstance;
    WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClass.lpszMenuName = NULL;
    WndClass.lpszClassName = _T("Window Class Name");
    RegisterClass(&WndClass);
 
    hwnd = CreateWindow(_T("Window Class Name"),
        _T("Window Title Name"),
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL
    );
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return (int)msg.wParam;
}
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg,
    WPARAM wParam, LPARAM lParam)
{
    static vector<HANDLE> threadList;
    TP* p;
    HANDLE hThread;
    static DWORD threadID;
    switch (iMsg)
    {
    case WM_CREATE:
        break;
    case WM_LBUTTONDOWN: {
        p = new TP; // heap 메모리에 할당에서 주소를 전달하면 해결 할 수 있다.
        TP& tp = *p;
        tp.hwnd = hwnd;
        tp.pt.x = LOWORD(lParam);
        tp.pt.y = HIWORD(lParam);
 
        hThread = CreateThread(NULL, 0, DrawThread, &tp, 0, &threadID);
        threadList.push_back(hThread);
    }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        for (unsigned i = 0; i < threadList.size(); i++)
            CloseHandle(threadList[i]);
        break;
    }
    return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
DWORD __stdcall DrawThread(LPVOID pParam) { // Worker 쓰레드 라고한다.
    Sleep(1000); // 공유 변수를 쓰게 되면 값을 늦게 가져와서 마우스 클릭이 더 빨랐을 경우 문제가 발생한다 (같은 좌표에 그림)
    TP* p = (TP*)pParam;
    HWND hwnd = p->hwnd;
    HDC hdc = GetDC(hwnd);
    POINT pt = p->pt;
    while (1) {
        for (int i = 0; i < 100; i += 5)
        {
            Rectangle(hdc, pt.x, pt.y, pt.x + i, pt.y + i);
            Sleep(40);
        }
    }
    delete p;
    ReleaseDC(hwnd, hdc);
    return 0;
}
 
 
오른쪽 마우스로 정지했다가 다시 시작하는 프로그램
#include <windows.h>
#include <TCHAR.H>
#include <vector>
using namespace std;
 
struct TP { // 쓰레드 파라미터
    HWND hwnd;
    POINT pt; // 클릭한 좌표
};
 
DWORD __stdcall DrawThread(LPVOID pParam);
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg,
    WPARAM wParam, LPARAM lParam);
 
HINSTANCE g_hInst;
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpszCmdLine, int nCmdShow)
{
    g_hInst = hInstance;
 
    HWND hwnd;
    MSG      msg;
    WNDCLASS WndClass;
    WndClass.style = CS_HREDRAW | CS_VREDRAW;
    WndClass.lpfnWndProc = WndProc;
    WndClass.cbClsExtra = 0;
    WndClass.cbWndExtra = 0;
    WndClass.hInstance = hInstance;
    WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClass.lpszMenuName = NULL;
    WndClass.lpszClassName = _T("Window Class Name");
    RegisterClass(&WndClass);
 
    hwnd = CreateWindow(_T("Window Class Name"),
        _T("Window Title Name"),
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL
    );
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return (int)msg.wParam;
}
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg,
    WPARAM wParam, LPARAM lParam)
{
    static vector<HANDLE> threadList;
    TP* p;
    HANDLE hThread;
    static DWORD threadID;
    switch (iMsg)
    {
    case WM_CREATE:
        break;
    case WM_LBUTTONDOWN:
    {
        p = new TP;
        TP& tp = *p;
        tp.hwnd = hwnd;
        tp.pt.x = LOWORD(lParam);
        tp.pt.y = HIWORD(lParam);
 
        hThread = CreateThread(NULL, 0, DrawThread, &tp, 0, &threadID);
        threadList.push_back(hThread);
    }
    break;
    case WM_RBUTTONDOWN:
    {
        static bool brun = true;
        if (brun) {
            for (unsigned i = 0; i < threadList.size(); i++)
            {
                SuspendThread(threadList[i]); //오른쪽 마우스 클릭시 정지하도록 함
            }
            brun = false;
        }
        else {
            for (unsigned i = 0; i < threadList.size(); i++)
            {
                ResumeThread(threadList[i]);
            }
            brun = true;
        }
    }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        for (unsigned i = 0; i < threadList.size(); i++) // 얻어온 핸들 모두 닫기
            CloseHandle(threadList[i]);
        break;
    }
    return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
DWORD __stdcall DrawThread(LPVOID pParam) { // Worker 쓰레드 라고한다.
    Sleep(1000); // 공유 변수를 쓰게 되면 값을 늦게 가져와서 마우스 클릭이 더 빨랐을 경우 문제가 발생한다 (같은 좌표에 그림)
    TP* p = (TP*)pParam;
    HWND hwnd = p->hwnd;
    HDC hdc = GetDC(hwnd);
    POINT pt = p->pt;
    while (1) {
        for (int i = 0; i < 100; i += 5)
        {
            Rectangle(hdc, pt.x, pt.y, pt.x + i, pt.y + i);
            Sleep(40);
        }
    }
    delete p;
    ReleaseDC(hwnd, hdc);
    return 0;
}
댓글
댓글쓰기 폼