'이론'에 해당되는 글 25건

  1. 2007/10/10 9.17(월) 이론-2(WM_NCHITTEST)
  2. 2007/10/10 9.17(월) 이론-1
  3. 2007/10/10 9.13(목) 이론-3
  4. 2007/10/10 9.13(목) 이론-2
  5. 2007/10/10 9.13(목) 이론-1

9.17(월) 이론-2(WM_NCHITTEST)

from Study/API 2007/10/10 15:47 view 19673
1. WM_NCHITTEST

- Cursor가 움직이거나 마우스 버튼을 누르거나 놓을 때, System은 커서 아래 있는 윈도우(마우스를 캡쳐한 경우 캡쳐한 윈도우)에게 WM_NCHITTEST 메시지를 보낸다.(sent)
- 이때 대부분 윈도우 프로시저는 이 메세지를 직접 처리 하지 않고 DefWindowProc으로 보내는데 DefWindowProc는 커서의 좌표를 조사해서 커서가 현재 윈도우의 어느 부분에 커서가 있는지 나타내는
Hit Test Code 를 리턴한다.
- WM_NCHITTEST의 결과로 얻어진 HitTestCode가 다음 메시지를 결정하는데 사용된다.

- 예제 코드( Control키를 누른 상태에서 클라이언트 영역에서 마우스의 왼쪽 버튼을 누르면 윈도우를 이동 )
    // WM_NCHITTEST 를 처리하는 방법
    case WM_NCHITTEST:
        {
            // 1. 먼저 DefWindowProc()으로 전달해서 hit test code를 얻는다.
            int code = DefWindowProc( hwnd, msg, wParam, lParam );

            // 2. code를 조작한다.
            if( code == HTCLIENT && GetKeyState( VK_CONTROL ) < 0 )
                code = HTCAPTION;

            // 3. code를 리턴한다. - 다음 메세지는 이 리턴값에 의해 결정된다.
            return code;
        }

Tag | ,

9.17(월) 이론-1

from Study/API 2007/10/10 15:22 view 26695
1.  WinMain() : 윈도우 클래스를 등록,생성

- CreateWindowEx() 는 WM_CREATE메세지를 발생시킨다. 이때 이 메세지를 처리를 먼저하고 HANDLE값을 반환한다.
- DestroyWindow()는 WM_DESTROY를 발생하며 윈도우를 파괴시킨다.
- 비Q메시지는 API함수 호출시 주로 발생하며 메세지 처리 함수에 직접 전달한다.
- 입력 메시지(마우스 메세지, 키보드 메세지)를 제외한 대부분의 메시지가 non-queued Message 이다.


- SendInput을 통하여 마우스, 키보드 드라이버에서 SHIQ로 가상으로 키를 넣을 수 있다.(화상키보드)
- 키보드 : 활성화된 윈도우에 메시지를 입력한다. Raw가 담당..
- 스레드당 한개 씩 메세지 Q를 갖는다. GetMessage를 통해서 메시지를 끄집어 낸다.
- DispatchMessage는 WndProc에 메시지를 전달해주는 역할을 한다.

- WM_PAINT
 => GetMessage does not remove WM_PAINT messages from the queue. The messages remain in the queue until processed. 참고(페졸드책:108page)
 윈도우 프로시저가 WM_PAINT 메시지를 처리하면서 BeginPaint()를 호출하면, 클라이언트 영역 전체는 유효화된다.
 또한 프로그램은 ValidateRect()를 호출함으로써 클라이언트 영역의 임의 직사각형 영역을 유효화할 수도 있다. 만약 이 호출의 결과로 무효 영역 전체가 유효화된다면, 메시지 큐에 현재 저장되어 있는 WM_PAINT 메시지는 제거된다.

- WM_KEYDOWN, WM_CHAR 메시지 ( 제프리 : 990p 메시지Q 꺼내오기)
1. QS_SENDMESSAGE 플래그가 설정되어 있으면 해당 메시지를 적절한 윈도우 프로시저로 보낸다. 이 작업 후에 함수는 리턴 하지 않고 계속 다음 메시지를 기다린다.
 2. POST 메시지 큐에 메시지가 있으면 인자로 전달된 MSG 구조체에 해당 메시지 정보를 복사한 후 리턴한다.
 3. QS_QUIT 플래그가 설정되어 있으면 WM_QUIT 메시지를 리턴하고, QS_QUIT 플래그를 제거한다.
 4. 하드웨어 입력 큐에 메시지(WM_KEYDOWN, WM_LBUTTONDOWN, …)가 있다면 MSG 구조체에 해당 메시지 정보를 복사한 후 리턴한다.
 5. QS_PAINT 플래그가 설정되어 있으면 WM_PAINT 메시지를 리턴한다.
 6. QS_TIMER 플래그가 설정되어 있으면 WM_TIMER 를 리턴한다.

WM_KEYDOWN, WM_CHAR, WM_KEYUP 의 처리 순서도 위의 알고리즘을 통하면 쉽게 이해할 수 있다. 기본적으로 사용자가 키보드를 눌렀다 떼게 되면 WM_KEYDOWN, WM_KEYUP 이 하드웨어 입력 메시지 큐에 추가된다.
WM_KEYDOWN 이 TranslateMessage 를 통하면 적절한 형태의 WM_CHAR 메시지가 PostMesage 로 큐에 추가된다. 물론 이 과정에서 WM_CHAR 가 WM_KEYUP 보다 늦게 추가되었지만 위의 알고리즘의 우선순위 판정에 의해서 다음 번 처리되는 메시지는 WM_CHAR 가 되는 것이다.


2. 사용자 정의 메시지

- SendMessage : 동기 메시지 전달(Non-Queue) GetMessage에서 리턴하지 않는다??
- PostMessage : 비동기 메시지 전달( 리턴값을 받을수 없다. ) 메시지를 보낸후에 대기하지 않는다.

- 0x000~0x03FF    : 미리 정의 메시지
- 0x0400~0x7FFF  : Control Message            WM_USER+a
- 0x8000~0xBFFF  : Application Message      WM_APP+a
- 0xC000~0xFFFF : Register Window Message()
- 0x10000~          : Reserved 보호되는 영역

- WPARAM => UINT : 16비트 시절 2바이트로 word였다. 지금은 4바이트
- LPARAM => ULONG

3. 메시지 Q 모양
- 우선순위 GetMessage Remark 참고

1. Sent messages
2. Posted messages
3. Input (hardware) messages and system internal events
4. Sent messages (again)
5. WM_PAINT messages
6. WM_TIMER messages

- WM_PAINT는 중복되었을때 무효영역의 합해진 크기를 지니게 된다. PAINTSTRUCT에 저장 넘어감.

1. SendMessage( 우선적으로 처리하게 한다.)
2. SendMesageNotify( 리턴을 기달리지 않는다. 그러면서 우선적으로 처리하게 된다. )





 

Tag | ,

9.13(목) 이론-3

from Study/API 2007/10/10 14:12 view 21576
1. Window Object

- CreateWindow : OS가 윈도우를 관리할 때 가지고 있는 구조체를 가지고 윈도우를 표현한다.
- ShowWindow는 이 구조체의 위치를 Handle로 받아 표시한다.
- Handle Table
- 이 구조체에 접근할 수 있는 함수는
- SetWindowLong, SetWindowLongPtr( 32 or 64bit 호환 ), GetWindowLong, GetWindowLongPtr


- 윈도우는 눈에 보이는 구조체 일뿐 이라고 할 수 있다. ( WND32 구조체 )

- 등록된 윈도우 클래스로 부터 여러개의 윈도우를 만들수 있는데 윈도우클래스 관리구조체에 여분의 메모리를 추가 하여 사용자가 사용할 수 있다.
Tag | ,

9.13(목) 이론-2

from Study/API 2007/10/10 13:45 view 19719
1. EXE의 종류
   
- Console App : 콘솔창을 생성한다. main, 콘솔(/SUBSYSTEM:CONSOLE)
- GUI App : 윈도우창을 생성.           WinMain,Windows (/SUBSYSTEM:WINDOWS)
- Net App : CLR을 동작한다.

- Linker 옵션의 Subsytem차이 일 뿐이다.
- #pragma comment( linker, "[옵션]" )

- WhatExe ( EXE의 종류를 파악한다. )

more..




 

2. Data Type

P Pointer를 나타낸다. ( ex : PPOINT -> POINT* )
LP 32비트 Code에서는 P와 완전히 같다. WIN32에서 PSTR과 LPSTR은 같은 코드.
T,_t T는 DBCS와 UNICODE Type을 동시에 지원하기 위한 매크로이다.(TCHAR->char,wchar_t)
W UNICODE Type이다.
C const를 의미한다.
STR 문자열을 나타낸다.( ex : PSTR->char*)
H H로 시작하는 대부분의 Type은 핸들형 Type을 나타낸다.( ex : HWND, HPEN, HBRUSH )

- 윈도우 구조체의 크기를 얻는 이유( Window Version이 많아서-_-.. )
- 구조체의 크기는 조건에 따라 달라지므로 구조체에서 크기를 저장하는 변수를 가지고 있다.


3. HANDLE 개념 : 객체를 가리키는 번호, 32bit 정수(long), 고유의 번호를 가진다.

- OS는 HANDLE 번호를 만들어서 리턴해준다.
- HWND : 윈도우 번호
- HPEN : 펜 번호
- HBRUSH : 브러시 번호

4. 윈도우 만들기 GUI 윈도우 생성!!

- 모든 윈도우는 윈도우 클래스로 부터 만들어진다.

- 배경색, 아이콘, 이름, 윈도우틀(클래스).. 이 필요하다.
- 윈도우 클래스를 시스템에 등록한다.
- 등록된 클래스로 윈도우를 생성한다.
- 윈도우를 보여준다.

- 미리 가져다 쓸수 있는 등록된 클래스가 40~50개가 있다.(button, edit...)
- OS는 윈도우클래스모음 List를 가지고 이를 관리한다. 65536개를 관리 가능하다.


5. 윈도우 핸들

- API함수의 대부분은 핸들만 알고 있다면 윈도우를 조작가능 하다. ex) MoveWindow, Setmenu...
- 핸들을 얻을 수 있는 함수들.  ex) FindWindow, WindowFromPoint
- 예제 코드 ( 계산기 자식 윈도우 )

more..


- 예제코드 ( 계산기 자식윈도우 숨기기 )

more..


Tag | ,

9.13(목) 이론-1

from Study/API 2007/10/10 12:06 view 19477
  1. UNICODE
    1. 초기 한 글자를 1Byte(256) 라서 문자를 표현하는데에 한계가 있었다.
    2. So, 한 글자를 2Byte(65536) 으로 문자를 표현 했지만 메모리를 너무 잡아먹는다.
    3. So, 영어권 : 1Byte, 다른나라 : 2Byte 로 정해 해결하였다.
    4. UNICODE : 모든 글자에 고유한 번호를 지정하였다.
    5. 매크로기반 코드가 나오게 되는 이유 : (tchar.h에 정의된 것)
      1. Strlen은 null 하나만 있어도 길이를 구해주기 때문에 제대로 문자열의 길이를 구하지 못한다. null 두개 일때의 길이를 구하는 함수는 wcslen이 있다.
    6. WBCS는 네트워크에 용량이 많아지는 단점이 있다.
    7. DBCS 는 모든 나라 말을 표현 하지 못한다. 영어 + 그 지역의 언어만 표현한다.
    8. 이를 해결하기 위해 UTF=> 한글+영어+일본어.. 호환을 해주게 된다.
    9. UTF는 각 언어에 1byte,2byte,3byte,4byte 를 할당하여 표현한다.

  2. 정적 라이브러리
    1. 잘 만들어 놓은 함수 -> obj -> lib 으로 만들기 위해선 링크만 해주면 된다.
    2. static Library(정적 라이브러리)는 오브젝트(obj)파일의 집합이라 할 수 있다.
    3. lib를 만들때의 주의 점은 name mangling으로 호출규약이 c와cpp가 다르므로 extern "C"로 만들 함수를 감싸주는 것이 필요하다.
    4. lib의 특징은 exe의 기계어 코드가 포함되어 실행파일로 만들어지므로 exe만 배포하여 프로그램을 실행 할 수 있다는데에 있다.
    5. 단점은 lib가 중복되어 배포될 수 있다는 점이다.(메모리 낭비) 또한, Update 할때 마다 프로그램을 다시 Build 해줘야 하는 단점이 있다.

  3. DLL(PE포맷)
    1. 배포시 lib(type), dll, .h 를 같이 동봉해야 한다.
    2. .edata : 정보를 누출해야 다른 실행파일에서 접근 할수 있으므로 import 해줘야 한다.
    3. edata는 제공하는 함수에 대한 정보들이 있다. export, import를 구현해야 한다.
    4. lib => object lib은 함수의 기계어 코드가 포함되어 있어서 파일의 크기가 크지만,
    5. lib => type lib은 링크 정보만을 가지고 있다.

  4. 라이브러리를 추가하는 2가지 방법
    1. 소스 : pragma comment( lib, "라이브러리" )
    2. 설정: 프로젝트설정->Linker->Input->Additional depends(추가 종속성)

      5. 다른 윈도우의 HWND에  DestroyWindow( hwnd ); 가 먹히지 않는 이유.

MSDN 에서는 이문제를 한줄로 표현 해놓았는데
"A thread cannot use DestroyWindow to destroy a window created by a different thread"
"스레드간의 WM_DESTROY 메세지 보내는 것을 허용하지 않는다."  란다.-_-..
GetLastError 로 확인 해보면 ERROR_ACCESS_DENIED( 접근 금지 ) 에러코드가 생성된다.
이 문장을 본 한 블로거는 이런 표현을 썻다. 왓 더~ 헬~
"WHAT THE...!?! I have words for that that are inappropriate for this blog. I need a good chunk of lye for cleaning of the mouth."
출처 : http://cubicspot.blogspot.com/2005_03_01_archive.html
아무튼 위대한 MS의 Windows 개발자가 막아놨다. -_-..


 

Tag | ,