190704-2 CHECKER3.C -- Mouse Hit-Test Demo Program No. 3
교육을 받으면서 노트필기 했던 내용을 날것 그대로 업로드합니다.
A
/*-------------------------------------------------
CHECKER3.C -- Mouse Hit-Test Demo Program No. 3
(c) Charles Petzold, 1998
-------------------------------------------------*/
#include <windows.h>
#pragma warning ( disable:4312)
#define DIVISIONS 3
#define WM_DRAWXMSG WM_APP+100
typedef struct _Data {
POINT pt;
int click;
} Data, *PData;
enum {CLICK, REQINIT, REPINIT};
#pragma region region
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM);
TCHAR szChildClass[] = TEXT("Checker3_Child");
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("Checker3");
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 = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("Program requires Windows NT!"),
szAppName, MB_ICONERROR);
return 0;
}
wndclass.lpfnWndProc = ChildWndProc;
wndclass.cbWndExtra = sizeof(long);
wndclass.hIcon = NULL;
wndclass.lpszClassName = szChildClass;
RegisterClass(&wndclass);
hwnd = CreateWindow(szAppName, TEXT("CopyDataA"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
#pragma endregion
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND hwndChild[DIVISIONS][DIVISIONS];
int cxBlock, cyBlock, x, y;
switch (message)
{
case WM_CREATE:
for (x = 0; x < DIVISIONS; x++)
for (y = 0; y < DIVISIONS; y++)
hwndChild[x][y] = CreateWindow(szChildClass, NULL,
WS_CHILDWINDOW | WS_VISIBLE,
0, 0, 0, 0,
hwnd, (HMENU)(y << 8 | x),
(HINSTANCE)GetWindowLong(hwnd, GWLP_HINSTANCE),
NULL);
{
HWND hRemoteHwnd = FindWindow(NULL, "CopyDataB");
if (hRemoteHwnd != NULL) { // B가 열려있으면
COPYDATASTRUCT cds{ REQINIT,0,NULL };
SendMessage(hRemoteHwnd, WM_COPYDATA, (WPARAM)hwnd, (LPARAM)& cds);
}
}
return 0;
case WM_SIZE:
cxBlock = LOWORD(lParam) / DIVISIONS;
cyBlock = HIWORD(lParam) / DIVISIONS;
for (x = 0; x < DIVISIONS; x++)
for (y = 0; y < DIVISIONS; y++)
MoveWindow(hwndChild[x][y],
x * cxBlock, y * cyBlock,
cxBlock, cyBlock, TRUE);
return 0;
case WM_LBUTTONDOWN:
MessageBeep(0);
return 0;
case WM_COPYDATA:
{
PCOPYDATASTRUCT pcds = (PCOPYDATASTRUCT)lParam; // 끝나기 전 까지만 유효함
switch (pcds->dwData) {
case CLICK:
{
Data data = *(Data*)pcds->lpData;
HWND hChild = GetDlgItem(hwnd, MAKEWORD(data.pt.x, data.pt.y));
SetWindowLong(hChild, 0, data.click);
InvalidateRect(hwnd, NULL, TRUE);
}
break;
case REQINIT:
{
Data pdata[DIVISIONS][DIVISIONS];
for (int x = 0; x < DIVISIONS; ++x) {
for (int y = 0; y < DIVISIONS; ++y)
{
pdata[x][y].pt.x = LOBYTE(GetWindowLong(hwndChild[x][y], GWLP_ID));
pdata[x][y].pt.y = HIBYTE(GetWindowLong(hwndChild[x][y], GWLP_ID));
pdata[x][y].click = GetWindowLong(hwndChild[x][y], 0);
}
}
COPYDATASTRUCT cds = { REPINIT,sizeof(Data) * DIVISIONS * DIVISIONS,(LPVOID)pdata };
SendMessage((HWND)wParam, WM_COPYDATA, (WPARAM)hwnd, (LPARAM)& cds);
}
break;
case REPINIT:
{
PData pdata = (PData)pcds->lpData;
//9개의 _Data가 날라온다.
for (int i = 0; i < DIVISIONS * DIVISIONS; i++)
{
DWORD winId = MAKEWORD(pdata[i].pt.x, pdata[i].pt.y);
HWND hChild = GetDlgItem(hwnd, winId);
SetWindowLong(hChild, 0, pdata[i].click); // 엑스트라정보(클릭정보)를 설정한다.
InvalidateRect(hwnd, NULL, TRUE); // 다시그린다.
}
}
break;
}
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
switch (message)
{
case WM_CREATE:
SetWindowLong(hwnd, 0, 0); // on/off flag
return 0;
case WM_DRAWXMSG:
{
HWND hRemoteHwnd = FindWindow(NULL, ("CopyDataB"));
if (hRemoteHwnd != NULL) {
COPYDATASTRUCT cds = { 100,7, (PVOID)"Hello!" };
SendMessage(hRemoteHwnd, WM_COPYDATA, (WPARAM)hwnd, (LPARAM)& cds);
}
}
break;
case WM_LBUTTONDOWN:
SetWindowLong(hwnd, 0, 1 ^ GetWindowLong(hwnd, 0));
{
int x = LOBYTE(LOWORD(GetWindowLong(hwnd, GWLP_ID))); // 내 윈도우의 아이디 값을 얻어온다.
int y = HIBYTE(LOWORD(GetWindowLong(hwnd, GWLP_ID)));
HWND hRemoteHwnd = FindWindow(NULL, ("CopyDataB"));
if (hRemoteHwnd != NULL) {
Data data = { {x,y},GetWindowLong(hwnd,0) };
COPYDATASTRUCT cds = { CLICK,sizeof(data), (LPVOID)&data };
SendMessage(hRemoteHwnd, WM_COPYDATA, (WPARAM)hwnd, (LPARAM)& cds);
}
}
InvalidateRect(hwnd, NULL, FALSE);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rect);
Rectangle(hdc, 0, 0, rect.right, rect.bottom);
if (GetWindowLong(hwnd, 0))
{
MoveToEx(hdc, 0, 0, NULL);
LineTo(hdc, rect.right, rect.bottom);
MoveToEx(hdc, 0, rect.bottom, NULL);
LineTo(hdc, rect.right, 0);
}
EndPaint(hwnd, &ps);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
B
/*-------------------------------------------------
CHECKER3.C -- Mouse Hit-Test Demo Program No. 3
(c) Charles Petzold, 1998
-------------------------------------------------*/
#include <windows.h>
#pragma warning ( disable:4312)
#define DIVISIONS 3
#define WM_DRAWXMSG WM_APP+100
typedef struct _Data {
POINT pt;
int click;
} Data, * PData;
enum { CLICK , REQINIT, REPINIT};
#pragma region region
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM);
TCHAR szChildClass[] = TEXT("Checker3_Child");
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("Checker3");
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 = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("Program requires Windows NT!"),
szAppName, MB_ICONERROR);
return 0;
}
wndclass.lpfnWndProc = ChildWndProc;
wndclass.cbWndExtra = sizeof(long);
wndclass.hIcon = NULL;
wndclass.lpszClassName = szChildClass;
RegisterClass(&wndclass);
hwnd = CreateWindow(szAppName, TEXT("CopyDataB"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
#pragma endregion
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND hwndChild[DIVISIONS][DIVISIONS];
int cxBlock, cyBlock, x, y;
switch (message)
{
case WM_CREATE:
for (x = 0; x < DIVISIONS; x++)
for (y = 0; y < DIVISIONS; y++)
hwndChild[x][y] = CreateWindow(szChildClass, NULL,
WS_CHILDWINDOW | WS_VISIBLE,
0, 0, 0, 0,
hwnd, (HMENU)(y << 8 | x),
(HINSTANCE)GetWindowLong(hwnd, GWLP_HINSTANCE),
NULL);
{
HWND hRemoteHwnd = FindWindow(NULL, "CopyDataA");
if (hRemoteHwnd != NULL) { // A가 열려있으면
COPYDATASTRUCT cds{ REQINIT,0,NULL };
SendMessage(hRemoteHwnd, WM_COPYDATA, (WPARAM)hwnd, (LPARAM)& cds);
}
}
return 0;
case WM_SIZE:
cxBlock = LOWORD(lParam) / DIVISIONS;
cyBlock = HIWORD(lParam) / DIVISIONS;
for (x = 0; x < DIVISIONS; x++)
for (y = 0; y < DIVISIONS; y++)
MoveWindow(hwndChild[x][y],
x * cxBlock, y * cyBlock,
cxBlock, cyBlock, TRUE);
return 0;
case WM_LBUTTONDOWN:
MessageBeep(0);
return 0;
case WM_COPYDATA:
{
PCOPYDATASTRUCT pcds = (PCOPYDATASTRUCT)lParam; // 끝나기 전 까지만 유효함
switch (pcds->dwData) {
case CLICK:
{
Data data = *(Data*)pcds->lpData;
HWND hChild = GetDlgItem(hwnd, MAKEWORD(data.pt.x, data.pt.y));
SetWindowLong(hChild, 0, data.click);
InvalidateRect(hwnd, NULL, TRUE);
}
break;
case REQINIT:
{
Data pdata[DIVISIONS][DIVISIONS];
for (int x = 0; x < DIVISIONS; ++x) {
for (int y = 0; y < DIVISIONS; ++y)
{
pdata[x][y].pt.x = LOBYTE(GetWindowLong(hwndChild[x][y], GWLP_ID));
pdata[x][y].pt.y = HIBYTE(GetWindowLong(hwndChild[x][y], GWLP_ID));
pdata[x][y].click = GetWindowLong(hwndChild[x][y], 0);
}
}
COPYDATASTRUCT cds = { REPINIT,sizeof(Data) * DIVISIONS * DIVISIONS,(LPVOID)pdata };
SendMessage((HWND)wParam, WM_COPYDATA, (WPARAM)hwnd, (LPARAM)& cds);
}
break;
case REPINIT:
{
PData pdata = (PData)pcds->lpData;
//9개의 _Data가 날라온다.
for (int i = 0; i < DIVISIONS*DIVISIONS; i++)
{
DWORD winId = MAKEWORD(pdata[i].pt.x, pdata[i].pt.y);
HWND hChild = GetDlgItem(hwnd, winId);
SetWindowLong(hChild, 0, pdata[i].click); // 엑스트라정보(클릭정보)를 설정한다.
InvalidateRect(hwnd, NULL, TRUE); // 다시그린다.
}
}
break;
}
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
switch (message)
{
case WM_CREATE:
SetWindowLong(hwnd, 0, 0); // on/off flag
return 0;
case WM_DRAWXMSG:
{
HWND hRemoteHwnd = FindWindow(NULL, ("CopyDataB"));
if (hRemoteHwnd != NULL) {
COPYDATASTRUCT cds = { 100,7, (PVOID)"Hello!" };
SendMessage(hRemoteHwnd, WM_COPYDATA, (WPARAM)hwnd, (LPARAM)& cds);
}
}
break;
case WM_LBUTTONDOWN:
SetWindowLong(hwnd, 0, 1 ^ GetWindowLong(hwnd, 0));
{
int x = LOBYTE(LOWORD(GetWindowLong(hwnd, GWLP_ID))); // 내 윈도우의 아이디 값을 얻어온다.
int y = HIBYTE(LOWORD(GetWindowLong(hwnd, GWLP_ID)));
HWND hRemoteHwnd = FindWindow(NULL, ("CopyDataA"));
if (hRemoteHwnd != NULL) {
Data data = { {x,y},GetWindowLong(hwnd,0) };
COPYDATASTRUCT cds = { CLICK,sizeof(data), (LPVOID)& data };
SendMessage(hRemoteHwnd, WM_COPYDATA, (WPARAM)hwnd, (LPARAM)& cds);
}
}
InvalidateRect(hwnd, NULL, FALSE);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rect);
Rectangle(hdc, 0, 0, rect.right, rect.bottom);
if (GetWindowLong(hwnd, 0))
{
MoveToEx(hdc, 0, 0, NULL);
LineTo(hdc, rect.right, rect.bottom);
MoveToEx(hdc, 0, rect.bottom, NULL);
LineTo(hdc, rect.right, 0);
}
EndPaint(hwnd, &ps);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
'System Programming' 카테고리의 다른 글
[system programming] 메일슬롯(Mailslot), FileMapping, UnmapViewOfFile (0) | 2019.07.07 |
---|---|
[system programming] 파이프, 양방향 이름있는 파이프(named pipe) (0) | 2019.07.06 |
[system programming] IPC 메세지, COPYDATASTRUCT (0) | 2019.07.05 |
[system programming] 플래그, 자원 관리 클래스 (0) | 2019.07.05 |
[system programming] 유저, 커널모드 동기화 (크리티컬 섹션, 뮤텍스, 세마포어, 이벤트 등) (0) | 2019.07.05 |