-2

This is the code as attempted so far:

#include <windows.h>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
    static TCHAR szAppname[] = TEXT ("win0") ;
    WNDCLASS wndclass ;
    MSG msg ;
    HWND hwnd ;

    wndclass.style = CS_HREDRAW | CS_VREDRAW ;
    wndclass.cbWndExtra = 0 ;
    wndclass.cbClsExtra = 0 ;
    wndclass.lpfnWndProc = WndProc ;
    wndclass.lpszClassName = szAppname ;
    wndclass.lpszMenuName = NULL ;
    wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
    wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
    wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
    wndclass.hInstance = hInstance ;

    if (!RegisterClass (&wndclass))
    {
        MessageBox (NULL, TEXT ("Register fail"), szAppname, 0) ;
        return 0 ;
    }
    hwnd = CreateWindow (   szAppname,
                            TEXT ("mywin"),
                            WS_OVERLAPPEDWINDOW,
                            CW_USEDEFAULT,
                            CW_USEDEFAULT,
                            CW_USEDEFAULT,
                            CW_USEDEFAULT,
                            NULL,
                            NULL,
                            hInstance,
                            NULL) ;

    ShowWindow (hwnd, iCmdShow) ;
    UpdateWindow (hwnd) ;

    while (GetMessage (&msg, NULL, 0, 0))
    {
        TranslateMessage (&msg) ;
        DispatchMessage (&msg) ;
    }

    return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static int cxClient, cyClient, Left, Top, Right, Down ;
    PAINTSTRUCT ps ;
    HDC hdc ;
    RECT rect ;

    Right = 20 ; Down = 20 ;

    switch (message)
    {
    case WM_SIZE :
        cxClient = LOWORD (lParam) ;
        cyClient = HIWORD (lParam) ;
        return 0 ;
    case WM_PAINT :
        hdc = BeginPaint (hwnd, &ps) ;

        SetRect (&rect, Left, Top, Right, Down) ;

        FillRect (hdc, &rect, CreateSolidBrush (RGB (100, 100, 100))) ;

        EndPaint (hwnd, &ps) ;
        return 0 ;
    case WM_KEYDOWN :
        InvalidateRect (hwnd, &rect, TRUE) ;

        switch (wParam)
        {
        case VK_UP :
            if (Top - 20 < 0)
            {
                Top = 0 ;
                Down = 20 ;
            }
            else
            {
                Top -= 20 ;
                Down -= 20 ;
            }
            SendMessage (hwnd, WM_PAINT, wParam, lParam) ;
            break ;
        case VK_DOWN :
            if (Down + 20 > cyClient)
            {
                Down = cyClient ;
                Top = Down - 20 ;
            }
            else
            {
                Down += 20 ;
                Top += 20 ;
            }SendMessage (hwnd, WM_PAINT, wParam, lParam) ;
            break ;
        case VK_LEFT :
            if (Left - 20 < 0)
            {
                Left = 0 ;
                Right = 20 ;
            }
            else
            {
                Left -= 20 ;
                Right -= 20 ;
            }SendMessage (hwnd, WM_PAINT, wParam, lParam) ;
            break ;
        case VK_RIGHT :
            if (Right + 20 > cxClient)
            {
                Right = cxClient ;
                Left = Right - 20 ;
            }
            else
            {
                Right += 20 ;
                Left += 20 ;
            }SendMessage (hwnd, WM_PAINT, wParam, lParam) ;
            break ;
        default :
            break ;
        }
        return 0 ;
    case WM_DESTROY :
        PostQuitMessage (0) ;
        return 0 ;

    }
    return DefWindowProc (hwnd, message, wParam, lParam);
}

I considered that I didn't deal the message well, so I can't control it.

4

1 回答 1

0

Apart from the fact that you should use some static variables in the Window Proc to keep your program's state (you should use the HWND as a key into key→value map to locate the right data structure), to make the window actually redraw you must "invalidate" it, i.e. tell Windows that the contents need to be redrawn. Sending a WM_PAINT message doesn't do this. InvalidateRect does, so you should call that function after changing the variables and not sending a message.

Instead you should call InvalidateRect just after setting the variables.

于 2013-10-22T15:50:25.207 回答