picturebox1设置为自动刷新,它的hwnd为picHwnd,hdc为picHdc用户区域为picRect,执行下列语句:
InvalidateRect picHdc, picRect, True
UpdateWindow picHwnd
BitBlt picHdc, 0, 0, picW, picH, hpicDC, 0, 0, vbSrcCopy
执行后,picturebox只是闪烁一下,并没有象设想的那样加载图片,如果把前两句直接替换为VB语句picturebox1.picture=loadpicture(),则显示正常,请教诸位是什么原因。

解决方案 »

  1.   

    LRESULT CALLBACK WndProc ( HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
    {
          static HBITMAP hBitmap ;
          static int      cxClient, cyClient, cxSource, cySource ;
          BITMAP          bitmap ;
          HDC             hdc, hdcMem ;
          HINSTANCE       hInstance ;
          int             x, y ;
          PAINTSTRUCT     ps ;
         
          switch (message)
          {
          case  WM_CREATE:
               hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;           hBitmap = LoadBitmap (hInstance, TEXT ("Bricks")) ;           GetObject (hBitmap, sizeof (BITMAP), &bitmap) ;           cxSource = bitmap.bmWidth ;
               cySource = bitmap.bmHeight ;           return 0 ;      case  WM_SIZE:
               cxClient = LOWORD (lParam) ;
               cyClient = HIWORD (lParam) ;
               return 0 ;      case  WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;           hdcMem = CreateCompatibleDC (hdc) ;
               SelectObject (hdcMem, hBitmap) ;           for (y = 0 ; y < cyClient ; y += cySource)
               for (x = 0 ; x < cxClient ; x += cxSource)
               {
                    BitBlt (hdc, x, y, cxSource, cySource, hdcMem, 0, 0, SRCCOPY) ;
              }           DeleteDC (hdcMem) ;
               EndPaint (hwnd, &ps) ;
               return 0 ;
         
    case  WM_DESTROY:
               DeleteObject (hBitmap) ;
               PostQuitMessage (0) ;
               return 0 ;
          }
          return DefWindowProc (hwnd, message, wParam, lParam) ;
    }上面这段代码是Charles Petzold的书中的。我想,你要用BitBlt这样的API函数来干活,有没有DC的begin准备和后来的Release释放,另外,对于位图,它们的DC是否是相容的,你是否需要创建相容的DC。我对VB不熟。VB语句picturebox1.picture=loadpicture()应该在背后帮你做了这些准备和扫尾工作。picturebox只是闪烁一下,这说明InvalidateRect应该起作用了。
      

  2.   

    1)InvalidateRect 的第一个参数是 hWnd
    2)次序不对,应该是
    禁止刷新
    绘图
    强制刷新
      

  3.   

    要在ONPAINT等消息中来刷,不然图片只会刷新一次,闪下就没了
      

  4.   

    Tiger_zhao老师:
      非常高兴又一次见到您。您所说的两个问题,第一个是我整理上传时发生的笔误,第二个即次序问题我也试着调整过,但是问题依然存在。请问还有没有其它原因?
      

  5.   

    sjg20010414兄:
      您所提供的C代码我已经拜读过了,您所提出的DC兼容性问题原则上可以排除,因为源场景是通过picturebox使用CreateCompatibleDC函数创建的。另外,我希望实现交互式刷新,而BeginPaint和EndPaint两个函数好像只适应于PAINT事件,这也是我使用UpdateWindow 强制刷新的原因。谢谢您的指教,期待着您提供更多的解决方案。
        在这里,随便请教一下诸位:可不可以直接发送paint消息直接处理。我先试一下,也希望见帖诸位能帮助一下。谢谢了。
      
      

  6.   

    用 ValidateRect 对应 InvalidateRect。
    还有 AutoRedraw=True 的 PictureBox 绘图和显示是两个 hDC,不通过 VB 的函数绘图可能需要调用 Refresh 刷新一下。
      

  7.   


    InvalidateRect 的作用是将指定的屏幕区域设置为无效区域
    实际这个api将指定的矩形范围从屏幕上剪掉了他将引起重画过程,指定最后一个参数
    如果单纯的在调用完这个函数后又象lz一样画图,有两个可能导致失败
    1. 被重画消息将自己画图过程覆盖
    2. 该矩形区域已经无效,前次取得的句柄也已经无效set picturebox = loadxxx 是依靠重画消息实现的
      

  8.   

    你是不是没有取绘图用的 hDC
    Private Sub Command1_Click()
        Dim rc As RECT
        GetClientRect Picture1.hwnd, rc
        InvalidateRect Picture1.hwnd, rc, 1
        
        MoveToEx hDCPic, 100, 100, ByVal 0&
        AngleArc hDCPic, 100, 100, 50, 30, 300
        LineTo hDCPic, 100, 100
        
        'Refresh 是必须的,而下面这句可以不加'
        'ValidateRect Picture1.hwnd, rc
        Picture1.Refresh
    End SubPrivate Sub Form_Load()
        '★:如果下面两句次序交换,hDCPic 就是显示用 hDC,在上面作图是无用的'
        Picture1.AutoRedraw = True
        hDCPic = Picture1.hdc
    End Sub
      

  9.   

    把你的3行代码换成我Command1_Click()中的代码,能否成功。