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(),则显示正常,请教诸位是什么原因。
InvalidateRect picHdc, picRect, True
UpdateWindow picHwnd
BitBlt picHdc, 0, 0, picW, picH, hpicDC, 0, 0, vbSrcCopy
执行后,picturebox只是闪烁一下,并没有象设想的那样加载图片,如果把前两句直接替换为VB语句picturebox1.picture=loadpicture(),则显示正常,请教诸位是什么原因。
{
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)次序不对,应该是
禁止刷新
绘图
强制刷新
非常高兴又一次见到您。您所说的两个问题,第一个是我整理上传时发生的笔误,第二个即次序问题我也试着调整过,但是问题依然存在。请问还有没有其它原因?
您所提供的C代码我已经拜读过了,您所提出的DC兼容性问题原则上可以排除,因为源场景是通过picturebox使用CreateCompatibleDC函数创建的。另外,我希望实现交互式刷新,而BeginPaint和EndPaint两个函数好像只适应于PAINT事件,这也是我使用UpdateWindow 强制刷新的原因。谢谢您的指教,期待着您提供更多的解决方案。
在这里,随便请教一下诸位:可不可以直接发送paint消息直接处理。我先试一下,也希望见帖诸位能帮助一下。谢谢了。
还有 AutoRedraw=True 的 PictureBox 绘图和显示是两个 hDC,不通过 VB 的函数绘图可能需要调用 Refresh 刷新一下。
InvalidateRect 的作用是将指定的屏幕区域设置为无效区域
实际这个api将指定的矩形范围从屏幕上剪掉了他将引起重画过程,指定最后一个参数
如果单纯的在调用完这个函数后又象lz一样画图,有两个可能导致失败
1. 被重画消息将自己画图过程覆盖
2. 该矩形区域已经无效,前次取得的句柄也已经无效set picturebox = loadxxx 是依靠重画消息实现的
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