교내 전공과목인 윈도우즈 API수업을 정리합니다
* 참고용 주소: http://www.soen.kr/lecture/win32api/reference/Function/Alphabetic.htm
1. ButtonSubClassing
드디어 VS 2013버전으로 바꿨다. button반응에 대한 SubSystemClassing을 하자
(0). 프로펄티 설정
문자집합 설정해주기(Character set > user multi-Byte 선택
(1). 소스코드
/* 헤더파일 */
#include <string>
#define WM_SORI WM_USER +1// WM_SORI = 0x401값을 가지는 메시지임을 정의. (WM_USER가 0x400값임)
/* 필요한 변수 */
HWND hButton, hWndSori; //버튼 핸들
WNDPROC OldButtonProc;
char buffer[20]; // 출력할 문구 공간
/* ButtonSubProc */
LRESULT CALLBACK ButtonSubProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam){
switch (iMessage){
case WM_LBUTTONDOWN:
CallWindowProc(OldButtonProc, hWnd, iMessage, wParam, lParam);
hWndSori = FindWindow(NULL, TEXT("UserMes")); //캡션이 UserMes인 Window를 찾는다
if (hWndSori == NULL){
MessageBox(hWnd, TEXT(" 상대프로그램이 존재하지 않습니다."),
TEXT("이런!"), MB_OK);
}
else{
int ret = SendMessage(hWndSori, WM_SORI, 0, 0);
sprintf(buffer, "%d", ret);
SetFocus(NULL); // Focus를 없앤다, 없애지 않으면 모든 메시지는 hButton으로 전달된다
//hWndSori 윈도우의 윈도우 프록시져를 호출한다
}
return 0; // 즉, break
}
return CallWindowProc(OldButtonProc, hWnd, iMessage, wParam, lParam);
}
/* WndProc > case WM_CREATE */
hButton = CreateWindow(TEXT("button"), TEXT("Click me"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 10, 10, 200, 25, hWnd, (HMENU)101, g_hInst, NULL);
OldButtonProc = (WNDPROC)SetWindowLongPtr(hButton, GWLP_WNDPROC, (LONG_PTR)ButtonSubProc);
break;
/* WndProc > case WM_PAINT */
hdc = BeginPaint(hWnd, &ps);
TextOut(hdc, 50, 50, Mes, lstrlen(Mes));
TextOut(hdc, 50, 100, TEXT(buffer), lstrlen(buffer));
EndPaint(hWnd, &ps);
return 0;
(2). 실행결과
좌측창에서 버튼 누르면 우측창에서 반응함
2. ButtonSubClassing2
UserMes에서 리턴값을 가져와 출력하는 기능을 추가해보자
(1). 소스코드
//UserMes에서 리턴값 가져오기 위한 추가 변수
int ret;
HWND hStatic;//출력할 레이블 핸들
//SubProc작성
LRESULT CALLBACK ButtonSubProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam){
TCHAR buffer[20]; // 출력 문구 공간을 이번에는 내부에다 선언
switch (iMessage){
case WM_LBUTTONDOWN:
CallWindowProc(OldButtonProc, hWnd, iMessage, wParam, lParam);
hWndSori = FindWindow(NULL, TEXT("UserMes")); //캡션이 UserMes인 Window를 찾는다
if (hWndSori == NULL){
MessageBox(hWnd, TEXT(" 상대프로그램이 존재하지 않습니다."),
TEXT("이런!"), MB_OK);
}
else{
/* ret = SendMessage(hWndSori, WM_SORI, 0, 0); //찾으면 Message를 전달했었다
sprintf(buffer, "%d", ret);
SetFocus(NULL); // Focus를 없앤다, 없애지 않으면 모든 메시지는 hButton으로 전달된다
hWndSori 윈도우의 윈도우 프록시져를 호출한다 */
ret = PostMessage(hWndSori, WM_SORI, 0, 0);
wsprintf(buffer, TEXT("리턴값: %d"), ret);
SetWindowText(hStatic, buffer);
}
return 0; // 즉, break
}
return CallWindowProc(OldButtonProc, hWnd, iMessage, wParam, lParam);
}
// WndProc > WM_CREATE
case WM_CREATE:
hButton = CreateWindow(TEXT("button"), TEXT("Click me"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 10, 10, 200, 25, hWnd, (HMENU)101, g_hInst, NULL);
OldButtonProc = (WNDPROC)SetWindowLongPtr(hButton, GWLP_WNDPROC, (LONG_PTR)ButtonSubProc);
//레이블 컨트롤 작성
hStatic = CreateWindow(TEXT("static"), TEXT("-"), WS_CHILD | WS_VISIBLE, 10, 100, 200, 25, hWnd, (HMENU)102, g_hInst, NULL);
break;
(2). 실행결과
UserMes(좌측) 내부 코드에는 클릭이 들어오면 리턴값을 1로 보내겠다고 미리 작성했었다.
해당 값을 우측창이 출력하고 있다.
3-1. Thread를 통해 색상변화-색칠하기 작업을 하기
스레드를 통해 색상이 변해가며 색을 채우는, 다중작업을 구현하자
(1) 소스 코드
DWORD WINAPI ThreadFunc(LPVOID temp){
HDC hdc;
BYTE Blue = 0; //
HBRUSH hBrush, hOldBrush;
hdc = GetDC(hWndMain);
for (;;) {
Blue += 5;
Sleep(20);
hBrush = CreateSolidBrush(RGB(0, 0, Blue)); // rgb색상 값중 b에 대한 값만 5씩 변화하도록 함
hOldBrush = (HBRUSH)SelectObject(hdc, hBrush);
Rectangle(hdc, 10, 10, 400, 200);
SelectObject(hdc, hOldBrush);
DeleteObject(hBrush);
}
ReleaseDC(hWndMain, hdc);
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam){
DWORD ThreadID;
HANDLE hThread;
switch (iMessage) {
case WM_CREATE:
hWndMain = hWnd;
hThread = CreateThread(NULL, 0, ThreadFunc, NULL, 0, &ThreadID); //
CloseHandle(hThread); //
return TRUE;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}
- DWORD: 32비트 부호 없는 정수, LPVOID:모든 형식에 대한 포인터
- HANDLE CreateThread(
[in, optional] LPSECURITY_ATTRIBUTES lpThreadAttributes,
[in] SIZE_T dwStackSize,
[in] LPTHREAD_START_ROUTINE lpStartAddress,
[in, optional] __drv_aliasesMem LPVOID lpParameter,
[in] DWORD dwCreationFlags,
[out, optional] LPDWORD lpThreadId
);
=> 아무튼.. 프로세스에 대한 새 스레드를 생성함 - CloseHandle(HANDLE hObject)
- 열려진 핸들을 닫음, 실패시 0을 리턴(성공은 0이 아닌 값), 이 함수로 핸들을 닫는단들 스레드가 파괴되는 건 아님
(2) 실행 결과
4. RandGrp
점을 찍는 일과, 랜덤하게 사각영역을 채워나가는 일을 동시진행하도록 스레드로 설계/구현하자.
(1) 실행 결과
결과만 보고, 구현은 13주차를 정리하는 내일의 내가.