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;
}
'System Programming' 카테고리의 다른 글
[system programming] __declspec(thread) (0) | 2019.07.05 |
---|---|
[system programming] 핸들, 커널 오브젝트, 프로세스 등 (0) | 2019.07.04 |
[system programming] TLS, ResumeThread, nterlockedIncrement 등 (0) | 2019.07.04 |
[system programming] 커널오브젝트와 핸들, 핸들 테이블, 신호 비신호 상태, 쓰레드 등 (0) | 2019.07.04 |
[system programming] 핸들, 동기, 신호/비신호 (0) | 2019.07.03 |