Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Determining the default email client in HKCU

27 views
Skip to first unread message

Tony Toews [MVP]

unread,
Jan 11, 2010, 1:03:39 AM1/11/10
to
Folks

I want to locate the default email client so I can run some logic to
create new emails as appropriate using automation for the specific
email client. I've done lots of Outlook automation and sending
emails via STMP socket in the past but I want to make this routine use
the existing email client.

So I found How to modify the default Web browser and e-mail client
programmatically in Windows XP
http://support.microsoft.com/kb/299853. It states " You can
programmatically change the defaults for the system or individually
for each user. " and " Windows XP also implements new registry keys in
HKeyCurrentUser (HKCU) to store individual internet and e-mail client
information for each user as part of their profile if users select a
different client than the default. The following code sample adds a
Web browsing and e-mail client to the available options on the system
and shows how to modify both the global and the current user: "

I can find the HKEY_LOCAL_MACHINE\SOFTWARE\Clients\Mail (defaults)
entry on my own system j But when I review my registry I can't see
any entries in HKCU. Indeed Clients doesn't exist under HKCU

When I review the KB article that code gets kind of confusing.

What I'm wondering then is that, in this case, HKCU acts as on
override? If the HKCU\SOFTWARE\Clients\Mail isn't found then
HKLM\SOFTWARE\Clients\Mail is used instead?

Randy Birch's article at Visual Basic Registry Routines
RegQueryValueEx: Determine the User's Default Mail Client
http://vbnet.mvps.org/index.html?code/reg/regdefmailclient.htm
doesn't even mention HKCU.

Tony
--
Tony Toews, Microsoft Access MVP
Tony's Main MS Access pages - http://www.granite.ab.ca/accsmstr.htm
Tony's Microsoft Access Blog - http://msmvps.com/blogs/access/
For a convenient utility to keep your users FEs and other files
updated see http://www.autofeupdater.com/
Granite Fleet Manager http://www.granitefleet.com/

MikeD

unread,
Jan 12, 2010, 7:31:47 PM1/12/10
to

"Tony Toews [MVP]" <tto...@telusplanet.net> wrote in message
news:gselk5t3kf9s4avnj...@4ax.com...


> Folks
>
> I want to locate the default email client so I can run some logic to
> create new emails as appropriate using automation for the specific
> email client. I've done lots of Outlook automation and sending
> emails via STMP socket in the past but I want to make this routine use
> the existing email client.

You might want to clarify "automation". Many, if not most, email client
programs don't support OLE Automation. And even those that do are going to
have their own object model, so you'd have to write distinct code for each.
If what you mean by "automation" is something more standard, like the mailto
protocol, then you don't need to know beforehand what the default email
program is because the default email program will already be associated with
that protocol. But be aware that different email programs might support the
mailto protocol to different extents. For example, you might be able to add
text to the body of the email or specify attachments in one email program,
but not in another. IOW, the mailto protocol is only standard to a certain
point.

Therefore, IMO, your best option is to provide some kind of editor that's
built-in to your program and then use something like CDO to send the email
via SMTP. The problem with this is that you most likely should provide
options in your program so the user can specify the SMTP server and
credentials for logging on to that server.

Your editor could support HTML or just plain text. That all depends on what
you want to do. If you really want to go the extra mile, you could probably
use a RichTextBox for formatting and then convert the rich text to HTML. If
you've got many programs (or even just 2) for which you want this
functionality, you should probably write this functionality into an OCX or
DLL that can be used by all your apps. But opinions will vary on doing that
or just adding the code module(s) to each EXE project. As with most things,
there are pros and cons for each.

> So I found How to modify the default Web browser and e-mail client
> programmatically in Windows XP

If you're planning on modifying a user's default browser or email client,
rethink that. If you've written a program to replace either of those, than
you can provide an option to the user to make yours the default, but don't
just arbitrarily change the defaults to something else, unless your goal is
to really tick off users.

--
Mike

Karl E. Peterson

unread,
Jan 12, 2010, 8:19:05 PM1/12/10
to
MikeD submitted this idea :

>> So I found How to modify the default Web browser and e-mail client
>> programmatically in Windows XP
>
> If you're planning on modifying a user's default browser or email client,
> rethink that. If you've written a program to replace either of those, than
> you can provide an option to the user to make yours the default, but don't
> just arbitrarily change the defaults to something else, unless your goal is
> to really tick off users.

Agreed. However, it sounded like Tony was just using that article for
clues in his registry hunt to determine what /are/ the defaults, not to
set them.

--
.NET: It's About Trust!
http://vfred.mvps.org


MikeD

unread,
Jan 12, 2010, 10:27:35 PM1/12/10
to

"Karl E. Peterson" <ka...@exmvps.org> wrote in message
news:#0urn5#kKHA...@TK2MSFTNGP04.phx.gbl...

That's the impression I got as well, but was not 100% certain. That's why I
said "If" as the very first word. <g>

--
Mike

C. Kevin Provance

unread,
Jan 12, 2010, 10:46:32 PM1/12/10
to
Are you looking to obtain predetermined sys info from users in support
situations?

If so, I bypassed the whole email client by sending data to a PERL script on
my site and delivering it via email to me that way.

As far as return addresses and such, my error reoutine displays an HTML page
locally where the user can enter their email address and any other pertinent
data they want me to have.

--
2025
If you do not believe in time travel,
your beliefs are about to be tempered.

http://www.facebook.com/group.php?gid=43606237254


"Tony Toews [MVP]" <tto...@telusplanet.net> wrote in message
news:gselk5t3kf9s4avnj...@4ax.com...

Tony Toews [MVP]

unread,
Jan 13, 2010, 9:09:21 PM1/13/10
to
"MikeD" <nob...@nowhere.edu> wrote:

>>>> So I found How to modify the default Web browser and e-mail client
>>>> programmatically in Windows XP
>>>
>>> If you're planning on modifying a user's default browser or email client,
>>> rethink that. If you've written a program to replace either of those,
>>> than you can provide an option to the user to make yours the default, but
>>> don't just arbitrarily change the defaults to something else, unless your
>>> goal is to really tick off users.
>>
>> Agreed. However, it sounded like Tony was just using that article for
>> clues in his registry hunt to determine what /are/ the defaults, not to
>> set them.
>
>That's the impression I got as well, but was not 100% certain. That's why I
>said "If" as the very first word. <g>

Hehehehe. And yes, I have *no* intentions of changing anything.

Tony Toews [MVP]

unread,
Jan 13, 2010, 9:19:13 PM1/13/10
to
"MikeD" <nob...@nowhere.edu> wrote:

>> I want to locate the default email client so I can run some logic to
>> create new emails as appropriate using automation for the specific
>> email client. I've done lots of Outlook automation and sending
>> emails via STMP socket in the past but I want to make this routine use
>> the existing email client.
>
>You might want to clarify "automation". Many, if not most, email client
>programs don't support OLE Automation.

Right but there seems to be three email programs as the vast majority
in use in corporations. Outlook, Lotus Notes and Groupwise. I'm
happy to automate those three. The others I'll get to if folks
request them and if they are available.

>And even those that do are going to
>have their own object model, so you'd have to write distinct code for each.

Not a problem. I've already tested the Outlook automation code and
will be doing Lotus Notes in a day or so. I have to do some poking
about to see if I can download the Groupwise client and test it.

I also have what I need working to Eudora, my email client of choice,
via MAPI. Although interestingly enough when I create the email
using MAPI Eudora also does a send/receive of email as well which I
find rather puzzling. Oh well.

>If what you mean by "automation" is something more standard, like the mailto
>protocol, then you don't need to know beforehand what the default email
>program is because the default email program will already be associated with
>that protocol. But be aware that different email programs might support the
>mailto protocol to different extents. For example, you might be able to add
>text to the body of the email or specify attachments in one email program,
>but not in another. IOW, the mailto protocol is only standard to a certain
>point.

Hmm, I thought mailto only worked if you run it from a browser. Now
that would also be nice as another option. I'll poke about a bit
more on that one.

Note that all I want to do is create a subject and the body preferably
in HTML format. The user of the utility will fill in the recipient.

>Therefore, IMO, your best option is to provide some kind of editor that's
>built-in to your program and then use something like CDO to send the email
>via SMTP. The problem with this is that you most likely should provide
>options in your program so the user can specify the SMTP server and
>credentials for logging on to that server.

I prefer not to do all that. I'd like to keep this as easy as
possible with zero configuring on the part of the user. So detecting
the default email client and if Outlook, Lotus Notes or GroupWise then
run the automation code for that. If not one of those then default to
mailto or MAPI.

>Your editor could support HTML or just plain text. That all depends on what
>you want to do. If you really want to go the extra mile, you could probably
>use a RichTextBox for formatting and then convert the rich text to HTML.

Nah, it's just one paragraph with an embedded link. So that'll be raw
HTML on the VB6 screen. I will supply default HTML so if they want
to they can muck with it as they see fit.

>If
>you've got many programs (or even just 2) for which you want this
>functionality, you should probably write this functionality into an OCX or
>DLL that can be used by all your apps. But opinions will vary on doing that
>or just adding the code module(s) to each EXE project. As with most things,
>there are pros and cons for each.

Nah. The code is going directly into the main VB6 exe. I already
have code it their which prompts the user to download updates when
they are available or hotfixes so they can test something I've just
completed. That works for me.

>> So I found How to modify the default Web browser and e-mail client
>> programmatically in Windows XP
>
>If you're planning on modifying a user's default browser or email client,
>rethink that. If you've written a program to replace either of those, than
>you can provide an option to the user to make yours the default, but don't
>just arbitrarily change the defaults to something else, unless your goal is
>to really tick off users.

See my reply to your reply to Karl's reply. <still smiling>

Tony Toews [MVP]

unread,
Jan 13, 2010, 9:20:41 PM1/13/10
to
"C. Kevin Provance" <*@*.*> wrote:

>Are you looking to obtain predetermined sys info from users in support
>situations?

No, but I'm thinking of adding that capability as well.

>If so, I bypassed the whole email client by sending data to a PERL script on
>my site and delivering it via email to me that way.

Interesting idea. I'd want to think about that one a bit though.

>As far as return addresses and such, my error reoutine displays an HTML page
>locally where the user can enter their email address and any other pertinent
>data they want me to have.

Makes sense.

MikeD

unread,
Jan 14, 2010, 9:22:20 AM1/14/10
to

"Tony Toews [MVP]" <tto...@telusplanet.net> wrote in message

news:k6vsk5pcsq9080d7b...@4ax.com...


>
> Hmm, I thought mailto only worked if you run it from a browser. Now
> that would also be nice as another option. I'll poke about a bit
> more on that one.

Nope. You can use ShellExecute. For example:

Option Explicit

Private Declare Function ShellExecute Lib "shell32.dll" Alias
"ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal
lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String,
ByVal nShowCmd As Long) As Long

Private Sub Form_Click()

Dim sMailTo As String

sMailTo = "mailto:user@domain?Subject=Email Subject&Body=This is a test"
Call ShellExecute(0, "open", sMailTo, vbNullString, vbNullString,
vbNormalFocus)

End Sub

>
> Note that all I want to do is create a subject and the body preferably
> in HTML format. The user of the utility will fill in the recipient.

You can use the above but with this change:

sMailTo = "mailto:?Subject=Email Subject&Body=This is a test"

But again, I don't think all email clients support the protocol to this
extent, notably the body text. Also, you need to replace CR/LFs with this
string: "%0d%0a".

sMailTo = "mailto:user@domain?Subject=Email Subject&Body=This is a
test." & vbCrLf & "This is test line 2."
sMailTo = Replace$(sMailTo, vbCrLf, "%0d%0a")

I don't think there's a way to specifically use HTML. It's going to use
plain text or HTML as set as the default sending format. But I'm not sure
about that.

This will at least get you started.

--
Mike

T Jones

unread,
Jan 14, 2010, 7:07:37 PM1/14/10
to
It amazes me how many times over the last 12 years I've seen someone ask a
question as to how to make something happen in code and responders jump on
them with "I don't know why you 'd want to do that", or "Why do you want to
do that?" Who cares what you think! If someone wants to find where the
default email flag is kept, either tell them, or don't.

I always thought that the NG's was a place to get coding answers, not to
have someone jump on the questioner with their own views as to why/what they
should do. If someone wants an opinion as to whether something should be
done, they'd ask, but please people, just answer, or don't answer the coding
question. Not everyone wants your opinion.

Now ... wait for the 'opinions' to fly. :-)


MikeD

unread,
Jan 14, 2010, 8:10:22 PM1/14/10
to
"T Jones" <speed...@hotmail.com> wrote in message
news:#1RKBbXl...@TK2MSFTNGP05.phx.gbl...

> It amazes me how many times over the last 12 years I've seen someone ask a
> question as to how to make something happen in code and responders jump on
> them with "I don't know why you 'd want to do that", or "Why do you want
> to do that?" Who cares what you think! If someone wants to find where the
> default email flag is kept, either tell them, or don't.

Perhaps you're being a little short-sighted here. Some people, new to
programming perhaps (but even those that aren't newbies), may not know
what's a good thing to do and what's a bad thing to do for a particular task
or goal or whatever you want to call it. They just have an idea that popped
into their head on ONE way to possibly solve the problem. We're educating
them by telling them that perhaps that idea is not the best in the world,
and usually providing alternatives or suggestions. Would YOU want a program
changing YOUR default email program, web browser, or anything else in your
system? I doubt it.

>
> I always thought that the NG's was a place to get coding answers, not to
> have someone jump on the questioner with their own views as to why/what
> they should do. If someone wants an opinion as to whether something should
> be done, they'd ask, but please people, just answer, or don't answer the
> coding question. Not everyone wants your opinion.

Nobody "jumped" on Tony.

And opinions are one of the BEST things these newsgroups have to offer
because you might not have considered those opinions. Sometimes opinions
just aren't presented...let's say "tactfully", in which case they're
probably falling on deaf ears even if the opinion has merit.

Sure, newsgroups are for getting answers. But for the programming
newsgroups in particular, they're also for getting enlightened...and that
occurs by stating opinions. Is it wrong that some of us feel obliged to
point out the bad things, or even questionable things, somebody might be
proposing to do? If you think it is, you don't understand what the
newsgroups, and perhaps even peer-to-peer support, is all about.

--
Mike

Tony Toews [MVP]

unread,
Jan 14, 2010, 9:47:41 PM1/14/10
to
"MikeD" <nob...@nowhere.edu> wrote:

>Nobody "jumped" on Tony.

Agreed on that. I certainly didn't take it that way. More along the
lines of the guy behind the counter at the parts store saying "Ok, now
be sure you ...."

>Sure, newsgroups are for getting answers. But for the programming
>newsgroups in particular, they're also for getting enlightened...and that
>occurs by stating opinions. Is it wrong that some of us feel obliged to
>point out the bad things, or even questionable things, somebody might be
>proposing to do?

I do that all the time myself.

Tony Toews [MVP]

unread,
Jan 14, 2010, 9:45:46 PM1/14/10
to
"T Jones" <speed...@hotmail.com> wrote:

>It amazes me how many times over the last 12 years I've seen someone ask a
>question as to how to make something happen in code and responders jump on
>them with "I don't know why you 'd want to do that", or "Why do you want to
>do that?" Who cares what you think! If someone wants to find where the
>default email flag is kept, either tell them, or don't.

I ask folks on a regular basis why they are trying to do something as
maybe they are totally nuts.

>I always thought that the NG's was a place to get coding answers, not to
>have someone jump on the questioner with their own views as to why/what they
>should do. If someone wants an opinion as to whether something should be
>done, they'd ask, but please people, just answer, or don't answer the coding
>question. Not everyone wants your opinion.
>
>Now ... wait for the 'opinions' to fly. :-)

<smile>

Tony Toews [MVP]

unread,
Jan 14, 2010, 9:50:58 PM1/14/10
to
"MikeD" <nob...@nowhere.edu> wrote:

>> Hmm, I thought mailto only worked if you run it from a browser. Now
>> that would also be nice as another option. I'll poke about a bit
>> more on that one.
>
>Nope. You can use ShellExecute. For example:

I didn't know that.

>Private Sub Form_Click()
>
> Dim sMailTo As String
>
> sMailTo = "mailto:user@domain?Subject=Email Subject&Body=This is a test"
> Call ShellExecute(0, "open", sMailTo, vbNullString, vbNullString,
>vbNormalFocus)
>
>End Sub

Thanks muchly. That's a better alternative then that MAPI as, for me
anyhow, MAPI/Eudora do "interesting" things.

>> Note that all I want to do is create a subject and the body preferably
>> in HTML format. The user of the utility will fill in the recipient.
>
>You can use the above but with this change:
>
> sMailTo = "mailto:?Subject=Email Subject&Body=This is a test"
>
>But again, I don't think all email clients support the protocol to this
>extent, notably the body text. Also, you need to replace CR/LFs with this
>string: "%0d%0a".
>
> sMailTo = "mailto:user@domain?Subject=Email Subject&Body=This is a
>test." & vbCrLf & "This is test line 2."
> sMailTo = Replace$(sMailTo, vbCrLf, "%0d%0a")
>
>I don't think there's a way to specifically use HTML. It's going to use
>plain text or HTML as set as the default sending format. But I'm not sure
>about that.
>
>This will at least get you started.

Sure will. Thanks muchly. You've saved me a bunch of digging out
that info.

Karl E. Peterson

unread,
Jan 14, 2010, 10:06:17 PM1/14/10
to
Tony Toews [MVP] formulated the question :

> "MikeD" <nob...@nowhere.edu> wrote:
>>> Note that all I want to do is create a subject and the body preferably
>>> in HTML format. The user of the utility will fill in the recipient.
>>
>> You can use the above but with this change:
>>
>> sMailTo = "mailto:?Subject=Email Subject&Body=This is a test"
>>
>> But again, I don't think all email clients support the protocol to this
>> extent, notably the body text. Also, you need to replace CR/LFs with this
>> string: "%0d%0a".
>>
>> sMailTo = "mailto:user@domain?Subject=Email Subject&Body=This is a
>> test." & vbCrLf & "This is test line 2."
>> sMailTo = Replace$(sMailTo, vbCrLf, "%0d%0a")
>>
>> I don't think there's a way to specifically use HTML. It's going to use
>> plain text or HTML as set as the default sending format. But I'm not sure
>> about that.
>>
>> This will at least get you started.
>
> Sure will. Thanks muchly. You've saved me a bunch of digging out
> that info.

If you're gonna go with that, don't monkey with manually escaping the
URL. Windows will do that for you...

Private Declare Function UrlEscape Lib "Shlwapi.dll" Alias
"UrlEscapeA" (ByVal pszURL As String, ByVal pszEscaped As String, ByRef
pcchEscaped As Long, ByVal dwFlags As Long) As Long

Private Declare Function UrlUnescape Lib "Shlwapi.dll" Alias
"UrlUnescapeA" (ByVal pszURL As String, ByVal pszUnescaped As String,
ByRef pcchUnescaped As Long, ByVal dwFlags As Long) As Long

Private Const URL_DONT_ESCAPE_EXTRA_INFO As Long = &H2000000

Public Function EscapeURL(ByVal URL As String) As String
' Purpose: A thin wrapper for the UrlEscape API function.
Dim EscTxt As String
Dim nLen As Long

' Create a maximum sized buffer.
nLen = Len(URL) * 3
EscTxt = Space$(nLen)

If UrlEscape(URL, EscTxt, nLen, 0) = 0 Then
EscapeURL = Left$(EscTxt, nLen)
End If
End Function

Public Function UnescapeURL(ByVal URL As String) As String
' Purpose: A thin wrapper for the UrlUnescape API function.
Dim EscTxt As String
Dim nLen As Long

' Create a maximum sized buffer.
nLen = Len(URL) * 3
EscTxt = Space$(nLen)

If UrlUnescape(URL, EscTxt, nLen, 0) = 0 Then
UnescapeURL = Left$(EscTxt, nLen)
End If
End Function

Realize there's a hard limit to the length of the URL. Seems like it's
around 2k chars, if I recall correctly. Ah, here it is:

Maximum URL length is 2,083 characters in Internet Explorer
http://support.microsoft.com/kb/208427

Tony Toews [MVP]

unread,
Jan 15, 2010, 12:01:57 AM1/15/10
to
Karl E. Peterson <ka...@exmvps.org> wrote:

Useful stuff snipped.

>Realize there's a hard limit to the length of the URL. Seems like it's
>around 2k chars, if I recall correctly. Ah, here it is:
>
>Maximum URL length is 2,083 characters in Internet Explorer
>http://support.microsoft.com/kb/208427

Eh? 2083? Ok, look I can understand something under 2048. But
slightly over 2048? <shrug>

Tony Toews [MVP]

unread,
Jan 15, 2010, 2:33:46 AM1/15/10
to
"MikeD" <nob...@nowhere.edu> wrote:

>> Hmm, I thought mailto only worked if you run it from a browser. Now
>> that would also be nice as another option. I'll poke about a bit
>> more on that one.
>
>Nope. You can use ShellExecute. For example:

Thanks a bunch. It's working just great! (Until the users get their
hands on it.)

Tony Toews [MVP]

unread,
Jan 15, 2010, 4:11:47 PM1/15/10
to
Karl E. Peterson <ka...@exmvps.org> wrote:

>If you're gonna go with that, don't monkey with manually escaping the
>URL. Windows will do that for you...

Ahh, excellent. You never know what the users might want to put in the
email text.

My API module alone is now at 1709 lines of code according to MZTools.
Total lines of code in this project are 10,841, comments 2419. Each
line lovingly hand crafted or stolen. <smile>

Tony Toews [MVP]

unread,
Jan 15, 2010, 4:17:05 PM1/15/10
to
Karl E. Peterson <ka...@exmvps.org> wrote:

>If you're gonna go with that, don't monkey with manually escaping the
>URL. Windows will do that for you...

BTW you can only do this to the contents of the email body. Doesn't
work when you do the entire mailto line. Only took me ten seconds to
figure out so no big deal.

Dee Earley

unread,
Jan 19, 2010, 5:23:52 AM1/19/10
to
On 14/01/2010 02:19, Tony Toews [MVP] wrote:
> Note that all I want to do is create a subject and the body preferably
> in HTML format. The user of the utility will fill in the recipient.

This is exactly what simple MAPI is for.
It's a standard interface that mail apps should handle to allow for
creation/sending of emails.

I've used it from VB to create a blank email with an attachment in
Outlook express/Live mail, Outlook, Thunderbird

"mailto:" URLs work in some cases but for anything more than just the
recipient is non standard.

--
Dee Earley (dee.e...@icode.co.uk)
i-Catcher Development Team

iCode Systems

Tony Toews [MVP]

unread,
Jan 19, 2010, 3:34:56 PM1/19/10
to
Dee Earley <dee.e...@icode.co.uk> wrote:

>> Note that all I want to do is create a subject and the body preferably
>> in HTML format. The user of the utility will fill in the recipient.
>
>This is exactly what simple MAPI is for.
>It's a standard interface that mail apps should handle to allow for
>creation/sending of emails.

Trouble is I've had a great deal of difficulty finding simple MAPI
sample code in VB6. The more complex MAPI apparently requires some
kind of DLL.

Tony Toews [MVP]

unread,
Jan 19, 2010, 4:10:50 PM1/19/10
to
Dee Earley <dee.e...@icode.co.uk> wrote:

>> Note that all I want to do is create a subject and the body preferably
>> in HTML format. The user of the utility will fill in the recipient.
>
>This is exactly what simple MAPI is for.
>It's a standard interface that mail apps should handle to allow for
>creation/sending of emails.
>
>I've used it from VB to create a blank email with an attachment in
>Outlook express/Live mail, Outlook, Thunderbird
>
>"mailto:" URLs work in some cases but for anything more than just the
>recipient is non standard.

BTW I'd like to give them as many options as possible so that,
hopefully, one of them works. I also support Outlook natively and
will be adding Lotus Notes and GroupWise native code too. So one way
or another I should be covered. And I probably have too many options
that hardly anyone will use anyhow. <smile>

Karl E. Peterson

unread,
Jan 19, 2010, 6:19:59 PM1/19/10
to
Tony Toews [MVP] used his keyboard to write :

> Karl E. Peterson <ka...@exmvps.org> wrote:
>
> Useful stuff snipped.
>
>> Realize there's a hard limit to the length of the URL. Seems like it's
>> around 2k chars, if I recall correctly. Ah, here it is:
>>
>> Maximum URL length is 2,083 characters in Internet Explorer
>> http://support.microsoft.com/kb/208427
>
> Eh? 2083? Ok, look I can understand something under 2048. But
> slightly over 2048? <shrug>

Only Microsoft... <sigh>

Karl E. Peterson

unread,
Jan 19, 2010, 6:21:36 PM1/19/10
to
Tony Toews [MVP] explained on 1/15/2010 :

> Karl E. Peterson <ka...@exmvps.org> wrote:
>
>> If you're gonna go with that, don't monkey with manually escaping the
>> URL. Windows will do that for you...
>
> Ahh, excellent. You never know what the users might want to put in the
> email text.

And speaking of Microsoft, have you noticed they're using illegal
characters (parenthesis) in their URLs now?

> My API module alone is now at 1709 lines of code according to MZTools.
> Total lines of code in this project are 10,841, comments 2419. Each
> line lovingly hand crafted or stolen. <smile>

Heh...

"Good artists copy; Great artists steal."
~Picasso

Karl E. Peterson

unread,
Jan 19, 2010, 6:22:31 PM1/19/10
to
Tony Toews [MVP] formulated on Friday :

> Karl E. Peterson <ka...@exmvps.org> wrote:
>
>> If you're gonna go with that, don't monkey with manually escaping the
>> URL. Windows will do that for you...
>
> BTW you can only do this to the contents of the email body. Doesn't
> work when you do the entire mailto line.

Eh? I'm sure I have in the past. That's why I needed it.

Dee Earley

unread,
Jan 20, 2010, 4:59:52 AM1/20/10
to
On 19/01/2010 20:34, Tony Toews [MVP] wrote:
> Dee Earley<dee.e...@icode.co.uk> wrote:
>
>>> Note that all I want to do is create a subject and the body preferably
>>> in HTML format. The user of the utility will fill in the recipient.
>>
>> This is exactly what simple MAPI is for.
>> It's a standard interface that mail apps should handle to allow for
>> creation/sending of emails.
>
> Trouble is I've had a great deal of difficulty finding simple MAPI
> sample code in VB6. The more complex MAPI apparently requires some
> kind of DLL.

At its "simplest":

Option Explicit

'Very ripped off from mapi32.bas and modified to use the real simple
MAPI functions
Private Type MAPIMessage
Reserved As Long
lpSubject As Long 'String
lpNoteText As Long 'String
MessageType As String
DateReceived As String
ConversationID As String
Flags As Long
lpOriginator As Long
RecipCount As Long
lpRecips As Long
FileCount As Long
lpFiles As Long
End Type

Private Type MapiRecip
Reserved As Long
RecipClass As Long
lpName As Long
lpAddress As Long
EIDSize As Long
lpEntryID As Long
End Type

Private Type MapiFile
Reserved As Long
Flags As Long
Position As Long
lpPathName As Long
lpFileName As Long
FileType As Long
End Type

Private Declare Function MAPISendMail Lib "MAPI32.DLL" (ByVal Session As
Long, ByVal UIParam As Long, ByRef Message As Any, ByVal Flags As Long,
ByVal Reserved As Long) As Long

'Private Const SUCCESS_SUCCESS = 0
'Private Const MAPI_USER_ABORT = 1
'Private Const MAPI_E_USER_ABORT = MAPI_USER_ABORT
'Private Const MAPI_E_FAILURE = 2
'Private Const MAPI_E_LOGIN_FAILURE = 3
'Private Const MAPI_E_LOGON_FAILURE = MAPI_E_LOGIN_FAILURE
'Private Const MAPI_E_DISK_FULL = 4
'Private Const MAPI_E_INSUFFICIENT_MEMORY = 5
'Private Const MAPI_E_BLK_TOO_SMALL = 6
'Private Const MAPI_E_TOO_MANY_SESSIONS = 8
'Private Const MAPI_E_TOO_MANY_FILES = 9
'Private Const MAPI_E_TOO_MANY_RECIPIENTS = 10
'Private Const MAPI_E_ATTACHMENT_NOT_FOUND = 11
'Private Const MAPI_E_ATTACHMENT_OPEN_FAILURE = 12
'Private Const MAPI_E_ATTACHMENT_WRITE_FAILURE = 13
'Private Const MAPI_E_UNKNOWN_RECIPIENT = 14
'Private Const MAPI_E_BAD_RECIPTYPE = 15
'Private Const MAPI_E_NO_MESSAGES = 16
'Private Const MAPI_E_INVALID_MESSAGE = 17
'Private Const MAPI_E_TEXT_TOO_LARGE = 18
'Private Const MAPI_E_INVALID_SESSION = 19
'Private Const MAPI_E_TYPE_NOT_SUPPORTED = 20
'Private Const MAPI_E_AMBIGUOUS_RECIPIENT = 21
'Private Const MAPI_E_AMBIG_RECIP = MAPI_E_AMBIGUOUS_RECIPIENT
'Private Const MAPI_E_MESSAGE_IN_USE = 22
'Private Const MAPI_E_NETWORK_FAILURE = 23
'Private Const MAPI_E_INVALID_EDITFIELDS = 24
'Private Const MAPI_E_INVALID_RECIPS = 25
'Private Const MAPI_E_NOT_SUPPORTED = 26

'Private Const MAPI_ORIG = 0
Private Const MAPI_TO = 1
'Private Const MAPI_CC = 2
'Private Const MAPI_BCC = 3

Private Const MAPI_DIALOG = &H8

Public Function MailtoWithAttachment(ByVal Recipient As String, ByVal
Subject As String, ByVal Body As String, ByVal Attachment As String) As
Boolean
Dim Message As MAPIMessage
Dim RecipientA() As Byte
Dim Recipients(0) As MapiRecip
Dim AttachmentA() As Byte
Dim Attachments(0) As MapiFile
Dim SubjectA() As Byte
Dim BodyA() As Byte

Dim Result As Long

'Set the recipient
RecipientA = StrConv(Recipient & vbNullChar, vbFromUnicode)
Recipients(0).lpName = VarPtr(RecipientA(0))
Recipients(0).RecipClass = MAPI_TO
Message.RecipCount = 1
Message.lpRecips = VarPtr(Recipients(0))

'Add the attachment
AttachmentA = StrConv(Attachment & vbNullChar, vbFromUnicode)
Attachments(0).lpPathName = VarPtr(AttachmentA(0))
Attachments(0).Position = -1
Message.FileCount = 1
Message.lpFiles = VarPtr(Attachments(0))

'Subject
SubjectA = StrConv(Subject & vbNullChar, vbFromUnicode)
Message.lpSubject = VarPtr(SubjectA(0))

'And body
BodyA = StrConv(Body & vbNullChar, vbFromUnicode)
Message.lpNoteText = VarPtr(BodyA(0))

'Try and send the email
Result = MAPISendMail(0, 0, ByVal VarPtr(Message), MAPI_DIALOG, 0&)
'Return false if there was a problem (ignoring canel)
MailtoWithAttachment = Result = 0 Or Result = 1
End Function

The biggest pain was passing unicode strings in the structures (hence
the StrConv and VarPtr calls)

Dee Earley

unread,
Jan 20, 2010, 6:22:18 AM1/20/10
to

> And speaking of Microsoft, have you noticed they're using illegal
> characters (parenthesis) in their URLs now?

They're not illegal.
See RFC 3986 section 2.2 and RFC 2616 section 3.2.3.

While "(" and ")" are "reserved", it is up to the server how it treats
them, especially as then and the hex encoded values are distinct.

Tony Toews [MVP]

unread,
Jan 20, 2010, 3:14:55 PM1/20/10
to
Dee Earley <dee.e...@icode.co.uk> wrote:

>> Trouble is I've had a great deal of difficulty finding simple MAPI
>> sample code in VB6. The more complex MAPI apparently requires some
>> kind of DLL.
>
>At its "simplest":

And that works just fine even without the recipient. At least in
Eudora, my default email handler. I'll test it with OE in a bit.

Thanks, Tony

Karl E. Peterson

unread,
Jan 20, 2010, 3:59:04 PM1/20/10
to
It happens that Dee Earley formulated :

>> And speaking of Microsoft, have you noticed they're using illegal
>> characters (parenthesis) in their URLs now?
>
> They're not illegal.
> See RFC 3986 section 2.2 and RFC 2616 section 3.2.3.
>
> While "(" and ")" are "reserved", it is up to the server how it treats them,
> especially as then and the hex encoded values are distinct.

Interesting that FireFox escapes them when you copy the URL directly
from the address bar. I haven't tried running them through the
EscapeURL API. Perhaps "illegal" was the wrong word?

Tony Toews [MVP]

unread,
Jan 21, 2010, 2:43:36 AM1/21/10
to
Karl E. Peterson <ka...@exmvps.org> wrote:

>Interesting that FireFox escapes them when you copy the URL directly
>from the address bar. I haven't tried running them through the
>EscapeURL API. Perhaps "illegal" was the wrong word?

Wonky?

mayayana

unread,
Jan 21, 2010, 9:09:28 AM1/21/10
to
>
> Interesting that FireFox escapes them when you copy the URL directly
> from the address bar. I haven't tried running them through the
> EscapeURL API. Perhaps "illegal" was the wrong word?
>

Illegal is good enough for me. Or maybe "idiotic"
would be more to the point. Or maybe "superfluous"?
Isn't it always "(VS.85)"? But it might mean something
in Microsoftese. Let's see. SV1 in the userAgent means
"XP Service Pack 2". So (VS.85) must mean "MSDN -
revision 2009 - 1st rendering". :)


Dee Earley

unread,
Jan 21, 2010, 9:17:54 AM1/21/10
to

It's being used exactly as the RFC specifies it, for different
versions/languages of a page.
See http://msdn.microsoft.com/en-us/library/bzesc19x(VS.0).aspx
Load one of them and look at the "other versions" box"

They could equally use parameters, but i expect this is a bit more cache
friendly (and is valid :)

mayayana

unread,
Jan 21, 2010, 9:59:00 AM1/21/10
to

> It's being used exactly as the RFC specifies it, for different
> versions/languages of a page.
> See http://msdn.microsoft.com/en-us/library/bzesc19x(VS.0).aspx
> Load one of them and look at the "other versions" box"
>

Interesting. I didn't know that was what it was. That
explains why I always get the same number. Gracias. :)

> They could equally use parameters, but i expect this
> is a bit more cache friendly (and is valid :)

While it may be valid it's still somewhat non-standard.
I'm using OE, and your link above ends at the first (.
"(VS.0).aspx" displays as plain text. If I use context
menu -> Copy Link I only get up to the first (.

This is in Microsoft's own software. I'm using OE5, so
maybe it's changed in later versions, but if Firefox
escapes it and OE doesn't see it as part of a URL, it's
hard to see how someone at Microsoft arrived at that
particular brainstorm and thought it was a good idea --
unless perhaps the language syntax is a new addition
by the W3C that older software won't know about. I know
that MS does love to conform to standards. :)

Karl E. Peterson

unread,
Jan 21, 2010, 1:13:51 PM1/21/10
to
on 1/21/2010, mayayana supposed :

>> It's being used exactly as the RFC specifies it, for different
>> versions/languages of a page.
>> See http://msdn.microsoft.com/en-us/library/bzesc19x(VS.0).aspx
>> Load one of them and look at the "other versions" box"
>>
>
> Interesting. I didn't know that was what it was. That
> explains why I always get the same number. Gracias. :)
>
>> They could equally use parameters, but i expect this
>> is a bit more cache friendly (and is valid :)
>
> While it may be valid it's still somewhat non-standard.
> I'm using OE, and your link above ends at the first (.
> "(VS.0).aspx" displays as plain text. If I use context
> menu -> Copy Link I only get up to the first (.

Yeah, I'm using another highly compliant newsreader (MesNews) and it
has this same fault. In fact, the fact that it didn't render the links
properly was what led me to conclude "illegal" in the first place.

Karl E. Peterson

unread,
Jan 21, 2010, 1:14:12 PM1/21/10
to
Tony Toews [MVP] wrote :

> Karl E. Peterson <ka...@exmvps.org> wrote:
>
>> Interesting that FireFox escapes them when you copy the URL directly
>> from the address bar. I haven't tried running them through the
>> EscapeURL API. Perhaps "illegal" was the wrong word?
>
> Wonky?

Apparently, yeah! That might be most accurate.

Karl E. Peterson

unread,
Jan 21, 2010, 1:17:06 PM1/21/10
to
Dee Earley submitted this idea :

Interestingly, EscapeURL (Win7 x64) leaves them intact. That'd
indicate FireFox is using it's own routine, and providing the safest
(most portable) expression available.

Dee Earley

unread,
Jan 22, 2010, 3:59:43 AM1/22/10
to
On 21/01/2010 18:14, Karl E. Peterson wrote:
> Tony Toews [MVP] wrote :
>> Karl E. Peterson <ka...@exmvps.org> wrote:
>>
>>> Interesting that FireFox escapes them when you copy the URL directly
>>> from the address bar. I haven't tried running them through the
>>> EscapeURL API. Perhaps "illegal" was the wrong word?
>>
>> Wonky?
>
> Apparently, yeah! That might be most accurate.

Or just "reserved" :)

Dee Earley

unread,
Jan 22, 2010, 4:08:32 AM1/22/10
to
On 21/01/2010 14:59, mayayana wrote:
>> They could equally use parameters, but i expect this
>> is a bit more cache friendly (and is valid :)
>
> While it may be valid it's still somewhat non-standard.

Technically, it IS the standard, just very few people use it.. :)

> I'm using OE, and your link above ends at the first (.
> "(VS.0).aspx" displays as plain text. If I use context
> menu -> Copy Link I only get up to the first (.

Oh, OE is well known as the mecca of good software design!

> This is in Microsoft's own software. I'm using OE5, so
> maybe it's changed in later versions, but if Firefox
> escapes it and OE doesn't see it as part of a URL, it's
> hard to see how someone at Microsoft arrived at that
> particular brainstorm and thought it was a good idea --
> unless perhaps the language syntax is a new addition
> by the W3C that older software won't know about. I know
> that MS does love to conform to standards. :)

Oddly, RFC 1738 (from 1994) doesn't list them as reserved at all and can
be left unencoded.

Karl E. Peterson

unread,
Jan 22, 2010, 5:46:44 PM1/22/10
to
Dee Earley presented the following explanation :

> On 21/01/2010 18:14, Karl E. Peterson wrote:
>> Tony Toews [MVP] wrote :
>>> Karl E. Peterson <ka...@exmvps.org> wrote:
>>>
>>>> Interesting that FireFox escapes them when you copy the URL directly
>>>> from the address bar. I haven't tried running them through the
>>>> EscapeURL API. Perhaps "illegal" was the wrong word?
>>>
>>> Wonky?
>>
>> Apparently, yeah! That might be most accurate.
>
> Or just "reserved" :)

For what, dinner?

mayayana

unread,
Jan 22, 2010, 6:54:11 PM1/22/10
to

> > Or just "reserved" :)
>
> For what, dinner?
>
That's an interesting question. This site calls
it "unsafe":
http://www.tcpipguide.com/free/t_URLGeneralSyntax-4.htm

I was unable to find any definitive explanation
at w3c.org. It appears that the standard treatment
is to convert reserved/unsafe characters to %hex
format. Like using spaces, a parenthesis is reserved/
unsafe/wonky/illegal. Then again, how do we know
that view is not "deprecated" or "no longer supported"? :)

I think it's safe to say that Microsoft was "daft"
in their decision. (If I may be so bold a to use a
precise, technical term.)


Karl E. Peterson

unread,
Jan 22, 2010, 7:56:42 PM1/22/10
to
mayayana wrote :

Well, even if it *is* the standard, as Dee says, why would MSFT *only*
choose to follow "standards" that everyone else seems to think are
<ahem> daft, and virtually ignore entirely those that everyone else
adheres to???

Dee Earley

unread,
Jan 25, 2010, 7:32:58 AM1/25/10
to
On 22/01/2010 23:54, mayayana wrote:
>>> Or just "reserved" :)
>>
>> For what, dinner?
>>
> That's an interesting question. This site calls
> it "unsafe":
> http://www.tcpipguide.com/free/t_URLGeneralSyntax-4.htm
>
> I was unable to find any definitive explanation
> at w3c.org. It appears that the standard treatment
> is to convert reserved/unsafe characters to %hex
> format. Like using spaces, a parenthesis is reserved/
> unsafe/wonky/illegal. Then again, how do we know
> that view is not "deprecated" or "no longer supported"? :)

The point is that the latest definitive URL and the HTTP specifications
specifically say it SHOULD NOT be encoded when used to define
subcomponents (as MS are doing), and if encoded should be treated as
distinct from the unencoded version.

From 2616, 3.2.3:
> Characters other than those in the "reserved" and "unsafe" sets (see
> RFC 2396 [42]) are equivalent to their ""%" HEX HEX" encoding.

mayayana

unread,
Jan 25, 2010, 10:44:09 AM1/25/10
to

>
> The point is that the latest definitive URL and the HTTP specifications
> specifically say it SHOULD NOT be encoded when used to define
> subcomponents (as MS are doing), and if encoded should be treated as
> distinct from the unencoded version.
>

Ah. The plot thickens. So they don't work half
the time when unencoded, but they mean something
else when encoded. That's clever. I really don't see
why you feel so strongly about this. It appears to me
that there was bad judgement in the design and more
bad judgement on the part of Microsoft in using those
characters. Who cares what's "official" if it doesn't
work?


Dee Earley

unread,
Jan 25, 2010, 12:09:40 PM1/25/10
to

It does work if people adhere to the standards :)
That is why I feel most strongly about.

Nobody

unread,
Jan 26, 2010, 2:10:06 PM1/26/10
to
"Dee Earley" <dee.e...@icode.co.uk> wrote in message
news:%23nIdIqb...@TK2MSFTNGP02.phx.gbl...

Wikipedia also seems to use parentheses in their URL's. Example(You need to
use Copy & Paste with some email programs, such as OE):

http://en.wikipedia.org/wiki/Template_(programming)


0 new messages