home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l430 / 1.ddi / CHAP6.ZIP / DDCLIENT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-09  |  7.4 KB  |  236 lines

  1. /*
  2.     DDCLIENT.C -- Illustrates 3.0 and 3.1 Drag and Drop protocols
  3.  
  4.     Copyright (c) Dave Maxey 1992
  5.  
  6.     From Chapter 6 of "Undocumented Windows" (Addison-Wesley 1992)
  7.     by Andrew Schulman, Dave Maxey and Matt Pietrek
  8.  
  9.     Build using: WINIOBC DDCLIENT (for Borland C++ v3.00)
  10.                  WINIOMS DDCLIENT (for Microsoft C/SDK)
  11.                      
  12.     DDCLIENT.C is slightly changed from the way it appears in the book
  13.     because the DRAGOBJ_ constants (from DRAGDROP.H) have been split out. 
  14.     The DDCLIENT.C in the text incorrectly assumed that DRAGOBJ_PROGRAM, 
  15.     for example, included the DRAGOBJ_EXTERNAL flag.
  16. */
  17.  
  18. #include <windows.h> 
  19. #include <string.h> 
  20. #include <dos.h> 
  21. #include "wmhandlr.h" 
  22. #include "winio.h" 
  23. #include "dragdrop.h"
  24. #ifndef __BORLANDC__
  25. #define MK_FP(a,b)  ((void far *)(((unsigned long)(a) << 16) | (b)))
  26. #endif
  27.  
  28. BOOL tInClientArea = FALSE;
  29.  
  30. // We also get documented drag and drop in 3.1
  31. // Here we don't use the documented API, but rather manipulate the
  32. // undocumented DROPINFO structure directly.
  33. long my_dropfiles(HWND hwnd, WORD wMsg, WORD wParam, DWORD lParam)
  34.     {
  35.     LPDROPINFO lpDropInfo;
  36.     int i = 0;
  37.     LPSTR lpszFile;
  38.     
  39.     printf("WM_DROPFILES received\n");
  40.     
  41.     lpDropInfo = (LPDROPINFO) GlobalLock(wParam);
  42.     lpszFile = (LPSTR) &lpDropInfo->chBuffer;
  43.     
  44.     while (*lpszFile)
  45.         {
  46.         i++;
  47.         printf("%02d File name : %Fs\n", i, lpszFile);
  48.         lpszFile = (LPSTR) ((DWORD) lpszFile + lstrlen(lpszFile) + 1);
  49.         }
  50.     
  51.     GlobalUnlock(wParam);
  52.  
  53.     // Replicates the functionality of DragFinish!
  54.     GlobalFree(wParam);
  55.     
  56.     return 1;
  57.     }
  58.  
  59. // Handles WM_DROPOBJECT - Sent when user releases left button
  60. // inside our client area.
  61. long drop_handler(HWND h, WORD wMsg, WORD wParam, DWORD lParam)
  62.     {
  63.     LPOFSTRUCT lpofstruct;
  64.     LPDRAGINFO lpDragInfo;
  65.     LPSTR lpTail, lpHead, lpFileName;
  66.     WORD wSourceDS;
  67.     int i = 0;
  68.     char szPath[120];
  69.     char *szFile;
  70.     BOOL bPath;
  71.     static const char *szObjType[] = {"executable", "data/text file",
  72.         "directory", "multiple files/dirs"};
  73.     
  74.     // Reset ready for next drag/drop
  75.     tInClientArea = FALSE;
  76.     
  77.     lpDragInfo = (LPDRAGINFO) lParam;
  78.     
  79.     // Get source app (File Manager, presumably) DS
  80.     wSourceDS = (GetWindowWord(lpDragInfo->hwndSource, GWW_HINSTANCE)
  81.         & 0xfffc) | 1;
  82.  
  83.     // Use wFlags field (without top bit, and decremented to
  84.     // zero-base) as index to get object type string.
  85.     printf("Drop in progress...\n"
  86.         "------------------------------\n"
  87.         "Object type  : %s\n",
  88.         szObjType[(lpDragInfo->wFlags - 1) & 3]);
  89.     
  90.     // hOfstruct only non-NULL when a single file, and
  91.     // extension has association
  92.     if (lpDragInfo->hOfstruct)
  93.         {
  94.         lpofstruct = (LPOFSTRUCT) MK_FP(lpDragInfo->hOfstruct, 0);
  95.         printf("01 File name : %Fs\n\t(Extension has association)\n"
  96.             "------------------------------\n"
  97.             "Drop completed successfully\n\n",
  98.             lpofstruct->szPathName);
  99.         
  100.         return DRAG_FILE;
  101.         }
  102.  
  103.     // This returns a list of files and complete directory paths
  104.     // by forming a far pointer into the source application's near
  105.     // heap and parsing to space characters. If a list item has no
  106.     // path, we assume that the source app is or emulates FileMan,
  107.     // and use the source window title to obtain the directory.
  108.     // This technique is not only a hack, but it only works in v3.0!
  109.     // In 3.1 we can use the documented API.
  110.     
  111.     if ((GetWindowText(lpDragInfo->hwndSource,
  112.             (LPSTR) szPath, sizeof(szPath))) ||
  113.         (GetWindowText(GetParent(lpDragInfo->hwndSource),
  114.             (LPSTR) szPath, sizeof(szPath))))
  115.         {
  116.         szFile = szPath + strlen(szPath);
  117.         while (szFile && (*szFile != '\\')) szFile--;
  118.         ++szFile;
  119.         }
  120.     else
  121.         szFile = szPath;
  122.  
  123.     lpTail = (LPSTR) MK_FP(wSourceDS, (WORD) (lpDragInfo->szList));
  124.     
  125.     do {
  126.         // Separate out next 'token', record whether it contains a path
  127.         lpHead = lpTail;
  128.         bPath = FALSE;
  129.         while (*lpTail != ' ')
  130.             if (*lpTail++ == '\\')
  131.                 bPath = TRUE;
  132.  
  133.         *lpTail = 0;
  134.         
  135.         // if list item has no path, use szPath.
  136.         if (! bPath)
  137.             {
  138.             lstrcpy((LPSTR) szFile, lpHead);
  139.             lpFileName = (LPSTR) &szPath;
  140.             }
  141.         else
  142.             lpFileName = lpHead;
  143.             
  144.         printf("%02d %s : %Fs\n",
  145.             ++i,
  146.             bPath ? "Directory" : "File name",
  147.             lpFileName);
  148.         
  149.         *lpTail++ = ' ';
  150.         
  151.         } while (*lpTail);
  152.  
  153.     printf("-----------------------------\n"
  154.             "Drop completed successfully\n\n");
  155.  
  156.     return DRAG_FILE;
  157.     }
  158.  
  159.  
  160. // Handles WM_QUERYDROPOBJECT - Sent whenever the object being
  161. // dragged moves over our window.
  162. long query_handler(HWND h, WORD w, WORD wParam, DWORD lParam)
  163.     {
  164.     LPDRAGINFO lpDragInfo = (LPDRAGINFO) lParam;
  165.  
  166.     // Dragged icon has reached client area (wParam == 0).
  167.     // Since lParam is a DRAGINFOPTR, we can decide whether we
  168.     // want to accept on the basis of file-type, and whether or
  169.     // not 'associated'. This code is only here to illustrate
  170.     // the point, and is a pointless and redundant test,
  171.     // and accepts all object types.
  172.     if ((wParam == 0) &&
  173.         ((lpDragInfo->wFlags == DRAGOBJ_PROGRAM | DRAGOBJ_EXTERNAL) ||
  174.         (lpDragInfo->wFlags == DRAGOBJ_DATA | DRAGOBJ_EXTERNAL) ||
  175.         (lpDragInfo->wFlags == DRAGOBJ_DIRECTORY | DRAGOBJ_EXTERNAL) ||
  176.         (lpDragInfo->wFlags == DRAGOBJ_MULTIPLE | DRAGOBJ_EXTERNAL) ||
  177.         (lpDragInfo->hOfstruct != NULL)))
  178.         return 1;
  179.     else
  180.         return 0;
  181.     }
  182.  
  183.  
  184. // Handles WM_DRAGSELECT - Sent whenever the object being
  185. // dragged moves into or out of our client area. We don't actually
  186. // need to handle this one.
  187. long select_handler(HWND h, WORD w1, WORD w2, DWORD l)
  188.     {
  189.     printf("Drag %s\n",
  190.         (tInClientArea ^= 1) ? "in progress" : "suspended");
  191.     
  192.     return 1;
  193.     }
  194.             
  195. // Handles WM_DRAGMOVE - Sent whenever the object being
  196. // dragged is dragged after we have signaled acceptance of it.
  197. // We don't actually need to handle this one, either.
  198. long move_handler(HWND h, WORD w1, WORD w2, DWORD l)
  199.     {
  200.     return 1;
  201.     }
  202.  
  203.  
  204. int main() 
  205.     {
  206.     winio_settitle(__hMainWnd, "Drag'n'Drop Client");
  207.  
  208.     winio_about("DDCLIENT"
  209.         "\nIllustrates 3.0 and 3.1 Drag and Drop protocols"
  210.         "\n\nFrom Chapter 6 of"
  211.         "\n\"Undocumented Windows\" (Addison-Wesley, 1992)"
  212.         "\nby Andrew Schulman, David Maxey and Matt Pietrek"
  213.         );
  214.     
  215.     wmhandler_set(__hMainWnd, WM_DROPOBJECT,
  216.         (WMHANDLER) drop_handler);
  217.     wmhandler_set(__hMainWnd, WM_QUERYDROPOBJECT,
  218.         (WMHANDLER) query_handler);
  219.     wmhandler_set(__hMainWnd, WM_DRAGSELECT,
  220.         (WMHANDLER) select_handler);
  221.     wmhandler_set(__hMainWnd, WM_DRAGMOVE,
  222.         (WMHANDLER) move_handler);
  223.     wmhandler_set(__hMainWnd, WM_DROPFILES,
  224.         (WMHANDLER) my_dropfiles);
  225.     
  226.     printf(
  227.         "This program lists any files dragged over and\n"
  228.         "dropped on it from the accompanying DDSERVER\n"
  229.         "program, or from File Manager, or any other\n"
  230.         "program that uses the undocumented 3.0 or\n"
  231.         "partially documented 3.1 protocol.\n\n"
  232.         "Waiting for drag'n'drop messages...\n\n");
  233.     
  234.     return 0;
  235.     }
  236.