home *** CD-ROM | disk | FTP | other *** search
- //
- // LOG.C
- // Pegasus Mail for Windows extension providing a simple
- // logging interface.
- //
- // Copyright (c) 1994-95, 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"
-
- // 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
-
- char szFormDlgClassName [] = "bordlg_log";
- char do_logging = 1;
- HFONT hLogFont;
- HWND last_focus;
-
- int register_form_classes (void);
-
- HINSTANCE hLibInstance; // set in LibMain, used throughout the DLL
-
-
- #pragma warn -par
-
- WORD FAR PASCAL _export FORMINIT (WORD version, int variant, HWND hParent,
- char *data, HWND *hDialog, char *callback_name)
- {
- RECT r, r2;
- char szBuf [80];
- int i;
- HWND hControl;
- BYTE tm [7];
-
- // First, check to see if the version of the form manager is
- // one we can work with. This check is pretty arbitrary - you
- // should probably assume that you may not work with any version
- // where the major version number is higher than the original
- // version you targeted.
-
- if ((version & 0xFF00) > 0x100) return 0;
-
- // Now check the variant number; for this extension, we only
- // provide a COMPOSER format.
-
- if (variant != 0) return 0;
-
- (*hDialog) = CreateDialog (hLibInstance, (LPCSTR) "LOG", hParent, NULL);
- if ((*hDialog) == NULL) return 0;
-
- if (! hLogFont)
- hLogFont = CreateFont (14, 0, 0, 0, 400, FALSE,
- FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS,
- CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
- DEFAULT_PITCH | FF_DONTCARE, "Arial");
- SendMessage (GetDlgItem (*hDialog, 101), WM_SETFONT,
- (WPARAM) hLogFont, (LPARAM) TRUE);
-
- return 1;
- }
-
-
- LONG FAR PASCAL _export LogProc (HWND hWnd, WORD wMsg,
- WORD wParam, LONG lParam)
- {
- // Service routine for the form's enclosed dialog. This is a
- // standard windows modeless WndProc.
-
- DWORD dwResult = 0;
- BOOL fCallDefProc = TRUE;
- char buffer [80], *s, *to, *subj;
- RECT r;
- HWND hControl;
- HCURSOR hOldCursor;
- BYTE tm [7];
-
- switch (wMsg)
- {
- case WM_FM_INIT :
- CheckDlgButton (hWnd, 102, do_logging);
- break;
-
- case WM_DESTROY :
- if (hLogFont)
- {
- SendMessage (GetDlgItem (hWnd, 101), WM_SETFONT,
- (WPARAM) 0, FALSE);
- DeleteObject (hLogFont);
- }
- break;
-
- case WM_FM_INITFOCUS :
- SetFocus (GetDlgItem (hWnd, 101));
- break;
-
- case WM_FM_RESTOREFOCUS :
- // There's a glitch in the way the Windows MDI manager
- // seems to manage focus which means that we can have
- // focus taken away and not returned when the user does
- // anything outside our window. WinPMail has some quite
- // complex logic to deal with this case and will send
- // this message whenever focus should be restored in
- // our window. We set focus to the last active control
- // (which we know from trapping EN_SETFOCUS messages).
-
- if (last_focus) SetFocus (last_focus);
- break;
-
- case WM_FM_SENDMAIL :
- to = (char *) SendMessage (GetParent (hWnd), WM_F_GETMESSAGEFIELD, WMSG_TO, 0);
- subj = (char *) SendMessage (GetParent (hWnd), WM_F_GETMESSAGEFIELD, WMSG_SUBJECT, 0);
- wsprintf (buffer, "Mail sent to '%.25s', '%.25s'.\r\n", to, subj);
- SendDlgItemMessage (hWnd, 101, EM_REPLACESEL, 0, (LPARAM) buffer);
- break;
-
- case WM_FM_LOGEVENT :
- if (! do_logging) break;
- SendMessage (GetParent (hWnd), WM_F_GETDATETIME, 0, (LPARAM) tm);
- wsprintf (buffer, "%02d:%02d:%02d : ", tm [3], tm [4], tm [5]);
- s = strchr (buffer, '\0');
- switch (wParam)
- {
- case WLOG_OPEN_FILE :
- wsprintf (s, "Open file %.40s", lParam);
- break;
-
- case WLOG_DEL_FILE :
- wsprintf (s, "Delete file %.40s", lParam);
- break;
-
- case WLOG_NEW_FILE :
- wsprintf (s, "Creating new file");
- break;
-
- case WLOG_REN_FILE :
- wsprintf (s, "Renaming file %.40s", lParam);
- break;
-
- case WLOG_OPEN_FOLDER :
- wsprintf (s, "Open folder %.40s", lParam);
- break;
-
- case WLOG_DEL_FOLDER :
- wsprintf (s, "Delete folder %.40s", lParam);
- break;
-
- case WLOG_NEW_FOLDER :
- wsprintf (s, "Create new folder", lParam);
- break;
-
- case WLOG_REN_FOLDER :
- wsprintf (s, "Rename folder %.40s", lParam);
- break;
-
- case WLOG_EDIT_FILE :
- wsprintf (s, "Edit dlist %.40s", lParam);
- break;
-
- case WLOG_ACTIVATE :
- if (lParam)
- wsprintf (s, "WinPMail restored");
- else
- wsprintf (s, "WinPMail minimized");
- break;
-
- case WLOG_NEWMESSAGE : // Ignore this one for now
- return 0;
-
- case WLOG_NEWMESSAGE2 :
- wsprintf (s, "Started new message");
- break;
-
- case WLOG_ENTERPREFS :
- wsprintf (s, "Entered preference screen %ld", lParam);
- break;
-
- case WLOG_GETMAIL :
- wsprintf (s, "Getting mail via POP3");
- break;
-
- case WLOG_SMTPSEND :
- wsprintf (s, "Sending mail via SMTP");
- break;
-
- case WLOG_LOADEXTENSION :
- return 0;
-
- case WLOG_NEWEXTENSION :
- wsprintf (s, "Loading extension %.40s", lParam);
- break;
-
- case WLOG_ERROR :
- wsprintf (s, "Error %ld reported", lParam);
- break;
-
- case WLOG_WARNING :
- wsprintf (s, "Warning %ld reported", lParam);
- break;
-
- case WLOG_OPENNEWMAIL :
- wsprintf (s, "Opening/resynching new mail folder");
- break;
-
- default :
- wsprintf (s, "Unknown event %d", wParam);
- break;
- }
-
- SendDlgItemMessage (hWnd, 101, EM_REPLACESEL, 0, (LPARAM) buffer);
- SendDlgItemMessage (hWnd, 101, EM_REPLACESEL, 0, (LPARAM) ".\r\n");
- break;
-
- case WM_COMMAND :
- fCallDefProc = FALSE;
- if (HIWORD (lParam) == EN_SETFOCUS)
- {
- // We have to trap EN_SETFOCUS messages so we know which
- // control was active last. When a menu selection is made
- // our current control will lose focus and because of a
- // curiosity in Windows' MDI management, we won't get it
- // back. Instead, WinPMail generates a WM_FM_RESTOREFOCUS
- // message which signals to us that we should set focus to
- // whatever the last active control was.
-
- last_focus = (HWND) LOWORD (lParam);
- break;
- }
-
- switch (wParam)
- {
- case 102 :
- do_logging = IsDlgButtonChecked (hWnd, 102);
- 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 = LogProc;
- 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
- }
-
-