블로그 이미지
이태원에서 사는 다섯식구의 무직 가장. 흰둥에미

카테고리

분류 전체보기 (184)
Itaewon (2)
ryu's?? (1)
20121210이전 (20)
20130827이전 (147)
soo'study (13)
Total34,674
Today8
Yesterday13

'API'에 해당되는 글 13건

  1. 2013.01.20 14장. 그리기 (1)
  2. 2013.01.19 13장. 메시지
  3. 2013.01.18 12장. 윈도우 관리
  4. 2013.01.15 11장. 윈도우 (1)
  5. 2013.01.15 10장. MFC 소개
  6. 2013.01.15 9장. API 실습
  7. 2013.01.15 8장. 대화상자
  8. 2013.01.14 7장. 컨트롤
  9. 2013.01.14 6장. 그래픽
  10. 2013.01.13 5장. 리소스

DC

DC의 정의

- DC에는 그리기에 필요한 여러 가지 정보가 저장되어 있으며, 프로그램은 DC의 정보를 참조하여 그리기를 수행하고, DC의 정보를

  조작하여 그리는 방법을 변경함.

DC의 구조

- DC는 그리기 관련 정보를 가지고 있는 데이터 구조체임.

  배경색, 모드, 비트맵, 브러시, 펜, 폰트등을 포함한 많은 데이터들이 포함되어 있다.

  윈도우 관련 헤더에는 DC에 대한 타입 정의는 선언되어 있지 않으며, 각 속성에 대해 얻고, 변경하는 함수를 이용해서 DC를 사용.

DC의 종류

- 디스플레이 DC : 화면 출력에 사용, 프린터 DC : 프린터 출력, 메모리 DC : 비트맵 출력에 사용, 정보 DC : 정보 취득에 사용.

  Common DC

  - 일반적으로 사용하는 DC를 의미하며, GetDC나 BeginPaint 함수를 이용해 매번 디폴트 속성의 DC를 얻을 수 있음.

    사용이 완료된 후 반드시 ReleaseDC나 EndPaint로 DC를 해제해 줘야함.

  Private DC

  - 윈도우 생성시 한번 발급받아, 종료시 해제 함. 윈도우 클래스 스타일에 CS_OWNDC 스타일을 지정해서 사용하며,

    한번 설정된 속성은 바꿔주지 않으면 그대로 유지됨.

  Class DC

  - CS_CLASSDC플래그를 주고 사용가능하며, 해당 윈도우 클래스로부터 만들어지는 모든 윈도우는 클래스 DC를 사용.

    없다고 생각하고 쓰지 말아라.

  Window DC

  - Common DC와 비슷하게 사용. 단 윈도우 좌상단이 원점이고, 클리핑 또한 비작업영역을 포함하여 이루어짐.

    WM_NCPAINT나 WM_NCACTIVATE 메시지에서 비작업영역에 대해 커스터마이징 할것이 아니라면 사용을 비추.

    HDC GetWindowDC(HWND hWnd);

    - 위 함수를 이용해 DC를 얻고, ReleaseDC함수로 DC를 해제.

  Parent DC

  - 버튼이나 에디트 등의 차일드 컨트롤에서 그리기 속도를 최대한 빠르게 하기 위해 사용. 최상위 윈도우나 팝업 윈도우는 사용불가.

    CS_PARENTDC 플래그가 지정되어야 하며, 사용 비추.

GetDeviceCaps

- int GetDeviceCaps(HDC hdc, int nIndex);

  - hdc가 가진 장치의 특성을 파악하는 함수, DC에 어떤 특정한 작업을 하기 전에 지원하는지 여부를 확인 할 수 있음.

    nIndex 는 조사하고자 하는 값.

DRIVERVERSION

The device driver version.

TECHNOLOGY

Device technology. It can be any one of the following values.

DT_PLOTTER Vector plotter DT_RASDISPLAY Raster display DT_RASPRINTER Raster printer DT_RASCAMERA Raster camera DT_CHARSTREAM Character stream DT_METAFILE Metafile DT_DISPFILE Display file 

If the hdc parameter is a handle to the DC of an enhanced metafile, the device technology is that of the referenced device as specified to the CreateEnhMetaFile function. To determine whether it is an enhanced metafile DC, use the GetObjectType function.

HORZSIZE

Width, in millimeters, of the physical screen.

VERTSIZE

Height, in millimeters, of the physical screen.

HORZRES

Width, in pixels, of the screen; or for printers, the width, in pixels, of the printable area of the page.

VERTRES

Height, in raster lines, of the screen; or for printers, the height, in pixels, of the printable area of the page.

LOGPIXELSX

Number of pixels per logical inch along the screen width. In a system with multiple display monitors, this value is the same for all monitors.

LOGPIXELSY

Number of pixels per logical inch along the screen height. In a system with multiple display monitors, this value is the same for all monitors.

BITSPIXEL

Number of adjacent color bits for each pixel.

PLANES

Number of color planes.

NUMBRUSHES

Number of device-specific brushes.

NUMPENS

Number of device-specific pens.

NUMFONTS

Number of device-specific fonts.

NUMCOLORS

Number of entries in the device's color table, if the device has a color depth of no more than 8 bits per pixel. For devices with greater color depths, 1 is returned.

ASPECTX

Relative width of a device pixel used for line drawing.

ASPECTY

Relative height of a device pixel used for line drawing.

ASPECTXY

Diagonal width of the device pixel used for line drawing.

PDEVICESIZE

Reserved.

CLIPCAPS

Flag that indicates the clipping capabilities of the device. If the device can clip to a rectangle, it is 1. Otherwise, it is 0.

SIZEPALETTE

Number of entries in the system palette. This index is valid only if the device driver sets the RC_PALETTE bit in the RASTERCAPS index and is available only if the driver is compatible with 16-bit Windows.

NUMRESERVED

Number of reserved entries in the system palette. This index is valid only if the device driver sets the RC_PALETTE bit in the RASTERCAPS index and is available only if the driver is compatible with 16-bit Windows.

COLORRES

Actual color resolution of the device, in bits per pixel. This index is valid only if the device driver sets the RC_PALETTE bit in the RASTERCAPS index and is available only if the driver is compatible with 16-bit Windows.

PHYSICALWIDTH

For printing devices: the width of the physical page, in device units. For example, a printer set to print at 600 dpi on 8.5-x11-inch paper has a physical width value of 5100 device units. Note that the physical page is almost always greater than the printable area of the page, and never smaller.

PHYSICALHEIGHT

For printing devices: the height of the physical page, in device units. For example, a printer set to print at 600 dpi on 8.5-by-11-inch paper has a physical height value of 6600 device units. Note that the physical page is almost always greater than the printable area of the page, and never smaller.

PHYSICALOFFSETX

For printing devices: the distance from the left edge of the physical page to the left edge of the printable area, in device units. For example, a printer set to print at 600 dpi on 8.5-by-11-inch paper, that cannot print on the leftmost 0.25-inch of paper, has a horizontal physical offset of 150 device units.

PHYSICALOFFSETY

For printing devices: the distance from the top edge of the physical page to the top edge of the printable area, in device units. For example, a printer set to print at 600 dpi on 8.5-by-11-inch paper, that cannot print on the topmost 0.5-inch of paper, has a vertical physical offset of 300 device units.

VREFRESH

For display devices: the current vertical refresh rate of the device, in cycles per second (Hz).

A vertical refresh rate value of 0 or 1 represents the display hardware's default refresh rate. This default rate is typically set by switches on a display card or computer motherboard, or by a configuration program that does not use display functions such as ChangeDisplaySettings.

SCALINGFACTORX

Scaling factor for the x-axis of the printer.

SCALINGFACTORY

Scaling factor for the y-axis of the printer.

BLTALIGNMENT

Preferred horizontal drawing alignment, expressed as a multiple of pixels. For best drawing performance, windows should be horizontally aligned to a multiple of this value. A value of zero indicates that the device is accelerated, and any alignment may be used.

SHADEBLENDCAPS

Value that indicates the shading and blending capabilities of the device. See Remarks for further comments.

SB_CONST_ALPHA Handles the SourceConstantAlpha member of the BLENDFUNCTION structure, which is referenced by the blendFunction parameter of the AlphaBlend function. SB_GRAD_RECT Capable of doing GradientFill rectangles. SB_GRAD_TRI Capable of doing GradientFill triangles. SB_NONE Device does not support any of these capabilities. SB_PIXEL_ALPHA Capable of handling per-pixel alpha in AlphaBlend. SB_PREMULT_ALPHA Capable of handling premultiplied alpha in AlphaBlend. 

RASTERCAPS

Value that indicates the raster capabilities of the device, as shown in the following table.

RC_BANDING Requires banding support. RC_BITBLT Capable of transferring bitmaps. RC_BITMAP64 Capable of supporting bitmaps larger than 64 KB. RC_DI_BITMAP Capable of supporting the SetDIBits and GetDIBits functions. RC_DIBTODEV Capable of supporting the SetDIBitsToDevice function. RC_FLOODFILL Capable of performing flood fills. RC_PALETTE Specifies a palette-based device. RC_SCALING Capable of scaling. RC_STRETCHBLT Capable of performing the StretchBlt function. RC_STRETCHDIB Capable of performing the StretchDIBits function. 

CURVECAPS

Value that indicates the curve capabilities of the device, as shown in the following table.

CC_NONE Device does not support curves. CC_CHORD Device can draw chord arcs. CC_CIRCLES Device can draw circles. CC_ELLIPSES Device can draw ellipses. CC_INTERIORS Device can draw interiors. CC_PIE Device can draw pie wedges. CC_ROUNDRECT Device can draw rounded rectangles. CC_STYLED Device can draw styled borders. CC_WIDE Device can draw wide borders. CC_WIDESTYLED Device can draw borders that are wide and styled. 

LINECAPS

Value that indicates the line capabilities of the device, as shown in the following table:

LC_NONE Device does not support lines. LC_INTERIORS Device can draw interiors. LC_MARKER Device can draw a marker. LC_POLYLINE Device can draw a polyline. LC_POLYMARKER Device can draw multiple markers. LC_STYLED Device can draw styled lines. LC_WIDE Device can draw wide lines. LC_WIDESTYLED Device can draw lines that are wide and styled. 

POLYGONALCAPS

Value that indicates the polygon capabilities of the device, as shown in the following table.

PC_NONE Device does not support polygons. PC_INTERIORS Device can draw interiors. PC_POLYGON Device can draw alternate-fill polygons. PC_RECTANGLE Device can draw rectangles. PC_SCANLINE Device can draw a single scanline. PC_STYLED Device can draw styled borders. PC_WIDE Device can draw wide borders. PC_WIDESTYLED Device can draw borders that are wide and styled. PC_WINDPOLYGON Device can draw winding-fill polygons. 

TEXTCAPS

Value that indicates the text capabilities of the device, as shown in the following table.

TC_OP_CHARACTER Device is capable of character output precision. TC_OP_STROKE Device is capable of stroke output precision. TC_CP_STROKE Device is capable of stroke clip precision. TC_CR_90 Device is capable of 90-degree character rotation. TC_CR_ANY Device is capable of any character rotation. TC_SF_X_YINDEP Device can scale independently in the x- and y-directions. TC_SA_DOUBLE Device is capable of doubled character for scaling. TC_SA_INTEGER Device uses integer multiples only for character scaling. TC_SA_CONTIN Device uses any multiples for exact character scaling. TC_EA_DOUBLE Device can draw double-weight characters. TC_IA_ABLE Device can italicize. TC_UA_ABLE Device can underline. TC_SO_ABLE Device can draw strikeouts. TC_RA_ABLE Device can draw raster fonts. TC_VA_ABLE Device can draw vector fonts. TC_RESERVED Reserved; must be zero. TC_SCROLLBLT Device cannot scroll using a bit-block transfer. Note that this meaning may be the opposite of what you expect. 

COLORMGMTCAPS

Value that indicates the color management capabilities of the device.

CM_CMYK_COLOR Device can accept CMYK color space ICC color profile. CM_DEVICE_ICM Device can perform ICM on either the device driver or the device itself. CM_GAMMA_RAMP Device supports GetDeviceGammaRamp and SetDeviceGammaRamp CM_NONE Device does not support ICM.

WM_PAINT 메시지

무효영역

- 응용 프로그램이 윈도우에 그리기를 수행하는 경우가 있음. 효과적인 그리기를 위해, 복잡한 메커니즘이 사용되며,

  이 중 화면의 일부가 변경되어 다시 그려져야 할 부분을 무효영역(Invalide Region == Update Region)이라 함.

  BOOL InvalidateRect(HWND hWnd, CONST RECT* lpRect, BOOL bErase);

  - hWnd 윈도우의 lpRect영역을 무효화하여 다시 그리도록 하는 함수, lpRect가 NULL인 경우 윈도우 전체가 무효화 됨.

    bErase는 무효영역의 배경을 먼저 지울것인가를 지정하는 것으로, TRUE이면 BeginPaint함수가 배경을 먼저 지운후 그려짐.

    무효영역을 계산하는 과정이 복잡하거나, 시간이 소요되더라도 모든 작업영역을 다시그리는 것보다는 훨씬 더 빠르기 때문에,

    무효영역을 계산하여 InvalidateRect의 인자로 넣어주는 것이 좋음.

  BOOL ValidateRect(HWND hWnd, CONST RECT *lpRect);

  - hWnd 윈도우의 lpRect의 영역을 유효화하여 그리기 영역에서 제외 시키는 함수.

  BOOL InvalidateRgn(HWND hWnd, HRGN hRgn, BOOL bErase);

  BOOL ValidateRgn(HWND hWnd, HRGN hRgn);

  - Rect대신 Region 영역에 대해 유/무효화를 수행하는 함수들.

  WM_PAINT 메시지가 보내지는 시점.

  - 첫째로 메시지 큐에 대기중인 메시지가 없어야 함.(우선 순위가 WM_TIMER를 제외하곤 가장 낮은 메시지)

    둘째로 무효영역이 있어야 함.

    응용 프로그램이 아닌 운영체제가 직접 WM_PAINT 메시지를 큐에 넣는다. 응용 프로그램에서는 다만 무효영역을 만들 뿐이며,

    무효영역이 있으면 운영체제가 적당한 때에 WM_PAINT 메시지를 보내 다시 그리도록 함.

  WM_PAINT 통합

  - WM_PAINT 메시지는 메시지 큐에 동시에 두개가 들어가지 않으며, 무효영역을 합치고 메시지도 하나로 줄이는 최적화 동작을 함.

  UpdateWindow 함수

  - 화면이 무효화 되는 시점과 실제로 그려지는 시점은 비동기적임.

    무효화되는 즉시 화면을 다시 그릴때 사용하는 함수는 UpdateWindow임.

    메시지 큐를 거치지 않고, WM_PAINT 메시지를 윈도우 프로시저로 보내기 때문에 바로 처리하게 함.

    단 무효영역이 없을 경우, WM_PAINT 메시지를 발생시키지 않음.

    BOOL RedrawWindow(HWND hWnd, CONST RECT *lprcUpdate, HRGN hrgnUpdate, UINT flags);

    - UpdateWindow 함수와 비슷하지만, 영역 지정이나, 그리기 방법 지정등 더많은 기능이 있다.

클리핑 영역

- 무효영역이란 다시 그려져야 할 부분이지만, 운영체제가 실제 그리기에 사용하는 영역은 클리핑 영역이다.

  화면에 보이는 가시 영역을 말한다. 무효영역은 운영체제에 의해 설정되거나 응용 프로그램이 InvalidateRect 등의 함수로 직접 설정.

  클리핑 영역은 BeginPaint함수에 의해 계산된다.

윈도우 스타일

- 윈도우 스타일 중에 무효영역과 클리핑 영역에 관계된 것들

  WS_CLIPCHILDREN

  - 윈도우가 이 스타일을 가지면 차일드의 영역을 클리핑 영역에서 제외함으로써 차일드가 불필요하게 다시 그려지지 않도록 함.

    즉, 차일드위에 뭔가를 그릴 수 없음.

  WS_CLIPSIBLING

  - 차일드 윈도우에만 적용되는 스타일로, 차일드끼리 겹쳐있을 때 서로의 영역을 침범하지 않도록 함.

  CS_HREDRAW, CS_VREDRAW

  - 가로, 세로 윈도우 크기가 변경될 때 전체 작업영역을 무효화하게 하는 클래스 스타일.

PAINTSTRUCT

- WM_PAINT의 앞에서 BeginPaint함수를 호출할 때 전달하는 인자

  PAINTSTRUCT 구조체의 뒤쪽 세개 멤버는 운영체제가 사용하는 런타임 데이터이므로 무시

  hdc는 DC의 핸들, fErase는 배경을 지울것인가를 지정하는 값으로 0이 아닌값이면 지울 필요가 있는 것.

  rcPaint는 그리기를 해야 할 사각영역을 가짐. 이영역을 잘 활용하면 그리는 속도를 훨씬 더 빠르게 할 수 있음.

BeginPaint

- BeginPaint함수의 동작

  1. 그리기를 위해 DC를 발급받음

  2. 클리핑 영역을 조사하여 DC에 설정

  3. 무효영역을 없애(유효화) 다시 WM_PAINT 메시지가 호출되지 않도록 함.

  4. 다시 그려지는 영역에 캐럿이 있다면, 그리기를 시작하기 전에 숨겨 캐럿이 파괴되지 않도록 함. EndPaint에서 복구됨

  5. 윈도우의 배경을 지우기 위해 WM_ERASEBKGND메시지를 보내고, WM_NCPAINT도 보낸다.

그리기 메시지

- 비작업영역을 커스터마이징 하기위해 WM_NCPAINT메시지를 가로채고, GetWIndowDC로 윈도우 DC를 얻어 원하는대로 그릴 수 있음

  WM_ERASEBKGND 메시지는 배경 브러시가 등록되어 있을 경우 이 브러시로 배경을 칠하는데 이는 곧 배경을 지우는 것

  WM_ERASEBKGND의 wParam으로 DC핸들이 전달되고, 이 핸들은 해제할 필요가 없음.

  GetDC를 이용해 얻은 DC 사용시 문제가 발생할 수 있다. 클리핑 영역이 설정되어 있지 않아 화면 어느 곳이나 그릴 수 있으며 따라서

  배경에 의해 기존 그림이 덮여버릴수 있다.

GetDC

- 대부분의 그리기 동작은 WM_PAINT 메시지 처리 루틴에서 수행하는 것이 정상적임.

  그러나 특수한 경우 WM_PAINT메시지 밖에서 그리기를 하는 것이 더 효율적이거나 즉시 그리기를 해야만 할 때가 있음.

  이때 GetDC함수로 DC 핸들을 얻고, 그리기가 끝난 후, ReleaseDC함수로 해제해준다.

  HDC GetDCEx(HWND hWnd, HRGN hrgnClip, DWORD flags);

  - GetDC에 비해 클리핑 영역 지정에 대한 옵션을 지정할 수 있음

  HWND WindowFromDC(HDC hDC);

  - GetDC의 반대 동작을 하는 함수이다.

그리기 정보의 보관

정보 보관의 필요성

- 윈도우즈용 프로그램의 그리기는 모두 WM_PAINT 메시지에 모아져야 하며 언제든지 WM_PAINT 메시지가 전달되면 원래의 모습대로

  깜쪽같이 그릴수 있어야 하므로, 그리기에 대한 정보들은 어딘가에 저장되어 있어야함.

비트맵에 저장하기

- 메모리 비트맵을 사용하면 어떤 복잡한 형태의 그림이라도 기억할 수 있는 장점이 있으며, 속도도 만족할 만큼 빠르다.

  단 메모리가 조금 많이 드는 것이 단점.

DC 관리

LockWindowUpdate

- BOOL LockWindowUpdate(HWND hWndLock);

  - 화면을 그리기는 작업을 한번에 하기 위해, 화면 그리기를 금지/해제하는 함수

    금지 대상이 될 윈도우 핸들을 인자로 넘기며, NULL을 넘기면 락을 해제 한다는 의미가 된다.

SaveDC

- DC에는 여러 가지 복잡한 정보들이 많이 포함되어 있어, 많은 부분을 변경하였을 때 DC를 저장해 두어야 할 필요가 있을 때 사용

  int SaveDC(HDC hdc);

  - DC의 모든 설정 상태를 스택에 저장해 놓는다. 그리곤 핸들에 해당하는 정수 값을 리턴한다.

  BOOL RestoreDC(HDC hdc, int nSavedDC);

  - SaveDC에서 얻은 정수값은 nSavedDC로 넘겨, hdc에 해당 DC의 핸들을 받는다.

CreateDC

- 윈도우와 관련된 DC는 GetDC등의 함수로 구해 사용하지만 다음 함수를 사용하면 DC를 만들 수도 있음

  HDC CreateDC(LPCTSTR lpszDriver, LPCTSTR lpszDevice, LPCTSTR lpszOutput, CONST DEVMODE* lpInitData);

  - 주로 프린터 DC를 만들 때 사용하지만, 화면 DC를 만들 때도 쓸 수 있음.

    ex) CreateDC("DISPLAY", NULL, NULL, NULL); 이라고 호출하면 전체 화면에 대한 DC를 얻을 수 있음.

신고

'20130827이전 > WinAPI' 카테고리의 다른 글

키보드 입력  (0) 2013.01.28
컴파일 관련 에러 - 1  (0) 2013.01.26
14장. 그리기  (1) 2013.01.20
13장. 메시지  (0) 2013.01.19
12장. 윈도우 관리  (0) 2013.01.18
11장. 윈도우  (1) 2013.01.15
Posted by 흰둥에미

아.. 대망의 메시지

윈도우 프로시저

- 윈도우즈가 이전 운영체제인 도스와 구분되는 가장 큰 차이점은 이벤트 드리븐, 즉 메시지 기반의 운영체제라는 점

  윈도우 프로시저는 윈도우 클래스당 하나씩(윈도우당 하나씩이 아님) 배정되며, 메시지에 대응하는 방식을 정의하여, 행동 양식을 결정

  LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam);

  - 위는 윈도우 프로시저의 원형으로, WNDCLASS구조체의 lpfnWndProc멤버에 이 함수의 포인터가 대입됨.

    운영체제에 의해 호출되는 콜백 함수, 사용자는 SendMessage 함수등을 이용해 간접적으로 호출 해야함.

    윈도우 프로시저는 재진입이 가능한 함수, WndProc 실행중에 또 WndProc가 호출될 수 있다는 듯.

    따라서 지역 변수는 가급적 적게 사용하는 편이 좋음.

메시지 큐

- 시스템이나 사용자의 의해 발생

  사용자 입력시, 시스템 상황 변화를 통지, 윈도우간의 통신을 위해, 특정 함수 호출에 의해 등등

  메시지는 크게 메시지 큐로 들어가는 큐 메시지와 곧바로 윈도우 프로시저로 보내지는 비큐 베시지로 구분됨.

  큐 메시지 - 주로 사용자의 입력으로부터 발생(WM_KEYDOWN, WM_LBUTTONDOWN), 그 외 WM_PAINT, WM_TIMER, WM_QUIT등.

                  시스템 메시지 큐에 저장되어 스레드 메시지 큐로 보내지며 최종적으로 윈도우 프로시저에 의해 입력 순서로 처리됨.

  비큐 메시지 - 윈도우에게 특정 사실을 알리거나 명령을 보내기 위해 큐를 통하지 않고 바로 윈도우 프로시저로 보내지는 메시지.

                     대부분의 메시지들은 비큐 메시지, 메시지 큐와 메시지 루프를 거치지 않으므로 신속하게 처리됨.

  운영체제는 하나의 시스템 메시지 큐(System Idle)를 관리하며, 또한 각 스레드(윈도우가 아닌)별로 하나씩 메시지 큐를 생성함.

  하지만 모든 스레드가 메시지 큐를 가지지는 않음, 윈도우를 전혀 가지지 않는 작업 스레드는 필요가 없기에 생성되지 않음.

메시지 루프

- 사용자에 의해 입력된 메시지는 시스템 메시지 큐에 일단 저장되고, 스레드 메시지 큐로 이동했다가, 메시지 루프에 의해

  해당 윈도우의 윈도우 프로시저로 보내져 처리됨.

  큐에 유지되는 메시지는 아래와 같음

typedef struct tagMSG

{

    HWND hwnd;

    UINT message;

    WPARAM wParam;

    LPARAM lParam;

    DWORD time;  //메시지가 발생한 시간.

    POINT pt;       //메시지 발생시의 마우스 좌표

} MSG;

    WndProc에서 time과 pt가 필요한 경우, DWORD GetMessagePos(VOID)와 LONG GetMessageTime(VOID)로 직접 조사해야 함.

    메시지 루프는 메시지 큐에서 메시지를 꺼내 메시지 처리 함수로 보내는 일을 함.

    BOOL GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax);

    - 스레드 메시지 큐에 대기중인 메시지를 꺼내 첫 번째 인수로 전달된 MSG 구조체에 복사, 메시지를 큐에서 제거하고 TRUE를 리턴

      만약 큐에서 가져온 메시지가 WM_QUIT이면 FALSE를 리턴하여 메시지 루프를 탈출하게 함.

      나머지 세 인수는 메시지 필터링에 사용되며, hWnd는 해당 윈도우와 그 차일드로 보내지는 메시지만 가져오게 하는 인수.

      wMsgFilterMin, wMsgFilterMax에 메시지의 범위를 지정하면 이 범위 내의 메시지만 가져오는데, 쓰지 않을 경우 0으로 지정.

    TranslateMessage는 가상키 입력을 WM_CHAR메시지로 바꾸는 역할을 함.

    DispatchMessage는 메시지를 윈도우 프로시저로 보내 처리하도록 함, MSG구조체의 hWnd멤버에 따라 해당 윈도우로 전달.

    따라서 while(GetMessage(...) { TranslateMessage(..); DispatchMessage(..); } 가 기본 메시지 루프이며,

    단축키가 있을 경우, GetMessage함수 호출 후, 단축키인지 검사하는 TranslateAccelerator를 호출하는 루틴이 추가됨.

PeekMessage

- GetMessage는 블록되는 함수이므로, 메시지가 없을땐 GetMessage함수에서 리턴되지 않는다. 메시지가 들어올 때까지 대기하게

  되며, 이 데드 타임에는 다른 작업을 할 수가 있음. 이때 논블록 함수인 PeekMessage를 이용하여, 메시지 큐에서 메시지를 꺼내거나

  검사하되 메시지가 없더라도 즉각 리턴할 수 있음. 리턴값이 TRUE이면 메시지가 있는 것이고, FALSE이면 없는 것이다.

  마지막 인수인 wRemoveMsg 플래그는 메시지가 있을 경우 큐에서 제거할 것인지, 아닌지를 지정하는 인수(PM_(NO)REMOVE)

  단 PeekMessage함수를 사용할 땐, WM_QUIT메시지에 대한 예외 처리가 필요(GetMessage와 리턴값이 FALSE일때의 의미가 다름)

  메시지 루프외에 사용용도로는 원하는 메시지가 있는지 검사해보는 용도나,

  시간이 오래걸리는 작업 중 다른 메시지를 처리할 기회를 주기 위해 쓰기도 함(메시지 펌프)

아이들 타임

- 응용 프로그램이 아무 것도 하지 않고 노는 시간을 아이들 타임, 데드 타임이라 함.

  타이머를 이용하며, 아이들 타임을 활용하기에는 해상도가 낮고, 메시지의 우선 순위가 느려 반응성이 좋지 않음.

  스레드는 작업에 따라 사용가능하지만, 중요도가 낮은 작업이나, 짧은 작업에 사용하기엔 부담스러움.

  따라서 메시지 루프를 PeekMessage를 이용한 루틴으로 변경하여, 메시지가 없는 시간을 이용하도록 함.

  메시지 루프의 여러 변형을 이용해, 아이들 타임을 효과적으로 사용할 수 있음.

키 상태 조사하기

- WM_KEYDOWN은 키가 눌러질 대 보내지는 메시지, 키를 계속 누르고 있다고 해서 전달되는 것은 아님.

  따라서 키의 현재 상태(눌러졌는지 아니면 떨어져 있는지)를 조사할 때는 다음 두 함수를 사용한다.

  SHORT GetKeyState(int nVirtKey);

  SHORT GetAsyncKeyState(int vKey);

  - 일반키가 눌러져 있을 경우 최상위 비트가 1로 설정됨, CapsLock같은 토글키가 켜져 있을 경우 최하위 비트가 1로 설정됨.

    GetKeyState는 메시지가 발생했을 때의 상황을 조사, GetAsyncKeyState는 이 메시지가 처리될 때의 상황을 조사

  BOOL GetKeyboardState(PBYTE lpKeyState);

  - 256바이트 배열을 할당하여 인자로 넘기면, 모든 가상 키의 상태를 조사하며 가상 키 코드를 첨자로 키의 상태를 알 수 있음.

  입력 메시지를 받지 않고 자신이 원할 때 정보를 조사하는 방식을 폴링이라 함.

트리플 클릭

- 메시지가 발생한 시간과 위치 정보를 사용하면 트리플 클릭을 검출할 수 있음

  단 윈도우 클래스에 CS_DBLCLKS 스타일은 지정하지 말아야 함.

  4픽셀 내외의 위치를 0.5초보다 짧은 간격으로 눌러야 인정.

메시지통신

메시지 보내기와 붙이기

- 메시지를 보내는 함수 둘.

  BOOL PostMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

  - PostMessage 함수는 Msg 인수로 지정된 메시지를 hWnd 윈도우의 메시지 큐에 집어넣는다. 큐에 집어넣는게 성공하면 TRUE리턴

    이때 큐는 윈도우를 위한 큐가 아닌, 스레드를 위한 큐이다.

    다른 스레드의 큐에 메시지를 붙일 때는 BOOL PostThreadMessage(DWORD idThread, UINT Msg, WPARAM, LPARAM) 사용.

    단 스레드 큐가 없는 작업 스레드는 메시지를 받지 못함.

    hWnd가 NULL인 특수한 경우, 대상 윈도우가 없기 때문에 윈도우 프로시저가 처리할 수 없고, 반드시 메시지 루프에서 처리해야함.

  LRESULT SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

  - SendMessage 함수는 메시지를 큐에 넣지 않고, 윈도우 프로시저로 보내 즉각 처리하도록 하며, 처리가 끝날때까지 리턴하지 않음.

    부모 윈도우와 차일드 컨트롤간의 통신에 자주 사용됨.

메시지 데드락

- SendMessage 후 리턴되지 못하는 상황.(SendMessage에 의해 무언가는 처리하는 다른 스레드가 프로세스를 오랫동안 점유)

  첫번째 방법은 InSendMessage()함수를 호출하여, 리턴값이 TRUE(다른 스레드로 부터 온 메시지를 의미)라면,

  BOOL ReplyMessage(LRESULT lResult); 함수를 호출하여, SendMessage로 전달될 메시지를 즉시 리턴해준다.

  LRESULT는 SendMessage의 리턴값을 의미.

  두번째 방법은 SendMessage함수 대신, 다음 두 함수를 이용하는 것

  - BOOL SendNotifyMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM, lParam);

    - SendMessage와 유사하지만, hWnd가 다른 스레드의 윈도우일 경우는 대기를 하지 않고 즉시 리턴,

      따라서 끝까지 처리되어 리턴값을 받아야하는 경우는 사용 불가.

    LRESULT SendMessageTimeout(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, UINT fuFlags, UINT uTimeout,

                                                   PDWORD_PTR lpdwResult);

    - 지정한 경과 시간 이상이 지나면 메시지의 처리 여부에 상관없이 즉시 리턴함.

  요즘은 메시지 통신을 대체할 수 있는 IPC 방법이 많이 개발되어 요즘은 이런 문제가 거의 발생하지 않음.

메시지 콜백

- SendMessage 함수의 블록 특성을 피해가기 위한 함수

  BOOL SendMessageCallback(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, SENDASYNCPROC lpCallback,

                                             ULONG_PTR dwData);

  - 윈도우로 메시지를 보낸 후 즉시 리턴하되 콜백함수를 등록해 놓고 메시지 처리가 끝나면 콜백함수를 호출하도록 함.

    콜백함수 원형 - VOID CALLBACK SendAsyncProc(HWND hWnd, UINT uMsg, ULONG_PTR dwData, LRESULT lResult);

 실제로는 IPC나 동기화 오브젝트가 더 실용적임.

브로드캐스팅

- long BroadcastSystemMessage(DWORD dwFlags, LPDWORD lpdwRecipients, UINT uiMessage, WPARAM, LPARAM);

  시스템 전반에 중요한 정보를 전달할 때 사용

서브클래싱

서브클래싱이란

- 윈도우 프로시저로 전달되는 메시지를 중간에 가로채는 기법

  새로운 윈도우 프로시저 함수를 만들어 두고 특정 윈도우의 윈도우 프로시저 번지를 새로 만든 윈도우 프로시저의 번지로 변경하면,

  모든 메시지는 새로 만든 윈도우 프로시저(서브클래스 프로시저)로 전달됨.

  서브클래스 프로시저의 동작

  - 통과 : 원래의 프로시저로 전달

    직접 처리 : 원하는 메시지는 직접 처리함.

    변형 : 메시지를 변경하여 원래의 윈도우 프로시저로 전달.

  WNDPROC SetWindowLongPtr(HWND hWnd, GWLP_WNDPROC, WNDPROC lpNewWndProc);

  - lpNewWndProc는 새로운 프로시저의 포인터, hWnd는 적용 대상. 리턴값은 이전 윈도우 프로시저의 포인터.

  LRESULT CallWindowProc(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

  - 원래의 프로시저를 호출하기 위한 함수로, lpPrevWndFunc에 호출하기 위한 윈도우 프로시저를 지정.

  주의할 점

  - 윈도우의 원래 기능을 보존

    서브클래스 프로시저는 어떠한 일이 있어도 여분 메모리(cbWndExtra, cbClsExtra로 지정한 메모리)를 건드려서는 안됨.

전역 서브클래싱

- 인스턴스 서브클래싱 : 윈도우가 만들어진 후 그 윈도우 하나에 대해서만 SetWindowLongPtr함수를 이용해 윈도우 프로시저를

                                 교체하는 것

  전역 서브클래싱 : 특정 윈도우가 아닌 윈도우 클래스에 대해 서브클래싱 하는 것, 윈도우 클래스의 WNDCLASS 구조체를 직접 변경

                           SetClassLongPtr함수를 이용하며, 이미 만들어진 윈도우에 대해서는 전혀 효과가 없음.

  - 윈도우 클래스를 조작하는 것이지만 윈도우 클래스 자체는 핸들이 없으므로, 대상이 되는 윈도우가 최소한 하나는 있어야 함.

    숨겨진 윈도우를 미리 만들어 놓거나, 더미 윈도우를 하나 만들고 서브클래싱 후 없애는 방법을 쓰기도 함.

슈퍼클래싱

- 기존의 베이스 클래스의 정보를 바탕으로 완전히 새로운 클래스를 만드는 것(객체 상속과 비슷한 개념)

  단, SCROLLBAR 클래스는 슈퍼클래싱을 해서는 안된다고 알려져 있음(이유는 모름?)

  BOOL GetClassInfo(HINSTANCE hInstance, LPCTSTR lpClassName, LPWNDCLASS lpWndClass);

  - 슈퍼클래싱의 핵심 함수로, lpClassName 윈도우 클래스의 정보를 조사하여, WNDCLASS 구조체를 얻음.

  위 함수를 이용해 얻은 WNDCLASS의 정보를 수정하여, RegisterClass 함수를 호출하면 새로운 윈도우 클래스가 등록됨.

  단, 클래스 이름, hInstance, 윈도우 프로시저는 반드시 변경해줘야 하며,  기존의 윈도우 프로시저의 주소는 잘 보관해 둬야함.

메시지 크래커

고전적인 메시지 처리

- 1. 윈도우 프로시저 내에서 switch-case 문을 이용해서 처리.

  2. 개별 메시지 처리 함수를 만들어 윈도우 프로시저 내 switch-case 문에서 호출

  3. 메시지에 따라 WPARAM과 LPARAM이 의미하는 바에 착안하여, 윈도우 프로시저내에서 파라미터를 메시지에 맞게 분석하여,

     원하는 정보로 변경하여 개별 메시지 처리 함수를 호출하게 함.

   세번째 방법을 메시지 크래커라 하며, windowsx.h에 매크로로 정의 되어 편히 사용할 수 있도록 지원.

Windowsx.h

- 메시지 크래커가 매크로로 작성되어 있음.

컨트롤제어

- 메시지 크래커의 도 다른 기능으로 컨트롤을 제어하는 매크로 구문들이 있음.

메시지 크래커의 장단점

- 이식성에서 유리, 그 외 단점들...

사용자 정의 메시지

메시지 범위

- 메시지 ID의 실제값은 Winuser.h에 정의 되어 있음.

  WM_USER는 0x400으로  이후로 내부 통신용(WM_APP 이전까지)

  WM_APP은 0x800으로 외부 통신용.

사용자 정의 메시지

- #define문을 이용하여 WM_USER+X의 형식으로 메시지를 정의하고, 윈도우 프로시저나 메시지 루프에서 정의된 메시지를 처리하면 됨

  같은 응용 프로그램 내, 부모 윈도우와 차일드 윈도우는 물론, 다른 프로그램과의 통신도 가능하다.

문자열로 메시지 등록하기

- 프로그램끼리 동일한 사용자 메시지 값을 정의할 수 있고, 그에 따라 혼선 내지 원치 않는 결과가 발생할 수 있음.

  UINT RegisterWindowMessage(LPCTSTR lpString);

  - 문자열로 받고 싶은 메시지의 이름을 전달하면, 빈 ID를 리턴해줌. 만약 등록된 이름이면 등록된 ID를 리턴함.

    어차피 중복이란 발생할 수 있지만, 이름이 중복되지 않는 한 절대로 이 ID를 다른 프로그램이 사용할 경우가 없어짐.



신고

'20130827이전 > WinAPI' 카테고리의 다른 글

컴파일 관련 에러 - 1  (0) 2013.01.26
14장. 그리기  (1) 2013.01.20
13장. 메시지  (0) 2013.01.19
12장. 윈도우 관리  (0) 2013.01.18
11장. 윈도우  (1) 2013.01.15
10장. MFC 소개  (0) 2013.01.15
Posted by 흰둥에미

윈도우와 관련된 API함수들의 공통점은 첫 번째 인수로 윈도우 핸들을 받거나, 윈도우 핸들을 리턴하는 경우가 많은 것

생성 및 파괴

- 아래 두 함수는 윈도우를 파괴하거나 최소화함.

  BOOL DestroyWindow(HWND hWnd);

  - 지정한 윈도우를 파괴

    WM_DESTROY 메시지를 보내 종료 처리 기회를 부여, 키보드 포커스를 버리고 메뉴를 파괴하고 메시지 큐를 완전히 비움.

    동작중인 타이머가 있으면 파괴, 클립보드 소유권을 제거

    자식 윈도우를 가지고 있는 경우 차일드를 같이 파괴하는데, WM_DESTROY 메시지가 전달됨.

    직계 자식에게만 WM_DESTROY 메시지가 전달되며, 손자, 증손자에게는 메시지가 전파되는 형식.

  BOOL CloseWindow(HWND hWnd);

  - 윈도우를 단순히 최소화하기만 함, ShowWindow(hWnd, SW_MINIMIZE)와 기능적으로 동일

위치와 크기

- 윈도우의 위치와 크기를 얻을 때는 아래 두 함수를 사용.

  BOOL GetWindowRect(HWND hWnd, LPRECT lpRect);

  - 윈도우의 좌표이므로, 화면 좌표 기준

  BOOL GetClientRect(HWND hWnd, LPRECT lpRect);

  - 대상 윈도우의 작업영역 좌표를 구함, 좌상단은 항상 0,0

- 윈도우의 위치와 크기를 동시에 변경하는 함수

  MoveWindow(HWND hWnd, int X, int Y, int nWidth, int nHeight, BOOL bRepaint);

  - 인수의 의미는 순서대로 핸들, 좌상단 좌표, 너비, 높이, 그리고 윈도우를 다시 그릴지의 여부이다.

- 다음 함수는 MoveWindow의 기능에 더불어, 윈도우의 Z순서 변경, 크기 변경 및 이동에 몇 가지 옵션을 줄 수 있음.

  BOOL SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags);

  - hWndInsertAfter 멤버는 윈도우의 Z순서

HWND_BOTTOM

(HWND)1

Places the window at the bottom of the Z order. If the hWnd parameter identifies a topmost window, the window loses its topmost status and is placed at the bottom of all other windows.

HWND_NOTOPMOST

(HWND)-2

Places the window above all non-topmost windows (that is, behind all topmost windows). This flag has no effect if the window is already a non-topmost window.

HWND_TOP

(HWND)0

Places the window at the top of the Z order.

HWND_TOPMOST

(HWND)-1

Places the window above all non-topmost windows. The window maintains its topmost position even when it is deactivated.

  - uFlags는 이 함수의 동작 방식을 설정하는 여러 가지 플래그의 조합

SWP_ASYNCWINDOWPOS

0x4000

If the calling thread and the thread that owns the window are attached to different input queues, the system posts the request to the thread that owns the window. This prevents the calling thread from blocking its execution while other threads process the request.

SWP_DEFERERASE

0x2000

Prevents generation of the WM_SYNCPAINT message.

SWP_DRAWFRAME

0x0020

Draws a frame (defined in the window's class description) around the window.

SWP_FRAMECHANGED

0x0020

Applies new frame styles set using the SetWindowLong function. Sends a WM_NCCALCSIZE message to the window, even if the window's size is not being changed. If this flag is not specified, WM_NCCALCSIZE is sent only when the window's size is being changed.

SWP_HIDEWINDOW

0x0080

Hides the window.

SWP_NOACTIVATE

0x0010

Does not activate the window. If this flag is not set, the window is activated and moved to the top of either the topmost or non-topmost group (depending on the setting of the hWndInsertAfter parameter).

SWP_NOCOPYBITS

0x0100

Discards the entire contents of the client area. If this flag is not specified, the valid contents of the client area are saved and copied back into the client area after the window is sized or repositioned.

SWP_NOMOVE

0x0002

Retains the current position (ignores X and Y parameters).

SWP_NOOWNERZORDER

0x0200

Does not change the owner window's position in the Z order.

SWP_NOREDRAW

0x0008

Does not redraw changes. If this flag is set, no repainting of any kind occurs. This applies to the client area, the nonclient area (including the title bar and scroll bars), and any part of the parent window uncovered as a result of the window being moved. When this flag is set, the application must explicitly invalidate or redraw any parts of the window and parent window that need redrawing.

SWP_NOREPOSITION

0x0200

Same as the SWP_NOOWNERZORDER flag.

SWP_NOSENDCHANGING

0x0400

Prevents the window from receiving the WM_WINDOWPOSCHANGING message.

SWP_NOSIZE

0x0001

Retains the current size (ignores the cx and cy parameters).

SWP_NOZORDER

0x0004

Retains the current Z order (ignores the hWndInsertAfter parameter).

SWP_SHOWWINDOW

0x0040

Displays the window.

  - SWP_NOSIZE나 SWP_NOMOVE 플래그를 지원하기에 MoveWindow 함수를 이용해 윈도우를 이동, 조절하는 것보다 간편함

- 여러 개의 윈도우 위치를 한꺼번에 옮겨 차일드를 일괄 재배치할 때는 다음 세 함수가 사용됨.

  - HDWP BeginDeferWindowPos(int nNumWindows);

    - 위 함수는 복수 윈도우의 크기와 위치를 저장하기 위한 메모리를 할당

    HDWP DeferWindowPos(HDWP hWinPosInfo, HWND hWnd, HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT uFlags);

    - 위 함수는 윈도우들의 배치 상태를 BeginDeferWindowPos로 내부적으로 할당한 배열에 기록.

      옮기고자 하는 윈도우들에 대해 루프를 돌며 배열에 순서대로 기록하면 됨.

    BOOL EndDeferWindowPos(HDWP hWinPosInfo);

    - 위에서 만들어진 정보대로 윈도우를 일괄 재배치, 각각에 대해 SetWindowPos를 호출하는 것보다 빠르고 깔끔함.

- 윈도우의 위치와 크기를 조사 및 변경하는 또 다른 함수

  - BOOL GetWIndowPlacement(HWND hWnd, WINDOWPLACEMENT* lpwndpl);

    BOOL SetWindowPlacement(HWND hWnd, CONST WINDOWPLACEMENT* lpwndpl);

    - 윈도우의 위치, 크기는 물론이고 최대, 최소화 상태를 한꺼번에 조사 및 변경할 수 있음.

      typedef struct tagWINDOWPLACEMENT
     {
         UINT  length;
         UINT  flags;
         UINT  showCmd;
         POINT ptMinPosition;
         POINT ptMaxPosition;
         RECT  rcNormalPosition;
     } WINDOWPLACEMENT;
     length는 버전 확인용, showCmd는 현재 보이기 상태, 마지막 세 멤버는 각각 최소, 최대, 노멀 좌표를 지정.

      현재 좌표 상태를 종료 직전에 레지스트리에 저장해 놓고 다음 실행시에 그대로 불러오기 위해 주로 사용.

- 화면 좌표와 작업 영역

  - GetCursorPos에서 구해지는 좌표는 항상 화면 좌표, WM_LBUTTONDOWN의 lParam은 작업 영역 좌표

    GetWindowRect함수는 윈도우의 화면상 위치(타이틀 바의 모서리 위치)

    게다가 제어판에서 사용자가 선택한 옵션에 따라 달라질 수 있으므로 GetSystemMetrics 함수로 일일이 조사해야 정확한 값이나옴.

  - 위와 같은 번거로움을 해결하기 위해 다음 두 함수가 있음.

    BOOL ScreenToClient(HWND hWnd, LPPOINT lpPoint);

    - 화면 좌표를 작업영역 좌표로

    BOOL ClientToScreen(HWND hWnd, LPPOINT lpPoint);

    - 작업영역 좌표를 화면 좌표로

    - ScreenToClient(hWnd, (LPPOINT)&rect);  ScreenToClient(hWnd, (LPPOINT)&rect+1);

  - int MapWindowPoints(HWND hWndFrom, HWND hWndTo, LPPOINT lpPoints, UINT cPoints);

    - ScreenToClient 대신 위 함수를 사용할 수도 있음.

      특정 윈도우를 기준으로 한 좌표들을 다른 윈도우를 기준으로 한 좌표로 변환

  - void MoveToParentCenter(HWND hWnd);

    - 부모 윈도우의 정중앙으로 이동 시키는 함수.

작업영역 크기 설정

- 작업영역을 특정한 크기로 맞추어야 한다면 아래의 함수를 사용한다.

  - BOOL AdjustWindowRect(LPRECT lpRect, DWORD dwStyle, BOOL bMenu);

    BOOL AdjustWindowRectEx(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle);

    - 원하는 작업영역의 크기를 주면 작업영역 크기에 맞는 윈도우 크기를 계산

더보기

상태 조사 및 변경

- 타이틀 바에 나타나는 캡션 문자열의 조사, 변경을 위한 함수, 외에도 버튼 윈도우 캡션, 에디트의 문자열등에도 사용

  - int GetWindowText(HWND hWnd, LPTSTR lpString, int nMaxCount);

    BOOL SetWindowText(HWND hWnd, LPCTSTR lpString);

    int GetWindowTextLength(HWND hWnd);

- 윈도우의 현재 상태를 조사

  - BOOL IsWindow(HWND hWnd);

    BOOL IsWindowVisible(HWND hWnd);

    BOOL IsWindowEnabled(HWND hWnd);

    BOOL IsChild(HWND hWndParent, HWND hWnd);

    BOOL IsIconic(HWND hWnd);

    BOOL IsZoomed(HWND hWnd);

- 윈도우의 상태를 변경하는 함수.

  - BOOL EnableWindow(HWND hWnd, BOOL bEnable);

    BOOL ShowWindow(HWND hWnd, int nCmdShow);

Z순서 변경

- SetWindowPos 함수로 바꿀 수 있음.

  BOOL SetForegroundWindow(HWND hWnd); --> FindWindow와 연동해서 많이 쓰임

  - 자신이 포그라운드이거나 포그라운드 프로세스가 없을 때, hWnd가 속한 스레드를 포그라운드 상태로 만든다.

    BringWindowToTop함수는 지정한 윈도우를 Z순서의 제일 처음으로 이동시키는데 마찬가지로 포그라운드 스레드가 호출할때만 동작

  HWND GetForegroundWindow(VOID);

  - 포그라운드의 윈도우 핸들을 얻음.

  HWND SetActiveWindow(HWND hWnd);

  - 활성 윈도우를 변경, 단 같은 스레드 내의 윈도우에 대해서만 동작하며, 다른 스레드의 윈도우를 활성화하지는 못함.

  HWND GetActiveWindow(VOID);

  - 활성 윈도우의 핸들을 리턴.

윈도우 찾기

- 윈도우간의 상호 작용을 위해선 핸들이 필요

  - HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName);

    - 윈도우 클래스 이름이나 캡션을 인수로 주어 해당하는 윈도우 핸들을 리턴(하나의 인수만도 가능, 두 개 다 넣으면 캡션은 무시)

      자신이 직접 만든 윈도우에만 제한적으로 사용 가능

  - HWND FindWindowEx(HWND hwndParent, HWND hwndChildAfter, LPCTSTR lpszClass, LPCTSTR lpszWindow);

    - hwndParent 윈도우에 속한 차일드 윈도우를 검색, NULL일 경우 데스크탑 윈도우의 차일드를 검색

      hwndChildAfter 는 검색을 시작할 차일드 윈도우를 지정(Z순서에 따라)

  - HWND WindowFromPoint(POINT Point);

    - 화면 좌표로 윈도우를 검색, 단 숨겨진 윈도우나 사용금지된 윈도우는 검색 대상에서 제외, 스태틱 컨트롤 아래의 윈도우를 조사

  - HWND ChildWindowFromPoint(HWND hWndParent, POINT Point);

    HWND ChildWindowFromPointEx(HWND hwndParent, POINT pt, UINT uFlags);

    - Point는 hWndParent 부모 윈도우의 작업영역 좌표임, Point가 작업영역의 범위를 벗어나면 NULL을 리턴

      uFlags에 검색 제외 조건을 지정 할 수 있음.

윈도우 열거

- BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam);

  - 실행중인 모든 최상위 윈도우들을 열거(시스템이 생성한 일부 최상위 윈도우는 WM_CHILD스타일이 있어도 예외적으로 열거됨)하여,

    첫 번째 인수로 지정된 콜백함수를 호출, lParam은 콜백함수로 전달될 데이터

    콜백 함수가 FALSE를 리턴하면 열거가 중지됨.

    콜백 함수 원형 - BOOL CALLBACK EnumWindowProc(HWND hWnd, LPARAM lParam);

- BOOL EnumChildWindows(HWND hWndParent, WNDENUMPROC lpEnumFunc, LPARAM lParam);

  BOOL EnumThreadWindows(DWORD dwThreadId, WNDENUMPROC lpfn, LPARAM lParam);

  - 특정 부모 윈도우의 차일드만 열거하거나, 특정 스레드에 속한 윈도우의 목록을 조사하는 함수들.

윈도우 관련 메시지

생성

- CreateWindow 함수가 호출될 때 비작업영역이 생성되고 난 직후에 WM_NCCREATE메시지가 전달되며,

  작업영역이 생성되고 난 직후 WM_CREATE 메시지가 전달된다.

  WM_CREATE에서는 프로그램(또는 해당 윈도우)에 필요한 초기화를 한다. 이 때 hWnd는 유효한 윈도우 핸들을 가지고 있다.

  차일드 윈도우를 생성하기에 적절한 시점임.

  lParam으로 CREATESTRUCT 구조체를 전달받으며, CreateWindow에서 지정한 인수를 모두 조사할 수 있음.

파괴

- 프로그램 닫기가 수행되면, WM_CLOSE메시지가 전달된다.

  이 메시지를 DefWindowProc로 넘기면 디폴트로 DestroyWindow를 호출하므로, 윈도우가 파괴된다.

  WM_CLOSE메시지에서 프로그램 종료 여부를 물어 볼 수 있다.

  윈도우가 파괴될 때는 차례대로 WM_DESTROY, WM_NCDESTROY 메시지가 전달된다.

  위 메시지에서 필요한 종료 처리를 주로 한다(파일을 닫거나, 동적 메모리를 해제 한다거나, 전역 자원을 해제하는 등)

  메인 윈도우일 경우 PostQuitMessage 함수를 호출하여 응용 프로그램을 종료하는 중요한 처리도 해야 함.

  WM_DESTROY메시지에서 종료 확인은 안됨.

크기 변경

- 윈도우의 크기가 변경될 때는 WM_SIZE 메시지가 전달된다.

  이 때 차일드의 위치를 재정렬한다. GetClientRect 함수로 직접 조사하여 재정렬이 이루어지면, 외부에서 재정렬이 필요할 때 단순히

  WM_SIZE 메시지만 보내면 됨.

  wParam - SIZE_MAXHIDE 다른 윈도우가 최대화되었을 때 모든 팝업 윈도우로 전달됨.

                SIZE_MAXMIZED 최대화 됨, SIZE_MAXSHOW 다른 윈도우가 복구되었을 때 모든 팝업 윈도우로 전달

                SIZE_MINIMIZED 최소화 됨. SIZE_RESTORED 최소,최대화가 아닌 크기 변경

  LOWORD(lParam) - 작업 영역의 폭

  HIWORD(lParam) - 작업 영역의 높이

  wParam 값 중 특히 SIZE_MINIMIZED에 대해서는 다소 특별한 처리가 요구됨.(작업 영역의 폭이 0이 되므로)

  - 부모의 작업영역을 분할하여 차일드를 배치하는 경우, 어차피 복구되면 원래 상태로 재배치해야 하므로 최소화될 때는 차일드를 굳이 

    다시 배치할 필요가 없음.

    문자열을 윈도우 폭에 맞게 정렬하는 경우는 최소화 상태일 때는 금지(폭이 0인 윈도우에 대해 문서의 길이는 무한대가 되어 버림

    if (wParam != SIZE_MINIMIZED) { }

- WM_SIZING 메시지는 사용자가 윈도우 크기를 변경하고 있을 때 발생

  wParam - 윈도우의 경계선이 어느쪽인가를 나타냄 WMSZ_BOTTOM, WMSZ_LEFT, WMSZ_TOP

  lParam - 현재 윈도우의 영역을 화면 좌표로 가지고 있는 RECT 구조체의 포인터가 전달됨.

  이 메시지에서 좌표를 변경했으면 반드시 TRUE를 리턴해야 함.

* 바탕화면 등록 정보의 "마우스 끄는 동안 창 내용 표시" 옵션이 켜져 있으면 WM_SIZE도 드래그하는 중에 매번 전달됨

- WM_GETMINMAXINFO는 윈도우의 크기나 위치를 바꾸기 전에 이메시지를,

  응용 프로그램으로 보내어 위치와 크기에 대해 제한을 할 수 있는 기회를 줌.

  - lParam - MINMAXINFO라는 구조체의 포인터가 전달됨.

    typedef struct tagMINMAXINFO {
    POINT ptReserved;
    POINT ptMaxSize;
    POINT ptMaxPosition;
    POINT ptMinTrackSize;
    POINT ptMaxTrackSize;
    } MINMAXINFO;

이동

- 윈도우가 이동중일 때는 WM_MOVING 메시지가 전달됨. 이 때 윈도우의 위치나 크기가 어떻게 변하는가를 감시하거나 강제로 변경할

  수 있음.

  WM_MOVE 메시지는 윈도우의 이동이 완료되었을 때 전달됨, lParam의 상,하위 워드에는 각각 새 위치의 x좌표와 y좌표가 전달됨.

- 다음 두 메시지는 윈도우의 위치와 크기, Z순서가 변할때 전달됨.

  이동중일 때는 WM_WINDOWPOSCHANGING 메시지가 전달되고, 이동이 완료되었을 땐 WM_WINDOWPOSCHANGED가 전달됨.

  lParam에는 WINDOWPOS 구조체가 전달됨.

  typedef struct tagWINDOWPOS { /* wp */
     HWND hwnd;
     HWND hwndInsertAfter;
     int x;
     int y;
     int cx;
     int cy;
     UINT flags;
  } WINDOWPOS;

액티브 상태 변경

- 사용자의 입력을 받아들일 수 있는 활성화 상태의 윈도우는 오직 하나만 존재

  WM_ACTIVATEAPP 메시지는 응용 프로그램이 활성화되거나 비활성화될 때 보내짐. wParam이 TRUE이면 이 메시지를 받은

  프로그램이 활성화되는 것이고, FALSE이면 비활성화되는 것. lParam으로는 활성화 상태가 변경될 때 상대편 윈도우를 소유한

  스레드의 ID가 전달됨.

  WM_NCACTIVATE 메시지는 비작업영역의 활성화 상태가 변경될 때 보내지는데 wParam이 TRUE이면 활성화, FALSE이면 비활성화

  WM_ACTIVATE 메시지는 활성화 상태가 변경되는 개별 윈도우에게 보내지는 메시지

  LOWORD(wParam)에 활성화 여부가 전달(WA_INACTIVE:비활성, WA_CLICKACTIVE:클릭에의한활성, WA_ACTIVE:그외활성)

  HIWORD(wParam)이 0이외의 값을 가지면 윈도우가 최소화 되어 있는 것

  lParam은 윈도우의 활성/비활성화에 따라 활성상태가 변경된 상대편 윈도우의 핸들이 전달.

  같은 프로그램 내부에서는 WM_ACTIVATE메시지만 전달됨.

- 포커스가 변경될 땐, WM_SETFOCUS, WM_KILLFOCUS 메시지가 전달 됨. (SetFocus와 GetFocus함수)

  wParam으로는 포커스를 얻거나 잃은 윈도우의 핸들이 전달됨.

상태 변경

- WM_SHOWWINDOW 메시지는 윈도우가 보여지거나 숨겨지기 직전에 보내짐,

  wParam이 TRUE이면 윈도우가 보이기 직전이며, FALSE이면 숨겨지기 직전임

  lParam은 이 메시지가 보내진 이유, ShowWindow 함수에 의해 발생한 메시지이면 값은 0

  - SW_OTHERUNZOOM : 최대화되어 있던 다른 윈도우의 복구에 의해, SW_OTHERZOOM : 다른 윈도우의 최대화로 가려짐

    SW_PARENTCLOSING : 소유자 윈도우가 최소화됨. SW_PARENTOPENING : 소유자 윈도우가 복구됨.

- WM_ENABLE 메시지는 윈도우 사용 금지/허가 상태가 변경될 때 발생, wParam이 TRUE면 사용 허가, FALSE이면 사용 금지

  EnableWindow 함수에 의해 위 메시지를 발생 시킬 수 있음.

WM_NCHITTEST

- 현재 마우스 커서 위치가 윈도우의 어떤 부분인지를 조사할 때 윈도우에게 WM_NCHITTEST라는 메시지를 먼저 보냄

  lParam에는 커서의 현재 좌표가 전달됨,

  일반적으로 DefWindowProc로 바로 전달후, 리턴되는 값을 참조하여, 커서를 바꾸고 디폴트 처리를 함.

  리턴값이 중요한 의미를 가짐.

HTBORDER

18

In the border of a window that does not have a sizing border.

HTBOTTOM

15

In the lower-horizontal border of a resizable window (the user can click the mouse to resize the window vertically).

HTBOTTOMLEFT

16

In the lower-left corner of a border of a resizable window (the user can click the mouse to resize the window diagonally).

HTBOTTOMRIGHT

17

In the lower-right corner of a border of a resizable window (the user can click the mouse to resize the window diagonally).

HTCAPTION

2

In a title bar.

HTCLIENT

1

In a client area.

HTCLOSE

20

In a Close button.

HTERROR

-2

On the screen background or on a dividing line between windows (same as HTNOWHERE, except that the DefWindowProc function produces a system beep to indicate an error).

HTGROWBOX

4

In a size box (same as HTSIZE).

HTHELP

21

In a Help button.

HTHSCROLL

6

In a horizontal scroll bar.

HTLEFT

10

In the left border of a resizable window (the user can click the mouse to resize the window horizontally).

HTMENU

5

In a menu.

HTMAXBUTTON

9

In a Maximize button.

HTMINBUTTON

8

In a Minimize button.

HTNOWHERE

0

On the screen background or on a dividing line between windows.

HTREDUCE

8

In a Minimize button.

HTRIGHT

11

In the right border of a resizable window (the user can click the mouse to resize the window horizontally).

HTSIZE

4

In a size box (same as HTGROWBOX).

HTSYSMENU

3

In a window menu or in a Close button in a child window.

HTTOP

12

In the upper-horizontal border of a window.

HTTOPLEFT

13

In the upper-left corner of a window border.

HTTOPRIGHT

14

In the upper-right corner of a window border.

HTTRANSPARENT

-1

In a window currently covered by another window in the same thread (the message will be sent to underlying windows in the same thread until one of them returns a code that is not HTTRANSPARENT).

HTVSCROLL

7

In the vertical scroll bar.

HTZOOM

9

In a Maximize button.

더보기

특수한 윈도우

윈도우 리전

- 불규칙한 모양의 윈도우를 만들 때는 리전을 사용

  int SetWindowRgn(HWND hWnd, HRGN hRng, BOOL bRedraw);

  - 리전 생성 함수로 리전을 만든 후 이 함수로 hRgn을 윈도우 리전으로 설정

    윈도우 리전에 사용되는 좌표는 작업영역 좌표가 아닌 윈도우 좌표이므로 신경써야 함.

반투명한 윈도우

- 레이어드 윈도우, WS_EX_LAYERED 확장 스타일을 주어 생성

  BOOL SetLayeredWIndowAttributes(HWND hWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);

  - 일단 레이어드 윈도우가 되면, 위 함수를 호출하기 전에는 화면에 보이지 않음.

    crKey - 투명으로 처리할 색상, bAlpha - 윈도우 전체의 반투명 정도를 지정 (0이면 완전 투명)

    dwFlags - 두 효과중 어떤 효과를 적용할 것인가를 지정(LWA_COLORKEY crKey적용, LWA_ALPHA bAlpha적용, OR가능)

  UpdateLayeredWIndow라는 함수를 이용해 모양도 자유 자재로 바꿀 수 있고, 더 많은 효과를 줄 수 있음.

윈도우 애니메이션

- BOOL AnimateWindow(HWND hWnd, DWORD dwTime, DWORD dwFlags);

  - 메뉴가 슬라이딩 된다거나, Fade-in 효과등은 위 함수로 구현.

    dwTime - 애니메이션 시간, dwFlags - 애니메이션 종류와 방식.



신고

'20130827이전 > WinAPI' 카테고리의 다른 글

14장. 그리기  (1) 2013.01.20
13장. 메시지  (0) 2013.01.19
12장. 윈도우 관리  (0) 2013.01.18
11장. 윈도우  (1) 2013.01.15
10장. MFC 소개  (0) 2013.01.15
9장. API 실습  (0) 2013.01.15
Posted by 흰둥에미

자.. 여기서부턴 책의 내용을 다 쓰지 않는다.

10장까지는 다 읽으며, 요약하고, 필요없는 부분만 추려내고 했지만..

여기서부턴 내용이 깊게 들어가니까,

몰랐는데 필요하거나 외우고 있는게 좋다라고 생각되는 부분,

반드시 알아야 할 부분들만 정리한다.

저자도 일차 통독 후, 레퍼런스 용으로 쓰라고 권한다..;;


윈도우

- 정의 : 프로그램이 출력 결과를 내 보내고 사용자로부터 입력을 받아들이는 화면상의 사각영역


윈도우의 구성요소

- 중요한 건 작업영역(Client Area)

  그 외 부분은 (Non Client Area) (함수들에 NC~~ 이런것들이 이와 관련된 함수들이다.)


윈도우 클래스

정의

- CreateWindow 함수의 첫 번째 인수 lpszClassName은 만들고자 하는 윈도우의 클래스를 지정하며, 생략할 수 없음.

  제일 중요한 것은 메시지 처리 방식을 지정하는 윈도우 프로시저이며, 윈도우의 모양과 기능에 고유성을 부여.

  윈도우 생성과정이 RegisterClass와 CreateWindow로 분리됨으로써, 여러가지 이점이 있다.

  (여러개의 똑같은 윈도우 생성, 미리 정의해 놓은 윈도우 클래스 사용 등등)

윈도우 클래스의 종류

- 시스템 전역 클래스 - button, edit, scrollbar, listbox 등이며 클래스 이름이 시스템에 의해 미리 정해져 있음.

  응용 프로그램 전역 클래스

  - 주로 DLL에 의해 등록되며 프로세스의 모든 모듈에서 이 클래스를 사용할 수 있음.

    여러 프로그램이 함께 공유해야할 커스텀 컨트롤을 만들 때 사용됨.

    클래스 스타일에 CS_GLOBALCLASS 스타일을 지정해야 함.

  응용 프로그램 로컬 클래스

  - 응용 프로그램 자신이 메인 윈도우나 차일드 또는 커스텀 컨트롤을 만들기 위해 프로그램 선두에서 등록하는 클래스

    운영체제는 응용 프로그램 로컬 -> 응용 프로그램 전역 -> 시스템 전역 순으로 윈도우 클래스를 찾으므로,

    시스템 전역 클래스를 자신이 만든 로컬 클래스로 오버라이드 하는 것도 가능하다.

WNDCLASS구조체

- 이 구조체에 값을 채워 넣은 후 RegisterClass 함수를 호출하면 윈도우 클래스가 등록됨.

  lpszClassName, lpfnWndProc, hInstance 세 멤버는 반드시 지정해야 함.

  hbrBackground - NULL로 지정하면, WM_ERASEBKGND 메시지에서 직접 배경을 지워줘야함.

  cbClsExtra - 윈도우 클래스에서 사용하고자 하는 여분의 메모리양을 바이트 단위로 지정.

                     SetClassLong(Ptr), GetClassLong(Ptr) 함수를 이용해 접근

  cbWndExtra- CreateWindow로 생성하는 윈도우마다 여분의 메모리를 지정.

                     SetWindowLong(Ptr), GetWindowLong(Ptr)함수를 이용해 접근.

윈도우 클래스의 스타일

- CS_HREDRAW - 폭이 변경되면 윈도우를 다시 그림

  CS_VREDRAW - 높이가 변경되면 윈도우를 다시 그림.

  CS_NOCLOSE - 시스템 메뉴의 닫기 명령을 사용하지 못함(x버튼, ALT-F4도 불가), 별도의 종료 방법을 제공해야 함.

  ...

WNDCLASSEX

- Win32 API는 WNDCLASSEX구조체를 쓸 수 있다.

  WNDCLASS 구조체에 cbSize와 hIconSm 멤버가 추가된 구조체

  - cbSize : 구조체 버전 확인을 위해 구조체의 크기를 대입하는 방법을 위한 멤버(첫 번째 멤버)

    hIconSm : 16X16 사이즈의 아이콘을 지정.

- ATOM RegisterClassEx(CONST WNDCLASSEX* lpwcx);

  - 정의한 구조체와 등록 함수는 반드시 짝이 일치해야 하며, WNDCLASSEX구조체를 사용한 경우 cbSize도 정확하게 지정해야 함.

SetClassLong

- DWORD GetClassLong(HWND hWnd, int nIndex);

  DWORD SetClassLong(HWND hWnd, int nIndex, LONG dwNewLong);

  - 윈도우가 만들어진 후에 WNDCLASS 구조체의 값을 변경하거나 조사하고자 할 때는 위 두 함수를 사용

    하지만 64bit 운영체제를 지원하지 않기에 아래 함수를 사용해야 함.

  LONG_PTR GetClassLongPtr(HWND hWnd, int nIndex);

  ULONG_PTR SetClassLongPtr(HWND hWnd, int nIndex, LONG_PTR dwNewLong);

  - LONG_PTR은 윈도우즈 버전에 따라 32비트가 되기도 하고, 64비트가 되기도 함.

    nIndex - 조사하거나 설정하고자 하는 값으로, GCL_로 시작되는 값은 32비트로 고정된 타입

                 GCLP_로 시작되는 값은 64비트 호환 타입임.

스타일의 종류

- WS_로 시작되는 일반적인 윈도우 스타일이 있고, LBS_는 리스트 박스, BS_는 버튼, ES_는 에디트, CBS는 콤보 박스의 스타일

  일반적인 윈도우의 스타일

WS_BORDER

0x00800000L

The window has a thin-line border.

WS_CAPTION

0x00C00000L

The window has a title bar (includes the WS_BORDER style).

WS_CHILD

0x40000000L

The window is a child window. A window with this style cannot have a menu bar. This style cannot be used with the WS_POPUP style.

WS_CHILDWINDOW

0x40000000L

Same as the WS_CHILD style.

WS_CLIPCHILDREN

0x02000000L

Excludes the area occupied by child windows when drawing occurs within the parent window. This style is used when creating the parent window.

WS_CLIPSIBLINGS

0x04000000L

Clips child windows relative to each other; that is, when a particular child window receives a WM_PAINT message, the WS_CLIPSIBLINGS style clips all other overlapping child windows out of the region of the child window to be updated. If WS_CLIPSIBLINGS is not specified and child windows overlap, it is possible, when drawing within the client area of a child window, to draw within the client area of a neighboring child window.

WS_DISABLED

0x08000000L

The window is initially disabled. A disabled window cannot receive input from the user. To change this after a window has been created, use the EnableWindow function.

WS_DLGFRAME

0x00400000L

The window has a border of a style typically used with dialog boxes. A window with this style cannot have a title bar.

WS_GROUP

0x00020000L

The window is the first control of a group of controls. The group consists of this first control and all controls defined after it, up to the next control with the WS_GROUP style. The first control in each group usually has the WS_TABSTOP style so that the user can move from group to group. The user can subsequently change the keyboard focus from one control in the group to the next control in the group by using the direction keys.

You can turn this style on and off to change dialog box navigation. To change this style after a window has been created, use the SetWindowLong function.

WS_HSCROLL

0x00100000L

The window has a horizontal scroll bar.

WS_ICONIC

0x20000000L

The window is initially minimized. Same as the WS_MINIMIZE style.

WS_MAXIMIZE

0x01000000L

The window is initially maximized.

WS_MAXIMIZEBOX

0x00010000L

The window has a maximize button. Cannot be combined with the WS_EX_CONTEXTHELP style. The WS_SYSMENU style must also be specified.

WS_MINIMIZE

0x20000000L

The window is initially minimized. Same as the WS_ICONIC style.

WS_MINIMIZEBOX

0x00020000L

The window has a minimize button. Cannot be combined with the WS_EX_CONTEXTHELP style. The WS_SYSMENU style must also be specified.

WS_OVERLAPPED

0x00000000L

The window is an overlapped window. An overlapped window has a title bar and a border. Same as the WS_TILED style.

WS_OVERLAPPEDWINDOW

(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX)

The window is an overlapped window. Same as the WS_TILEDWINDOW style.

WS_POPUP

0x80000000L

The windows is a pop-up window. This style cannot be used with the WS_CHILD style.

WS_POPUPWINDOW

(WS_POPUP | WS_BORDER | WS_SYSMENU)

The window is a pop-up window. The WS_CAPTION and WS_POPUPWINDOW styles must be combined to make the window menu visible.

WS_SIZEBOX

0x00040000L

The window has a sizing border. Same as the WS_THICKFRAME style.

WS_SYSMENU

0x00080000L

The window has a window menu on its title bar. The WS_CAPTION style must also be specified.

WS_TABSTOP

0x00010000L

The window is a control that can receive the keyboard focus when the user presses the TAB key. Pressing the TAB key changes the keyboard focus to the next control with the WS_TABSTOP style.

You can turn this style on and off to change dialog box navigation. To change this style after a window has been created, use the SetWindowLong function. For user-created windows and modeless dialogs to work with tab stops, alter the message loop to call the IsDialogMessage function.

WS_THICKFRAME

0x00040000L

The window has a sizing border. Same as the WS_SIZEBOX style.

WS_TILED

0x00000000L

The window is an overlapped window. An overlapped window has a title bar and a border. Same as the WS_OVERLAPPED style.

WS_TILEDWINDOW

(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX)

The window is an overlapped window. Same as the WS_OVERLAPPEDWINDOW style.

WS_VISIBLE

0x10000000L

The window is initially visible.

This style can be turned on and off by using the ShowWindow or SetWindowPos function.

WS_VSCROLL

0x00200000L

The window has a vertical scroll bar.

msdn 발췌

 - 윈도우는 크게 오버랩드, 차일드, 팝업으로 분류되며, 상호 배치되는 성질이 있기에 동시에 같이 사용할 수는 없음.

 - WS_BORDER는 크기 조절 불가, 기본은 WS_THICKFRAME

 - 닫기 버튼은 윈도우 스타일에서 지정할 수 없으며, 윈도우 클래스의 CS_NOCLOSE 스타일로 지정.

 - WS_H(V)SCROLL 스타일을 지정하면 작업영역에 스크롤바가 나타남(동작을 위해선 범위와 메시지 처리 코드도 추가되어야 한다)

확장 스타일

 - CreateWindow함수에서 첫 번째 인수로 dwExStyle이 추가된 CreateWindowEx함수에 쓰임.

 - WS_EX_로 시작된다.

WS_EX_ACCEPTFILES

0x00000010L

The window accepts drag-drop files.

WS_EX_APPWINDOW

0x00040000L

Forces a top-level window onto the taskbar when the window is visible.

WS_EX_CLIENTEDGE

0x00000200L

The window has a border with a sunken edge.

WS_EX_COMPOSITED

0x02000000L

Paints all descendants of a window in bottom-to-top painting order using double-buffering. For more information, see Remarks. This cannot be used if the window has a class style of either CS_OWNDC or CS_CLASSDC.

Windows 2000:  This style is not supported.

WS_EX_CONTEXTHELP

0x00000400L

The title bar of the window includes a question mark. When the user clicks the question mark, the cursor changes to a question mark with a pointer. If the user then clicks a child window, the child receives a WM_HELP message. The child window should pass the message to the parent window procedure, which should call the WinHelp function using the HELP_WM_HELP command. The Help application displays a pop-up window that typically contains help for the child window.

WS_EX_CONTEXTHELP cannot be used with the WS_MAXIMIZEBOX or WS_MINIMIZEBOX styles.

WS_EX_CONTROLPARENT

0x00010000L

The window itself contains child windows that should take part in dialog box navigation. If this style is specified, the dialog manager recurses into children of this window when performing navigation operations such as handling the TAB key, an arrow key, or a keyboard mnemonic.

WS_EX_DLGMODALFRAME

0x00000001L

The window has a double border; the window can, optionally, be created with a title bar by specifying the WS_CAPTION style in the dwStyle parameter.

WS_EX_LAYERED

0x00080000

The window is a layered window. This style cannot be used if the window has a class style of either CS_OWNDC or CS_CLASSDC.

Windows 8:  The WS_EX_LAYERED style is supported for top-level windows and child windows. Previous Windows versions support WS_EX_LAYERED only for top-level windows.

WS_EX_LAYOUTRTL

0x00400000L

If the shell language is Hebrew, Arabic, or another language that supports reading order alignment, the horizontal origin of the window is on the right edge. Increasing horizontal values advance to the left.

WS_EX_LEFT

0x00000000L

The window has generic left-aligned properties. This is the default.

WS_EX_LEFTSCROLLBAR

0x00004000L

If the shell language is Hebrew, Arabic, or another language that supports reading order alignment, the vertical scroll bar (if present) is to the left of the client area. For other languages, the style is ignored.

WS_EX_LTRREADING

0x00000000L

The window text is displayed using left-to-right reading-order properties. This is the default.

WS_EX_MDICHILD

0x00000040L

The window is a MDI child window.

WS_EX_NOACTIVATE

0x08000000L

A top-level window created with this style does not become the foreground window when the user clicks it. The system does not bring this window to the foreground when the user minimizes or closes the foreground window.

To activate the window, use the SetActiveWindow or SetForegroundWindow function.

The window does not appear on the taskbar by default. To force the window to appear on the taskbar, use the WS_EX_APPWINDOW style.

WS_EX_NOINHERITLAYOUT

0x00100000L

The window does not pass its window layout to its child windows.

WS_EX_NOPARENTNOTIFY

0x00000004L

The child window created with this style does not send the WM_PARENTNOTIFY message to its parent window when it is created or destroyed.

WS_EX_NOREDIRECTIONBITMAP

0x00200000L

The window does not render to a redirection surface. This is for windows that do not have visible content or that use mechanisms other than surfaces to provide their visual.

WS_EX_OVERLAPPEDWINDOW

(WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE)

The window is an overlapped window.

WS_EX_PALETTEWINDOW

(WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST)

The window is palette window, which is a modeless dialog box that presents an array of commands.

WS_EX_RIGHT

0x00001000L

The window has generic "right-aligned" properties. This depends on the window class. This style has an effect only if the shell language is Hebrew, Arabic, or another language that supports reading-order alignment; otherwise, the style is ignored.

Using the WS_EX_RIGHT style for static or edit controls has the same effect as using the SS_RIGHT or ES_RIGHT style, respectively. Using this style with button controls has the same effect as using BS_RIGHT and BS_RIGHTBUTTON styles.

WS_EX_RIGHTSCROLLBAR

0x00000000L

The vertical scroll bar (if present) is to the right of the client area. This is the default.

WS_EX_RTLREADING

0x00002000L

If the shell language is Hebrew, Arabic, or another language that supports reading-order alignment, the window text is displayed using right-to-left reading-order properties. For other languages, the style is ignored.

WS_EX_STATICEDGE

0x00020000L

The window has a three-dimensional border style intended to be used for items that do not accept user input.

WS_EX_TOOLWINDOW

0x00000080L

The window is intended to be used as a floating toolbar. A tool window has a title bar that is shorter than a normal title bar, and the window title is drawn using a smaller font. A tool window does not appear in the taskbar or in the dialog that appears when the user presses ALT+TAB. If a tool window has a system menu, its icon is not displayed on the title bar. However, you can display the system menu by right-clicking or by typing ALT+SPACE.

WS_EX_TOPMOST

0x00000008L

The window should be placed above all non-topmost windows and should stay above them, even when the window is deactivated. To add or remove this style, use the SetWindowPos function.

WS_EX_TRANSPARENT

0x00000020L

The window should not be painted until siblings beneath the window (that were created by the same thread) have been painted. The window appears transparent because the bits of underlying sibling windows have already been painted.

To achieve transparency without these restrictions, use the SetWindowRgn function.

WS_EX_WINDOWEDGE

0x00000100L

The window has a border with a raised edge.

      - WS_EX_TOPMOST는 탑 모스트 윈도우로 만드는 속성.

      - 스타일 이름 뒤에 EDGE가 붙어 있는 확장 스타일은 모두 경계선을 장식하는데 주로 차일드를 장식할 때 사용.

SetWindowLong

- LONG GetWindowLong(HWND hWnd, int nIndex);

  LONG SetWindowLong(HWND hWnd, int nIndex, LONG dwNewLong);

  - 윈도우를 만들 때 설정했던 윈도우의 속성들을 실행중에 조사하거나 바꾸고자 할때 위 두 함수를 사용

  - 64비트 윈도우와의 호환을 위해 아래 함수를 사용한다.

  LONG_PTR GetWindowLongPtr(HWND hWnd, int nIndex);

  LONG_PTR SetWindowLongPtr(HWND hWnd, int nIndex, LONG_PTR dwNewLong);

  - 두 번째 인수 nIndex는 조사하거나 변경하고자 하는 속성으로 대부분 CreateWindow함수의 인수들

차일드

- 윈도우끼리는 수직적인 계층 관계를 이룸.

  단, 차일드는 WM_DESTROY를 처리하지 않으며, PostQuitMessage함수를 호출할 필요도 없고, 호출해서도 안된다.

작업영역의 분할

- WNDCLASS 구조체에 차일드 윈도우에 원하는 속성, 윈도우 프로시저 등을 지정하고, RegisterClass로 등록한 후,

- CreateWindow에 WS_CHILD|WS_CLIPCHILDREN속성을 주고, 부모의 윈도우 핸들로 메인 윈도우의 핸들 주고 생성 후,

  메인 윈도우의 윈도우 프로시저의 WM_SIZE에서 MoveWindow를 이용해 원하는 곳에 위치 시킨다.

- 메인 윈도우가 차일드로 완전희 덮여 있는 상태일 때 메인 윈도우의 작업영역은 전혀 보이지 않으므로, WM_PAINT 메시지를 처리할

  필요가 없다.

- 만약 배경브러시가 있다면, WM_PAINT에 의해 차일드가 지워졌다 그려졌다를 반복 하므로, 깜빡임이 심해진다. 이때 메인 윈도우에 

  CLIP_CHILDREN 스타일을 주어 차일드가 차지한 영역은 그리기에서 아예 제외시켜 버리는 것도 좋은 방법.

팝업 윈도우

- WM_POPUP 스타일로 만들고, 부모 윈도우의 바깥으로 나갈수도 있다. 부모보다 항상 위에 존재하게 된다.

윈도우간의 계층구조

- 데스크탑 윈도우가 윈도우 계층의 루트

- 응용 프로그램은 아주 특별한 경우를 제외하고는 최소한 하나의 윈도우를 가지는데, 제일 처음 만들어지는 것을 메인 윈도우라고 함.

소유자

- CreateWindow함수의 hwndParent이수에 차일드 윈도우인 경우, 실제로는 그 차일드를 소유하고 있는 윈도우가 소유자가 된다.

  HWND GetParent(HWND hWnd);

  HWND SetParent(HWND hWndChild, HWND hWndNewParent);

  - 윈도우의 부모 윈도우를 조사하거나 설정할 때 사용하는 함수.

  HWND GetWindow(HWND hWnd, UINT uCmd);

  - uCmd : GW_로 시작하는 값들, 만약 지정한 관계의 윈도우가 없으면 NULL을 리턴.

cbWndExtra

- cbClsExtra, cbWndExtra 멤버는 각각 윈도우 클래스와 개별 윈도우를 위한 멤버로 필요시 바이트 단위로 지정(보통은 0)

윈도우 프로퍼티

- cbClsExtra, cbWndExtra 멤버 변수와 비슷한 역할을 하는 기억장치

  윈도우를 서브 클래싱한 경우는 cbClsExtra, cbWndExtra 멤버의 정확한 사용 여부나 용도를 알아내기 힘들기에 프로퍼티를 사용함.

  BOOL SetProp(HWND hWnd, LPCTSTR lpString, HANDLE hData);

  HANDLE GetProp(HWND hWnd, LPCTSTR lpString);

  HANDLE RemoveProp(HWND hWnd, LPCTSTR lpString);

  - lpString 은 프로퍼티의 이름, HANDLE은 저장되거나 읽어올 데이터(HANDLE 타입이어야 함을 의미)

- 같은 윈도우 클래스로부터 만들어진 윈도우는 모든 것을 공유하므로 각자의 정보를 내부적으로 저장할 수 있는 여분 메모리나 프로퍼

  티 같은 기억 공간이 반드시 필요하다. 객체 지향 환경에서는 윈도우를 래핑하는 객체의 멤버에 정보를 기억해 놓는 더 편리한 방법있음


신고

'20130827이전 > WinAPI' 카테고리의 다른 글

13장. 메시지  (0) 2013.01.19
12장. 윈도우 관리  (0) 2013.01.18
11장. 윈도우  (1) 2013.01.15
10장. MFC 소개  (0) 2013.01.15
9장. API 실습  (0) 2013.01.15
8장. 대화상자  (0) 2013.01.15
Posted by 흰둥에미

클래스 라이브러리

- 이 책에선 MFC를 얘기하며, API와 MFC 둘 다 윈도우즈 프로그램을 만드는데 사용하는 용도는 같고,

  상호 대체성이 있는 개발 방법이며 또한 의존적인 관계에 있다고 함.

  MFC

  - OOP(구체적으로 C++기반)


MFC 프로젝트

- MFC 프로젝트 생성 후, OnDraw 함수에서 CDC 객체(API의 DC를 클래스화)를 이용해 텍스트 출력


MFC의 주요 구조.

- 프로젝트 생성에 따라 다르지만, CView와 CDocument를 가지는 구조이며,

  데이터는 CDocument에서 관리 되며, CDocument의 데이터로 CView에서 출력하는 구조.

  DDX 라는게 있었었다.. 잘 기억이 나질 않아.


API와 MFC의 관계

- API에서는 HWND를 인수로 넘기는 함수들이 있지만,

  MFC에서는 CWnd객체가 핸들을 가지고 있으므로, 동일한 동작을 하기위해 CWnd의 멤버 함수를 이용하는 케이스가 많다.

  (전부 다 인지는 정확히 모른다.)


MSDN

상황별 도움말

검색

즐겨보기

MSDN 온라인

- 구글링을 하면, MSDN도 나오고, 다른 사람 소스도 나온다.


빌드 속도 개선

- #define WIN32_LEAN_AND_MEAN 매크로를 이용하여, windows.h헤더 내 자주 사용되는 헤더들만 포함시킬 수 있음.


STRICT 매크로

- 데이터 타입들끼리 구분되도록 하여 소스의 안전성과 이식성을 높이는 역할을 함.

  주로 핸들 타입을 고유하게 정의하며, 이 외에 콜백함수나 포인터의 타입을 고유하게 정의하기도 함.


에러 처리

- 에러 처리를 꼼꼼히 하자.

신고

'20130827이전 > WinAPI' 카테고리의 다른 글

12장. 윈도우 관리  (0) 2013.01.18
11장. 윈도우  (1) 2013.01.15
10장. MFC 소개  (0) 2013.01.15
9장. API 실습  (0) 2013.01.15
8장. 대화상자  (0) 2013.01.15
7장. 컨트롤  (0) 2013.01.14
Posted by 흰둥에미

소코반

- 맵 그리기 힘듦...

  함수들 분석으로 끝낼꺼임.

  void DrawScreen(HDC hdc);

  - 맵의 문자에 따라 DrawBitmap함수를 이용해 해당 좌표에 그림을 찍어주는 함수.

  BOOL TestEnd();

  - 게임이 클리어 되었는지 각 타일들을 체크하는 함수

  void Move(int dir);

  - dir(키보드 키값임)에 따라, 주인공의 이동.

  void InitStage();

  - 맵에 따라 화면을 초기화 

  void DrawBitmap(HDC hdc, int x, int y, HBITMAP hBit);

  - x, y로 주어진 좌표에 hBit로 전달되는 비트맵을 출력하는 함수.

  개작

  - 취소 및 재실행

    MoveInfo (이전 좌표와 팩과 같이 움직였는지를 저장하는 구조체)

    위 MoveInfo구조체를 Undo할수 있는 횟수만큼의 배열로 가지고 저장.

  - 캐릭터 회전

    캐릭터 비트맵을 네가지(상,하,좌,우)로 만들어 이동한 방향에 따라 표시해줌.

  - 사운드 출력

    PlaySound라는 함수를 이용해 출력.


Testris

- 구현해 보자.

  정확히는 따라쳐 보자.

  주석도 없고, 설명 읽기도 귀찮아서, GetAround함수만 한참 쳐다보다 끝났다.

  Shape배열은 각 모양(9개)의 회전(4가지)을 표현.

  GetAround 함수는 대충 계산한 함수이더라.

  로직

  - 블럭이 한칸 내려오면, 멈춰야 하는가 확인(블럭이나, 바닥에 닿아서)

    멈추면, 없애야 할 줄이 있는가 확인 후, 줄을 없앰.

    새로운 블럭의 출현 (이때 GetAround함수로 주위가 비어있는지 확인후, 비어있지 않으면 게임 종료)

    다시 반복


짝맞추기

- 각 타일들을 좌표를 이용해 구할지, 아니면 각 타일들을 윈도우로 만들어 클릭 메시지를 처리할지가 변수

신고

'20130827이전 > WinAPI' 카테고리의 다른 글

11장. 윈도우  (1) 2013.01.15
10장. MFC 소개  (0) 2013.01.15
9장. API 실습  (0) 2013.01.15
8장. 대화상자  (0) 2013.01.15
7장. 컨트롤  (0) 2013.01.14
6장. 그래픽  (0) 2013.01.14
Posted by 흰둥에미

사용자와의 대화

- 응용 프로그램과 사용자와의 대화 수단으로 간단하게는 버튼, 에디트, 리스트 박스 등의 컨트롤이 사용됨.

  많은 양의 정보를 효율적으로 입력받기 위해 주로 대화상자(Dialog)를 사용한다.

  동작 방식에 따라 크게 모달형과 모달리스형으로 나뉘어짐.

  모달 다이얼로그

  - 대화상자를 닫기 전에 다른 윈도우로 전환할 수 없으며 반드시 확인버튼이나 취소버튼을 눌러 대화상자를 닫아야 함.

    하지만 다른 프로그램의 실행까지 방해하지는 않기 때문에, 다른 프로그램으로는 전환할 수 있다.

  모달리스 다이얼로그

  - 대화상자를 열어 놓은 채로 다른 윈도우로 전환할 수 있는 대화상자

    모달 다이얼로그에 비해, 프로그래밍하기 까다로움.


About

- 기본적으로 대화상자 템플릿과 대화상자 프로시저가 필요함

  대화상자 템플릿 - 대화상자의 모양과 대화상자 내의 컴트롤 배치 상태가 저장되는 이진 정보, 편집기로 만들수 있음

  대화상자 프로시저 - 대화상자에서 발생하는 메시지를 처리함.

  int DialogBox(HINSTANCE hInstance, LPCTSTR lpTemplate, HWND hWndParent, DLGPROC lpDialogFunc);

  - 첫 번째 인수는 대화상자 리소스를 가진 인스턴스의 핸들, 두 번째 인수는 대화상자 템플릿의 리소스 ID이다.

    세 번째 인수는 대화상자를 소유할 부모 윈도우, 네 번째 인수는 대화상자 프로시저의 이름임.

    대화상자를 닫으면 DialogBox 함수가 리턴하는데 이때 리턴하는 값은 대화상자의 종료 함수인 EndDialog함수가 지정하는 값.


대화상자 프로시저

- 대화상자 프로시저와 윈도우 프로시저 비교

  - 윈도우 프로시저는 LRESULT(long)형의 값을 리턴, 대화상자 프로시저는 BOOL형의 값을 리턴

    윈도우 프로시저는 메시지를 처리했을 때 0을 리턴하고, 따로 관여하지 않는 메시지는 DefWindowProc로 보내지만,

    대화상자 프로시저는 메시지를 제대로 처리했으면 TRUE를 리턴하고 메시지를 처리하지 못했으면 FALSE를 리턴해야 함.

    즉 관여하지 않는 메시지는 FALSE를 리턴해주면 됨.

    대화상자 프로시저는 WM_CREATE 메시지 대신 WM_INITDIALOG 메시지를 받아들이며, 이 곳에서 필요한 초기화를 함.

    대화상자의 컨트롤들에 의해 발생되는 통지 메시지는 WM_COMMAND에서 처리해준다.

    일반 윈도우와 마찬가지로 LOWORD(wParam)에 메시지를 보낸 컨트롤의 ID가 전달, HIWORD(wParam)에 통지 코드가 전달됨.

  BOOL EndDialog(HWND hDlg, int nResult);

  - 이 함수가 호출되면 모달 대화상자가 닫힌다.

    두 번째 인수 nResult는 대화상자를 호출한 DialogBox함수의 리턴값으로 전달됨, 주로 취소 여부를 리턴


대화상자 프로젝트

- 대화상자가 메인 윈도우가 되는 형태의 프로그램을 대화상자 기반의 프로그램(Dialog Base)이라 함.

  대화상자의 부모는 HWND_DESKTOP으로 지정(NULL과 동일)하여 대화상자가 메인 윈도우가 되게 함.

  메인 윈도우가 없으므로 윈도우 프로시저는 필요없고, 대화상자 프로시저가 필요함.


컨트롤의 종류

크기조정 및 이동

컨트롤 편집

정렬

- 리소스 편집기를 잘 쓰자.

  각 컨트롤들은 각각의 속성이 있고, 필요한 정보를 속성창을 이용해 편집할 수도 있음.


컨트롤의 값 읽기

- 핸들과 ID

  대화상자 내의 컨트롤들은 ID라는 고유의 이름을 가지는데 CreateWindow 함수로 직접 만들 때는 hMenu인수로 ID를 지정,

  리소스 편집기를 사용할 때는 속성 대화상자에서 지정.

  HWND GetDlgItem(HWND hDlg, int nIDDlgItem);

  - 차일드 컨트롤의 ID를 알고 있으면,

    위 함수에 대화상자의 핸들과 컨트롤의 ID를 인수로 주고, 차일드 컨트롤의 윈도우 핸들을 구할 수 있다.

  int GetDlgCtrlID(HWND hwndCtl);

  - 위의 함수와 반대 함수로, 차일드 컨트롤의 윈도우 핸들을 이용해 컨트롤의 ID를 얻는다.

  핸들은 특성상 운영체제가 일방적으로 발급하기에 번호의 연속성이 없으며, 반복적인 처리가 불가능.

  따라서 사용자가 직접 번호를 지정할 수 있는 ID가 필요하다.

  LONG SendDlgItemMessage(HWND hDlg, int nID, UINT Msg, WPARAM wParam, LPARAM lParam);

  - SendMessage(GetDlgItem(hDlg,ID)...)과 같은 역할을 하는 함수이다.

- 정수와 문자열

  대화상자와 컨트롤간에 교환할 수 있는 정보의 종류는 크게 문자열과 정수형 두 가지가 있음.

  UINT GetDlgItemText(HWND hDlg, int nID, LPTSTR lpString, int nMaxCount);

  BOOL SetDlgItemText(HWND hDlg, int nID, LPCTSTR lpString);

  - hDlg는 대화상자의 윈도우 핸들, nID는 컨트롤의 ID, lpString은 읽어올 문자열 버퍼(또는 쓸 문자열) , nMaxCount는 버퍼길이

  UINT GetDlgItemInt(HWND hDlg, int nID, BOOL* lpTranslated, BOOL bSigned);

  BOOL SetDlgItemInt(HWND hDlg, int nID, UINT nValue, BOOL bSigned);

  - bSigned가 TRUE일 경우 부호있는 정수값, FALSE일 경우 부호를 무시하고 무조건 양수

    lpTranslated 인수는 정수를 읽어들일 때 에디트에 숫자 이외의 문자가 있거나 숫자가 너무 클 경우 발생한 에러를 지정.

    (에러 검사가 필요없을 땐, NULL 지정, 에디트의 경우 ES_NUMBER스타일을 주면 숫자만 입력가능함.)

    nValue는 컨트롤에 쓸 정수

- 논리형

  - BOOL형과 열거형도 대화상자를 통해 입력받을 수 있음.

    BOOL형은 체크 박스, 열거형은 라디오 버튼이나 리스트 박스를 사용.

    BOOL CheckDlgButton(HWND hDlg, int nIDButton, UINT uCheck);

    - uCheck에 원하는 체크 상태를 인수로 전달하면 버튼의 체크 상태를 변경

      SendMessage(GetDlgItem(hDlg,nIDButton), BM_SETCHECK, uCheck, 0);의 변형

      SendDlgItemMessage(hDlg, nIDButton, BM_SETCHECK, uCheck, 0);의 변형

    UINT IsDlgButtonChecked(HWND hDlg, int nIDButton);

    - 체크 상태를 리턴해준다.

      SendMessage(GetDlgItem(hDlg,nIDButton), BM_GETCHECK, 0, 0);의 변형

      SendDlgItemMessage(hDlg, nIDButton, BM_GETCHECK, 0, 0);의 변형

    함수 이름에 Dlg가 있지만 일반 윈도우의 차일드에 대해서도 사용할 수 있음.


InfoDlg

- 윈도우와 차일드 대화상자와의 통신

  윈도우의 전역변수를 통해 필요한 정보를 공유하고,

  대화상자에서 변경 및 적용된 내용(WM_COMMAND를 이용)에 따라 윈도우를 갱신해줌.


DlgCheck

- InfoDlg와 비슷한 예제로써, 대화상자를 통해 입력받는 값이 BOOL형과 열거형

  라디오 버튼 중 체크된 버튼을 구할 때는 모든 라디오 버튼에게 일일이 질문을 해서 체크된 버튼을 찾는 방법밖에 없음

  MFC에는 아래와 같은 역할을 하는 함수가 존재

  int GetCheckedRadioButton(HWND hDlg, int First, int Last)
  {
       int id;
       for (int id=First; id<=Last; ++id)
       {
           if (BST_CHECKED == IsDlgButtonChecked(hDlg, id)) return id;
       }
       return -1;
  }


독서 도우미

- 대화상자를 메인으로, 타이머, 체크박스, 버튼, 에디트, 스태틱 컨트롤 등을 이용하여 작성.


모달리스형 대화상자.

- 대화상자를 열어놓은 채로 메인 윈도우를 조작할 수 있기 때문에, 모달형 대화상자보다 복잡하며 사용하기도 어려움.

  골치아픈 문제가 발생할 수도 있으며, 메인 윈도우가 변경된 값을 즉각 인지할 수 있어야 함.

  BOOL IsWindow(HWND hWnd);

  - hWnd가 유효한 윈도우 핸들인지 검사하는 함수로써, 모달리스 다이얼로그는 부모 윈도우를 조작할 수 있으므로,

    동일한 대화상자가 두 개 만들어지는 현상을 체크하기 위해서 사용.

  HWND CreateDialog(HINSTANCE hInstance, LPCTSTR lpTemplate, HWND hWndParent, DLGPROC lpDialogFunc);

  - 모달형 대화상자를 위한 DialogBox와 동일한 인수를 갖지만, 호출후에 다이얼로그가 나타나진 않는다.

    따라서 ShowWindow(HWND hWnd, int nShow); 함수를 이용해 화면에 나타나게 해야함.

  대화상자를 닫을 때는, DestroyWindow함수를 사용해야 하며, 대화상자 핸들에는 NULL을 대입해서 다시 사용할 수 있게 해줘야함.

  BOOL IsDialogMessage(HWND hDlg, LPMSG lpMsg);

  - lpMsg가 hDlg의 핸들을 갖는 대화상자를 위한 메시지인지 검사하고, 맞으면 대화상자로 이 메시지를 전달하고 TRUE를 리턴,

    아니면 FALSE를 리턴




신고

'20130827이전 > WinAPI' 카테고리의 다른 글

10장. MFC 소개  (0) 2013.01.15
9장. API 실습  (0) 2013.01.15
8장. 대화상자  (0) 2013.01.15
7장. 컨트롤  (0) 2013.01.14
6장. 그래픽  (0) 2013.01.14
5장. 리소스  (0) 2013.01.13
Posted by 흰둥에미

컨트롤의 정의

- 사용자와의 인터페이스를 이루는 도구.

  사용자로부터 명령과 입력을 받아들이고, 출력 결과를 보여주는 입출력 도구.

  표준 컨트롤

  - 버튼(button : 버튼, 체크, 라디오), 에디트(edit), 리스트 박스(listbox), 콤보 박스(combobox), 스크롤 바(scrollbar), 스태틱(static)

  CreateWindow함수의 첫 번째 인수로 클래스 이름을 주면 해당 컨트롤을 만들 수 있음.


Button

- Button이라는 클래스명은 윈도우즈가 미리 사용하고 있으므로, 사용할 수 없음


버튼 만들기

- CreateWindow의 첫 번째 인수로 "button"을 줘야 버튼 컨트롤이 생성된다.

  두 번째 인수로 들어가는 Caption은 버튼의 경우 버튼 위에 나타난다.

  세 번째 인수는 윈도우의 속성값으로, 컨트롤은 차일드 윈도우이므로 WS_CHILD 스타일을 반드시 주어야 한다.

  - 또한 WS_VISIBLE 스타일을 주어야 ShowWindow 함수의 호출없이 나타난다.

     BS_PUSHBUTTON, BS_DEFAULTPUSHBUTTON, BS_CHECKBOX, BS_3STATE, BS_AUTOCHECKBOX

     BS_AUTO3STATE, BS_RADIOBUTTON, BS_AUTORADIOBUTTON, BS_GROUPBOX

  체크 박스나 라디오 버튼도 일종의 버튼이며, 위 스타일 값을 이용해 생성 할 수 있다.

  아홉 번째 인수는 윈도우에서 사용할 메뉴의 핸들이지만, 차일드 컨트롤은 메뉴를 가지지 않으므로, 컨트롤의 ID지정 용도로 사용함.

  열한 번째 인수는 사용자 정의 데이터로써 MDI에서 사용, 우선은 NULL

  리턴값은 버튼 윈도우의 핸들을 반환함.


부모와의 통신

- 컨트롤은 자신에게 무슨일이 발생했을 때, 부모 윈도우로 통지 메시지를 보낸다.(WM_COMMAND)

  버튼을 클릭할 경우 발생하는 WM_COMMAND에서 전달되는 인수는 아래와 같다.

  - HIWORD(wParam)은 통지코드(버튼,메뉴,엑셀러레이터의 경우 항상 BN_CLICKED이다.)

    LOWORD(wParam)은 컨트롤의 ID

    lParam은 메시지를 보낸 차일드 윈도우의 핸들이다.


체크 박스의 종류

- CreateWindow함수 호출시 스타일에 BS_CHECKBOX(두가지 상태), BS_3STATE(세가지 상태)등의 스타일을 주어서 생성.

  선택/비선택과 세가지 상태는 Grayed라는 상태가 추가됨

  자동 체크 박스와 수동 체크 박스가 있음. (CreateWindow의 스타일 인수에 AUTO가 붙은 스타일로 생성시 자동 체크 박스)


Check

- COLOR_BTNFACE는 버튼 표면의 색상을 의미


컨트롤의 메시지

- 컨트롤은 자신에게 어떤 변화가 있을때, 부모 윈도우로 메시지를 보내며 이를 통지 메시지라고 함.

  부모 윈도우가 차일드 윈도우의 현재 상태를 알아보거나, 상태를 바꾸고자 할 때도 차일드 윈도우로 메시지를 보낸다.

  BM_GETCHECK - 체크 박스가 현재 체크되어 있는 상태인지를 리턴값으로 체크, wParam, lParam은 사용하지 않음.

  BM_SETCHECK - 체크 박스의 체크 상태를 변경하며, wParam에 변경할 상태를 지정.

  체크 박스의 상태

  - BST_UNCHECKED       0  - 현재 체크되어 있지 않음.

    BST_CHECKED            1  - 현재 체크되어 있음.

    BST_INDETERMINATE  2  - 체크도 아니고 안 체크도 아닌 상태


라디오 버튼

- CreateWindow에 "button"클래스와 BS_RADIOBUTTON, BS_AUTORADIOBUTTON 스타일을 주어 생성.

  체크 박스와 마찬가지로 수동, 자동이 있음.

  BS_GROUPBOX 스타일은 버튼의 일종으로 화면으로 보여지기만 하며, 라디오 그룹을 사용자에게 표시하기 위해 사용.

  같은 그룹에 속한 라디오 버튼은 오직 하나만 선택할 수 있음.

  그룹을 이루는 첫 번째 라디오 버튼에만 WS_GROUP스타일을 주고, 나머지 라디오 버튼은 WS_GROUP스타일을 주지 않으면 됨.

  BOOL CheckRadioButton(HWND hDlg, int nIDFirst, int nIDLast, int nIDCheck);

  - hDlg는 라디오 버튼의 부모 윈도우의 핸들

    nIDFirst - 그룹의 시작 버튼, nIDLast - 그룹의 마지막 버튼, nIDCheck - 선택될 버튼.


에디트

- 문자열을 직접 입력받을 때 사용하는 컨트롤

  "edit" 윈도우 클래스로부터 생성

  스타일

  - ES_AUTOHSCROLL, ES_AUTOVSCROLL (수평/수직 스크롤 지원), ES_LEFT, ES_CENTER, ES_RIGHT(정렬),

    ES_LOWERCASE, ES_UPPERCASE(소/대문자로 표시), ES_MULTILINE(여러 줄 편집가능), 

    ES_NOHIDESEL(포커스를 잃더라도 선택된 영역을 표시), ES_READONLY(읽기 전용)

  통지 메시지

  - EN_CHANGE(문자열이 변경됨), EN_ERRSPACE(메모리가 부족), EN_HSCROLL, EN_VSCROLL(수평/수직 스크롤 바를 클릭),

    EN_KILLFOCUS(포커스를 잃음), EN_SETFOCUS(포커스를 얻음), EX_MAXTEXT(지정한 문자열 길이를 초과),

    EN_UPDATE(문자열이 변경되기 직전)

    EN_CHANGE와 EN_UPDATE

    - EN_UPDATE는 문자열이 변경된 후 화면 출력 직전에 보내는 메시지이며 이 메시지가 발생했을 때 사용자는 문자열 길이에 따라,

      에디트의 폭을 늘리거나 별도의 조치를 취할수 있다.

      EN_CHANGE는 문자열이 화면으로 출력되고 난 후 보내지는 메시지이다.

  GetWindowText 함수를 사용하여 문자열을 얻을 수 있음.(컨트롤도 윈도우의 일종이기 때문에 윈도우 관리 함수를 모두 사용 가능)

  여러 줄 편집, 블록 선택, 클립 보드 지원까지 다양한 기능을 가지고 있음.


컨트롤도 윈도우다

- 윈도우를 조작하는 고급 기법들이 컨트롤에도 그대로 적용됨


리스트 박스

- 선택 가능한 여러개의 항목들을 나열해 놓고 그 중 하나를 선택하는 컨트롤

  "listbox"라는 윈도우 클래스로 생성

  스타일

  - LBS_MULTIPLESEL, LBS_NOTIFY(선택시 부모 윈도우로 통지 메시지를 보냄), LBS_SORT,

    LBS_OWNERDRAW(문자열이 아닌 비트맵이나 그림을 넣을수 있음), LBS_STANDARD(LBS_NOTIFY|LBS_SORT|WS_BORDER)

  핸들링 메시지

  - LB_ADDSTRING(리스트 박스에 항목 추가, lParam으로 추가하고자 하는 문자열의 주소를 전달, 정렬된 상태로 추가됨)

    LB_INSERTSTRING(리스트 박스에 항목 추가, wParam은 인덱스(-1이면 맨뒤), lParam은 문자열의 주소, 정렬되지 않음)

    LB_SETTOPINDEX(항목 추가시 반환되는 주소를 이용해, 리스트 박스의 포커스를 지정)

    LB_GETCURSEL(현재 선택된 아이템의 인덱스를 얻음), LB_SETCURSEL(wParam으로 전달된 항목을 선택)

    LB_GETTEXT(지정한 항목의 문자열을 읽음, wParam인덱스, lParam문자열버퍼)

    LB_GETCOUNT(항목의 개수를 조사)

  통지 메시지

  - LBN_DBLCLK, LBN_ERRSPACE(메모리 부족), LBN_KILLFOCUS, LBN_SELCANCEL(선택을 취소)

    LBN_SELCHANGE(선택이 변경), LBN_SETFOCUS(포커스를 얻음)


콤보 박스

- 에디트 컨트롤과 리스트 박스를 결합해 놓은 컨트롤

  "combobox" 윈도우 클래스를 사용하여 생성.

  스타일

  - CBS_SIMPLE(리스트 박스가 항상 펼쳐져 있음), CBS_DROPDOWN(에디트와 리스트 박스), CBS_DROPDOWNLIST(리스트만)

  핸들링 메시지 - 리스트 박스와 거의 동일하며, Prefix가 CB_ 로 되어 있음.

  통지 메시지 - CBN_EDITCHANGE(에디트가 변경될 때 발생하는 메시지)


스크롤 바

- "scrollbar"윈도우 클래스로 생성.

  수평 스크롤은 SBS_HORZ, 수직 스크롤은 SBS_VERT 스타일을 지정

  스크롤 바는 범위와 현재 위치값을 가지는데 다음 두 함수로 이 값들을 지정.

  BOOL SetScrollRange(HWND hWnd, int nBar, int nMinPos, int nMaxPos, BOOL bRedraw);

  - hWnd를 가지는 스크롤 바에 최대값, 최소값을 지정한다.

    nBar는 메인 윈도우의 표준 스크롤 바 또는 별도의 스크롤 바 컨트롤을 지정하는데, 이 값이 SB_CTL이면 별도의 컨트롤을 지정.

  int SetScrollPos(HWND hWnd, int nBar, int nPos, BOOL bRedraw);

  - nPos를 이용해 스크롤 바의 현재 위치를 지정.

  통지 메시지

  - 다른 컨트롤 들과 달리 스크롤 바는 WM_HSCROLL, WM_VSCROLL의 별도의 메시지를 보낸다.

    LOWORD(wParam) - 스크롤 바 내의 눌린 위치, HIWORD(wParam) - 현재 위치, lParam - 스크롤바의 핸들

    LOWORD(wParam)

    - SB_LINELEFT, SB_LINEUP(왼쪽 또는 위 화살표를 누름), SB_LINERIGHT, SB_LINEDOWN(오른쪽 또는 아래 화살표를 누름)

      SB_PAGELEFT, SB_PAGEUP(왼쪽 또는 위 몸통부분을 누름), SB_PAGERIGHT, SB_PAGEDOWN(오른쪽 또는 아래 몸통)

      SB_THUMBPOSITION(스크롤 박스 드래그 후, 마우스를 놓음), SB_THUMBTRACK(스크롤 박스를 드래그 하는 중, 계속 발생)


스태틱

- 오로지 문자열을 보여주는 컨트롤, "static" 윈도우 클래스로 생성

  TextOut은 WM_PAINT에서 그리기 관리를 해줘야 하지만, 스태틱은 윈도우이므로 메시지처리기가 내장되어 있으므로 스스로 그림.


컨트롤의 3요소

- 스타일, 통지 메시지, 핸들링 메시지(부모 윈도우가 보내는 메시지)


  

신고

'20130827이전 > WinAPI' 카테고리의 다른 글

9장. API 실습  (0) 2013.01.15
8장. 대화상자  (0) 2013.01.15
7장. 컨트롤  (0) 2013.01.14
6장. 그래픽  (0) 2013.01.14
5장. 리소스  (0) 2013.01.13
4장. 입력  (0) 2013.01.13
Posted by 흰둥에미

GDI 오브젝트

- GDI(Graphic Device Interface)는 화면, 프린터 등의 모든 출력 장치를 제어하는 윈도우즈의 핵심 모듈 중 하나

  펜, 브러시, 비트맵, 폰트 등 GDI오브젝트를 모아놓은 것을 DC라 함.

  GDI 오브젝트의 종류

 GDI 오브젝트

핸들 타입   설명 디폴트 

HPEN

선을 그을 때 사용

검정색의 가는 실선
브러시 HBRUSH  면을 채울 때 사용  흰색 
 폰트 HFONT  문자 출력에 사용되는 글꼴  시스템 글꼴 
 비트맵 HBITMAP  비트맵 이미지 
 팔레트 HPALETTE  팔레트 
 리전 HRGN  화면상의 영역 

  GDI오브젝트를 생성하는 함수를 부르고 이 함수가 리턴하는 핸들을 받아서 사용.

  DC가 BeginPaint나 GetDC 함수에 의해 처음 만들어졌을 때, 위와 같은 디폴트 값을 갖고 있음.


스톡 오브젝트

- 윈도우즈가 기본적으로 제공하는 GDI 오브젝트

  HGDIOBJ GetStockObject(int fnObject);

  - fnObject 인수에는 사용하고자 하는 스톡 오브젝트를 지정(주로 브러시와 펜으로 ...._BRUSH, ...._PEN으로 정의되어 있음)

    DC_BRUSH와 DC_PEN은 각각 SetDCBrushColor, SetDCPenColor함수로 설정.

    여러 종류의 스톡 오브젝트를 리턴하므로, 원하는 타입(HBRUSH, HPEN등)으로 캐스팅 하여 사용.

  HGDIOBJ SelectObject(HDC hdc, HGDIOBJ hgdiobj);

  - GDI 오브젝트를 DC에 선택할 때 사용하는 함수

    hdc - DC의 핸들

    hgdiobj - DC에서 새로 선택할 GDI오브젝트의 핸들

    리턴값은 새로 선택되는 오브젝트 이전에 선택되어 있던 같은 종류의 오브젝트 핸들.

    원하는 GDI오브젝트 사용후, DC를 원래의 상태로 복원하기 위해 위 리턴값을 저장해 두어야 한다.


색상

- 색상 표현을 위해 COLORREF라는 데이터 형을 사용 ( typedef DWORD COLORREF )

  상위부터 8비트씩 X, Blue, Green, Red를 의미.

  RGB(r,g,b) 매크로를 이용하여, COLORREF형 값을 만듦.

  GetRValue(rgb), GetGValue(rgb), GetBValue(rgb) 는 COLORREF형 변수에서 각 색상 요소의 농도를 분리해내는 매크로.


- 선을 그을때 사용하는 GDI 오브젝트

  HPEN CreatePen(int fnPenStyle, int nWidth, COLORREF crColor);

  - 스톡 펜 이외의 펜을 생성할 때 사용하는 함수

    fnPenStyle - PS_SOLID, PS_DASH, PS_DOT, PS_DASHDOT, PS_DASHDOTDOT 등의 선 모양

                      (굵기가 1일때만 효과 적용, 2이상이면 무조건 실선)

    nWidth - 선의 폭을 지정, 단 이 값이 0일 경우는 맵핑 모드에 상관없이 무조건 1픽섹 두께의 선이 생성됨.

    crColor - 선의 색상을 지정

    리턴값 - 새로 만든 펜의 핸들이 리턴

  BOOL DeleteObject(HGDIOBJ hObject);

  - GDI 오브젝트는 메모리를 사용하기 때문에, 사용한 후 반드시 이 함수를 이용하여 삭제해야 함.

    주의할 점은 DC에 현재 선택되어 있는 GDI 오브젝트는 살제할 수 없음.


브러시

- 채워지는 면을 채색하는 용도

  스톡 브러시 외의 브러시를 생성할 때 사용하는 함수 둘. 모두 생성한 브러시의 핸들을 리턴해 줌.

  HBRUSH CreateSolidBrush(COLORREF crColor);

  - 단색의 브러시를 생성.

  HBRUSH CreateHatchBrush(int fnStyle, COLORREF clrref);

  - fnStyle - HS_BDIAGONAL(좌하향 줄무늬), HS_CROSS(바둑판 무늬), HS_DIAGCROSS(대각 바둑판)

                 HS_FDIAGONAL(우하향 줄무늬), HS_HORIZONTAL(수평선), HS_VERTICAL(수직선)


Old의 의미

- GDI 오브젝트를 생성후 사용하고 해제해 주기 위해, DC에 기존에 있던 GDI 오브젝트를 임시로 담아둠.


투명 오브젝트

- 스톡 오브젝트 중 NULL_BRUSH(=HOLLOW_BRUSH), NULL_PEN이 투명 오브젝트를 그리기 위한 GDI 오브젝트임.


흑백에서의 그리기 모드

- COPY - 새로 그려지는 그림이 기존 그림을 덮어버림.

  OR - 대응되는 비트를 OR연산하여 새로운 값을 만들어 그린다.

  AND - 대응되는 비트를 AND연산하여 새로운 값을 만들어 그린다.

  XOR - 대응되는 비트를 XOR연산하여 새로운 값을 만들어 그린다.


그리기 모드의 종류

- 윈도우즈에서 사용하는 디폴트 그리기 모드는 R2_COPYPEN 모드(그려지는 그림이 기존 그림을 덮어버림)

  int SetROP2(HDC hdc, int fnDrawMode);

  - 그리기 모드를 변경하는 함수로 hdc는 그리기 모드를 변경하고자 하는 DC의 핸들

    fnDrawMode - R2_BLACK(항상 검정색), R2_WHITE(항상 흰색), R2_NOP(아무것도 안그림), R2_NOT(원래 그림 반전)

                         R2_COPYPEN(원래 그림을 덮어 그림), R2_NOTCOPYPEN(새 그림을 반전), R2_NOTXORPEN(XOR결과의 반대로)

                         R2_MASKPEN(AND연산으로 겹치는 부분만), R2_XORPEN(XOR연산으로 겹치는 부분만 반전)

  int GetROP2(HDC hdc);

  - hdc의 그리기 모드를 구하는 함수.


그리기 모드

- 이미 그려진 그림을 보존하기 위해, 그리는 중의 선을 반전 모드로 그려 이 선이 지워질 때 원래대로 복구해 놓는다.

  그러기 위해서는 절대 색상으로 삭제, 그리기를 해서는 안되며 이미 그려진 그림과 논리 연산을 취하는 방법을 사용하며,

  위 SetROP2 함수를 이용한다.

  흑백에서는 R2_NOT 모드, 컬러에서는 R2_NOTXORPEN이 가장 완벽하다.


비트맵

- 그림 출력을 위해 비트맵을 사용. 이미지를 픽셀단위로 화면에 일일이 출력하는 건 무리수!

  복잡한 그림을 출력하는 용도 외에도 화면의 일정영역을 복사해서 옮기거나, 잠시 보관해 두기도 하며, 화려한 애니메이션에도 활용


메모리 DC

- 비트맵을 곧바로 화면 DC로 출력하는 함수는 없음. 비트맵을 직접 출력하는 것은 속도가 느리고, 여러 문제 발생의 여지가 있음

  미리 비트맵 화면을 준비하고, 출력할 때 이미 준비된 데이터를 화면으로 전송하는 방식.

  메모리 DC - 화면 DC와 동일한 특성을 가지며, 그 내부에 출력 표면을 가진 메모리 영역.

                   화면 DC에서 가능한 출력들은 물론 불가능 한것까지 가능

                   메모리 DC에 먼저 그림을 그린 후, 그 결과만을 화면으로 고속 복사하는 방법(더블 버퍼링)이 있음.

                   비트맵도 일종의 GDI 오브젝트이지만, 화면 DC에는 선택할 수 없고 메모리 DC만이 비트맵을 선택할 수 있음.

  HDC CreateCompatibleDC(HDC hdc);

  - 인수로 주어진 DC와 동일한 특성을 가지는 DC를 메모리에 만들고, 그 핸들을 리턴

  HBITMAP LoadBitmap(HINSTANCE hInstance, LPCTSTR lpBitmapName);

  - hInstance - 비트맵 리소스를 가진 인스턴스의 핸들

    lpBitmapName - 비트맵 리소스의 이름

    위 함수에서 리턴된 비트맵 핸들을 SelectObject함수로 메모리 DC에 선택하면, 메모리 DC상에 비트맵이 그려진다.


BitBlt

- DC간의 영역끼리 고속 복사를 수행한다.

  BOOL BitBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, DWORD dwRop);

  - hdcDest - 복사 대상 DC

    그다음 네개의 인자 - 복사 대상의 X, Y, Width, Height

    hdcSrc - 복사원

    nXSrc, nYSrc - 복사원의 좌표 (BitBlt 는 비트맵의 크기를 변경하지 않음, 복사대상에 지정된 폭과 너비를, 복사원에서도 사용)

    dwRop - 래스터 연산 방법을 지정

                 BLACKNESS(대상영역을 검정색으로 채움), DSTINVERT(화면을 반전), MERGECOPY(소스 비트맵과 대상 화면을 AND)

                 MERGEPAINT(소스 비트맵과 대상 화면을 OR), SRCCOPY(소스 영역을 대상 영역에 복사), WHITENESS(흰색으로 채움)

  비트맵도 GDI 오브젝트 이므로, DeleteObject함수로 지우고,

  사용이 끝난 메모리 DC는 DeleteDC라는 함수를 이용해 해제한다.


StretchBlt

- DC간 비트맵을 전송하는데 확대 및 축소가 가능

  BOOL StretchBlt(HDC hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,

            HDC hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, DWORD dwRop);

  - 복사원(hdcSrc)의 지정한 영역이 복사 대상(hdcDest)의 지정한 영역의 크기만큼 확대(또는 축소)되어 출력

  원칙적으로 비트맵은 WM_CREATE에서 미리 읽어 두고, WM_PAINT에서는 출력 만을 해야함.

  WM_DESTROY에서는 비트맵을 해제해줘야 한다.

  * GetObject 함수는 GDI 오브젝트 핸들로부터 펜, 브러시, 비트맵 등의 정보를 조사하는 함수.

  * 비트맵 출력 절차중 가장 느린 함수는 LoadBitmap 함수이다.


비트맵 만들기

- 비트맵 편집기로 직접 제작할 수 있음.


폰트

- 폰트를 만들고 DC로 전송한 후 문자열을 출력하면 DC에 선택된 폰트를 사용하여 문자열을 출력


CreateFont

- HFONT CreateFont(int nHeight, int nWidth, int nEscapement, int nOrientation, int fnWeight, DWORD fdwItalic,

             DWORD fdwUnderline, DWORD fdwStrikeOut, DWORD fdwCharSet, DWORD fdwOutputPrecision,

             DWORD, fdwClipPrecision, DWORD fdwQuality, DWORD fdwPitchAndFamily, LPCTSTR lpszFace);

  nHeight - 폰트의 높이를 논리적인 단위로 지정하며, 0일땐 디폴트 크기를 사용.

  nWidth - 폰트의 폭을 지정, 0이면 nHeight에 따라 폭을 자동으로 결정.

  lpszFace - 글꼴의 이름을 나타내는 문자열을 설정.


폰트 생성

- LOGFONT 구조체는 CreateFont 함수의 인수 전체를 멤버로 가짐.

  이 구조체에 원하는 값을 먼저 대입한 후 CreateFontIndirect 함수로 이 구조체의 번지를 넘겨 폰트를 생성할 수도 있음.

  HFONT CreateFontIndirect(CONST LOGFONT* lplf);

  - 전달되는 인수가 적으므로 CreateFont에 비해 빠름.

    여러벌의 폰트를 만들때에도 LOGFONT의 멤버중 일부만을 변경하여 재사용 가능

    뒤에 Indirect가 붙은 몇몇 함수들은 이런식으로 구조체의 주소를 받는 함수이다.


텍스트의 색상

- 폰트 오브젝트외에 출력되는 문자열에 영향을 주는 함수들.

  UINT SetTextAlign(HDC hdc, UINT fMode);

  COLORREF SetTextColor(HDC hdc, COLORREF crColor);

  - Text의 Color를 Set하는 함수

    GetTextColor가 반대의 함수.

  COLORREF SetBkColor(HDC hdc, COLORREF crColor);

  - 글자 뒤쪽의 배경 색상을 지정하는 함수

    GetBkColor가 반대의 함수.

  int SetBkMode(HDC hdc, int iBkMode);

  - 배경 색상을 사용할 방법을 지정

    iBkMode - OPAQUE(불투명한 배경을 사용, 디폴트)

                    TRANSPARENT(투명한 배경색상을 사용)


글자 회전시키기

- CreateFont의 세 번째 인수인 nEscapement를 변경하면 문자열의 각도를 바꿀수 있음.


신고

'20130827이전 > WinAPI' 카테고리의 다른 글

8장. 대화상자  (0) 2013.01.15
7장. 컨트롤  (0) 2013.01.14
6장. 그래픽  (0) 2013.01.14
5장. 리소스  (0) 2013.01.13
4장. 입력  (0) 2013.01.13
3장. 출력  (0) 2013.01.12
Posted by 흰둥에미

리소스의 분리

- 프로그램은 코드와 데이터로 구성. 데이터는 프로그램의 처리 대상, 코드는 데이터를 처리하는 수단.

  코드의 논리와 무관한 데이터들을 리소스라고함.

  메뉴, 비트맵, 엑셀러레이터, 문자열, 아이콘, 커서 등

  리소스 제작과정과 코딩과정의 분리의 이점.

  - 디자이너와 프로그래머가 분담하여 작업하기 용이.

    리소스를 수정하더라도, 소스를 일일이 다시 컴파일 할 필요가 없음.

    리소스의 재사용이 용이

    실행중 리소스를 교체 가능. (다국어 버전, 스킨, 플러그인 등)


리소스 편집기

- 리소스의 소스파일은 rc확장자를 가짐(텍스트 파일).

  리소스 컴파일러에 의해 컴파일 되면 res확장자를 가진 이진 파일이 생성됨.

  다국어 버전을 만들 때 양쪽의 ID를 일치시킨다거나 일련의 컨트롤에 연속적인 ID를 부여하는 등,

  직접 작성의 필요가 있을때 resource.h 파일을 수정한다. (rc파일을 직접 수정할 일은 거의 없음.)


리소스 작성

  MAKEINTRESOURCE 매크로 - 숫자로 정의된 리소스를 그와 매칭 되는 문자열 형태로 변경해 줌.

  메뉴 항목을 선택시, WM_COMMAND 메시지가 발생됨.

  윈도우를 종료시킬땐, DestoryWindow 함수를 이용해야 하며, PostQuitMessage로 종료해선 안됨.


WM_COMMAND

- 메뉴 항목 선택 시 발생하는 메시지.

  wParam 의 LOWORD가 선택된 메뉴의 ID

  엑셀러레이터를 누를 때도 발생, 버튼, 에디트 박스 등의 컨트롤이 부모 윈도우로 통지 메시지를 보낼 때도 발생.

  lParam - 통지 메시지를 발생시킨 컨트롤의 윈도우 핸들.

  LOWORD(wParam) - 메뉴나 엑셀러레이터, 컨트롤의 ID

  HIWORD(wParam) - 컨트롤이 보내는 통지 메시지, 메뉴가 선택된 경우 0, 엑셀러레이터가 선택된 경우 1


메뉴 편집기

- 비주얼 스튜디오의 리소스 편집기 사용법


아이콘, 커서

- 새로운 아이콘을 추가하면, 아이콘 편집기가 열리며 아이콘을 저장한 후,

  소스상 WNDCLASS 구조체의 값을 지정할 때, hIcon멤버에 LoadIcon(hInstance, MAKEINTRESOURCE(아이콘ID))를 지정하면 됨.

  커서도 리소스 추가후,

  소스상 WNDCLASS 구조체의 값을 지정할 때, hCursor멤버에 LoadCursor(hInstance, MAKEINTRESOURCE(커서ID))를 지정하면 됨.


엑셀러레이터

- 엑셀러레이터란 쉽게 말해 단축키이며, 진짜 단축키(ShortCut)과는 의미가 조금 다름.

  단축키는 반드시 Alt키와 함께 사용하며, 메뉴에 있는 항목을 키보드로 선택하는 빠른 방법

  엑셀러레이터는 메뉴와 상관없이 사용하는 '단축키'를 의미

  ID, 보조키, 키, 키의 형식 등의 정보 엑셀러레이터를 구성함.

  사용을 위해선 아래와 같이 코드를 작성.

  HACCEL hAccel;
  hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(엑셀러레이터ID));
  while(GetMessage(&Message, NULL, 0, 0))
  {
      if (!TranslateAccelerator(hWnd, hAccel, & Message))
      {
          TranslateMessage(&Message);
          DispatchMessage(&Message);
       }
  }

  HACCEL LoadAccelerators(HINSTANCE hInstance, LPCTSTR lpTableName);

  - 리소스로부터 엑셀러레이터 테이블을 읽어들임.

    lpTableName은 엑셀러레이터 테이블의 이름 문자열(MAKEINTRESOURCE매크로를 이용)

  int TranslateAccelerator(HWND hWnd, HACCEL hAccTable, LPMSG lpMsg);

  - 키보드 메시지를 WM_COMMAND메시지로 변경하여 엑셀러레이터가 동작할 수 있도록 함.

     키보드 메시지가 WM_COMMAND메시지로 변경되면, TRUE를 리턴하며, 메시지 루프의 일반 메시지 처리기로 넘어가지 않는다.

     TranslateMessage와의 차이점은 TranslateMessage의 경우 WM_KEYDOWN으로부터 WM_CHAR을 추가로 발생시키지만,

     TranslateAccelerator은 WM_KEYDOWN이 사라지고 WM_COMMAND 메시지를 발생시킨다.


문자열 테이블

- 문자열들도 리소스의 일종으로 취급

  문자열은 최대 4K까지의 길이를 가질 수 있음.

  문자열 편집기에서 ID, 값, 문자열을 지정하여 사용할 수 있음.

  int LoadString(HINSTANCE hInstance, UINT uID, LPTSTR lpBuffer, int nBufferMax);

  - hInstance는 WinMain의 첫 번째 인수로 들어오는 프로그램의 인스턴스

    uID는 읽어올 문자열의 ID

    lpBuffer - 문자열을 읽어올 버퍼

    nBufferMax - 버퍼의 길이, 버퍼 오버런의 방지를 위해

  문자열 리소스의 이점은 본문의 초반에 나온 리소스가 코드와 분리되어 나타나는 장점과 일맥상통.



신고

'20130827이전 > WinAPI' 카테고리의 다른 글

7장. 컨트롤  (0) 2013.01.14
6장. 그래픽  (0) 2013.01.14
5장. 리소스  (0) 2013.01.13
4장. 입력  (0) 2013.01.13
3장. 출력  (0) 2013.01.12
2장. 첫번째 예제  (0) 2013.01.12
Posted by 흰둥에미

최근에 달린 댓글

최근에 받은 트랙백

글 보관함