Call CopyMemory2(gDM.DevMode, gDM.lpDevMode, Len(gDM.DevMode))这句代码,执行的时候,有时好使,有时就出错,是在特定的打印机时出错,程序直接提示系统异常,VB的错误处理截获不了错误信息。
现在我的问题是,用什么方法,可以把出错时的错误信息能截获下来, 或者 能想办法即使这行代码错了,也让程序继续执行下去。有些急了,各位高手,拜托了啊。
现在我的问题是,用什么方法,可以把出错时的错误信息能截获下来, 或者 能想办法即使这行代码错了,也让程序继续执行下去。有些急了,各位高手,拜托了啊。
gDM.DevMode为目标地址,如果是数组,应该为数组首单元desArray(0);
gDM.lpDevMode为源地址,如果是数组应该也为数组首单元surArray(0);
对于最后的Length,你要保证gDM.DevMode的确有给定Length的长度,如果是数组,则Ubound(desArray)>=Length-1;
而且gDM.lpDevMode也必须有Length的长度的数据,如果是数组,则Ubound(surArray)>=Length-1;如果以上有一个条件没有满足,很有可能导致内存溢出,程序无故退出等问题。
Call CopyMemory2(gDM.DevMode, gDM.lpDevMode, Len(gDM.DevMode))
中把gDM.DevMode,gDM.lpDevMode用特定的值取代,再把原本获取的地方注释掉!
err.LastDllError这个我没有用过吗,怎么用啊,再有,结合我给的那行代码,他们结合使用啊,谢谢拉
private sub subxxx()
on error goto errhandle:
'//调用copymemory的地方
exit sub
errhandle:
msgbox err.LastDllError
end sub
to (打死不掉牙) :subxxx这样的方法我用过,不好用,截获不到。再帮想想还有什么好的办法吗啊,谢谢了
你说的各项参数获取不到是指什么?
是指Call CopyMemory2(gDM.DevMode, gDM.lpDevMode, Len(gDM.DevMode))
中的gDM.DevMode, gDM.lpDevMode参数值为空吗?
Len(gDM.DevMode)---->改为:Len(gDM.lpDevMode)
'Example Name: Maintaining Form Aspect Ratio During Resizing'------------------------------------------------------------------------------
' BAS Module Code
'------------------------------------------------------------------------------
Option Explicit
Public defWindowProc As Long
Private Const GWL_WNDPROC As Long = (-4)
Private Const WM_DESTROY = &H2
Private Const WM_SIZING = &H214'wParam for WM_SIZING message
Private Const WMSZ_LEFT = 1
Private Const WMSZ_RIGHT = 2
Private Const WMSZ_TOP = 3
Private Const WMSZ_TOPLEFT = 4
Private Const WMSZ_TOPRIGHT = 5
Private Const WMSZ_BOTTOM = 6
Private Const WMSZ_BOTTOMLEFT = 7
Private Const WMSZ_BOTTOMRIGHT = 8Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End TypePrivate Declare Function GetWindowLong Lib "user32" _
Alias "GetWindowLongA" _
(ByVal hwnd As Long, _
ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" _
Alias "SetWindowLongA" _
(ByVal hwnd As Long, _
ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Private Declare Function CallWindowProc Lib "user32" _
Alias "CallWindowProcA" _
(ByVal lpPrevWndFunc As Long, _
ByVal hwnd As Long, _
ByVal uMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As LongPrivate Declare Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMemory" _
(hpvDest As Any, _
hpvSource As Any, _
ByVal cbCopy As Long)Public Sub Unhook(fhwnd As Long)
If defWindowProc Then
Call SetWindowLong(fhwnd, GWL_WNDPROC, defWindowProc)
defWindowProc = 0
End IfEnd SubPublic Sub Hook(fhwnd As Long)
defWindowProc = SetWindowLong(fhwnd, _
GWL_WNDPROC, _
AddressOf WindowProc)
End SubFunction WindowProc(ByVal hwnd As Long, _
ByVal uMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long Dim rc As RECT
Select Case uMsg
Case WM_SIZING
CopyMemory rc, ByVal lParam, LenB(rc)
Select Case wParam
Case WMSZ_LEFT
rc.Bottom = (rc.Right - rc.Left) + rc.Top
CopyMemory ByVal lParam, rc, LenB(rc)
WindowProc = 1
Case WMSZ_RIGHT
rc.Bottom = (rc.Right - rc.Left) + rc.Top
CopyMemory ByVal lParam, rc, LenB(rc)
WindowProc = 1
Case WMSZ_TOP
rc.Right = (rc.Bottom - rc.Top) + rc.Left
CopyMemory ByVal lParam, rc, LenB(rc)
WindowProc = 1
Case WMSZ_BOTTOM
rc.Right = (rc.Bottom - rc.Top) + rc.Left
CopyMemory ByVal lParam, rc, LenB(rc)
WindowProc = 1
Case WMSZ_TOPLEFT
rc.Left = (rc.Top - rc.Bottom) + (rc.Right)
CopyMemory ByVal lParam, rc, LenB(rc)
WindowProc = 1
Case WMSZ_TOPRIGHT
rc.Right = (rc.Bottom - rc.Top) + rc.Left
CopyMemory ByVal lParam, rc, LenB(rc)
WindowProc = 1
Case WMSZ_BOTTOMLEFT
rc.Bottom = (rc.Right - rc.Left) + (rc.Top)
CopyMemory ByVal lParam, rc, LenB(rc)
WindowProc = 1
Case WMSZ_BOTTOMRIGHT
rc.Bottom = (rc.Right - rc.Left) + rc.Top
CopyMemory ByVal lParam, rc, LenB(rc)
WindowProc = 1
End Select
Case WM_DESTROY:
If defWindowProc <> 0 Then
Call Unhook(form1.hwnd)
End If
End Select
'处理windows消息
WindowProc = CallWindowProc(defWindowProc, _
hwnd, _
uMsg, _
wParam, _
lParam)End Function
'------------------------------------------------------------------------------
' Form Code
'------------------------------------------------------------------------------
'在Form中需要一个Command Button(Command1)
Option ExplicitPrivate Sub Form_Load()
With form1
.Width = 6000
.Height = 6000
Call Hook(.hwnd)
End With
End SubPrivate Sub Command1_Click()
Unload Me
End Sub
Private Sub Form_Unload(Cancel As Integer)
Call Unhook(Me.hwnd)
End Sub
而且使用这个函数,有时在IDE环境下不能工作正常的,必须得编译后才能看到效果!所以楼主只能一点点的调试了
' Type ifDevMode
' hDevMode As Long
' lpDevMode As Long
' DevModeSize As Long
' DevMode As tagDevMode
' End Type
'
' Type tagDevMode
' dmDevicName(1) As Byte
' dmSpecVersion As Integer
' dmDriverVersion As Integer
' dmSize As Integer
' dmDriverExtra As Integer
' dmFields As Long
' dmOrientation As Integer
' dmPaperSize As Integer
' dmPaperLength As Integer
' dmPaperWidth As Integer
' dmScale As Integer
' dmCopies As Integer
' dmDefaultSource As Integer
' dmPrintQuality As Integer
' dmColor As Integer
' dmDuplex As Integer
' dmYResolution As Integer
' dmTTOption As Integer
' dmCollate As Integer
' dmFormName(1) As Byte
' dmUnusedPadding As Integer
' dmBitsPerPel As Integer
' dmPelsWidth As Long
' dmPelsHeight As Long
' dmDisplayFlags As Long
' dmDisplayFrequency As Long
'End Type
但VB下使用要注意它的传递类型 否则是肯定非操的 还有 这个是无法捕获的 LZ只要弄清楚 memcpy 参数的传递类型 就不会非操了不过 初学者要彻底弄清楚这个 也不容易
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long楼主是想把 gDM.lpDevMode 所指向的一块数据区拷贝到 gDM 的 DevMode 这个结构体成员的内存区吧?如果是这样的话,试试:
Call CopyMemory2(gDM.DevMode, ByVal gDM.lpDevMode, Len(gDM.DevMode))当然,执行这句前,你得确保 gDM.lpDevMode 所指向的那片数据块包含正确的 tagDevMode 数据信息。
声明方式不一样,调用时的写法也不一样。
错误的调用方法有可能造成程序崩溃。
按照你申明的不同 传递方式也不同
把有问题的参数 用byval LONG型申明 然后传递 地址指针 试试
也就是用varptr 获取变量的内存首地址传递 以前用VB时 也碰到过 频繁调用memcpy时 确实会非操 就算传递的参数都是正确的
可以试试 NT函数NtWriteVirtualMemory 句柄用-1代替 就是自身内存了
我以前就是这样解决的非操问题 总之 就是觉得VB 一点都不方便
还是VC好 直接操作内存 想怎么弄 怎么弄 哈哈 非常方便