본문 바로가기
운영체제/[ecourse] Windows Programming

2-1. 윈도우 핸들과 API

by 헛둘이 2022. 9. 6.

본 글은 코드누리의 Windows Programming 강좌를 개인 학습 목적으로 정리한 글 입니다.

https://www.ecourse.co.kr/

 

ecourse 온라인 강의 – S/W 교육의 새로운 시도

개강 예정 과정입니다. {"title":"\uac1c\uac15 \uc608\uc815 \uacfc\uc815\uc785\ub2c8\ub2e4.","show_title":"1","post_type":"course","taxonomy":"course-cat","term":"COMMINGSOON","post_ids":"","course_style":"popular","featured_style":"course","masonry

www.ecourse.co.kr

핸들이란?
  • 운영체제에는 윈도우들을 관리하기 위해 번호를 부여한다.
  • 다양한 종류의 객체가 있고 그 객체에 대한 고유한 번호가 핸들이다.
  • Create...로 시작하는 함수로 개체를 만들면 핸들이 반환된다.
  • 다양한 API 함수는 1번째 인자로 핸들을 전달 받는 경우가 많다.
윈도우 관련 함수는 윈도우 핸들을 받고, 비트맵 관련 함수는 비트맵 핸들을 받는다.

 

 

 

 

 


윈도우 핸들 구하는 방법
  • 윈도우 핸들을 알면 API를 사용해서 윈도우를 조작할 수 있다.
  • 윈도우를 직접 만드는 경우는 CreateWindowEx 함수의 반환값을 통해 윈도우를 조작할 수 있다.
  • 이미 만들어진 윈도우의 경우는 FindWindow나 WindowFromPoint를 사용하여 핸들을 가져올 수 있다.

가장 흔하게 사용되는 FindWindow 함수

#include <iostream>
#include <Windows.h>
using namespace std;
int main()
{
    HWND hwnd = FindWindow(0, L"제목 없음 - Windows 메모장");
    cout << hwnd; // 000507F4
}
  • FindWindow를 사용해서 hwnd에 메모장의 핸들을 가져온다. 
  • FindWindow가 실패하면 NULL을 반환한다.
  • DestroyWindow의 경우 다른 스레드에 의해 생성된 윈도우를 파괴할 수 없다.

 


핸들 타입의 정체는?
  • HWND와 HICON을 예시로 들면
  • 핸들이란 고유한 정수값이므로 int형에 저장해도 되지 않을까?
  • typedef int HICON
  • typedef int HWND
  • => 하지만 HWND가 들어갈 곳에 HICON이 들어가면 안되므로 문제가 된다.
struct HWND__
{
} 
typedef struct HWND__* HWND;
  • 포인터는 정수를 저장할 수 있으므로 문제가 없고,
  • 구조체 포인터끼리는 암시적 형변환이 되지 않으므로 이렇게 하면 문제가 없다.
그럼 HANDLE은 모든 핸들을 담는데 이건 무슨 타입일까?
=> void* 타입

 

 

 

 


윈도우 OBJECT
  • 윈도우를 최소화시키면 이는 어떤 구조체에 의해 관리될 것이다.
  • CreateWindowEx 함수는 이런 구조체를 만드는 것이라고 생각할 수 있다.
  • 그리고 이걸 보여주는 건 ShowWindow 함수일 것이다.
  • 이런 구조체 정보에 접근할 수 있는 함수가 있는데 아래 2개 이다.
  • GetWindowLongPtr
  • SetWindowLongPtr
  • 그렇다고 모든 멤버에 접근 가능한 것은 아니고, 일부만 가능하다.
#include <iostream>
#include <Windows.h>
using namespace std;
int main()
{
    HWND hwnd = FindWindow(0, L"제목 없음 - Windows 메모장");
    
    LONG style = GetWindowLongPtr(hwnd, GWL_STYLE); // 스타일을 가져옴

    style &= ~WS_CAPTION;
    style &= ~WS_THICKFRAME;

    SetWindowLongPtr(hwnd, GWL_STYLE, style);
}
  • style 멤버에 접근해서 캡션 바와 크기를 늘렸다 줄였다 하는 프레임을 제거한다.

 

 

 

 

 


윈도우 메시지
  • 윈도우가 어떤 동작을 할 때마다 메시지가 나온다.
  • (WM_CREATE, WM_SIZE, WM_MOVE 등...)
  • 어떤 메시지에 대한 추가 정보는 WPARAM과 LPARAM에 저장되어 들어온다.

 

마우스 클릭

  • 마우스 클릭의 경우 LPARAM에 같이 들어오게 된다.
  • 상위 16비트에는 Y좌표, 하위 16비트에는 X좌표가 들어온다.
int x = lParam & 0x0000ffff; // 상위 16비트를 0으로 미는 코드
int y = lParam >> 16;        // 상위 16비트를 우측으로 밀어서 초기화
SendMessage(hwnd, WM_CLOSE, 0, 0);
PostMessage(hwnd, WM_CLOSE, 0, 0);
  •  A 프로세스와 B 프로세스가 있을 때,
  •  B 프로세스가 A 프로세스에게 WM_LBUTTONDOWN 메시지를 보내서 마우스가 눌린 것처럼 작동하게 할 수 있다.
  • 그 함수로는 SendMessage 함수와 PostMessage 함수가 있다.
  • SendMessage는 그 메시지가 A 프로세스에서 처리될 때까지 대기하고,
  • PostMessage는 그 메시지가 처리되든 말든 신경쓰지 않는다.
  • DestroyWindow는 B 프로세스를 파괴할 수 없으나, SendMessage(hwnd,. WM_CLOSE, 0, 0)을 사용하면 파괴할 수 있다.

 

 

 

 

'운영체제 > [ecourse] Windows Programming' 카테고리의 다른 글

2-3. 라이브러리 개념  (0) 2022.09.07
2-2. 실행 파일 포맷  (0) 2022.09.07
1-5. C++과 MASM  (0) 2022.09.05
1-4. Stack Frame  (0) 2022.09.04
1-3. Calling Convention  (0) 2022.09.03

댓글