标题:本人毕业设计 急求vb方面 中英文对照翻译文章
只看楼主
ioriliao
Rank: 7Rank: 7Rank: 7
来 自:广东
等 级:贵宾
威 望:32
帖 子:2829
专家分:647
注 册:2006-11-30
得分:0 

--------------------------------------------------------------------------------

Tip 20: Define constants using a TypeLib or an Enum.
When you create error values try not to use the so-called Magic Numbers. Thirteen is such a number, as in Err.Raise Number:=13. What does 13 mean? Basically it's a pain to resolve, so attempt always to use more meaningful names.

Visual Basic doesn't come with a set of symbolic constants defined for its own errors so I thought I'd put one together for you. Here's a snippet:


Public Enum vbErrorCodes
VBErrReturnWithoutGoSub = 3
VBErrInvalidProcedureCall = 5
VBErrOverflow = 6
VBErrOutOfMemory = 7
VBErrSubscriptOutOfRange = 9
VBErrThisArrayIsFixedOrTemporarilyLocked = 10
VBErrDivisionByZero = 11
VBErrTypeMismatch = 13
VBErrOutOfStringSpace = 14
VBErrExpressionTooComplex = 16
VBErrCantPerformRequestedOperation = 17
VBErrUserInterruptOccurred = 18
VBErrResumeWithoutError = 20
VBErrOutOfStackSpace = 28
VBErrSubFunctionOrPropertyNotDefined = 35
.
.
.
End Enum

Once you've added it to your project, this snippet is browsable via Visual Basic's Object Browser. You'll find the code on the companion CD. To see how you might define constants using a type library, see Chapter 7.


/images/2011/147787/2011051411021524.jpg" border="0" />
2007-05-22 10:43
ioriliao
Rank: 7Rank: 7Rank: 7
来 自:广东
等 级:贵宾
威 望:32
帖 子:2829
专家分:647
注 册:2006-11-30
得分:0 

--------------------------------------------------------------------------------

Tip 21: Keep error text in a resource file.
Resource files (RES files) are good things in which to keep your error text and messages, and most C developers use them all the time, especially if they're shipping products internationally. That said, Visual Basic itself uses resource files—recognize some of these sample strings taken from Visual Basic's own resources?


STRINGTABLE FIXED IMPURE
BEGIN
3 "Return without GoSub"
5 "Invalid procedure call or argument"
6 "Overflow"
7 "Out of memory"
.
.
.

13029 "Sa&ve Project Group"
13030 "Sav&e Project Group As..."
13031 "Ma&ke %s..."
.
.
.
23284 "Compile Error in File '|1', Line |2 : |3"
.
.
.

END

In fact, Visual Basic 6 uses a total of 2,934 resource files.

The %s in string 13031 is used to indicate (to a standard C library function) where a substring should be inserted—the binary name (?.EXE, ?.DLL, ?.OCX) in this case. The |1, |2, and |3 in string 23284 shows where replacement strings should be inserted, this time using a different technique. In fact, this latter technique (which you can use even on the %s strings) can be seen operating if you look at ResolveResString in the Visual Basic source code for SETUP1.VBP. It looks more or less like this (this is slightly tidied up):


'-----------------------------------------------------------
' FUNCTION: ResolveResString
' Reads string resource and replaces given macros with given
' values
'
' Example, given a resource number of, say, 14:
' "Could not read '|1' in drive |2"
' The call
' ResolveResString(14, "|1", "TXTFILE.TXT", "|2", "A:")
' would return the string
' "Could not read 'TXTFILE.TXT' in drive A:"
'
' IN: [nResID] - resource identifier
' [vReplacements] - pairs of macro/replacement value
'-----------------------------------------------------------
'
Public Function ResolveResString( _
ByVal nResID As Integer _
, ParamArray vReplacements() As Variant _
) As String

Dim nMacro As Integer
Dim sResString As String

sResString = LoadResString(nResID)

' For each macro/value pair passed in ...
For nMacro = LBound(vReplacements) To UBound(vReplacements) Step 2

Dim sMacro As String
Dim sValue As String

sMacro = CStr(vReplacements(nMacro))
sValue = vbNullString

If nMacro < UBound(vReplacements) Then
sValue = vReplacements(nMacro + 1)
End If

' Replace all occurrences of sMacro with sValue.
Dim nPos As Integer

Do
nPos = InStr(sResString, sMacro)

If 0 <> nPos Then
sResString = Left$(sResString, nPos - 1) & _
sValue & _
Mid$(sResString, nPos + Len(sMacro))
End If

Loop Until nPos = 0

Next nMacro

ResolveResString = sResString

End Function

To see all this code work, compile the strings and add them to your project. (Save the strings as an RC file, and then run the resource compiler on the RC file like so: C:\rc -r ?.rc. Add the resulting RES file to your application by selecting Add File from the Project menu.) Then add this code to Form1's Load event:


MsgBox ResolveResString( _
23284 _
, "|1" _
, "Fubar.bas" _
, "|2" _
, "42" _
, "|3" _
, ResolveResString(7) _
)

This will produce the following message box:

Keeping message text in a resource file keeps strings (which could include SQL strings) neatly together in one place, and also flags them as discardable data, stuff that Windows can throw away if it must. Don't worry about this—Windows can reload strings from your binary image if it needs them. Your code is treated in exactly the same way and you've never worried about that being discarded, have you? Keeping read-only data together like this allows Visual Basic and Windows to better optimize how they use memory. Resource files also provide something akin to reuse as they usually allow you to be "cleverer" in your building of SQL and error text—they might even provide a way for you to share data like this across several applications and components. (See the notes on using a ROOS earlier in this chapter.)




/images/2011/147787/2011051411021524.jpg" border="0" />
2007-05-22 10:45
ioriliao
Rank: 7Rank: 7Rank: 7
来 自:广东
等 级:贵宾
威 望:32
帖 子:2829
专家分:647
注 册:2006-11-30
得分:0 

--------------------------------------------------------------------------------

Tip 22: Always handle errors in controls and components (that you build).
Errors in controls
When a control raises an unhandled error (by the control), the error is reported and the control becomes disabled—it actually appears hatched—or the application terminates. (See Figure 1-7 and Figure 1-8.)

Figure 1-7 Containing form before the error


Figure 1-8 Containing form after the error

It's important to know that errors in a UserControl can be propagated to two different levels. If the errors are caused wholly by the control, they will be handled by the control only. If the errors are instigated via a call to an external interface on the control, from the containing application, they will be handled by the container. Another way to state this is to say that whatever is at the top of the call stack will handle unhandled errors. If you call into a control, say from a menu selection in the container, the first entry in your call stack will be the container's code. That's where the mnuWhatever_Click occurred. If the control raises an error now, the call stack is searched for a handler, all the way to the top. In this case, any unhandled control error has to be handled in the container, and if you don't handle it there, you're dead when the container stops and, ergo, so does the control. However, if the control has its own UI or maybe a button, your top-level event could be a Whatever_Click generated on the control itself. The top of your call stack is now your control code and any unhandled errors cause only the control to die. The container survives, albeit with a weird-looking control on it. (See Figure 1-8.)

This means that you must fragment your error handling across containers and controls, not an optimal option. Or you need some way of raising the error on the container even if the container's code isn't on the stack at the moment the error occurs. A sort of Container.Err.Raise thing is required.

In each of our container applications (those applications that contain UserControls), we have a class called ControlErrors (usually one instance only). This class has a bundle of miscellaneous code in it that I won't cover here, and a method that looks something like this:


Public Sub Raise(ParamArray v() As Variant)

On Error GoTo ControlErrorHandler:

' Basically turns a notification into an error -
' one easy way to populate the Err object.
Err.Raise v(0), v(1), v(2), v(3), v(4)

Exit Sub

ControlErrorHandler:

MsgBox "An error " & Err.Number & " occurred in " & Err.Source & _
" UserControl. The error is described as " & Err.Description

End Sub
In each container application we declare a new instance of ControlErrors, and for each of our UserControls we do what's shown below.


If True = UserControl1.UsesControlErrors Then

Set UserControl1.ErrObject = o

End If

UsesControlErrors returns True if the UserControl has been written to "know" about a ControlErrors object.

In each control—to complete the picture—we have something like this (UsesControlErrors is not shown):


Private ContainerControlErrors As Object

Private Sub SomeUIWidget_Click()

On Error GoTo ErrorHandler:

Err.Raise ErrorValue

Exit Sub

ErrorHandler:

' Handle top-level event error.

' Report error higher up?
If Not ContainerControlErrors Is Nothing Then

ContainerControlErrors.Raise ErrorValue

End If

End Sub

Public Property Set ErrObject(ByVal o As Object)

Set ContainerControlErrors = o

End Property

We know from this context that SomeUIWidget_Click is a top-level event handler (so we must handle errors here), and we can make a choice as to whether we handle the error locally or pass it on up the call chain. Of course, we can't issue a Resume Next from the container once we've handled the (reporting of the) error—that's normal Visual Basic. But we do at least have a mechanism whereby we can report errors to container code, perhaps signalling that we (the control) are about to perform a Resume Next or whatever.

Errors in OLE servers
Raising errors in a Visual Basic OLE Automation server is much the same as for a stand-alone application. However, some consideration must be given to the fact that your server may not be running in an environment in which errors will be visible to the user. For example, it may be running as a service on a remote machine. In these cases, consider these two points:


Don't display any error messages. If the component is running on a remote machine, or as a service with no user logged on, the user will not see the error message. This will cause the client application to lock up because the error cannot be acknowledged.

Trap every error in every procedure. If Visual Basic's default error handler were executed in a remote server, and assuming you could acknowledge the resulting message box, the result would be the death of your object. This would cause an Automation error to be generated in the client on the line where the object's method or property was invoked. Because the object has now died, you will have a reference in your client to a nonexistent object.
To handle errors in server components, first trap and log the error at the source. In each procedure, ensure that you have an Err.Raise to guarantee that the error is passed back up the call stack. When the error is raised within the top-level procedure, the error will propagate to the client. This will leave your object in a tidy state; indeed, you may continue to use the same object.

If you are raising a user-defined error within your component you should add the constant vbObjectError (&H80040000&). Using vbObjectError causes the error to be reported as an Automation error. To extract the user-defined error number, subtract vbObjectError from Err.Number. Do not use vbObjectError with Visual Basic-defined errors; otherwise, an "Invalid procedure call" error will be generated.



/images/2011/147787/2011051411021524.jpg" border="0" />
2007-05-22 10:47
ioriliao
Rank: 7Rank: 7Rank: 7
来 自:广东
等 级:贵宾
威 望:32
帖 子:2829
专家分:647
注 册:2006-11-30
得分:0 

--------------------------------------------------------------------------------

Tip 23: Use symbolic debugging information.
For extra tricky debugging, you should check out the Visual Studio debugger (which you get to by starting Visual C++). You obviously need the whole thing, in Visual Studio terms, to use this debugger in Visual Basic (or have a third-party debugger that can use the symbolic debugging information produced by Visual Basic). You'll also need some instructions on using the debugger, as it's one of the least documented features that I've ever seen.

To use the Visual Studio debugger, if you have it, do the following.

Build your Visual Basic application using the Compile To Native Code option. On the Compile tab of the Project Properties dialog box, select the Create Symbolic Debug Info and No Optimization options. Make sure that you build the EXE/DLL/OCX (I'll assume you're debugging a simple EXE from here on in) so that the binary is stored in the same folder as the source code. Start Visual C++, select Open from the File menu, and then select your built EXE file. Select Open from the File menu again (more than once if necessary) to select the source files you want to debug and trace through (FRM, BAS, CLS, etc.). Move the cursor to the line(s) where you want to start your debugging, and hit F9 to set a breakpoint. Once you've done this, hit F5. If you've set a breakpoint on, say, a Form_Load that runs as the program starts, you should immediately have broken to the debugger at this point. One more thing—use F10 to step through your code, not F8.

See your Visual Studio documentation (and Chapter 7) for more on how to use the debugger.


More on Client/Server Error Handling

Components should be nonintrusive about their errors. Instead of raising their own errors in message boxes, or through other UI, directly to the user, the components should pass any error that cannot be handled and corrected entirely within the component to their client's code, where the developer can decide how to handle it.

It is possible and even highly likely that a component you're using is itself a client of other components. What should you do when your component gets an error from one that it's using? Well, if you can't recover from the error, you should encapsulate it. It's bad practice merely to raise the other component's error to your client, since your client may well know nothing about this other component and is just dealing with your component. This means that you need to provide meaningful errors from your own component. Rather than passing up other component's errors or Visual Basic errors to your client, you need to define your own and use these. Public constants or Enums with good names are an excellent way of doing this, since they give a source for all errors in your component, and also should give strong clues about each error in its name.

When defining your own error numbers in components, remember that you should use vbObjectError and that currently Microsoft recommends keeping numbers added to it in a range between 512 and 65535.


Constant vbBaseErr As long = 512
Constant ComponentBaseErr As long = vbObjectError + vbBaseErr
Constant MaxErr As long = vbObjectError + 65535

Remember that there are two occasions when you can safely raise an error in Visual Basic:


When error handling is turned off

When in a procedure's error handler
It is possible to raise events to pass errors to clients in some circumstances. The standard Visual Basic Data control has an error event, for instance.

Logging errors and tracing procedure stacks in components raises some special problems. It clearly makes sense to log errors, which are sent back to a client from a component. Thus, if you're creating an OCX, you would raise an error and expect that the client code would log that error in its error log. Components on remote machines may also have specific requirements about where to log.

For components there are a number of possible error log locations:


Files (either flat files or Structured OLE storages)

NT Event Log (but beware of using this with components deployed in Microsoft Transaction Server)

Databases (but always have some other means to fall back on if your database connections fail)
It makes sense to add other information to a component's error log, because it's useful to know the UserID or Logon name, the machine name, the process ID, and the thread ID. We frequently use a class for this purpose, which returns the following:


Process ID

Thread ID

Machine name

Network version info

LanGroup

LanRoot

Current user name

Logon server

Domain

Number of users currently logged on

Other available domains
This information is useful for sorting information in a component's error log.

第一章完了,后面还有十七章(高级VB编程)好东西来的,但我不会看E文,哪个有志之士给译出来吧,如果有我就上传后面的


/images/2011/147787/2011051411021524.jpg" border="0" />
2007-05-22 10:49
ouzhiguang
Rank: 1
来 自:湖南长沙
等 级:新手上路
威 望:1
帖 子:240
专家分:0
注 册:2007-5-18
得分:0 
发几篇高级技术到我的邮箱里1989-09@163.com
2007-05-22 11:00
ioriliao
Rank: 7Rank: 7Rank: 7
来 自:广东
等 级:贵宾
威 望:32
帖 子:2829
专家分:647
注 册:2006-11-30
得分:0 

我能发在这里就算很好了...


/images/2011/147787/2011051411021524.jpg" border="0" />
2007-05-22 11:05
mt0507
Rank: 1
等 级:新手上路
帖 子:13
专家分:0
注 册:2007-5-21
得分:0 

版主真好。。。。。。。。。。这个请问是什么??程序?

2007-05-22 20:23
milk713785
Rank: 1
等 级:新手上路
帖 子:39
专家分:0
注 册:2007-5-9
得分:0 

版主真专业!早知道我的也叫你找了。

2007-05-22 23:08
张泽宇
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2011-6-6
得分:0 
格式的
2011-06-06 15:06



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-141325-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.023649 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved