9.18(화) 실습-1

2007/10/10 16:47

1. Caret 이동과 RegisterHotkey 등록, Animate Window 구현!!!

[ more.. | less.. ]
#define ID_SHOW 1
#define ID_HIDE 2
#define ID_EXEC 3LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    static int x = 0, y = 0;

    switch( msg )
    {   
    case WM_CREATE:
        {
            RegisterHotKey( hwnd, ID_EXEC, MOD_SHIFT, 'E' );
            RegisterHotKey( hwnd, ID_SHOW, MOD_SHIFT, 'S' );
            RegisterHotKey( hwnd, ID_HIDE, MOD_SHIFT, 'H' );
        }
        return 0;
    case WM_HOTKEY:
        switch( wParam )
        {
        case ID_EXEC:
            WinExec( "Freecell.exe", SW_SHOW );
            break;

        case ID_SHOW:
            AnimateWindow( hwnd, 1000, AW_SLIDE | AW_VER_NEGATIVE );
            break;

        case ID_HIDE:
            AnimateWindow( hwnd, 1000, AW_SLIDE | AW_VER_POSITIVE | AW_HIDE );
            break;
        }
        return 0;

    case WM_SETFOCUS:
        CreateCaret( hwnd, 0, 20, 20 );
        SetCaretPos( x, y );
        ShowCaret( hwnd );

        SetCaretBlinkTime( 500 );
        return 0;
    case WM_KILLFOCUS:
        HideCaret( hwnd );
        DestroyCaret();
        return 0;

    case WM_KEYDOWN:
        switch( wParam )
        {
        case VK_LEFT:    x = max( 0, x-20 );    break;
        case VK_RIGHT:    x = x + 20;    break;
        case VK_UP:        y = max( 0, y-20 );    break;
        case VK_DOWN:    y = y + 20;    break;
        default:    return 0;
        }
        SetCaretPos( x, y );
        return 0;

    case WM_DESTROY:
        UnregisterHotKey( hwnd, ID_SHOW );
        UnregisterHotKey( hwnd, ID_HIDE );
        UnregisterHotKey( hwnd, ID_EXEC );

        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc( hwnd, msg, wParam, lParam);
}

2. DC의 생성을 클래스화 해보기

[ more.. | less.. ]
class CDC
{
public:
    HWND    m_hWnd;
    HDC        m_hDC;

    // 모든 그리는 함수 800여개를 멤버로 제공한다.
    void TextOut( int x, int y, const char* s )
    {
        // 다시 Win32 API를 호출한다.
        ::TextOut( m_hDC, x, y, s, strlen(s) );
    }
};
class CPaintDC : public CDC
{
    PAINTSTRUCT m_ps;
public:
    CPaintDC( HWND hwnd )
    {
        m_hWnd = hwnd;
        m_hDC = BeginPaint( hwnd, &m_ps );
    }
    ~CPaintDC()
    {
        ::EndPaint( m_hWnd, &m_ps );
    }
};
class CWindowDC : public CDC
{
public:
    CWindowDC( HWND hwnd )
    {
        m_hWnd = hwnd;
        m_hDC = GetWindowDC( hwnd );
    }
    ~CWindowDC()
    {
        ReleaseDC( m_hWnd, m_hDC );
    }
};
class CClientDC : public CDC
{
public:
    CClientDC( HWND hwnd )
    {
        m_hWnd = hwnd;
        m_hDC = GetDC( hwnd );
    }
    ~CClientDC()
    {
        ReleaseDC( m_hWnd, m_hDC );
    }
};

3. 키상태 조사하기
[ more.. | less.. ]
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch( msg )
    {
    case WM_LBUTTONDOWN:
        {
            // 일반 키상태 조사 - 상위 8비트 조사
            if ( GetKeyState( VK_SHIFT ) & 0xFF00 )
                MessageBox( 0, "LBUTTON + SHIFT", "", MB_OK );

            // 대소문자 상태 조사
            if ( GetKeyState( VK_CAPITAL ) & 0x00FF )
                MessageBox( 0, "대문자 상태", "", MB_OK );
            else
                MessageBox( 0, "소문자 상태", "", MB_OK );
        }
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc( hwnd, msg, wParam, lParam);
}

4. MouseMessage(WM_MOUSELEAVE를 위해선 TRACKMOUSEENVET를 설정해줘야 한다!!!)
[ more.. | less.. ]
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    static BOOL bOver = FALSE;

    switch( msg )
    {   
    case WM_MOUSEWHEEL:
        {
            short delta = HIWORD( wParam );

            delta = ( delta / WHEEL_DELTA ) * 10;    // WHEEL_DELTA : 120

            RECT rc;
            GetWindowRect( hwnd, &rc );

            OffsetRect( &rc, 0, delta);

            SetWindowPos( hwnd, 0, rc.left, rc.top, 0, 0,
                            SWP_NOSIZE | SWP_NOZORDER );
        }
        return 0;

    case WM_MOUSEMOVE:
        {
            if( bOver == FALSE )
            {
                SetWindowText( hwnd, "마우스가 윈도우 위에 있습니다." );
                // MOUSELEAVE를 요청한다.
                TRACKMOUSEEVENT tme;
                tme.cbSize = sizeof(tme);
                tme.dwFlags = TME_LEAVE;
                tme.dwHoverTime = 0;
                tme.hwndTrack = hwnd;

                TrackMouseEvent( &tme );
                bOver = TRUE;
            }
        }
        return 0;

    case WM_MOUSELEAVE:
        SetWindowText( hwnd, "마우스가 벗어 났습니다." );
        bOver = FALSE;
        return 0;

    case WM_LBUTTONDOWN:
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc( hwnd, msg, wParam, lParam);
}


5. SendInput 으로 입력 스트림에 키보드 입력을 넣어보자.
[ more.. | less.. ]
int main()
{
    while( 1 )
    {
        INPUT input = { 0 };
        input.type = INPUT_KEYBOARD;
        input.ki.wVk = 'A';

        SendInput(
            1, // INPUT 배열의 갯수
            &input,
            sizeof(INPUT) );    // INPUT 구조체의 크기

        Sleep( 1000 );
    }
}

Tags

API, 실습