자료 저장소

# 윈도우


LONG_PTR GetClassLongPtr(HWND hWnd, int nIndex)
지정된 윈도우에 구조체 값을 조사한다. 

ULONG_PTR SetClassLongPtr(HWND hWnd,int nIndex, LONG_PTR dwNewLong)
지정된 윈도우에 구조체 값을 변경한다.

BOOL DestroyWindow(HWND hWnd)
지정한 윈도우를 파괴하는 간단한 동작을 하지만 내부적으로는 파괴되기 직전에 WM_DESTROY
메시지를 보내 종료 처리를 할 기회를 주며 키보드의 포커스를 버리고 메뉴를 파괴하고 메시지 큐를
완전히 비운다. 동작중인 타이머가 있으면 파괴하고 클립보드 소유권을 제거한다.
만약 파괴되는 윈도우가 부모 윈도우나 소유자일 경우, 즉 자식 윈도우를 가지고 있을 경우
차일드를 같이 파괴한다는 것인데 이때 각 차일드에게도 WM_DESTROY 메시지가 전달된다.
윈도우는 자신의 직계 자식만 파괴하며 손자나 증손자는 파괴하지 않는다. 그러나 직계 자식은
마찬가지 방법으로 자신의 차일드를 파괴하면서 WM_DESTROY 메시지를 보내므로 결국
직계 자식만 파괴하면 모든 후손들이 연쇄적으로 파괴되는 셈이다. 이런식으로 DestroyWindow 함수는
자신과 자신의 차일드, 그리고 그 후손들을 차례대로 파괴한다.

BOOL CloseWindow(HWND hWnd)
윈도우를 최소화 하는데 ShowWindow(hWnd,SW_MINIMIZE)와 기능적으로 동일하다.


# 윈도우 소유관계

 
HWND GetParent(HWND hWnd)
자신의 부모를 조사한다.

HWND SetParent(HWND hWndChild, HWND hWndNewParent)
2번째로 전달된 인자값으로 새로운 부모를 변경한다.

HWND GetWindow(HWND hWnd, UINT uCmd)
2번째 인자로 전달된 메시지의 윈도우 소유자를 조사한다.


BOOL SetProp(HWND hWnd, LPCSTR lpString, HANDLE hData)
hWnd 윈도우에 lpString이라는 이름으로 프로퍼티를 생성하고, 이 프로퍼티에 hData라는
값을 기억시킨다. 이 때 lpString이 이미 존재한다면 값을 변경한다.

HANDLE GetProp(HWND hWnd, LPCSTR lpString)
lpString이라는 이름의 프로퍼티에 기억되어 있는 값을 읽는다.
프로퍼티에 기억되는 값은 HANDLE형의 어떤 데이터라도 상관없다.
주로 메모리 핸들이나 파일 핸들 등의 핸들을 많이 기억해 놓으므로 프로퍼티의타입이
HANDLE로 되어 있지만,적절한 캐스팅으로 32비트의 어떤 값이라도 저장 해 놓을 수 있다.

HANDLE RemoveProp(HWND hWnd, LPCSTR lpString)
생성한 프로퍼티를 제거한다, 프로퍼티에 기억된 값을 리턴하고 만약 프로퍼티가 동적으로
할당된 메모리의 핸들이라면 메모리도 같이 해제해주어야 한다.
이런 해제 영역은 WM_DESTROY 등의 메시지에서 처리하는것이 적합하다.


# 윈도우의 위치와 크기

BOOL GetClientRect(HWND hWnd, LPRECT lpRect) 
작업 영역(현재 윈도우)의 크기를 조사한다.

BOOL GetWindowRect(HWND hWnd, LPRECT lpRect) 
대상 윈도우의 좌표를 구해 RECT 구조체에 채워 리턴한다.


BOOL MoveWindow(HWND hWnd,int x,int y,int nWidth,int nHeight,BOOL bRepaint)
동 대상이 되는 윈도우의 핸들을 첫 번째 인수로 주고 윈도우의 좌상단 좌표와 폭,높이를 준다.
이때 지정하는 좌상단 좌표는 최상위 윈도우일 경우는 화면 좌표이며 차일드 윈도우일 경우는
부모 윈도우의 작업영역 내에서의 좌표이다. 
마지막 인수인 bRepaint는 이동 후에 윈도우를 다시 그릴 것인가를 지정하며 이 값이 TRUE이면
동 후에 즉시 작업영역을 무효화하고 WM_PAINT 메시지를 보내 윈도우를 다시 그리도록 한다.

이 함수는 윈도우의 영역을 지정하는 방식이 XYWH 방식이다. 윈도우즈에서 사각영역을 지정하는
방법은 두가지가 있는데 RECT구조체, Ellipse, Recangle 함수는 LTRB 방식을 사용하고

CreateWindow, BitBlt 함수는 XYWH 방식을 사용한다.


L,T                 X,Y    W

   ┌──┐            ┌──┐

   │      │            │      │H

   └──┘            └──┘ 

             R,B


ex) (L,T)에서 (R,B)까지 윈도우를 배치하고 싶다면 다음과 같이 호출한다
MoveWindow(hWnd,L,T,R-L,B-T,TRUE)
XYWH 방식은 X,Y,X+W,Y+H 공식으로 LTRB로 변환한다.


BOOL SetWindowPos(HWND hWnd,HWND hWndInsertAfter,int X,int Y,int cx,int cy,UINT uFlags)
이 함수는 윈도우의 위치, 크기, Z순서를 동시에 또는 일부만 변경할 때 사용된다.
두번째 인수는 이 윈도우를 어느 윈도우 다음에 배치할 것인가를 지정하는 윈도우 핸들이다.
또는 다음과 같은 값을 줌으로써 윈도우의 Z순서를 강제로 변경 할 수 있다.

hWndInsertAfter 인수의 값

- HWND_TOP : Z순서의 제일 위에 윈도우를 배치한다.
- HWND_BOTTOM : Z순서의 바닥에 윈도우를 배치한다.
- HWND_TOPMOST : 탑 모스트 윈도우로 설정한다.
- HWND_NOTOPMOST : 탑 모스트 윈도우 설정을 취소한다.

마지막 인수 uFlags에 자주 쓰이는 쉬운 설정

- SWP_NOSIZE : 크기는 변경하지 않고 위치만 이동한다. cx,cy 인수가 무시된다.
- SWP_NOMOVE : 위치는 이동하지 않고 크기만 변경한다. x,y 인수가 무시된다.
- SWP_NOZORDER : 현재의 Z순서를 그대로 유지한다. hWndInsertAfter 인수를 무시한다.

 
# 윈도우를 일괄 적인 위치 및 크기 변경시

HDWP BeginDeferWindowPos(int nNumWindows)
복수 윈도우의 크기와 위치를 저장하기 위한 메모리를 할당한다. 이 메모리의 핸들은
HDWP 타입으로 리턴되는데 운영체제가 내부적으로 관리하는 불투명한 구조체 타입이므로
사용자가 직접 조작할 수는 없다. 인수로는 조정할 윈도우의 갯수를 전달하는데 이 갯수만큼 메모리를
초기 할당하되 DefWindowPos 함수가 필요할 경우 메모리를 재할당 하므로 대충 충분한 크기면된다.

HDWP DeferWindowPos(HDWP hWinPosInfo,HWND hWnd,HWND hWndInsertAfter,int x,int y,
        
int cx,int cy,UINT uFlags)
윈도우들의 배치 상태를 배열에 기록하는데 두 번째 이후의 인수들은 대체로 SetWindowPos의 인수와
거의 유사하다. 다만 uFlags에 쓸 수 있는 플래그의 종류가 조금 더 많을 뿐이다. 이동 대상 윈도우들은
같은 부모의 차일드여야 한다. 첫 번째 인수는 정보를 저장할 HDWP 타입이며 DeferWindowPos는
필요시 이 배열을 늘리고 그 핸들을 다시 리턴한다. 옮기고자 하는 윈도우의 위치와 크기를 루프를
돌며이 배열에 순서대로 기록하면 된다.

BOOL EndDeferWindowPos(HDWP hWinPosInfo)
위 함수들로 만들어진 정보대로 윈도우를 일괄 재배치한다. 이동,크기 조정이 화면을 한 번 갱신하는
동안 완료되므로 속도가 훨씬 빠르고 이동중인 중간 과정이 보이지 않으므로 훨씬 더 깔끔하다.



# 좌표계산

BOOL ScreenToClient(HWND hWnd,LPPOINT lpPoint)
BOOL ClientToScreen(HWND hWnd,LPPOINT lpPoint)


기준 윈도우의 핸들을 주고 POINT 구조체의 번지를 전달하면 이 구조체의 좌표(x,y)를 반대 좌표로
바꿔준다. 예를 들어 작업영역의 (10,20)이 화면상의 어디쯤에 해당하는지 알고싶다면 (10,20) 좌표를
가지는 POINT 구조체를 만들고 ClientToScreen 함수를 호출하면 윈도우의 위치와 속성등을 참조하여
화면 위치로 변환한다.

BOOL GetWindowPlacement(HWND hWnd,WINDOWPLACEMENT *lpwndpl)
hWnd 윈도우의 보이기 상태와 노멀 좌표, 최대, 최소 좌표를 lpwndpl구조체에 저장한다.

BOOL SetWindowPlacement(HWND hWnd,CONST WINDOWPLACEMENT *lpwndpl)
hWnd 윈도우의 보이기 상태와 노멀 좌표, 최대, 최소 좌표를 lpwndpl구조체의 정보대로 설정한다.

typedef struct __WINDOWPLACEMENT {
    UINT  length; // sizeof(WINDOWPLACEMENT)
    UINT  flags;
    UINT  showCmd; // SW_*   
    POINT ptMinPosition; // 최소화 좌표
    POINT ptMaxPosition; // 최대화 좌표
    RECT  rcNormalPosition; // 노멀 좌표
} WINDOWPLACEMENT;

이 구조체의 좌표들은 화면좌표가 아닌 워크 에리어 좌표이기 때문에 반드시
Set(Get)WindowPlacement에서만 사용하여야 한다.

댓글 로드 중…

최근에 게시된 글