home *** CD-ROM | disk | FTP | other *** search
- //
- // TPHONE.C
- // Pegasus Mail for Windows form, providing a telephone message
- // interface.
- //
- // Copyright (c) 1994, David Harris, All Rights Reserved.
- //
- // The author grants explicit permission for this source code to be
- // used or modified as required, subject only to the conditions that
- // the copyright notices above are preserved and that by using this
- // code you agree that the code is provided without warranty of any
- // kind, either explicit or implied, and you use it at your own
- // risk.
- //
-
- #define STRICT
- #include <windows.h>
- #include <bwcc.h>
- #include <stdio.h>
- #include <string.h>
- #include "..\wpmforms.h"
- #include "tphone.h" // Dialog control item IDs
-
- // Form dialogs and callbacks: a form DLL can export a function
- // which WinPMail's form manager will call with Windows messages
- // destined for the form's dialog or window (such as menu selections
- // and so forth). The function takes the following form:
-
- typedef long pascal far (*FORM_CALLBACK) (HWND hWnd, WORD wMsg,
- WPARAM wParam, LPARAM lParam);
-
- // The return from a form callback is passed back through the
- // Windows call chain if non-zero, otherwise the default window
- // proc is called. The reasons we call this function instead of
- // simply sending messages to the dialog itself are:
- //
- // 1: Dialogs can only return Boolean values, whereas the callback
- // can provide the long value Windows expects to pass back
- // through the calling chain.
- //
- // 2: Having a separate callback means that it is potentially
- // possible to have a form which does not create a dialog.
- //
- //
- // Minimum interface: the minimum interface a form DLL must provide
- // is a routine called "forminit" which is exported by name. "forminit"
- // has the following prototype:
- //
- // WORD FAR PASCAL _export FORMINIT (WORD version, int variant, HWND hParent,
- // char *data, HWND *hDialog, char *callback_name);
- //
- // "version" is passed in with the version of the WinPMail forms
- // manager which is running.
- // "variant" indicates what type of form is required - the following
- // values are currently defined:
- // 0: Create a form for composing a message
- // 1: Create a form for reading a message
- // "hParent" contains the handle of the WinPMail MDI child window
- // which is to contain the form.
- // "data" contains any string defined as being required for the
- // form in the menu interface.
- // "hDialog" should be filled in with the window handle of the
- // modeless dialog created within the MDI child window.
- // "callback_name" (optional) should be filled in with the name of the
- // function in the DLL of the exported function to which messages
- // should be sent or NULL if there is none. If NULL, messages are
- // sent to the dialog returned in "hDialog". You will use an
- // indirect callback of this kind when your extension does not
- // create a dialog within the enclosing parent window.
- //
- // When forminit is called, the DLL should register any window
- // classes it needs then create the dialog within the MDI parent
- // window and size it to the correct size. On return WinPMail will
- // resize the parent window to enclose the dialog correctly. The
- // DLL should NOT make the dialog visible - WinPMail will do that
- // as required.
-
- #define WM_MARGIN (WM_USER + 1099)
- #define WM_SETDIR (WM_USER + 400)
- #define WM_ADDFILE (WM_USER + 401)
- #define WM_STARTUP (WM_USER + 403)
- #define WM_GET_ALIST (WM_USER + 404)
-
- #define IDC_QUICKHELP_TO 970
- #define IDC_QUICKHELP_CC 971
-
-
- int register_form_classes (void);
-
-
- HINSTANCE hLibInstance; // set in LibMain, used throughout the DLL
- char szFormDlgName [] = "TM"; // Name of dialog resource template.
- char szFormDlgClassName [] =
- "bordlg_tm"; // Class name for the form dialog.
-
- char *months [] =
- {
- "Jan", "Feb", "Mar",
- "Apr", "May", "Jun",
- "Jul", "Aug", "Sep",
- "Oct", "Nov", "Dec"
- };
-
- #pragma warn -par
-
-
- WORD FAR PASCAL _export FORMINIT (WORD version, int variant, HWND hParent,
- char *data, HWND *hDialog, char *callback_name)
- {
- // First, check to see if the version of the form manager is
- // one we can work with.
-
- RECT r;
- char szBuf [80];
- int i;
- HWND hControl;
- BYTE tm [7];
-
- if ((version & 0xFF00) > 0x100) return 0;
-
- // Now check the variant number; for a telephone form, we only
- // provide a composition format.
-
- if (variant != 0) return 0;
-
- (*hDialog) = CreateDialog (hLibInstance, (LPCSTR) szFormDlgName, hParent, NULL);
- if ((*hDialog) == NULL) return 0;
- GetClientRect (*hDialog, &r);
- MoveWindow (*hDialog, 0, 0, r.right, r.bottom, FALSE);
- hControl = GetDlgItem (*hDialog, IDC_F_PHONETYPE);
- for (i = 1; i < 5; i ++)
- {
- LoadString (hLibInstance, i, szBuf, sizeof (szBuf));
- SendMessage (hControl, CB_ADDSTRING, 0, (LPARAM) szBuf);
- }
- SendMessage (hControl, CB_SETCURSEL, 0, 0);
- CheckDlgButton (*hDialog, IDC_F_PHONED, 1);
- CheckDlgButton (*hDialog, IDC_F_PLEASECALL, 1);
-
- SendMessage (hParent, WM_F_GETDATETIME, 0, (LPARAM) tm);
- sprintf (szBuf, "%d %s %d, %02d:%02d", tm [2], months [tm [1] - 1],
- tm [0], tm [3], tm [4]);
- SetDlgItemText (*hDialog, IDC_F_DATETIME, szBuf);
-
- // Some default values can be passed in the "data" parameter
- if ((data != NULL) && (*data))
- SetDlgItemText (*hDialog, IDC_F_AREACODE, data);
-
- SetFocus (GetDlgItem (*hDialog, IDC_F_TO));
- return 1;
- }
-
-
- static void strip_ampersands (char *source)
- {
- // Strip out any ampersands (&) which might appear in a
- // string (typically the title of a control). The string
- // is converted in place.
-
- char *dest;
-
- for (dest = source; *source; source ++)
- if (*source != '&') *dest ++ = *source;
- *dest = '\0';
- }
-
-
- int send_the_message (HWND hWnd)
- {
- // Called when the user clicks the "send" button. This routine
- // gets a temporary filename from WinPMail, writes the message
- // text into it then asks WinPMail to send it.
- // Returns: 1 if the message is sent OK
- // 0 if the delivery failed
-
- char szBuf [256], fname [80], subject [80], *gender, *s, *s2;
- HWND hParent;
- FILE *fil;
- int result, id;
-
- hParent = GetParent (hWnd);
- SendMessage (hParent, WM_F_NEWMESSAGE, 0, 0);
- SendMessage (hParent, WM_F_TEMPFILE, sizeof (fname), (LPARAM) fname);
- if ((fil = fopen (fname, "w+t")) == NULL)
- return 0;
-
- GetDlgItemText (hWnd, IDC_F_TO, szBuf, sizeof (szBuf));
- SendMessage (hParent, WM_F_TO, 0, (LPARAM) szBuf);
-
- GetDlgItemText (hWnd, IDC_F_NAME, szBuf, sizeof (szBuf));
- wsprintf (subject, "Phone call: %.45s", szBuf);
-
- // Now, we take a sort of semi-intelligent stab at working out
- // the gender of the caller...
-
- gender = "He/She";
- if (strnicmp (szBuf, "Mr ", 3) == 0) gender = "He";
- if ((strnicmp (szBuf, "Mrs", 3) == 0) ||
- (strnicmp (szBuf, "Ms", 2) == 0) ||
- (strnicmp (szBuf, "Miss", 4) == 0))
- gender = "She";
-
- SendMessage (hParent, WM_F_SUBJECT, 0, (LPARAM) subject);
-
- GetDlgItemText (hWnd, IDC_F_DATETIME, subject, sizeof (subject));
- fprintf (fil, "* At %s,\n", subject);
- GetDlgItemText (hWnd, IDC_F_OF, subject, sizeof (subject));
- fprintf (fil, "* %s, of %s", szBuf, subject);
-
- id = IDC_F_PHONED;
- if (IsDlgButtonChecked (hWnd, IDC_F_CALLED)) id = IDC_F_CALLED;
- if (IsDlgButtonChecked (hWnd, IDC_F_CALLEDBACK)) id = IDC_F_CALLEDBACK;
- GetDlgItemText (hWnd, id, szBuf, sizeof (szBuf));
- strip_ampersands (szBuf);
- fprintf (fil, " %s.\n", szBuf);
-
- id = IDC_F_PLEASECALL;
- if (IsDlgButtonChecked (hWnd, IDC_F_WILLCALL)) id = IDC_F_WILLCALL;
- if (IsDlgButtonChecked (hWnd, IDC_F_NOACTION)) id = IDC_F_NOACTION;
- fprintf (fil, "* ");
- switch (id)
- {
- case IDC_F_PLEASECALL :
- fprintf (fil, "%s would like you to call back", gender);
- break;
-
- case IDC_F_WILLCALL :
- fprintf (fil, "%s will call again later", gender);
- break;
-
- default :
- fprintf (fil, "No further action is required on your part");
- break;
- }
- fprintf (fil, ".\n");
-
- s = (char *) SendMessage (hParent, WM_F_GETTEXT, IDC_F_MESSAGE, 0);
- if (s != NULL)
- {
- fprintf (fil, "\n%s also left the following message:\n\n", gender);
- for (s2 = s; *s2; s2 ++) fputc (*s2, fil);
- SendMessage (hParent, WM_F_FREE, 0, (LPARAM) s);
- }
-
- fclose (fil);
- SendMessage (hParent, WM_F_MESSAGEFILE, 0, (LPARAM) fname);
-
- result = (int) SendMessage (hParent, WM_F_SENDMESSAGE, 0, 0);
- remove (fname);
- return result;
- }
-
-
- LONG FAR PASCAL _export FormProc (HWND hWnd, WORD wMsg,
- WORD wParam, LONG lParam)
- {
- // Service routine for the form's enclosed dialog. This is a
- // standard windows WndProc.
-
- DWORD dwResult = 0;
- BOOL fCallDefProc = TRUE;
-
- switch (wMsg)
- {
- case WM_COMMAND :
- fCallDefProc = FALSE;
- switch (wParam)
- {
- case IDC_F_CANCEL :
- PostMessage (GetParent (hWnd), WM_CLOSE, 0, 0);
- break;
-
- case IDC_F_RECADDR :
- SendMessage (GetParent (hWnd), WM_F_QUICKADDRESS,
- (WPARAM) (GetDlgItem (hWnd, IDC_F_TO)), 0);
- break;
-
- case IDC_F_SEND :
- if (send_the_message (hWnd))
- PostMessage (GetParent (hWnd), WM_CLOSE, 0, 0);
- break;
- }
- break;
- }
-
- if (fCallDefProc)
- dwResult = BWCCDefDlgProc (hWnd, wMsg, wParam, lParam);
-
- return dwResult;
- }
-
-
- #pragma warn -sus
-
- void unregister_form_classes (void)
- {
- // Remove any classes associated with the form; we have the
- // same problem here as we do with registering the classes
- // for the DLL - we only want to deregister the classes on
- // the last time we're unloaded.
-
- if (GetModuleUsage (hLibInstance) > 1) return; // Not a problem
- UnregisterClass (szFormDlgClassName, hLibInstance);
- }
-
-
- BOOL FAR PASCAL LibMain (HINSTANCE hInst, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine)
- {
- WNDCLASS wc;
-
- if (! hLibInstance)
- {
- hLibInstance = hInst;
- BWCCGetVersion (); // Forces BWCC to be dynamically loaded.
-
- // Register any window classes used by the form. Forms will usually
- // register either one or occasionally two classes which define
- // the composition and reader dialogs created by the DLL.
- //
- // There's a gotcha here, of course (aren't there always, in
- // Windows?)... You can't register a window class more than once,
- // so if the DLL has already been loaded and the user asks to
- // create a second instance of the form, we have to be careful
- // not to re-register the class. We do this by checking the
- // instance usage counter of the DLL - if it's greater than 1,
- // then we DON'T register the classes.
-
- wc.style = WS_CHILD;
- wc.lpfnWndProc = FormProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = DLGWINDOWEXTRA;
- wc.hInstance = hLibInstance;
- wc.hIcon = NULL;
- wc.hCursor = LoadCursor (NULL, IDC_ARROW);
- wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
- wc.lpszMenuName = NULL;
- wc.lpszClassName = szFormDlgClassName;
- if (! RegisterClass (&wc))
- MessageBeep (0);
- }
-
- return (TRUE); // Initialization went OK
- }
-
-