WinAPI시작하는데 어려웡..
갑자기 #include <Windows.h>해놓고
사용자 정의 자료형 엄청 나오고
유니코드 대비해서 LPCTSTR이런거 쓰라 그르고..
핸들이 뭔지도 잘 모르겠고
WndClass구조체는 또 안에 변수(이걸 뭐라그러더라) 엄청 많고
힘들다.
또 어떤새기는 널 문자 인식을 못해서 길이를 보내줘야하고..
WinAPI는 그냥 리버싱하려고 대충 배우는거라 생각해야겠담
실무에서는 WinApi많이 써??
그리고 아직 핸들 개념이 살짝 안잡히는데 이거 그냥 배우다보면 익힐수 있을까??
아님 잘 설명해주실분 ㅠ
처음엔 좀 배울 게 많음. 익숙해지면 그닥 안 어려움.
그거 외워쓰는사람 없음 다들 원리만 아는거
API는 Naming Convention(이름 규칙)이 좀 특별해서 그렇지 별로 특별한 건 없어. C언어에서 제공해 주는 unsigned int 이런 거 써서 정의되어 있으면 얼마나 편하겠느냐만은 그런 걸 안 쓰는 이유는 컴파일러에 따라 크기라던지 다 달라질 수 있으니까 자체적으로 타입을 정의하고 windows.h 안에 그걸 정의해서 헤더를 제공해 주고 프로그래머는 정의해 놓은 새로운 타입을 쓰라고 강요하는 거임. 그렇게 하면 환경이 달라지든 컴파일러가 달라지든 헤더만 MS 사에서 고쳐서 다시 제공해 주면 프로그래머들은 API로 짜놨던 코드를 다시 짤 필요가 없으니까 그런 거. 상위 호환성(forward compatibility)을 염두에 둔 것이다.
그 외에 윈도우 프로그래머들의 습관 중에 중괄호 시작도 꼭 새 줄에 쓰는 거랑 변수 이름을 헝가리안 표기법(Hungarian Notation)으로 짓는 특징이 있는데(API 함수들의 매개 변수도 이 표기법을 쓴 게 대부분이고) 이런 정도의 습관이 있다는 것만 파악하면 나머지는 그냥 C랑 같아.
우선 타입 이름부터 함께 보자. LPCTSTR. LP => long pointer의 약자. 포인터라는 뜻. API 타입에서 P(pointer)나 LP(long pointer)로 시작하면 포인터라는 뜻임. C => const. T => text(C언어의 기본 char형을 쓸 것인지 유니코드 문자 형 wchar_t을 쓸 것인지 프로젝트 설정에 따라 자동 결정). STR => 문자열(문자 배열 char []) => 문자열이 담겨있는 TCHAR 배열을 가리키는 포인터라는 의미.
아 마지막에 실수했다. 다시 적으면 => 문자열이 담겨있는 const TCHAR 배열을 가리키는 포인터라는 의미. 곧, const TCHAR *을 LPCTSTR이라고 적는 거임.
자 그러면 여기서 문제. char *는 API에서 어떻게 적을까? 대략 크게 세 가지 표현 정도가 있음. PSTR, LPSTR, PCHAR. 뭐 LPCHAR도 가능해 보이는데 이건 쓰는 걸 본 적이 없음. PSTR/LPSTR은 널 문자로 끝나는 문자열을 가리키는 포인터라는 의미겠고 PCHAR은 내용이 문자열인지는 모르겠고 그냥 char의 포인터라는 정보만을 주고 있음.
참고로 API에서 char는 CHAR라고 정의해 놨다. 또 다른 문제. short *는 API에서 어떻게 적을까? 답은 PSHORT 혹은 LPSHORT. 다음 문제. unsigned long(부호없는 32비트 정수)은 API에서 어떻게 적을까? 이건 두 가지 답이 있다. ULONG(unsigned long), DWORD(부호없는 32비트 정수라는 뜻). 비슷한 원리로 unsigned short는 USHORT라고 적기도, WORD라고 적기도 함. WORD/DWORD는 인텔 어셈블리어에서 나온 표현인데 API에서 쓴다. WORD의 원래 의미는 프로세서가 한번에 처리할 수 있는 정수 크기로 32비트에서는 32비트, 64비트에서는 64비트이지만
인텔 어셈에서는 16비트 시절의 인텔 어셈과의 호환성을 위해 WORD를 64비트 어셈에서도 그대로 16비트라는 의미로 쓰고 있고, 32비트 정수는 DWORD(Double Word), 64비트 정수는 QWORD(Quad Word)라고 부르고 있고 윈도우 API에서도 그대로 이걸 따르고 있음.
API에서 핸들이라고 하면 가장 많이 보게 되는 게 HANDLE 형(커널 객체의 핸들)이랑 HWND 형(윈도우 핸들)일텐데 HANDLE은 void *로, HWND은 이상한 구조체의 포인터로 정의되어 있을텐데 어쨌든 둘 다 그 내용물은 유저가 접근할 수 없는 것이라고 보면 돼. 그냥 그 포인터 값 자체가 의미를 지녀. 핸들이라고 함은 시스템에서 돌아가고 있는 어떤 개체를 제어할 수 있는 티켓 같은 개념이다. Open 관련 API로 시스템으로부터 핸들을 얻어오고, 볼일이 끝났으면 Close해서 핸들을 닫아 주지. 커널 객체는 저렇게 하는 게 일반적이고, 어떤 창에 대한 핸들 HWND은 그냥 창마다 붙어진 고유 번호의 개념에 더 가깝다고 보면 된다.
창의 핸들의 경우는 FindWindow API로 찾아오면 그 값을 바로 쓸 수 있고, 이 값은 그 창이 존재하는한 변하지 않음. 즉 핸들이라기 보단 창의 고유 번호(ID)에 가까움.
설명 자세하게 해주셨넴ㅋㅋㅋ 고마웡ㅋㅋ 핸들은 대강 윈도우의 주민번호라고 생각할겜
그러면 되도록이면 Windows.h에 있는 사용자 정의 자료형을 이용하는게 좋은거야?
ㅇㅇ 그렇지. 윈도우 프로그래밍할 때는 가급적 윈도우 형을 쓰는 게 좋아. 단순한 루틴에서야 char, int 를 조금씩은 쓸 수 있겠지만(for 문이라던가) 대부분의 루틴은 윈도우의 자료형대로 선언하고 쓰는 버릇을 들이는 게 좋음. 그렇게 습관되면 익숙해지는 것도 있고 윈도우 API랑 타입 문제로 충돌나는 일도 적을 테니까.
나도 윈도우 프로그래밍할 때는 DWORD dwProcessId = 0UL, dwProcessCount = 0UL 뭐 이딴 식으로 변수 선언하고 씀 ㅋㅋ