쑤쑤_CS 기록장

Windows 추가 내용 정리 본문

IT 지식 기록/TIPS - C 언어 수업 정리

Windows 추가 내용 정리

(╹◡╹)_ 2019. 2. 14. 19:14
728x90

<WM_PAINT 메시지>

윈도우즈 운영체제의 메시지 시스템은 메시지 큐와 메시지 테이블로 나누어집니다. 즉, 하니의 응용 프로그램에 메시지를 보관하는 방식이 두 가지라는 뜻입니다. 메시지 큐는 순서대로 들어와서 저장되고 먼저 저장한것부터 순서대로 처리되는 방식이고 CPU 상태와 상관없이 자기 순서가 되면 처리가 됩니다.

메시지 테이블은 전달 순서와 상관없이 메시지가 활성화되면 자신의 상태를 0에서 1로 바꿔놓고 처리를 대기하게 됩니다.

하지만 메시지 테이블에 있는 상태값은 메시지 큐에 있는 메시지들이 모두 처리되고 처리되기 때문에 메시지가 많아져서 처리가 지연되기 시작하면 메시지 테이블은 우선순위에서 밀려서 처리자체가 안됩니다. 그냥 무한대기 상태에 빠지고 메시지 큐에 있는 메시지들이 어느정도 처리가 다되고 나면 그때서야 메시지 테이블에 1로 되어 있는 메시지들이 처리되기 시작합니다.

따라서 WM_PAINT와 같이 메시지 테이블이 1로 셋팅되는 메시지들은 메시지 큐에 메시지들이 어느정도 처리되어야지 자신에게 처리 순서가 돌아오게 됩니다. 그리고 메시지 큐에 들어가는 메시지들은 발생한 횟수만큼 메시지 큐에 들어갈수 있지만 메시지 테이블에 기록되는 메시지들은 그냥 상태값을 0에서 1로 바꾸는 방식이기 때문에 10번 발생해도 1번만 기록 되게 됩니다. 즉, 처음 발생했을때는 0에서 1이되겠지만 나머지 아홉번은 1로 되어있는값을 다시 1로 변경하는 것이되어 9번이 무시되는 효과가 있습니다. 



<추가 내용 정리>

1.

GetDC 함수는 DC를 만드는 함수가 아니라 Window가 만들어질때 구성된 DC 핸들 값을 가져오는 함수입니다. 즉, 내가 만든게 아니라 만들어져 있다고 생각하면 됩니다.


2.

ReleaseDC 함수는 DC를 제거하는 함수가 아니라 DC를 다사용했으니 사용이 끝났다는 것을 알리는 함수입니다. 즉, 저 함수를 호출한다고 Window가 만들어놓은 DC가 없어지지 않는다는 뜻입니다.


3.

Window가 만들어질때 생성된 DC는 GDI Object 의 핸들값으로 채워지는 이 핸들값이 모두 Stock Object(자주 사용되는것을 미리 만들어서 모든 프로세스들이 함께 사용하는 값, 삭제하면 안됨)의 핸들 값이기 때문에 DC가 실제로 제거되더라도 이 핸들값은 삭제가 되지 않습니다. 즉, DC가 삭제될때 DC에 저장되어있는 핸들값은 삭제의 의무가 없어서 실제로 개발자가 생성해서 넣은 핸들이라고 하더라도 삭제되지 않습니다. 삭제 루틴 자체가 없습니다. 따라서 자신이 만들어서 핸들을 넣어두었다면 스스로 삭제하는 코드도 추가해야 합니다.


4.

SelectObject 함수에서 반환한 값을 백업하는 이유는 내가 만든 GDI Object는 내가 삭제할 것이기 때문에 DC에 삭제된 핸들값이 저장되어 문제가 되는 것을 방지하기 위한 것입니다. 즉, 기존에 사용하던 핸들값을 잠시 백업해두었다가 자신이 만든 핸들값이 삭제되면 그 값대신에 기존에 사용하던 값으로 복구하기 위한 것이죠. 그런데 이 백업했던 핸들을 삭제하게 되면 백업할 이유가 없습니다. 결국 삭제된 핸들값을 DC에 저장해두기 때문에 문제가 발생하게 됩니다.

+

GDI 시스템은 DC에 저장되어 있는 값을 가지고 그리기 작업을 진행합니다. 즉, 인식의 문제가 아니라 DC의 Pen 핸들값이 저장될 위치에 핸들값을 넣어두면 GDI 시스템은 그 핸들값을 읽어서 바로 작업을 하기 때문에, 원래 100이라는 숫자가 들어있었으면 100번 핸들에 해당하는 펜으로 그림을 그리다가 200이라는 숫자를 저장하면 200번에 해당하는 핸들값으로 그림을 그리게 되는 것입니다. 자신이 DC를 얻어온 시점에 DC의 펜 영역에 100이 저장되어있었다면 100번에 해당하는 객체로 그림을 그리고 있었다는 뜻이고 이 값을 내가 새로 만든 핸들인 200번으로 변경했다면, DC에는 200이 저장되어 있으니 GDI는 그림을 그릴때 이 200이라는 핸들을 사용해서 그림을 그리게 되는것입니다. 200은 핸들값이니 이 핸들값을 따라가면 사용자가 만든 펜에 접근이 가능하기 때문입니다. 그리고 이렇게 200을 사용하다가 자신이 작업을 끝내면 200에 해당하는 핸들을 삭제할텐데 이렇게 삭제해버리면 DC에 저장된 200이라는 값이 무용지물이 되기 때문에 기존에 사용하던 100으로 복구 시켜놓아야지 GDI가 잘못된 값을 사용하지 않게 되는 것입니다.


5.

Stock Object는 삭제할수없는 핸들값입니다. 따라서 DC에 저장된 객체는 Stock Object 일수 있기 때문에 확인없없이 삭제하면 안됩니다.


<Handle 개념에 대한 보충 설명>

https://blog.naver.com/tipsware/221464968465

728x90
Comments