일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- rao
- MATLAB
- Computer Architecture
- FastAPI
- 파이토치 트랜스포머를 활용한 자연어 처리와 컴퓨터비전 심층학습
- C++
- bloc
- BFS
- pytorch
- fastapi를 사용한 파이썬 웹 개발
- Algorithm
- DART
- Widget
- ML
- system hacking
- Stream
- 백준
- llm을 활용 단어장 앱 개발일지
- Dreamhack
- 영상처리
- ARM
- study book
- BOF
- PCA
- Kaggle
- MDP
- BAEKJOON
- Flutter
- Image Processing
- Got
- Today
- Total
Bull
[C언어] 콘솔창 현재 커서의 좌표 알아내기 본문
오목을 만들기 위해 마우스 좌표값을 얻어내어 그 위치에 바둑알을 두게 하고 싶어서 인터넷을 뒤져봤다.
자료도 거의 없고 비슷한 블로그에서 따온 게 많아 계속 헤맷다. 그 중 괜찮아 보이는 녀석(코드)를 정밀하게 관찰해 보았다. 나도 역시 다른 블로그에서 가져온 코드이다. 우선, 나는 이해력이 딸리니 설명할 수 있는 녀석의 코드는 자세히 설명해보겠다.
* 필요 라이브러리 : #include <Windows.h>
#include <stdio.h>
#include <Windows.h>
typedef struct cursor {
int x;
int y;
}Cursor;
int main() {
Cursor cs;
INPUT_RECORD rc;
DWORD dw;
COORD pos={ 0,0 };
while (1) {
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
// 콘솔 입력 버퍼의 출력모드 설정
ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &rc, 1, &dw);
// 콘솔 정보 읽어들임
cs.x = rc.Event.MouseEvent.dwMousePosition.X;
cs.y = rc.Event.MouseEvent.dwMousePosition.Y;
// 마우스 위치 값
FillConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), ' ', 100, pos, &dw);
// 화면 지우기
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
// 특정위치 (0,0)에 좌표이동
printf("%d, %d\n",cs.x,cs.y );
}
}
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
콘솔의 입력 버퍼의 입력 모드나 출력모드를 설정하겠다는 뜻이다.
BOOL WINAPI SetConsoleMode(
_In_ HANDLE hConsoleHandle,
_In_ DWORD dwMode
);
정의로 가보았다. HANDLE과 DWORD를 가진 구조체가 인자로 필요해 보인다.
문서에 보면 인자들의 종류가 나와있다.
ENABLE_PROCESSED_INPUT : Ctrl + C를 칠 수 있게 하도록 해주는 녀석이다.
ENABLE_MOUSE_INPUT : 마우스의 위치만으로도 입력을 받게 된다.
그렇다면 위 두 녀석은 매크로함수인 거 같은데 왜 DWORD구조체가 인자로 들어가지 않고 매크로함수가 들어가는 것일까?
typedef unsigned long DWORD;
정의를 봐도 모르겠어 인터넷에 쳐봤더니, WORD는 cpu가 한번에 처리할 수 있는 양을 말한다고 한다.
16비트 환경에선 WORD, 32비트 환경에선 DWORD를 사용한다고 한다.
뭔말인지 모르겠으니, 나는 숫자는 숫자인데 비트들의 경계를 구분지어주는 구조체라고 생각하겠다.
GetStdHandle은 Handle을 반환해준다. STD_INPUT_HANDLE은 아마 입력핸들을 도와주는 친구같다.
우리가 알아야 할 건 매크로 함수에 ~OUTPUT~이 아니라 INPUT이라는 단어를 넣어야한다는 것에 주의해야한다.
ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &rc, 1, &dw);
입력버퍼에 데이터를 읽고 버퍼의 내용을 삭제한다.
BOOL WINAPI ReadConsoleInput(
_In_ HANDLE hConsoleInput,
_Out_ PINPUT_RECORD lpBuffer,
_In_ DWORD nLength,
_Out_ LPDWORD lpNumberOfEventsRead
);
HANDLE GetStdHandle(STD_INPUT_HANDLE) : 컨트롤을 도와주는 녀석이다. 입력모드를 설정한다.
INPUT_RECORD &rc : 버퍼에 있는 내용들을 구조체가 INPUT_RECORD인 친구한테 저장한다.
DWORD 1 : rc에 저장할 배열 크기이다. 우리는 입력받을 장치가 마우스 하나 뿐이니 1개면 된다.
(LP)DWORD &dw : 버퍼에 입력된 수를 받는 변수에 대한 포인터이다. 왜 있는진 모르겠다.
FillConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), ' ', 100, pos, &dw);
화면을 지운다라고 되어 있지만, 공백을 채운다고 보면된다.
BOOL WINAPI FillConsoleOutputCharacter(
_In_ HANDLE hConsoleOutput,
_In_ TCHAR cCharacter,
_In_ DWORD nLength,
_In_ COORD dwWriteCoord,
_Out_ LPDWORD lpNumberOfCharsWritten
);
TCHAR ' ' : 공백을 채우겠다는 뜻, 얼만큼?
DWORD 100 : 100만큼, 어디서 부터?
COORD pos : 부터. COORD는 구조체를 보면 x좌표와, y좌표를 나타낼 수 있는 구조체인데 통상 이벤트 발생 시 인자로 자주 사용하는 거 같다.
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
설명이 필요 없어보인다. 커서의 위치를 바꿔주는 코드이다.
참고로, 속성에 들어가 저 빨간 공간안에 옵션은 체크를 해제해주어야 한다.
나는 마우스 커서가 올려져 있어도 좌표가 나오는 게 아니라 클릭 시 좌표가 나타나도록 하려한다.....
하지만 덕분에 하나 알았기 때문에 글로 기록해봄.
+++
if (rc.EventType == MOUSE_EVENT)
if (rc.Event.MouseEvent.dwButtonState & FROM_LEFT_1ST_BUTTON_PRESSED)
를 버퍼값을 rc에 입력 받은 후(ReadConsoleInput)에 넣어주면 끝!
참고 블로거 (여기는 SetConsoleMode함수 인자에 OUTPUT으로 돼있어서 처음에 안됐었음. 어쩌면 이 사람이 내게 준 과제가 아니었을까...?)
https://steemit.com/kr-dev/@codingman/c14--1558052700204
'Computer Language > C' 카테고리의 다른 글
정보과목용 C언어 정리 (0) | 2023.09.28 |
---|---|
C언어 연산자 우선순위 및 결합방향 표 (0) | 2023.09.14 |