Welcome!

PowerBuilder Authors: Chris Pollach, Yeshim Deniz, Jayaram Krishnaswamy, Kevin Benedict, Avi Rosenthal

Related Topics: PowerBuilder

PowerBuilder: Article

Add the Power of E-Mail to Your Applications

Add the Power of E-Mail to Your Applications

E-mail is almost as essential as the computer to the modern business world. To send messages, however, users must switch from their current application to the e-mail application. Not only is this annoying, cumbersome and time-consuming, it's completely unnecessary. As PowerBuilder programmers we can use the MAPI (mail application program interface) facilities that are built into the language to provide e-mail capabilities directly into our application.

If you're fortunate enough to work for someone who uses EAServer, you can even use PowerBuilder to create a centralized mail server, thus providing almost unlimited power in communications.

It doesn't take a lot of imagination to begin to see some advantages. One could have error messages automatically e-mailed to an account that collects and sends them to the appropriate maintenance programmers. This way you don't get those irritating phone calls from a user who has closed the error screen without writing down the error. You'll now know precisely what error was encountered.

This article shows how to implement PowerBuilder's e-mail capabilities and helps you build a simple window to send messages from within an application. Later on we can expand on these capabilities and add the aforementioned functionality.

To build e-mail capability into the system, create a custom nonvisual user object called n_cst_mailservice. Since we'll be using this nvo for several different tasks, put common code in the constructor and destructor events.

To use e-mail in an application you must create a MAPI session. This is done by creating an instance of the mailsession nonvisual class object that comes with PowerBuilder. First, declare it as an instance variable for n_cst_mailservice, then use the create function in the constructor event to actually create the instance of this object.

Since most functions for the mailsession nvo will return a value of type mailreturncode, an enumerated variable, we'll need to create an instance of this. We'll also need instances of the mailmessage object (to store data on a specific message) and the mailrecipient object (to hold data on the intended recipients of the message). These instance variables for n_cst_mailservice will look like this:

MailSession ims_mailsess
MailReturncode imrc_returncode
MailMessage imm_mailmessage
MailRecipient imrp_mailrecipient

Since Sybase doesn't provide a naming convention for these objects, I've created my own.

Next, instantiate the mailsession in the constructor event of n_cst_mailservice. I did this in the constructor event because this nvo will eventually contain several functions for different tasks. You may want to create it as a global object when the application opens and leave it in memory as long as the user is in the application; this will save the overhead of creating and destroying the mailsession object every time it's needed. This technique provides the flexibility to either create it once and let it reside in memory or create and destroy it as needed. Put the following code in the constructor event of n_cst_mailservice:

Ims_mailsession = create MailSession
We now have a mail session created so let's log the user on to this session. Create a user object function, of_logon, without arguments but with return code with a data type of long. Put the following code in of_logon:
Imrc_returncode = ims_mailsess.maillogon(maildownload!)
The maillogon function with the argument value of maildownload! will use the users' mail system ID and password to access their current e-mail sessions. If they're currently logged on or don't have their e-mail application open, it'll log them on to their e-mail software.

Now the fun starts. If the user is logged on to e-mail, this code will establish a session and be transparent to the user. If the user isn't logged on, the response window in Figure 1 will appear, prompting him or her to select one of the available e-mail session types.

OK must be selected, not Cancel. If the user cancels, a session won't be created and no e-mail can be sent. What I do is check imrc_returncode for a value of Success!, and if this isn't the case, I put out a message box telling the user to click OK on the next prompt. I then try again to establish a mail session. If we fail again, set a return code value of -1 for of_logon (see Listing 1).

Now that we're connected, create a second user object function, of_sendmessage, that will send a simple e-mail message to a single user. In a future article I'll cover how to send a message to multiple recipients, select recipients from the address book or simply type in their e-mail addresses. For now, use a single recipient such as a departmental e-mail address that's keyed in by the user.

Create the following arguments for of_sendmessage:

a_receipt boolean
a_recipient string
a_messagetext string
a_messagesubject string
The function should return a Boolean.

Put the code in Listing 2 into the function script. It'll load the mailmessage object with the necessary values and send the e-mail to the recipient. Note that the message recipient argument's value is placed in item 1 of an unbounded array. We'll take advantage of this later on to send the message to multiple recipients.

The final code for our nvo will go in the destructor event where we'll close the mailsession and destroy the mailsession object. The code will look like this:

Ims_mailsess.maillogoff()
Destroy ims_mailsess
Now that we've created this nvo, let's create a simple window, called w_email, that uses it to send an e-mail message to the desired recipient (see Figure 2).

From top to bottom and left to right, we have the following controls on this window:

st_1, sle_recipient, st_2, sle_subject, st_3, mle_message, st_status, cb_send and cb_exit.
Note: st_status has a 3D lowered border, which makes it look more like a microhelp.

First, we need some instance variables: three strings to pass as arguments when we want to send a message - a variable of type equal to the nvo, and a Boolean and a long to check return codes.

Boolean ib_return String is_message, is_recip, is_subject Long il_return N_cst_mailservice in_cst_mailservice

Next, instantiate the nvo using the instance variable previously declared and log on to a mail session. To do this, add the following lines of text to the window open event, then add your own error handling routine if il_return equals -1:

In_cst_mailservice = create n_cst_mailservice
Il_return = in_cst_mailservice.of_logon()
// add your own code to check the return code and take appropriate action
// return code of -1 is a failure and 1 is a success
Once users have entered the appropriate data in sle_recipient, sle_subject and mle_message, they'll click on cb_send to send the message. Put the following code in the clicked event of cb_send:
if of_validate() then parent.post event ue_send(0, 0)
Now create a custom user event on the window and name it ue_send. The code for this event (see Listing 3) uses the text from the controls as the arguments for the of_sendmessage, then displays a message in st_status that tells the user if the message has been sent or if any required data wasn't entered.

Now that our window looks the way we want, we'll add a little navigational control.

In the getFocus event of sle_recipient add the following line:

st_status.text = " Enter Recipient e-mail address ([email protected])"
In similar fashion add the following code to the getFocus event of the sle_subject control:
st_status.text = " Enter the Subject of the message"
Then add the following line into the getFocus of mle_message:
st_status.text = " Enter your message"

Okay, we've made some progress here but we can do better. Add a window function named of_resolve that doesn't return a value or take any arguments (see Listing 4). It checks the three input controls to make sure they're reasonable. If they are, it turns on the cb_send button and lets you send your message. This means that in the loseFocus event of each of the three controls you need to call of_resolve.

We also need a window function to validate that the message is ready to be sent. The code (see Listing 5) is called from the Exit button.

To finish up, the clicked event of cb_exit will be coded as follows:

if of_validate() then parent.post event ue_send(0, 0)
Next, create ue_exit on the window and add the following code:
close(this)
Finally, add the following to the window close event:
Destroy in_cst_mailservice
The code I've shown you is one way to add e-mail capability to an application. Its possibilities are limited only by your creativity, while the potential cost savings can be enormous. In my next article I'll show you how to add a function to n_cst_mailservice to send out reports via e-mail and how to automatically send e-mail notifications.

In a future issue of PBDJ, Rik Brooks will have an article that will show how to turn this into a shared Jaguar component that can serve as a custom mail server.

More Stories By Tom Hughes

Thomas J. Hughes is president of TJH Consulting, Inc., a New Jersey-based provider of client/server business solutions. Thomas holds an MBA in finance and has been working with PowerBuilder for over six years.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.