首先,我向解答出的朋友们保证,我会及时给你结贴,但不要让我等太多天,我怕我会忘记,但这几天我一定会观注此问题的。其实,我这问题已在CDSN上问过好多次了,但都得不到满意的答案。希望这次能有个高手能详细的帮我解答好这个问题,下面我也详细说明我的问题:在VB6中,我用pictureBox来画长方形小格图(因为我要求有保留BMP图片功能,所以不能用ImageBox控件),我是在pictureBox中用picture1.line的方法来画小方格图的,我在程序中要画的方格图很多,会超出屏幕的原来实际宽度和高度。但是pictureBox控件不会自动象IE浏览器那样当超过屏幕的长或高时,就自动生成一个长和高的滑条,通过鼠标拉动滑条可以看到超出屏幕的其它部份内容。现在我就问,如何解决pictureBox中画图时,当画出的图超出屏幕的部份怎么也用滑条拖动来解决?请列出代码来,因为起先有人说用两个picturebox控件来实现,但我怎么做都没有办法,不懂他们是怎么做到的?
用两个PictureBox控件,首先在窗体添加1个PictureBox控件Picture1,然后在Picture1中间用鼠标加载另1个PictureBox控件Picture2.
在穿体添加剂个HScroll控件于窗体或Picture1内,调整Picture2的Height.
垂直滚动条建议不要与水平滚动条同时使用,会报错或当机.
代码如下:Private Sub Form_Load()
Me.Height = 11295
Me.Width = 15360
Picture1.Width = Me.Width - 400
'Picture2.Height = Picture1.Height
Picture2.Width = Picture1.Width * 2.1'倍率可调整
End SubPrivate Sub HScroll1_Change()
Picture2.Left = -HScroll1 * 0.5倍率需调整
End Sub
Private Sub Form_Load()
Picture2.AutoRedraw = True
Picture2.Left = Picture1.Left
Picture2.Top = Picture1.Top
Picture2.Width = Picture1.Width * 10
Picture2.Height = Picture1.Height * 10
HScroll1.Min = 0
HScroll1.Max = 100
VScroll1.Min = 0
VScroll1.Max = 100End SubPrivate Sub HScroll1_Change()
Picture2.Left = -HScroll1.Value * 0.1 * Picture1.Width
End Sub
Private Sub Picture2_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
If flag Then
Picture2.Line (ox, oy)-(X, Y), vbRed
flag = False
Else
flag = True
ox = X
oy = Y
End If
End SubPrivate Sub VScroll1_Change()
Picture2.Top = -VScroll1.Value * 0.1 * Picture1.WidthEnd Sub
先在窗体上拖一个双屏幕长的frame1框(你的所有内容都可以在这上面拖出),高18000;宽15085;(窗体的属性Scalemode取1-Twip)
然后拖水平与垂直的两个滚动条;(注意:要在窗体上拖出)
Vscrloo1(竖滚动条)属性:LargeChange=20000,Max=11055
HScroll1(横)属性:LargeChange=8000;Max=1000;Top=18000;Width=14040
上面是偶的选用参数,你也可自选;
建立一个模块:下面代码放进去
Option Explicit
Public Type POINTL
x As Long
y As Long
End Type
Declare Function CallWindowProc _
Lib "user32" Alias "CallWindowProcA" _
(ByVal lpPrevWndFunc As Long, _
ByVal hwnd As Long, _
ByVal Msg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
Declare Function SetWindowLong _
Lib "user32" Alias "SetWindowLongA" _
(ByVal hwnd As Long, _
ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Declare Function SystemParametersInfo _
Lib "user32" Alias "SystemParametersInfoA" _
(ByVal uAction As Long, _
ByVal uParam As Long, _
lpvParam As Any, _
ByVal fuWinIni As Long) As Long
Declare Function ScreenToClient Lib "user32" _
(ByVal hwnd As Long, xyPoint As POINTL) As Long
Public Const GWL_WNDPROC = -4
Public Const SPI_GETWHEELSCROLLLINES = 104
Public Const WM_MOUSEWHEEL = &H20A
Public WHEEL_SCROLL_LINES As Long
Global lpPrevWndProc As Long
Public Sub Hook(ByVal hwnd As Long)
lpPrevWndProc = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf WindowProc)
Call SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, WHEEL_SCROLL_LINES, 0)
If WHEEL_SCROLL_LINES > Form1.VScroll1.Max Then
WHEEL_SCROLL_LINES = Form1.VScroll1.Max
End If
End Sub
Public Sub UnHook(ByVal hwnd As Long)
Dim lngReturnValue As Long
lngReturnValue = SetWindowLong(hwnd, GWL_WNDPROC, lpPrevWndProc)
End Sub
Function WindowProc(ByVal hw As Long, _
ByVal uMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
Dim pt As POINTL
Select Case uMsg
Case WM_MOUSEWHEEL
If wParam = -7864320 Then
If Form1.VScroll1.Value <= Form1.VScroll1.Max - 300 Then '4个300值可调鼠标滚轮移动屏幕的速度,可取300-1000(值越大,移动速度越快)
Form1.VScroll1.Value = Form1.VScroll1.Value + 300
Else
Form1.VScroll1.Value = Form1.VScroll1.Max
End If
ElseIf wParam = 7864320 Then
If Form1.VScroll1.Value >= 300 Then
Form1.VScroll1.Value = Form1.VScroll1.Value - 300
Else
Form1.VScroll1.Value = 0
End If
End If
Case Else
WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam)
End Select
End FunctionPublic Function HIWORD(LongIn As Long) As Integer
HIWORD = (LongIn And &HFFFF0000) \ &H10000
End Function
Public Function LOWORD(LongIn As Long) As Integer
LOWORD = LongIn And &HFFFF&
End Function下面代码放在窗体中:
Private Sub Form_Load()
Hook Me.hwnd
End Sub
Private Sub Form_Resize()
If Frame1.Height > Me.Height Then
VScroll1.Visible = True
Else
VScroll1.Visible = False
End If
If Frame1.Width > Me.Width Then
HScroll1.Visible = True
Else
HScroll1.Visible = False
End If
HScroll1.Left = 0
HScroll1.Top = Me.ScaleHeight - HScroll1.Height
VScroll1.Left = Me.ScaleWidth - VScroll1.Width
VScroll1.Top = 0
HScroll1.Width = Me.ScaleWidth
VScroll1.Height = Me.ScaleHeight
If VScroll1.Visible = True Then
If HScroll1.Visible = True Then
HScroll1.Width = Abs(Me.ScaleWidth - VScroll1.Width)
VScroll1.Height = Abs(Me.ScaleHeight - HScroll1.Height)
End If
End If
HScroll1.Max = (Frame1.Width - Me.Width) + 3 * VScroll1.Width
VScroll1.Max = (Frame1.Height - Me.Height) + 3 * HScroll1.Height
HScroll1.ZOrder
VScroll1.ZOrder
End Sub
Private Sub Form_Unload(Cancel As Integer)
UnHook Me.hwnd
End Sub
Private Sub HScroll1_Change()
Frame1.Left = -HScroll1.Value
End Sub
Private Sub VScroll1_Change()
Frame1.Top = -VScroll1.Value
End Sub
Private Sub VScroll1_GotFocus() '此段可防止滚动条闪烁,借用一个按钮控件
Command1.SetFocus
End Sub
关键的地方是当line超出屏幕时要首先设置picture的宽度也要大于屏幕,即picture大于要画的最大坐标
p1,和p2
p2在p1中,但是比p1小一圈,在p1中添加滚动条v1,h1。如此p2填充了p1中除了两个滚动条之外的其他空间在p2中画图,当你的坐标大于p2的width和height的时候,相应的增加p2的宽和高以保证可视,与此同时给v1,h1赋值 v1.max=p2.height-p1.height,h1.max=p2.width-p1.width.
此时,p2大于p1的部分不可见画完结束后,拖动滚动条v1的时候挪动p2.top可以看到隐藏的部分,h1挪动p2.left这个就是逻辑了,你仔细看看
我做过,成功了
Picture2.Line (10, 10)-(1000, 1000), , B
End SubPrivate Sub Form_Load()
Picture2.AutoRedraw = True
Picture2.Left = Picture1.Left - Picture2.Width
Picture2.Top = Picture1.Top - Picture2.Height
Picture2.Width = Picture1.Width * 5
Picture2.Height = Picture1.Height * 5
HScroll1.Min = 0
HScroll1.Max = 100
'VScroll1.Min = 0
'VScroll1.Max = 100End SubPrivate Sub HScroll1_Change()
Picture2.Left = -HScroll1.Value * 0.1 * Picture1.Width
Picture2.Line (10, 10)-(1000, 1000), , B
End Sub
如这样运行时会报错误:
实例错误'480':
不能创建AutoRedraw图像但如果我把上面的Picture2.AutoRedraw = True改为Picture2.AutoRedraw = false时就可以正常画图了,但是由于我要抓取Picture2中所画的图,因此,必须把Picture2.AutoRedraw值为true,这问题如何解决??
有没有类似PICTUREBOX的控件?即可以当容器画图又可以保存当前图的,此问题一直没解决,对PICTUREBOX失去信心了
你在设计的时候就将Picture2.AutoRedraw 设为 True试试
或者用DhtmlEdit也行。
用line方法+1个picturebox+内存dc+垂直、水平滚动条就可以了,根据两个滚动条的数值计算需要显示的起始坐标然后用api从内存dc中把相应区域的图形显示出来就可以了,同时可以实现放大缩小功能。
如果用line控件数组代替line方法会更简单一点。
AutoRedraw无论设不设为TRUE,结果都是错的.
lsftest() 兄的方法我很想知道,不懂能不能具体一点,如能加上点代码,更是感激不尽
其实可以google,baidu到相似代码的