home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast.iso / pcmag / vol11n16.zip / CLIPSERV.C < prev    next >
C/C++ Source or Header  |  1992-08-14  |  5KB  |  171 lines

  1. /* 
  2. CLIPSERV.C -- final version of clipboard server
  3.  
  4. Copyright (c) 1992 Ziff Davis Communications
  5. PC Magazine * Andrew Schulman (June 1992)
  6. */
  7.  
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <malloc.h>
  11. #include "windows.h"
  12. #include "objwnd.h"
  13. #include "clipserv.h"
  14.  
  15. #define WM_CLIPCMD      (WM_USER+1)
  16.  
  17. extern BOOL FAR PASCAL IsWinOldApTask(HANDLE);  /* undocumented */
  18.  
  19. static HWND this_hwnd, hwndNextViewer;
  20.  
  21. WORD put_clip_str(char far *s)
  22. {
  23.     WORD ret;
  24.     HANDLE h;
  25.     if (! (h = GlobalAlloc(GMEM_MOVEABLE, _fstrlen(s)+1)))
  26.         return 0;  /* insufficient memory */
  27.     while (! OpenClipboard(this_hwnd))
  28.         yield();   /* see OBJWND.C */
  29.     EmptyClipboard();
  30.     _fstrcpy(GlobalLock(h), s);
  31.     GlobalUnlock(h);
  32.     if (! (ret = SetClipboardData(CF_TEXT, h)))
  33.         GlobalFree(h);
  34.     CloseClipboard();
  35.     return ret;
  36. }
  37.  
  38. void do_run(HWND hwnd, char *cmd)
  39. {
  40.     char buf[128];
  41.     wsprintf(buf, "CLIPREPLY RUN %04X", WinExec(cmd, SW_NORMAL));
  42.     put_clip_str(buf);
  43. }
  44.  
  45. void do_dynlink(HWND hwnd, char *cmd)
  46. {
  47.     char *argv[ARG_MAX];
  48.     int argc;
  49.     argc = split(cmd, argv, ARG_MAX, " \t");
  50.     dynlink(hwnd, argc, argv);
  51. }
  52.  
  53. void do_settitle(HWND hwnd, char *cmd)
  54. {
  55.     SendMessage(hwnd, WM_SETTEXT, 0, (char far *) cmd);
  56. }
  57.  
  58. #define MATCH(s1, s2)   (strcmp((s1), (s2)) == 0)
  59. #define ISCMD(s1)       (MATCH(strupr(cmd), (s1)))
  60.  
  61. #pragma argsused
  62. long clipcmd(HWND hwnd, unsigned msg, WORD wparam, LONG lparam)
  63. {
  64.     static char buf[1024], *s=buf;
  65.     HWND owner = wparam;    // HWND of clipboard owner
  66.     char *cmd, *param;
  67.     _fstrncpy(buf, (char far *) lparam, 1024);
  68.     _ffree((char far *) lparam);
  69.     cmd = strtok(s, " \t");
  70.     param = s + strlen(cmd) + 1;
  71.     if (dynlink_error() == 0)
  72.     {
  73.         if (ISCMD("RUN"))            do_run(owner, param);
  74.         else if (ISCMD("DYNLINK"))   do_dynlink(owner, param);
  75.         else if (ISCMD("SETTITLE"))  do_settitle(owner, param);
  76.         else if (ISCMD("EXIT"))      SendMessage(hwnd, WM_DESTROY, 0, 0L);
  77.         else if (ISCMD("INSTCHECK")) put_clip_str("CLIPREPLY INSTOK");
  78.         else                         put_clip_str("CLIPREPLY CMD INVALID");
  79.     }
  80.     return 0;
  81. }
  82.  
  83. long check_clipboard(HWND hwnd, unsigned msg, WORD wparam, LONG lparam)
  84. {
  85.     char far *fp = 0;
  86.     HWND owner;
  87.     
  88.     if (hwndNextViewer)
  89.         SendMessage(hwndNextViewer, msg, wparam, lparam);
  90.     
  91.     /* only process CMDCLIP requests from OLDAPs */
  92.     owner = GetClipboardOwner();
  93.     if (IsWinOldApTask(GetWindowTask(owner)))
  94.     {
  95.         HANDLE hGMem;
  96.         if (! OpenClipboard(hwnd))
  97.             return 0;
  98.         if (hGMem = GetClipboardData(CF_TEXT))
  99.         {
  100.             LPSTR lp = GlobalLock(hGMem);
  101.             if (_fstrncmp(lp, "CMDCLIP ", 8) == 0)
  102.             {
  103.                 int len = _fstrlen(lp);
  104.                 if ((lp[len-1] == '\n') || (lp[len-1] == '\r'))
  105.                     lp[len-1] = '\0';   // remove CRLF
  106.                 if ((fp = _fmalloc(len+1)) != 0)
  107.                 {
  108.                     char far *fp1 = fp;
  109.                     char far *fp2 = &lp[8];     // remove "CMDCLIP "
  110.                     while (*fp1++ = *fp2++)
  111.                         ;
  112.                 }
  113.                 else
  114.                     ;   /* insufficient memory */
  115.             }
  116.             GlobalUnlock(hGMem);
  117.         }
  118.         CloseClipboard();
  119.     }
  120.     // don't send message until clipboard closed
  121.     if (fp)
  122.         SendMessage(hwnd, WM_CLIPCMD, owner, fp);
  123.     return 0;
  124. }
  125.  
  126. long changecbchain(HWND hwnd, unsigned msg, WORD wparam, LONG lparam)
  127. {
  128.     /* maintain linked list of clipboard viewers */
  129.     if (wparam == hwndNextViewer)
  130.         hwndNextViewer = LOWORD(lparam);
  131.     else if (hwndNextViewer)
  132.         SendMessage(hwndNextViewer, msg, wparam, lparam);
  133.     return 0;
  134. }
  135.  
  136. #pragma argsused
  137. long destroy(HWND hwnd, unsigned msg, WORD wparam, LONG lparam)
  138. {
  139.     ChangeClipboardChain(this_hwnd, hwndNextViewer);
  140.     fini_dynlink();
  141.     PostQuitMessage(0);
  142.     return 0;
  143. }
  144.  
  145. void fail(char *s)
  146. {
  147.     MessageBox(NULL, s, "CLIPSERV", MB_OK);
  148.     exit(1);
  149. }
  150.  
  151. #pragma argsused
  152. int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, 
  153.     LPSTR lpCmdLine, int nCmdShow)
  154. {
  155.     if (hPrevInstance)
  156.         fail("CLIPSERV already installed"); // only one instance
  157.             
  158.     init_dynlink(hInstance);
  159.     
  160.     this_hwnd = objwnd(hPrevInstance, hInstance, "clipserv");
  161.     hwndNextViewer = SetClipboardViewer(this_hwnd);
  162.     
  163.     on(WM_CHANGECBCHAIN, changecbchain);
  164.     on(WM_DRAWCLIPBOARD, check_clipboard);
  165.     on(WM_DESTROY, destroy);
  166.     on(WM_CLIPCMD, clipcmd);     /* user-defined message */
  167.     
  168.     return mainloop();  /* go resident */
  169. }
  170.  
  171.