윈도우(Window), 메세지(Message)
Windows API를 통해
간단한 Application은 만들어 보았지만
Application Hacking에 대한 이론이 옅어서
정리를 해보려고 합니다.
그럼 시작해 볼까요?
1. Window ▶
1) Window란 무엇일까요?
사용자의 입력을 처리하고 결과를 보여주는
Windows OS의 가장 중요한 I/O 구성요소 입니다.
Window에 알기 전에 먼저 Thread에 대해 알아야 합니다.
2) 그렇다면 Thread는?
[1] Thread는 Window를 생성하고 소유할 수 있으며
Window를 제어하는데 사용되는 메세지를 수신하기 위한
메세지 큐(Message Queue)를 함께 가지고 있습니다.
[2] 가지고 있는 메세지 큐에서 전달받은 메세지를 꺼내서
메세지에 대한 동작이 정의되어 있는 Callback함수를 호출하지요.
※ Callback함수 내에서는 메세지를 직접 처리하거나
시스템에 처리를 요청하구요.
※ 모든 스레드가 윈도우를 생성할 수 있지만
서비스 프로세스의 경우 윈도우를 표시할 수 없도록 설계되어 있어요.
서비스 프로세스는 사용자와의 상호작용은 없고
동작하는 작업만 처리하기 때문이지요.
[3] Foreground
화면에 아무리 많은 윈도우가 떠 있어도
사용자의 입력을 받을 수 있는 윈도우는 가장 상위(Foreground)에서
활성화(Activate)되어 있는 입력포커스를 가진 윈도우 하나 뿐입니다.
즉, 사용자의 모든 입력은 해당 윈도우로 전달이 되지요.
[4] 우선순위
윈도우가 활성화되는 시점에 해당 윈도우를 생성해서 소유하고 있는
스레드에 대해 높은 우선순위를 가지도록 설정합니다.
이유는.. 생각하시는대로
더 많은 CPU시간을 할당해서 사용자와의 상호작용이 효과적으로
처리하기 위함이겠죠?
이와같이 상위 윈도우를 소유해서
입력을 처리하게 되는 스레드를
Foreground Thread라고 부르고,
그 외 다른 윈도우들을 소유하고 있는
스레드를 Background Thread라고 부르지요.
조금 자세히 알아볼까요?
BOOL ::SetForegroundWindow(HWND hWnd),
HWND ::SetFocus(HWND hWnd)와 같은 API를 호출해서
프로그램 상에서 상위 윈도우를 변경하거나
입력 포커스를 지정할 수 있습니다.
그러나 이렇게 할 경우 사용자가 마우스로 윈도우를 선택하거나
Alt+Tab, Alt+Esc를 입력해서 상위 윈도우를 지정하는 것과는
다르게 동작합니다.
뭐가 다를지 생각해볼까요?
만약에 비밀번호를 입력해야 하는데
다른 응용프로그램이 API를 써서 자신을 활성화할 경우
입력정보를 사용자가 원하지 않는 응용프로그램이
처리하겠죠?
그래서 API에 의해 설정된 윈도우는 작업표시줄에서만 활성화 된 것처럼
표시되며 사용자 입력은 이전에 입력을 처리하던 윈도우로 전달됩니다.
하 지 만 !!
BOOL ::AttachThreadInput(DWORD idAttach, DWORD idAttachTo, BOOL fAttach) API를
사용해서 현재 입력을 처리하고 있는 스레드와 입력상태를 공유할 수 있습니다.
즉, 사용자의 입력을 처리하는 스레드가 아니더라도 사용자의 입력 윈도우를
강제로 변경할 수 있다는 말이지요.
현재 입력을 받고 있는 윈도우가 종료된다면?
다음 우선순위를 가지고 있는 중첩윈도우(Overlapped Window)
또는 팝업 윈도우(Popup Window)가 활성화되고
해당 윈도우 내부의 자식 윈도우의 순서에 따라서
입력을 전달받은 다음 윈도우가 설정됩니다.
또한
응용프로그램이 생성한 윈도우가 최소화(Minimize)되는 순간에
프로세스가 사용하는 메모리 크기도 최소크기로 줄어들지요.
프로세스에 할당되어 있는 가상메모리의 페이지(Page)영역에서 Disk가 아닌
실제 물리 메모리에 올라와있는 페이지 집합을 워킹셋(Working set)이라고 합니다.
댓글