Limitation using automatic formatting in all versions of Outlook

By Scott, August 30, 2007 8:56 AM

There is a limitation in the use of automatic formatting to control how a message is displayed in a folder’s message list.  I had been trying to use automatic formatting to change the color of messages in a particular folder if they contain a certain word in the body.  I have a rule that moves some daily reports I receive into the folder, and rather than open each report if nothing has changed in the results of the report since it last ran, I wanted to have messages that contain a word that is in them when they have been updated to display differently.  This way I can simply delete the reports with unchanged data, but still open them if I want to (which is why I am not using a rule to delete them upon arrival).

However, the automatic formatting was not being applied to messages that contained the keyword.  I tried several different ways within the conditions editor of applying the formatting, all with the same results.  I decided to open a case with Microsoft since we have loads of Premier incidents available to use.  I had to work through several engineers until I finally got to the Outlook development team who had to look at the source code to determine why it wasn’t working.

That is when they discovered the culprit: a limitation that is by design.  When using automatic formatting, only the first 256 characters of the message body will be searched.  This is for performance reasons.  I couldn’t understand why this would be the case since rules will search all of a message body.  Then I realized why and it does make sense:  Automatic formatting is part of the view for a folder.  Views are calculated and applied each time you switch to that folder, so displaying the font face/color/size and bold/italics of each message in the folder list is dynamically applied each time you switch to the folder.  The default automatic formatting rules for a folder include unread, overdue, and expired messages, plus group headers, etc.  There is definitely a performance risk if Outlook had to search the entire message body of every message in a folder to determine how it should be displayed.  To mitigate this, message body searches are limited to 256 characters when part of automatic formatting.

Rules aren’t subject to this limitation because they are one-time processes.  Rules are applied only when a message arrives or is sent (or when you manually run one).  So the workaround for my issue is to use a rule to search the body for a keyword, assign a category to it if there is a match, and then move it to the folder.  I then use automatic formatting to change how a message is displayed if the category is the one I assigned.  I have to create a rule for each keyword I am looking for (since I am also looking for reports that have errors), which isn’t as efficient as defining multiple automatic formatting rules, but it is an acceptable workaround since the results are the same.

How to CID Unlock an AKU2 Cingular 8125 (HTC Wizard)

By Scott, August 29, 2007 11:23 AM

Getting WM6 on my Cingular 8125 proved to be a much more vexing challenge than I anticipated, especially considering the development for it over at xda-developers.com.  The main issue was getting the 8125 CID Unlocked, which allows non-home carrier ROMs to be installed.  Running a multitude of tools to unlock the device resulted in failure but I couldn’t figure out why because it was supposed to work, especially on the Wizard.

Then I found this post on xda-developers.com which indicates that Wizards that have been upgraded to Windows Mobile 5 with AKU2 (notable for the DirectPush functionality) have the portion of the DOC (Disk on Chip) that stores the carrier ID set to read-only.  Faria’s instructions show how to successfully CID Unlock the device by first downgrading the ROM to a non-AKU2 version.  Of course, it can’t be any ROM since the CID is still locked, so it has to be one from Cingular or something cooked.

I could not find anywhere the Cingular 1.8 ROM that is recommend to use.  I trolled Google, AT&T forums, xda-developers, Google Groups, but the binaries had been pulled awhile ago.  The other option was a cooked ROM that doesn’t check for a carrier ID.  Again, I could not find the one mentioned, until I found a forum post that linked to another post on a French forum where the ROM is available.  That took awhile to download.

After finally having all the pieces necessary, I was able to downgrade this morning, CID Unlock the device, upgrade the IPL/SPL, radio, and finally Faria’s WM6 ROM:

Combining information and steps from a several different topics at xda-developers and elsewhere, this is what I did:

  1. Downloaded and installed the custom 1.05 ROM, called CUSTOM__RUU_Wizard_1050412_WWE_101_11210_WWE.exe.
  2. Downloaded and ran lokiwiz’s CID Unlocker .2b.
  3. Downloaded and installed the T-Mobile 2.26 ROM.
  4. Downloaded and installed IPL/SPL 3.08.
  5. Downloaded and installed radio 2.19.
  6. Downloaded and installed Faria’s WM6 ROM.

Woohoo!

Add attachment preview handlers for Outlook 2007 in Windows XP

By Scott, August 27, 2007 8:37 AM

Outlook 2007 comes with attachment previewers for a few file types, such as txt, but nothing for common attachment types like zip files, pictures, videos, web pages.  Outlook 2007 running on Vista comes with more because Vista has attachment previewing inbuilt.  I found a tool written by Gil Azar, which he in turn uses some code written by Stephen Toub in MSDN Magazine, that adds attachment previewing for the more common types.

This isn’t a difficult installation, but know that it is written by one person who made it available and so there isn’t any real support, but when I found an installation issue and emailed Gil with information of what I did to fix it, he promptly replied.

  1. Download the J# 2.0 redistributable package from MS.
  2. Download the previewer installation file from Gil’s website.
  3. Install the J# package.  No reboot is necessary and you shouldn’t have to exit any programs.
  4. Exit Outlook if it is running and install the previewer.

One bug I have found is that if you try and run a file from within a previewed zip file whose type isn’t registered in Windows, you will get an error (such as a file with no extension).  Outlook won’t crash or anything, but you will have to save the zip file to disk in order to do something with the unknown file type.

These are the combined (Gil’s and Stephen’s) file types it will preview:

  • PDF – This handler uses Adobe Reader’s ActiveX control
  • SWF – This handler uses Adobe Shockwave Flash’s ActiveX control.
  • HTML/HTM/XML – This handler uses Internet Explorer’s ActiveX control.
  • ASF/WMV/WMA/AVI/WAV/MPG/MPEG/MP3/MIDI/AIFF/AU – The same, but with Windows Media Player’s ActiveX control.
  • ZIP/GADGET/MSI/RESX/SNK/KEYS – Not implemented natively, but only forwards interface calls to Stephen Toub’s managed preview handlers.
  • CS/VB/SQL/JS – Like the previous group, not natively implemented, but added to a wrapper.

Script to format an LDAP filter for readability

By Scott, August 7, 2007 7:32 AM

I have automated DLs that use LDAP filters for membership criteria.  These filters are stored as binary data in the extensionData attribute of the group object, so they are not easily accessible by users who want to know what filter is being applied to a DL they own.

It was easy enough to extract the LDAP filter from the attribute, convert it to a string value, and display it.  But users don’t generally know how to read LDAP filters, let alone represented as a long line of text.  So I started looking for utilities or scripts that would take an LDAP filter, parse it, and display it with nesting.  Uh, yeah, there aren’t any.  I was determined, and so countless hours later I have a function that do such a thing.

The difficult part was keeping track of the level of nesting/indentation at any point. Since a filter can be written in almost any order as long as the resulting equation equals what you want, I couldn’t use any kind of static detection. Just because an open parentheses is following by another one doesn’t mean that you are, say, three levels nested. So the important part of the script keeps track of the indentation level as the cursor position moves through the filter.

I replace ampersands in the filter with crosshatches while working with it because I was having weird results otherwise, most likely because the ampersand is an operator in both LDAP and VBScript. And because the output is to an IE window and the indentation uses non-breaking spaces instead of the traditional tab (which doesn’t exist in HTML), I substitute the HTML string for a non-breaking space with a unique string of letters so the ampersand in that doesn’t get in the way.

Because this is part of a bigger script, I pulled out just the portion that formats the LDAP filter and displays it in an IE window. You just need to provide the "raw" filter, whether directly in the script or some other method. Copy and paste the code below or download it here.

Option Explicit
Dim strLDAPFilter, strFormattedFilter
Dim objIE, objDoc
strLDAPFilter = "YourLDAPFilter"
Set objIE =  CreateObject("InternetExplorer.Application")   objIE.AddressBar = False
objIE.Menubar = False
objIE.Toolbar = False
objIE.Resizable = True
objIE.Height = 450
objIE.Width = 700
objIE.Visible = True
objIE.Navigate("about:blank")
While objIE.Busy
	WScript.Sleep 100
Wend

Set objDoc = objIE.Document
objDoc.Open
objDoc.Write("<TITLE>LDAP Filter Display</TITLE>")
objDoc.Write("<BODY BGCOLOR=#C0C0C0>")

'Parse the LDAP filter and format results for display
'Apply nesting for readability
strFormattedFilter = FormatLDAPDisplay(strLDAPFilter)
objDoc.Write(strFormattedFilter)
'Format single-line LDAP filter to include nesting
Function FormatLDAPDisplay(strLDAPFilter)
	'Replace ampersands with crosshatches to keep them from interfering
	strLDAPFilter = Replace(strLDAPFilter, Chr(38), Chr(35))

	'Iterate through each character in filter and insert CRLF and nesting
	Dim intPos, intIndentCount, intWhileIndent
	Dim strIndentation, strInsert, strCharacter, strNewLDAPFilter
	Dim bolDblClose
	intPos = 1
	intIndentCount = 0
	Do While intPos < Len(strLDAPFilter)
		strCharacter = Mid(strLDAPFilter, intPos, 1)
		intWhileIndent = 1
		strIndentation = ""
		Select Case strCharacter
			'LDAP operators to watch for to modify nesting level.
			'NOT operator ignored because only used in one-off attribute value
			Case Chr(35), Chr(124)
				'Operator followed by open paren means nesting increase
				If Mid(strLDAPFilter, intPos + 1, 1) = Chr(40) Then
					intIndentCount = intIndentCount + 1
					'Build nest based on number of indentations
					Do While intWhileIndent <= intIndentCount
						'Use unique string as placeholder for nesting with HTML spaces
						strIndentation = strIndentation & "QZNBSPQZNBSPQZNBSPQZNBSP"
						intWhileIndent = intWhileIndent + 1
					Loop
					'Insert new string for formatting
					strNewLDAPFilter = Replace(strLDAPFilter, strCharacter, strCharacter & "<br>" & strIndentation, intPos, 1)
					'Restore full filter including new string
					strLDAPFilter = Left(strLDAPFilter, intPos - 1) & strNewLDAPFilter
					'Move current position to next character after inserted string
					intPos = intPos + Len(strIndentation) + 6
				Else
					intPos = intPos + 1
				End If
			Case Chr(40)
				Do While intWhileIndent <= intIndentCount
					strIndentation = "QZNBSPQZNBSPQZNBSPQZNBSP" & strIndentation
					intWhileIndent = intWhileIndent + 1
				Loop
				If Not strIndentation = "" Then
					'If open paren follows close paren, insert CRLF
					If Mid(strLDAPFilter, intPos - 1, 1) = Chr(41) Then
						strIndentation = strIndentation & "<br>"
					End If
					strNewLDAPFilter = Replace(strLDAPFilter, strCharacter, strIndentation & strCharacter, intPos, 1)
					strLDAPFilter = Left(strLDAPFilter, intPos - 1) & strNewLDAPFilter
					intPos = intPos + Len(strIndentation) +1
				Else
					intPos = intPos + 1
				End If
			Case Chr(41)
				'Two consecutive close paren means nesting reduces one level
				If Mid(strLDAPFilter, intPos + 1, 1) = Chr(41) Then
					intIndentCount = intIndentCount - 1
					bolDblClose = True
				End If
				Do While intWhileIndent <= intIndentCount
					strIndentation = strIndentation & "QZNBSPQZNBSPQZNBSPQZNBSP"
					intWhileIndent = intWhileIndent + 1
				Loop
				strNewLDAPFilter = Replace(strLDAPFilter, strCharacter, strCharacter & "<br>" & strIndentation, intPos, 1)
				strLDAPFilter = Left(strLDAPFilter, intPos - 1) & strNewLDAPFilter
				'Adjust position to account for two close paren
				If bolDblClose = True Then
					intPos = intPos + Len(strIndentation) + 5
					bolDblClose = Empty
				Else
					intPos = intPos + Len(strIndentation) + 6
				End If
			Case Else
				'No paren or operator means move to next character
				intPos = intPos + 1
		End Select
	Loop

	'Replace LDAP operators with words
	strLDAPFilter = Replace(strLDAPFilter, Chr(35), "<i>AND</i>")
	strLDAPFilter = Replace(strLDAPFilter, Chr(124), "<i>OR</i>")
	strLDAPFilter = Replace(strLDAPFilter, Chr(33), "<i>NOT </i>")
	'Replace spaceholders with HTML spaces
	strLDAPFilter = Replace(strLDAPFilter, "QZNBSP", Chr(38) & "nbsp;")
	FormatLDAPDisplay = strLDAPFilter
End Function

Set objIE = Nothing

Panorama Theme by Themocracy