home *** CD-ROM | disk | FTP | other *** search
/ PC Loisirs 18 / cd.iso / kit / mail / pmail.exe / forms / log / log.c next >
Encoding:
C/C++ Source or Header  |  1995-02-06  |  12.5 KB  |  369 lines

  1. //
  2. //  LOG.C
  3. //  Pegasus Mail for Windows extension providing a simple
  4. //  logging interface.
  5. //
  6. //  Copyright (c) 1994-95, David Harris, All Rights Reserved.
  7. //
  8. //  The author grants explicit permission for this source code to be
  9. //  used or modified as required, subject only to the conditions that
  10. //  the copyright notices above are preserved and that by using this
  11. //  code you agree that the code is provided without warranty of any
  12. //  kind, either explicit or implied, and you use it at your own
  13. //  risk.
  14. //
  15.  
  16. #define STRICT
  17. #include <windows.h>
  18. #include <bwcc.h>
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include "..\wpmforms.h"
  22.  
  23. //  Form dialogs and callbacks: a form DLL can export a function
  24. //  which WinPMail's form manager will call with Windows messages
  25. //  destined for the form's dialog or window (such as menu selections
  26. //  and so forth). The function takes the following form:
  27.  
  28. typedef long pascal far (*FORM_CALLBACK) (HWND hWnd, WORD wMsg,
  29.    WPARAM wParam, LPARAM lParam);
  30.  
  31. //  The return from a form callback is passed back through the
  32. //  Windows call chain if non-zero, otherwise the default window
  33. //  proc is called. The reasons we call this function instead of
  34. //  simply sending messages to the dialog itself are:
  35. //
  36. //   1: Dialogs can only return Boolean values, whereas the callback
  37. //      can provide the long value Windows expects to pass back
  38. //      through the calling chain.
  39. //
  40. //   2: Having a separate callback means that it is potentially
  41. //      possible to have a form which does not create a dialog.
  42. //
  43. //
  44. //  Minimum interface: the minimum interface a form DLL must provide
  45. //  is a routine called "forminit" which is exported by name. "forminit"
  46. //  has the following prototype:
  47. //
  48. //  WORD FAR PASCAL _export FORMINIT (WORD version, int variant, HWND hParent,
  49. //      char *data, HWND *hDialog, char *callback_name);
  50. //
  51. //  "version" is passed in with the version of the WinPMail forms
  52. //     manager which is running.
  53. //  "variant" indicates what type of form is required - the following
  54. //     values are currently defined:
  55. //       0: Create a form for composing a message
  56. //       1: Create a form for reading a message
  57. //  "hParent" contains the handle of the WinPMail MDI child window
  58. //     which is to contain the form.
  59. //  "data" contains any string defined as being required for the
  60. //     form in the menu interface.
  61. //  "hDialog" should be filled in with the window handle of the
  62. //     modeless dialog created within the MDI child window.
  63. //  "callback_name" (optional) should be filled in with the name of the
  64. //     function in the DLL of the exported function to which messages
  65. //     should be sent or NULL if there is none. If NULL, messages are
  66. //     sent to the dialog returned in "hDialog". You will use an
  67. //     indirect callback of this kind when your extension does not
  68. //     create a dialog within the enclosing parent window.
  69. //
  70. //  When forminit is called, the DLL should register any window
  71. //  classes it needs then create the dialog within the MDI parent
  72. //  window and size it to the correct size. On return WinPMail will
  73. //  resize the parent window to enclose the dialog correctly. The
  74. //  DLL should NOT make the dialog visible - WinPMail will do that
  75. //  as required.
  76.  
  77. #define WM_MARGIN (WM_USER + 1099)
  78. #define WM_SETDIR (WM_USER + 400)
  79. #define WM_ADDFILE (WM_USER + 401)
  80. #define WM_STARTUP (WM_USER + 403)
  81. #define WM_GET_ALIST (WM_USER + 404)
  82.  
  83. #define IDC_QUICKHELP_TO   970
  84. #define IDC_QUICKHELP_CC   971
  85.  
  86. char szFormDlgClassName [] = "bordlg_log";
  87. char do_logging = 1;
  88. HFONT hLogFont;
  89. HWND last_focus;
  90.  
  91. int register_form_classes (void);
  92.  
  93. HINSTANCE  hLibInstance;            // set in LibMain, used throughout the DLL
  94.  
  95.  
  96. #pragma warn -par
  97.  
  98. WORD FAR PASCAL _export FORMINIT (WORD version, int variant, HWND hParent,
  99.    char *data, HWND *hDialog, char *callback_name)
  100.    {
  101.    RECT r, r2;
  102.    char szBuf [80];
  103.    int i;
  104.    HWND hControl;
  105.    BYTE tm [7];
  106.  
  107.    //  First, check to see if the version of the form manager is
  108.    //  one we can work with. This check is pretty arbitrary - you
  109.    //  should probably assume that you may not work with any version
  110.    //  where the major version number is higher than the original
  111.    //  version you targeted.
  112.  
  113.    if ((version & 0xFF00) > 0x100) return 0;
  114.  
  115.    //  Now check the variant number; for this extension, we only
  116.    //  provide a COMPOSER format.
  117.  
  118.    if (variant != 0) return 0;
  119.  
  120.    (*hDialog) = CreateDialog (hLibInstance, (LPCSTR) "LOG", hParent, NULL);
  121.    if ((*hDialog) == NULL) return 0;
  122.  
  123.    if (! hLogFont)
  124.       hLogFont = CreateFont (14, 0, 0, 0, 400, FALSE,
  125.          FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS,
  126.          CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
  127.          DEFAULT_PITCH | FF_DONTCARE, "Arial");
  128.    SendMessage (GetDlgItem (*hDialog, 101), WM_SETFONT,
  129.       (WPARAM) hLogFont, (LPARAM) TRUE);
  130.  
  131.    return 1;
  132.    }
  133.  
  134.  
  135. LONG FAR PASCAL _export LogProc (HWND hWnd, WORD wMsg, 
  136.    WORD wParam, LONG lParam)
  137.    {
  138.    //  Service routine for the form's enclosed dialog. This is a
  139.    //  standard windows modeless WndProc.
  140.  
  141.    DWORD dwResult = 0;
  142.    BOOL fCallDefProc = TRUE;
  143.    char buffer [80], *s, *to, *subj;
  144.    RECT r;
  145.    HWND hControl;
  146.    HCURSOR hOldCursor;
  147.    BYTE tm [7];
  148.  
  149.    switch (wMsg)
  150.       {
  151.       case WM_FM_INIT :
  152.          CheckDlgButton (hWnd, 102, do_logging);
  153.          break;
  154.  
  155.       case WM_DESTROY :
  156.          if (hLogFont)
  157.             {
  158.             SendMessage (GetDlgItem (hWnd, 101), WM_SETFONT,
  159.                (WPARAM) 0, FALSE);
  160.             DeleteObject (hLogFont);
  161.             }
  162.          break;
  163.  
  164.       case WM_FM_INITFOCUS :
  165.          SetFocus (GetDlgItem (hWnd, 101));
  166.          break;
  167.  
  168.       case WM_FM_RESTOREFOCUS :
  169.          //  There's a glitch in the way the Windows MDI manager
  170.          //  seems to manage focus which means that we can have
  171.          //  focus taken away and not returned when the user does
  172.          //  anything outside our window. WinPMail has some quite
  173.          //  complex logic to deal with this case and will send
  174.          //  this message whenever focus should be restored in
  175.          //  our window. We set focus to the last active control
  176.          //  (which we know from trapping EN_SETFOCUS messages).
  177.  
  178.          if (last_focus) SetFocus (last_focus);
  179.          break;
  180.  
  181.       case WM_FM_SENDMAIL :
  182.          to = (char *) SendMessage (GetParent (hWnd), WM_F_GETMESSAGEFIELD, WMSG_TO, 0);
  183.          subj = (char *) SendMessage (GetParent (hWnd), WM_F_GETMESSAGEFIELD, WMSG_SUBJECT, 0);
  184.          wsprintf (buffer, "Mail sent to '%.25s', '%.25s'.\r\n", to, subj);
  185.          SendDlgItemMessage (hWnd, 101, EM_REPLACESEL, 0, (LPARAM) buffer);
  186.          break;
  187.  
  188.       case WM_FM_LOGEVENT :
  189.          if (! do_logging) break;
  190.          SendMessage (GetParent (hWnd), WM_F_GETDATETIME, 0, (LPARAM) tm);
  191.          wsprintf (buffer, "%02d:%02d:%02d : ", tm [3], tm [4], tm [5]);
  192.          s = strchr (buffer, '\0');
  193.          switch (wParam)
  194.             {
  195.             case WLOG_OPEN_FILE :
  196.                wsprintf (s, "Open file %.40s", lParam);
  197.                break;
  198.  
  199.             case WLOG_DEL_FILE :
  200.                wsprintf (s, "Delete file %.40s", lParam);
  201.                break;
  202.  
  203.             case WLOG_NEW_FILE :
  204.                wsprintf (s, "Creating new file");
  205.                break;
  206.  
  207.             case WLOG_REN_FILE :
  208.                wsprintf (s, "Renaming file %.40s", lParam);
  209.                break;
  210.  
  211.             case WLOG_OPEN_FOLDER :
  212.                wsprintf (s, "Open folder %.40s", lParam);
  213.                break;
  214.  
  215.             case WLOG_DEL_FOLDER :
  216.                wsprintf (s, "Delete folder %.40s", lParam);
  217.                break;
  218.  
  219.             case WLOG_NEW_FOLDER :
  220.                wsprintf (s, "Create new folder", lParam);
  221.                break;
  222.  
  223.             case WLOG_REN_FOLDER :
  224.                wsprintf (s, "Rename folder %.40s", lParam);
  225.                break;
  226.  
  227.             case WLOG_EDIT_FILE :
  228.                wsprintf (s, "Edit dlist %.40s", lParam);
  229.                break;
  230.  
  231.             case WLOG_ACTIVATE :
  232.                if (lParam)
  233.                   wsprintf (s, "WinPMail restored");
  234.                else
  235.                   wsprintf (s, "WinPMail minimized");
  236.                break;
  237.  
  238.             case WLOG_NEWMESSAGE :     //  Ignore this one for now
  239.                return 0;
  240.  
  241.             case WLOG_NEWMESSAGE2 :
  242.                wsprintf (s, "Started new message");
  243.                break;
  244.  
  245.             case WLOG_ENTERPREFS :
  246.                wsprintf (s, "Entered preference screen %ld", lParam);
  247.                break;
  248.  
  249.             case WLOG_GETMAIL :
  250.                wsprintf (s, "Getting mail via POP3");
  251.                break;
  252.  
  253.             case WLOG_SMTPSEND :
  254.                wsprintf (s, "Sending mail via SMTP");
  255.                break;
  256.  
  257.             case WLOG_LOADEXTENSION :
  258.                return 0;
  259.  
  260.             case WLOG_NEWEXTENSION :
  261.                wsprintf (s, "Loading extension %.40s", lParam);
  262.                break;
  263.  
  264.             case WLOG_ERROR :
  265.                wsprintf (s, "Error %ld reported", lParam);
  266.                break;
  267.  
  268.             case WLOG_WARNING :
  269.                wsprintf (s, "Warning %ld reported", lParam);
  270.                break;
  271.  
  272.             case WLOG_OPENNEWMAIL :
  273.                wsprintf (s, "Opening/resynching new mail folder");
  274.                break;
  275.  
  276.             default :
  277.                wsprintf (s, "Unknown event %d", wParam);
  278.                break;
  279.             }
  280.  
  281.          SendDlgItemMessage (hWnd, 101, EM_REPLACESEL, 0, (LPARAM) buffer);
  282.          SendDlgItemMessage (hWnd, 101, EM_REPLACESEL, 0, (LPARAM) ".\r\n");
  283.          break;
  284.  
  285.       case WM_COMMAND :
  286.          fCallDefProc = FALSE;
  287.          if (HIWORD (lParam) == EN_SETFOCUS)
  288.             {
  289.             //  We have to trap EN_SETFOCUS messages so we know which
  290.             //  control was active last. When a menu selection is made
  291.             //  our current control will lose focus and because of a
  292.             //  curiosity in Windows' MDI management, we won't get it
  293.             //  back. Instead, WinPMail generates a WM_FM_RESTOREFOCUS
  294.             //  message which signals to us that we should set focus to
  295.             //  whatever the last active control was.
  296.  
  297.             last_focus = (HWND) LOWORD (lParam);
  298.             break;
  299.             }
  300.  
  301.          switch (wParam)
  302.             {
  303.             case 102 :
  304.                do_logging = IsDlgButtonChecked (hWnd, 102);
  305.                break;
  306.             }
  307.          break;
  308.       }
  309.  
  310.    if (fCallDefProc)
  311.       dwResult = BWCCDefDlgProc (hWnd, wMsg, wParam, lParam);
  312.  
  313.    return dwResult;
  314.    }
  315.  
  316.  
  317. #pragma warn -sus
  318.  
  319. void unregister_form_classes (void)
  320.    {
  321.    //  Remove any classes associated with the form; we have the
  322.    //  same problem here as we do with registering the classes
  323.    //  for the DLL - we only want to deregister the classes on
  324.    //  the last time we're unloaded.
  325.  
  326.    if (GetModuleUsage (hLibInstance) > 1) return;      //  Not a problem
  327.    UnregisterClass (szFormDlgClassName, hLibInstance);
  328.    }
  329.  
  330.  
  331. BOOL FAR PASCAL LibMain (HINSTANCE hInst, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine)
  332.    {
  333.    WNDCLASS wc;
  334.  
  335.    if (! hLibInstance)
  336.       {
  337.       hLibInstance = hInst;
  338.       BWCCGetVersion ();      //  Forces BWCC to be dynamically loaded.
  339.  
  340.       //  Register any window classes used by the form. Forms will usually
  341.       //  register either one or occasionally two classes which define
  342.       //  the composition and reader dialogs created by the DLL.
  343.       //
  344.       //  There's a gotcha here, of course (aren't there always, in
  345.       //  Windows?)... You can't register a window class more than once,
  346.       //  so if the DLL has already been loaded and the user asks to
  347.       //  create a second instance of the form, we have to be careful
  348.       //  not to re-register the class. We do this by checking the
  349.       //  instance usage counter of the DLL - if it's greater than 1,
  350.       //  then we DON'T register the classes.
  351.  
  352.       wc.style          = WS_CHILD;
  353.       wc.lpfnWndProc    = LogProc;
  354.       wc.cbClsExtra     = 0;
  355.       wc.cbWndExtra     = DLGWINDOWEXTRA;
  356.        wc.hInstance      = hLibInstance;
  357.        wc.hIcon          = NULL;
  358.       wc.hCursor        = LoadCursor (NULL, IDC_ARROW);
  359.       wc.hbrBackground  = (HBRUSH) (COLOR_WINDOW + 1);
  360.       wc.lpszMenuName   = NULL;
  361.       wc.lpszClassName  = szFormDlgClassName;
  362.       if (! RegisterClass (&wc))
  363.          MessageBeep (0);
  364.       }
  365.  
  366.    return (TRUE);             // Initialization went OK
  367.    }
  368.  
  369.