November 30, 2008
Take a Screenshot
To take a screenshot, hold the home button and click the sleep button. The screen will flash white and the screenshot will be stored in your camera roll.
November 28, 2008
Soft Reset
Press and hold the Home button and the Sleep button to restart your iPhone. A white light will flash, the screen will shut off and then turn back on. Keep holding until the screen turns back on.
November 25, 2008
November 17, 2008
Press & Hold Alternate Characters
Hold a letter for a popup of various versions of the character (i.e. to type España with the "ñ" simply hold "n" and simply slide/release to the appropriate character).
November 15, 2008
Domain Suffix - On firmware 2.0
Hold down the ".com" key for ".net, .edu, .org" keys. Note: Slide your finger from .com to .net/.edu/.org, rather than lifting and pressing.
November 07, 2008
Tips 4
Implement a Fast Reset Method within a Form
There are many occasions where you need to reset the controls on a form, either in readiness for a new record, or perhaps when a record has been displayed and the user clicks the button to enter a new record.
You could, of course, reference each control on the form individually to reset its display. However, I tend to whip through every control on the form and perform the same function on each. Of course, not all controls have the same properties, so I preface my procedure with an On Error Resume Next statement that tells my code to ignore any errors and continue with the next line of code:
On Error Resume Next
For Each oControl In Controls
oControl.Text = "" 'mainly for text box controls
oControl.ListIndex = -1 'reset combo and list boxes.
Next
November 06, 2008
Tips 3
Implement an Exists Method within a Collection Class
One of my long standing gripes about the Collection object is the complete absence lack of an easy method to determine whether the member you're looking for exists within the collection. Therefore, when I'm writing a wrapper class for a collection, I always include my own.
However, I add a little more to the method than simply determining if the member exists in the collection. If the member is not found within the collection, I attempt to add it to the collection. This way, I can simplify the code at the client end by always calling the Exists method prior to assigning the member to a local object variable. Therefore, I know that if the Exists method returns true, I can safely go on to assign the member to the local object variable.
The code for a typical Exists method is shown below:
Public Function Exists(sDomainName As String) As Boolean
On Error GoTo Exists_Err
Dim oTemp As Domain
Set oTemp = mcolDomains.Item(sDomainName)
Exists = True
Set oTemp = Nothing
Exit Function
TrytoGet:
If Not LoadDomain(sDomainName) Then
Exit Function
Else
Exists = True
End If
Exit Function
Exists_Err:
If Err.Number = 5 Then
Resume TrytoGet
Else
'further error handling here for other error types
End If
End Function
As you can see, the idea is to test for the presence of a particular member of the collection by attempting to assign it to a temporary local object variable. If the member is not present, then error 5 ("Invalid Procedure Call or Argument") is raised. Trapping this, program flow proceeds to the LoadDomain function, which attempts to load the member into the collection.
The new VB6 Dictionary object (found in the Scripting Runtime Library) contains its own built-in Exists property. The custom Exists method for the collection object can therefore be cut down dramatically but still achieve the same results, as the following method illustrates:
Public Function Exists(sDomainName As String) As Boolean
If mdicWebsites.Exists(sDomainName) Then
Exists = True
Else
Exists = GetWebsite(sDomainName)
End If
End Function
Whether you're using the (now old fashioned) Collection object or the (new and fast) Dictionary object, your client code is identical, as the following fragment shows:
Private Sub cboDomainName_Click()
If moWebsites.Exists(cboDomainName.Text) Then
Set moWebsite = moWebsites.Website(cboDomainName.Text)
End If
End Sub
November 05, 2008
Tips 2
Implement a For Each...Next Statement against a Collection Class
Most of the time, we take for granted the For Each...Next loop, which iterates the members of an array or a collection. It's the fastest, most efficient method of visiting all the members of the collection or array, and we could care less that, as it enumerates the collection, the unseen code is actually generating new references to members of the collection with each iteration of the loop. However, as the provider of a collection class, it is up to you to provide an interface that the For Each...Next statement can work with.
This may sound a little daunting, but you'll be pleasantly surprised how easy it is to implement a property that enumerates members of the collection within your class. First of all, you must create a Property Get procedure called NewEnum with the type of IUnknown. Its syntax is always the same:
Public Property Get NewEnum() As IUnknown
Set NewEnum = mCol.[_NewEnum]
End Property
where mCol is the name of your private collection object variable.
Second, set the Procedure ID for this Property Get procedure to -4. To do this, select the Procedure Attributes option from the Tools menu, then click the Advanced button on the Procedure Attributes dialog. Enter a Procedure ID of -4. You should also check the "Hide this member" option to prevent the property from appearing in the IntelliSense drop down.
Most of the time, we take for granted the For Each...Next loop, which iterates the members of an array or a collection. It's the fastest, most efficient method of visiting all the members of the collection or array, and we could care less that, as it enumerates the collection, the unseen code is actually generating new references to members of the collection with each iteration of the loop. However, as the provider of a collection class, it is up to you to provide an interface that the For Each...Next statement can work with.
This may sound a little daunting, but you'll be pleasantly surprised how easy it is to implement a property that enumerates members of the collection within your class. First of all, you must create a Property Get procedure called NewEnum with the type of IUnknown. Its syntax is always the same:
Public Property Get NewEnum() As IUnknown
Set NewEnum = mCol.[_NewEnum]
End Property
where mCol is the name of your private collection object variable.
Second, set the Procedure ID for this Property Get procedure to -4. To do this, select the Procedure Attributes option from the Tools menu, then click the Advanced button on the Procedure Attributes dialog. Enter a Procedure ID of -4. You should also check the "Hide this member" option to prevent the property from appearing in the IntelliSense drop down.
November 03, 2008
Implement an IsSaved Property
Implement an IsSaved (or IsDirty) Property
I often find this technique very useful, but it takes a little extra work when you're creating your object classes. On balance, despite this up front investment of time, it saves a good deal of programming time by making it easy to determining when an object has changed and therefore needs to be saved.
To implement an IsSaved or IsDirty property, each Property Let procedure of a particular object must contain a line of code to determine if the value to be assigned to the property is different than its current value (which should be stored in a private member variable). If it is different, then the private member variable that represents the IsSaved property is set to False. For example:
Property Let CustStreetAddr(sVal as String)
If msCustStreetAddr <> sVal Then
msCustStreetAddr = sVal
mbIsSaved = False
End If
End Property
(Of course, you can also implement this the other way round by having an IsDirty property that returns True when the object needs to be saved.)
Back at the client end you can check to see if the object needs saving quickly and easily as follows:
If Not myObject.IsSaved Then
SaveTheObject
End If
On the server object, this is implemented as a simple Property Get procedure:
Property Get IsSaved() As Boolean
IsSaved = mbIsSaved
End Property
Another neat addition to this is to define an object event called something like ObjectChanged. Then the event can be fired whenever some attribute of the object changes:
Property Let CustStreetAddr(sVal As String)
If msCustStreetAddr <> sVal Then
msCustStreetAddr = sVal
mbIsSaved = False
RaiseEvent ObjectChanged()
End If
End Property
On the client form, you can then implement an event handler for the ObjectChanged event that enables the Save button when the object needs to be saved:
Sub MyObject_ObjectChanged()
cmdSave.Enabled = Not myObject.IsSaved
End Sub
This code enables the Save button when the object is not saved and disables the button when the object has been changed.
I should add a major qualification to this tip: don't update your object property based on the Change event handler of a text box. The Change event is fired for each keystroke that the text box receives. Therefore typing a word like "Stupid" into the text box will fire off 6 Change events - and the final result is that the text box could contain the same word that it originally started with, so that in fact its contents haven't changed at all despite the firing of six unnecessary events.
November 02, 2008
Domain Resolution
When typing a URL in Safari, you don't have to type the "www" or the ".com".For instance, for www.cnn.com just type "cnn" in the URL box. Note: Your search engine must be set to Google, not Yahoo.
Tips 1
Use #If ccDebug to View Hidden Automation Servers
One of the problems with testing and debugging a remote automation server is that the server application typically remains hidden, doing its work in the background. Hence, when something goes wrong, you frequently can't tell what has happened or where in your code your application is being derailed.
Consequently, when you're developing, testing, and debugging your application, it's a good idea to make sure that otherwise hidden automation server remain visible. You can do this by using code like the following to make sure that a new instance of an automation server (in this case Microsoft Word) is visible:
Dim objWord as Word.Application
Set objWord = New Application
#If ccDebug Then
objWord.Visible = True
#End If
You can define the project-level conditional compiler constant ccDebug in either of two ways:
*
By including the line
#Const ccDebug = 1
in the declarations section of a form or code module.
*
By using the Make tab of the Project Properties dialog (select the Project Properties option from the VB Project menu) and entering the following in the Conditional Compilation Arguments text box:
ccDebug = 1
Then, whenever your code runs in the design-time environment, you automation server will be visible. When you are ready to create the final executable, you should either set the ccDebug conditional compilation constant to 0 or, if you've used the Conditional Compilation Arguments text box, remove its definition.
November 01, 2008
Scroll to Top of Page
In any application, Safari included, you can automatically scroll to the top of the page by tapping on the "top bar", which has the time, service bars, and battery. In Safari, this not only brings you to the top of the page, but also brings up the URL bar.
Use vbCrLf in Embedded SQL Scripts
Use vbCrLf in Embedded SQL Scripts
Visual Basic contains quite a few intrinsic constants -- that is, constants that are now part of the VBA language but that you used to have to define in your code either explicitly or by adding the Constant.Bas file to your project. One of these is vbCrLf, which equates to the carriage return/line feed -- or Chr$(13) & Chr$(10) - character combination.
But why would I suggest that you include this constant in an embedded SQL script? After all, the code means nothing to SQL Server; it could care less that you want a carriage return and line feed at the end of each line. The answer: debugging, plain and simple. Quite often, you'll find yourself creating embedded SQL scripts that run to 10, 20 or more lines. For example,
sSQL = "SELECT * FROM anytable" _
& " WHERE userid = " & lUser _
& " AND color = '" & sColor "'"
If you define the SQL statement in this way, the SQL script is readable when viewed in the procedure, but what about when you want use the Immediate window to see the value of the sSQL variable at run time?
You enter
? sSQL
in the Immediate window, and a long, unbroken string is shown, running miles off into the distance.
However, if you simply suffix each line with vbCrLf, like this:
sSQL = "SELECT * FROM anytable" & vbCrLf _
& "WHERE userid = " & lUser & vbCrLf _
& "AND color = '" & sColor "'"
then you can quickly and easily read your completed SQL code to find the problem.
The previous example illustrates another benefit of vbCrLf: if you don't use it, you must remember to start (or end) each line with a space; otherwise,
sSQL = "SELECT * FROM anytable" & _
& "WHERE userid = " & lUser
becomes
"SELECT * FROM anytableWHERE userid = 1"
and your code will generate a SQL syntax error.
Subscribe to:
Posts (Atom)