本帖最后由 steven20027 于 2010-05-24 16:10:30 编辑

解决方案 »

  1.   


    之前有想过,不过没有想得太细。现在似乎想明白了。
    是不是因为使用了
    SetROP2(hdc, R2_NOT);
    第一次DrawLine的时候就把上次DrawLine画出的那条线用相反的颜色(也就是白色)给覆盖掉了?
    所以一旦少了一句,就会出现一簇直线?
      

  2.   

    那照上面那样理解的话,为什么下面代码画矩形的时候又没有把第一次画好的实心矩形给擦掉呢?
    #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 ("BlokOut1") ;
    HWND hwnd ;
    MSG msg ;
    WNDCLASS wndclass ;

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

    if (!RegisterClass (&wndclass))        
        {        
    MessageBox (NULL, TEXT ("Registration Failed!"), szAppName, MB_ICONINFORMATION) ;        
    return 0 ;        
    }

    hwnd = CreateWindow (szAppName, TEXT ("Mouse Button Demo"),        
    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 ;

    }
    void DrawRect(HWND hwnd, POINT ptBeg, POINT ptEnd){
    HDC hdc ;
    hdc = GetDC (hwnd) ;

    SetROP2 (hdc, R2_NOT) ;
    SelectObject (hdc, GetStockObject (NULL_BRUSH)) ;
    Rectangle (hdc, ptBeg.x, ptBeg.y, ptEnd.x, ptEnd.y) ;

    ReleaseDC (hwnd, hdc) ;

    }LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam){
    static BOOL fBlocking, fValidBox ;
    static POINT ptBeg, ptEnd, ptBoxBeg, ptBoxEnd ;
    HDC hdc ;
    PAINTSTRUCT ps ;

    switch (message)        
    {        
    case WM_LBUTTONDOWN :        
    ptBeg.x = ptEnd.x = LOWORD (lParam) ;        
    ptBeg.y = ptEnd.y = HIWORD (lParam) ;   
    SetCursor (LoadCursor (NULL, IDC_CROSS)) ;
    fBlocking = TRUE ;
            
    return 0 ;

    case WM_MOUSEMOVE :
    if (fBlocking)
    {
    SetCursor (LoadCursor (NULL, IDC_CROSS)) ;
    DrawRect (hwnd, ptBeg, ptEnd) ; //代码一
    ptEnd.x = LOWORD (lParam) ;
    ptEnd.y = HIWORD (lParam) ;
    DrawRect (hwnd, ptBeg, ptEnd) ; //代码二
    }
            
    return 0 ;

    case WM_LBUTTONUP :
    if (fBlocking)
    {
    DrawRect (hwnd, ptBeg, ptEnd) ;
    ptBoxBeg = ptBeg ;
    ptBoxEnd.x = LOWORD (lParam) ;
    ptBoxEnd.y = HIWORD (lParam) ;
    SetCursor (LoadCursor (NULL, IDC_ARROW)) ;
    fBlocking = FALSE ;
    fValidBox = TRUE ;
    InvalidateRect (hwnd, NULL, FALSE) ;
    }
            
    return 0 ;

    case WM_PAINT :        
    hdc = BeginPaint (hwnd, &ps) ;

    if (fValidBox)
    {
    SelectObject (hdc, GetStockObject (BLACK_BRUSH)) ;
    Rectangle (hdc, ptBoxBeg.x, ptBoxBeg.y,
    ptBoxEnd.x, ptBoxEnd.y) ;
    }
            
    //  if (fBlocking)
    //  {
    //  SetROP2 (hdc, R2_NOT) ;
    //  SelectObject (hdc, GetStockObject (NULL_BRUSH)) ;
    //  Rectangle (hdc, ptBeg.x, ptBeg.y, ptEnd.x, ptEnd.y) ;
    //  }
            
    EndPaint (hwnd, &ps) ;
            
    return 0 ;
            

    case WM_DESTROY :
    PostQuitMessage (0) ;

    return 0 ;
        }

    return DefWindowProc (hwnd, message, wParam, lParam) ;
    }我在WM_MOUSEMOVE中进行绘图时,并没有使目标区域失效,这样在接收到WM_LBUTTONUP消息之前也就不会发生重绘,那为什么在画后面的矩形的时候没有擦掉之前画的那个用黑色画笔填充的矩形呢?搞不懂了...
      

  3.   

    就是因为SetROP2(hdc, R2_NOT);,先调用DrawLine清除原来画的线,然后再画新的线。