1. 그리기 모드를 사용하여 선그리기.
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static POINTS ptFrom, ptTo;
switch( msg )
{
case WM_CREATE:
return 0;
case WM_LBUTTONDOWN:
ptFrom = MAKEPOINTS(lParam);
ptTo = MAKEPOINTS(lParam);
{
HDC hdc = GetDC(hwnd);
Rectangle( hdc, 100, 100, 200, 200 );
ReleaseDC(hwnd, hdc);
}
SetCapture( hwnd );
return 0;
case WM_LBUTTONUP:
{
if( GetCapture() == hwnd )
{
ReleaseCapture();
HDC hdc = GetDC(hwnd);
MoveToEx( hdc, ptFrom.x, ptFrom.y, 0 );
LineTo( hdc, ptTo.x, ptTo.y );
ReleaseDC( hwnd, hdc );
}
}
return 0;
case WM_MOUSEMOVE:
if( wParam & MK_LBUTTON )
{
POINTS pt = MAKEPOINTS(lParam);
HDC hdc = GetDC( hwnd );
SetROP2( hdc, R2_NOTXORPEN ); // 그리기 모드를 반전 모드로 만든다.
MoveToEx( hdc, ptFrom.x, ptFrom.y, 0 );
LineTo( hdc, ptTo.x, ptTo.y );
MoveToEx( hdc, ptFrom.x, ptFrom.y, 0 );
LineTo( hdc, pt.x, pt.y );
ptTo = pt;
ReleaseDC( hwnd, hdc );
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
2. Region의 활용
3. WM_PAINT(1) : 마우스 움직일때마다 사각형 그리고 계속 그려주기.
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static vector<POINTS> v;
switch( msg )
{
case WM_MOUSEMOVE:
{
POINTS pt = MAKEPOINTS( lParam );
HDC hdc = GetDC( hwnd );
Rectangle( hdc, pt.x, pt.y, pt.x + 50, pt.y + 50 );
v.push_back( pt );
ReleaseDC( hwnd, hdc );
}
return 0;
case WM_PAINT:
{
//HDC hdc = GetDC( hwnd );
//HideCaret( hwnd );
// WM_PAINT를 처리 할떄는 반드시 무효화 영역을 유효화 영역으로
// 변경해야 한다. 즉, QS_PAINT 플래그를 0으로 해야 한다.
//ValidateRect( hwnd, 0 );
//ShowCaret( hwnd );
//ReleaseDC( hwnd, hdc );
PAINTSTRUCT ps;
HDC hdc = BeginPaint( hwnd, &ps );
for( int i = 0; i < v.size(); ++i )
Rectangle( hdc, v[i].x, v[i].y, v[i].x + 50, v[i].y + 50 );
EndPaint( hwnd, &ps );
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
4. WM_PAINT2
more..
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static POINTS ptFrom, ptTo;
switch( msg )
{
case WM_CREATE:
return 0;
case WM_LBUTTONDOWN:
ptFrom = MAKEPOINTS(lParam);
ptTo = MAKEPOINTS(lParam);
{
HDC hdc = GetDC(hwnd);
Rectangle( hdc, 100, 100, 200, 200 );
ReleaseDC(hwnd, hdc);
}
SetCapture( hwnd );
return 0;
case WM_LBUTTONUP:
{
if( GetCapture() == hwnd )
{
ReleaseCapture();
HDC hdc = GetDC(hwnd);
MoveToEx( hdc, ptFrom.x, ptFrom.y, 0 );
LineTo( hdc, ptTo.x, ptTo.y );
ReleaseDC( hwnd, hdc );
}
}
return 0;
case WM_MOUSEMOVE:
if( wParam & MK_LBUTTON )
{
POINTS pt = MAKEPOINTS(lParam);
HDC hdc = GetDC( hwnd );
SetROP2( hdc, R2_NOTXORPEN ); // 그리기 모드를 반전 모드로 만든다.
MoveToEx( hdc, ptFrom.x, ptFrom.y, 0 );
LineTo( hdc, ptTo.x, ptTo.y );
MoveToEx( hdc, ptFrom.x, ptFrom.y, 0 );
LineTo( hdc, pt.x, pt.y );
ptTo = pt;
ReleaseDC( hwnd, hdc );
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
2. Region의 활용
more..
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static char str[] = "Clipping Region Test";
static HRGN hRgnUp, hRgnDown;
static int cx, cy;
switch( msg )
{
case WM_SIZE:
cx = LOWORD(lParam);
cy = HIWORD(lParam);
DeleteObject( hRgnUp );
DeleteObject( hRgnDown);
hRgnUp = CreateRectRgn( 0, 0, cx, cy/2 );
hRgnDown = CreateRectRgn( 0, cy/2, cx, cy );
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint( hwnd, &ps );
HFONT hFont = CreateFont(
72, 0, 0, 0, FW_BOLD, 0, 0, 0, 0,
0, 0, 0, 0, "Tahoma" );
HFONT hFontOld = (HFONT)SelectObject( hdc, hFont );
RECT rc = { 0, 0, cx, cy };
SetTextColor( hdc, RGB(255, 0, 0) );
SelectClipRgn( hdc, hRgnUp );
DrawText( hdc, str, -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER );
DeleteObject( SelectObject(hdc, hFontOld) );
EndPaint( hwnd, &ps );
}
return 0;
case WM_LBUTTONDOWN:
{
HDC hdc = GetDC( hwnd );
HRGN h1 = CreateEllipticRgn( 0, 0, 300, 300 );
HRGN h2 = CreateRoundRectRgn( 200, 200, 400, 400, 30, 30 );
HRGN h3 = CreateRectRgn( 0, 0, 0, 0 );
CombineRgn( h3, h1, h2, RGN_XOR );
// 영역의 활용 3. DC의 클리핑 영역 제한 - ( 텍스트의 색 부분 바꾸기 )
char s[] = "asdasdasddddddiijijijioijoioijoijijojojojojoijoj";
TextOut( hdc, 10, 20, s, strlen(s) );
SelectClipRgn( hdc, h1 );
SetTextColor( hdc, RGB(255, 0, 0) );
TextOut( hdc, 10, 20, s, strlen(s) );
// 영역의 활용 2. - Hitting Test( Region 영역 클릭 테스트 )
//POINT pt = { LOWORD(lParam) , HIWORD(lParam) };
POINTS pt = MAKEPOINTS( lParam );
if( PtInRegion( h1, pt.x, pt.y ) )
MessageBox( hwnd, "In Region", "", MB_OK );
// 영역의 활용 1. - 비정형 윈도우(윈도우창 가리기)
SetWindowRgn( hwnd, h2, TRUE );
DeleteObject( SelectObject( hdc, GetStockObject( BLACK_BRUSH ) ) );
DeleteObject( h1 );
DeleteObject( h2 );
DeleteObject( h3 );
ReleaseDC( hwnd, hdc );
}
return 0;
case WM_DESTROY:
DeleteObject( hRgnUp );
DeleteObject( hRgnDown );
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
{
static char str[] = "Clipping Region Test";
static HRGN hRgnUp, hRgnDown;
static int cx, cy;
switch( msg )
{
case WM_SIZE:
cx = LOWORD(lParam);
cy = HIWORD(lParam);
DeleteObject( hRgnUp );
DeleteObject( hRgnDown);
hRgnUp = CreateRectRgn( 0, 0, cx, cy/2 );
hRgnDown = CreateRectRgn( 0, cy/2, cx, cy );
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint( hwnd, &ps );
HFONT hFont = CreateFont(
72, 0, 0, 0, FW_BOLD, 0, 0, 0, 0,
0, 0, 0, 0, "Tahoma" );
HFONT hFontOld = (HFONT)SelectObject( hdc, hFont );
RECT rc = { 0, 0, cx, cy };
SetTextColor( hdc, RGB(255, 0, 0) );
SelectClipRgn( hdc, hRgnUp );
DrawText( hdc, str, -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER );
DeleteObject( SelectObject(hdc, hFontOld) );
EndPaint( hwnd, &ps );
}
return 0;
case WM_LBUTTONDOWN:
{
HDC hdc = GetDC( hwnd );
HRGN h1 = CreateEllipticRgn( 0, 0, 300, 300 );
HRGN h2 = CreateRoundRectRgn( 200, 200, 400, 400, 30, 30 );
HRGN h3 = CreateRectRgn( 0, 0, 0, 0 );
CombineRgn( h3, h1, h2, RGN_XOR );
// 영역의 활용 3. DC의 클리핑 영역 제한 - ( 텍스트의 색 부분 바꾸기 )
char s[] = "asdasdasddddddiijijijioijoioijoijijojojojojoijoj";
TextOut( hdc, 10, 20, s, strlen(s) );
SelectClipRgn( hdc, h1 );
SetTextColor( hdc, RGB(255, 0, 0) );
TextOut( hdc, 10, 20, s, strlen(s) );
// 영역의 활용 2. - Hitting Test( Region 영역 클릭 테스트 )
//POINT pt = { LOWORD(lParam) , HIWORD(lParam) };
POINTS pt = MAKEPOINTS( lParam );
if( PtInRegion( h1, pt.x, pt.y ) )
MessageBox( hwnd, "In Region", "", MB_OK );
// 영역의 활용 1. - 비정형 윈도우(윈도우창 가리기)
SetWindowRgn( hwnd, h2, TRUE );
DeleteObject( SelectObject( hdc, GetStockObject( BLACK_BRUSH ) ) );
DeleteObject( h1 );
DeleteObject( h2 );
DeleteObject( h3 );
ReleaseDC( hwnd, hdc );
}
return 0;
case WM_DESTROY:
DeleteObject( hRgnUp );
DeleteObject( hRgnDown );
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
3. WM_PAINT(1) : 마우스 움직일때마다 사각형 그리고 계속 그려주기.
more..
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static vector<POINTS> v;
switch( msg )
{
case WM_MOUSEMOVE:
{
POINTS pt = MAKEPOINTS( lParam );
HDC hdc = GetDC( hwnd );
Rectangle( hdc, pt.x, pt.y, pt.x + 50, pt.y + 50 );
v.push_back( pt );
ReleaseDC( hwnd, hdc );
}
return 0;
case WM_PAINT:
{
//HDC hdc = GetDC( hwnd );
//HideCaret( hwnd );
// WM_PAINT를 처리 할떄는 반드시 무효화 영역을 유효화 영역으로
// 변경해야 한다. 즉, QS_PAINT 플래그를 0으로 해야 한다.
//ValidateRect( hwnd, 0 );
//ShowCaret( hwnd );
//ReleaseDC( hwnd, hdc );
PAINTSTRUCT ps;
HDC hdc = BeginPaint( hwnd, &ps );
for( int i = 0; i < v.size(); ++i )
Rectangle( hdc, v[i].x, v[i].y, v[i].x + 50, v[i].y + 50 );
EndPaint( hwnd, &ps );
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
4. WM_PAINT2
more..
// 화면에 스코어를 그리는 부분을 함수로 만들고 싶다.
// 1. HWND 를 받아서 내부적으로 DC를 구하자. ( BeginPaint, GetDC 문제가 생긴다. )
// 2. HDC를 받아서 바로 사용하자. - OK..
void DrawScore( HDC hdc, int x, int y, int score )
{
// 여기서 x, y 좌표에 비트맵을 사용 score를 그려준다.
}
//-------------------------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static char s[] = "hello";
switch( msg )
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint( hwnd, &ps );
for( int i = 0; i < 500; i+=10)
Rectangle( hdc, i, i, 1000-i, 1000-i );
TextOut( hdc, 10, 10, s, strlen(s) );
EndPaint( hwnd, &ps );
}
return 0;
case WM_LBUTTONDOWN:
{
// 출력물이 변경되었다. !!!!
strcpy( s, "xxxxx" );
// 출력물을 다시 그려야 한다. - 어떻게 ??
// 1. 강제로 무효화영역을 만들자. - 꼭 필요한 곳을 계산해서 무효화하라.
// InvalidateRect( hwnd, 0, TRUE );
//RECT rc = { 10, 10, 100, 40 };
//InvalidateRect( hwnd, &rc, TRUE );
// 2. WM_PAINT 가 복잡한 코드가 많다면 성능 저하가 발생할 수도 있다.
// 간단한 그림은 직접 그리자. - 코드가 중복될 수 있는 단점은 있다.
HDC hdc = GetDC( hwnd );
TextOut( hdc, 10, 10, s, strlen(s) );
ReleaseDC( hwnd, hdc );
}
return 0;
case WM_RBUTTONDOWN:
{
strcpy( s, "xxxxx" );
// 다시 그리기 위해 무효화 영역 발생 메시지Q에 넣어주기만 한다.
InvalidateRect( hwnd, 0, TRUE );
// if( msg Q has WM_PAINT ) WndProc( hwnd, WM_PAINT ); 즉시 반영!!
UpdateWindow( hwnd );
// 다른 작업을 한다. - 5분 걸린다고 가정.
for( int i = 0; i < 100000000; ++i );
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
// 1. HWND 를 받아서 내부적으로 DC를 구하자. ( BeginPaint, GetDC 문제가 생긴다. )
// 2. HDC를 받아서 바로 사용하자. - OK..
void DrawScore( HDC hdc, int x, int y, int score )
{
// 여기서 x, y 좌표에 비트맵을 사용 score를 그려준다.
}
//-------------------------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static char s[] = "hello";
switch( msg )
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint( hwnd, &ps );
for( int i = 0; i < 500; i+=10)
Rectangle( hdc, i, i, 1000-i, 1000-i );
TextOut( hdc, 10, 10, s, strlen(s) );
EndPaint( hwnd, &ps );
}
return 0;
case WM_LBUTTONDOWN:
{
// 출력물이 변경되었다. !!!!
strcpy( s, "xxxxx" );
// 출력물을 다시 그려야 한다. - 어떻게 ??
// 1. 강제로 무효화영역을 만들자. - 꼭 필요한 곳을 계산해서 무효화하라.
// InvalidateRect( hwnd, 0, TRUE );
//RECT rc = { 10, 10, 100, 40 };
//InvalidateRect( hwnd, &rc, TRUE );
// 2. WM_PAINT 가 복잡한 코드가 많다면 성능 저하가 발생할 수도 있다.
// 간단한 그림은 직접 그리자. - 코드가 중복될 수 있는 단점은 있다.
HDC hdc = GetDC( hwnd );
TextOut( hdc, 10, 10, s, strlen(s) );
ReleaseDC( hwnd, hdc );
}
return 0;
case WM_RBUTTONDOWN:
{
strcpy( s, "xxxxx" );
// 다시 그리기 위해 무효화 영역 발생 메시지Q에 넣어주기만 한다.
InvalidateRect( hwnd, 0, TRUE );
// if( msg Q has WM_PAINT ) WndProc( hwnd, WM_PAINT ); 즉시 반영!!
UpdateWindow( hwnd );
// 다른 작업을 한다. - 5분 걸린다고 가정.
for( int i = 0; i < 100000000; ++i );
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}