home *** CD-ROM | disk | FTP | other *** search
- /*
- DDSERVER.C -- Demonstrates server end of Drag and Drop protocol
- in both 3.0 and 3.1 using DragObject
-
- Copyright (c) Dave Maxey 1992
-
- From Chapter 6 of "Undocumented Windows" (Addison-Wesley 1992)
- by Andrew Schulman, Dave Maxey and Matt Pietrek
-
- Build using: WINIOBC DDSERVER (for Borland C++ v3.00)
- WINIOMS DDSERVER (for Microsoft C/SDK)
- */
-
- #include <windows.h>
- #include <string.h>
- #include "wmhandlr.h"
- #include "winio.h"
- #include "dragdrop.h"
- #ifndef __BORLANDC__
- #define MK_FP(a,b) ((void far *)(((unsigned long)(a) << 16) | (b)))
- #endif
-
- #define ID_HELP 1
-
-
- void usage_help(HWND hwnd, WORD wId)
- {
- HWND hSave;
- static HWND hwndHelp = NULL;
-
- if (IsWindow(hwndHelp))
- {
- BringWindowToTop(hwndHelp);
- return;
- }
-
- if (! (hwndHelp = winio_window("HELP", 1, WW_HASMENU)))
- return;
-
- hSave = winio_setcurrent(hwndHelp);
-
- winio_setpaint(hwndHelp, FALSE);
-
- printf(
- "At any stage, in response to the prompt,\n"
- "\tyou may enter a list of one or more\n"
- "\tfilenames or directories. If more\n"
- "\tthan one is entered, each filename\n"
- "\tin the list should be separated by\n"
- "\ta space, eg:\n"
- "\t\tfile.001 file.002\n"
- "\n"
- "The currently defined files may be dragged\n"
- "\tout of DDSERVER into, for example the\n"
- "\tDDCLIENT program, or Program Manager.\n"
- "\n"
- "Note that when the program starts, no files\n"
- "\thave yet been defined, so dragging is\n"
- "\tnot possible until you have entered\n"
- "\tat least one file or directory.\n"
- "\n"
- "For more information, please refer to the\n"
- "\tDragObject entry in Chapter 6 of\n"
- "\t\"Undocumented Windows\".\n");
-
- winio_setpaint(hwndHelp, TRUE);
-
- winio_home(hwndHelp);
-
- winio_setcurrent(hSave);
- }
-
-
- /* Undocumented function DRAGOBJ */
- /* Compile with 3.0 SDK, run with 3.0/3.1 */
- extern DWORD FAR PASCAL DragObject(HWND hwndScope, HWND hwndOwner,
- WORD wFlags, WORD hOfstruct, char *szList, HCURSOR hDragCursor);
-
- char filelist[128];
- char szSaveTitle[128];
- WMHANDLER prev_lbuttondown, prev_lbuttonup, prev_mousemove;
- HCURSOR hDragCursor;
- BOOL bDrag = FALSE;
- WORD wDragType;
- HANDLE hOfstruct = 0;
- LPOFSTRUCT lpof;
- int cObjs;
- char *szArgv0;
-
- #include "checkord.c"
-
- WORD verr(WORD sel)
- {
- _asm mov ax, 1
- _asm verr word ptr sel
- _asm je short ok
- _asm dec ax
- ok:;
- }
-
- BOOL do_DragObject(void)
- {
- DWORD lRet;
-
- puts("Dragging...");
- GetWindowText(__hMainWnd, szSaveTitle, sizeof(szSaveTitle));
- winio_settitle(__hMainWnd, szArgv0);
- lRet = DragObject(GetDesktopWindow(), __hMainWnd, wDragType,
- hOfstruct, (char *) &filelist, hDragCursor);
- winio_settitle(__hMainWnd, szSaveTitle);
- printf("Returned %08lX\n", lRet);
-
- switch (lRet)
- {
- case DRAG_PRNT :
- printf("Dropped onto a print oriented app.\n"); break;
- case DRAG_FILE :
- printf("Dropped onto a file oriented app.\n"); break;
- case 1 :
- printf("Drop accepted (rejected if v3.1).\n"); break;
- default :
- printf("Drop not completed.\n"); return FALSE;
- }
- return TRUE;
- }
-
-
- void do_31Protocol(void)
- {
- DWORD pntDrop;
- HANDLE hDropInfo;
- DWORD dwSizeBlk;
- LPDROPINFO lpDropInfo;
- int i;
- LPSTR lpsz;
- char *sz;
- char szBuf[80];
- HWND hwndDrop;
-
- pntDrop = GetMessagePos();
-
- // Estimate size of allocation needed. This should be plenty.
- dwSizeBlk = (DWORD) cObjs * 128;
-
- hDropInfo =
- GlobalAlloc(GMEM_DDESHARE | GMEM_ZEROINIT, dwSizeBlk);
-
- lpDropInfo = (LPDROPINFO) GlobalLock(hDropInfo);
-
- lpDropInfo->wOfsFirst = 8;
- lpDropInfo->xDrop = LOWORD(pntDrop);
- lpDropInfo->yDrop = HIWORD(pntDrop);
- lpsz = (LPSTR) &lpDropInfo->chBuffer;
-
- // WinFile emulation!
- lstrcpy((LPSTR) &szBuf, szArgv0);
-
- // remove filename to leave \ terminated path
- *(strrchr(szBuf, '\\') + 1) = 0;
- sz = filelist;
-
- // copy in complete pathed filenames
- for (i = 0; i < cObjs; i++)
- {
- lstrcpy(lpsz, (LPSTR) &szBuf);
- lstrcat(lpsz, (LPSTR) strtok(sz, " "));
- lpsz = (LPSTR) ((DWORD) lpsz + lstrlen(lpsz) + 1);
- sz = NULL;
- }
- for (; i > 0; i--)
- filelist[strlen(filelist)] = ' ';
-
- GlobalUnlock(hDropInfo);
-
- // Find out who to send WM_DROPFILES to
- hwndDrop = WindowFromPoint(MAKEPOINT(pntDrop));
-
- SendMessage(hwndDrop, WM_DROPFILES, hDropInfo, 0L);
-
- // In case the client app doesn't follow the rules
- if (verr(hDropInfo))
- GlobalFree(hDropInfo);
- }
-
-
- BOOL free_sel(HWND hwnd)
- {
- if (hOfstruct)
- GlobalFree(hOfstruct);
- return TRUE;
- }
-
- long my_lbuttondown(HWND hwnd, WORD wMsg, WORD wParam,
- DWORD lParam)
- {
- // Only allow dragging if there is something to drag
- if (filelist[0])
- bDrag = TRUE;
- return (*prev_lbuttondown)(hwnd, wMsg, wParam, lParam);
- }
-
- long my_lbuttonup(HWND hwnd, WORD wMsg, WORD wParam,
- DWORD lParam)
- {
- bDrag = FALSE;
- return (*prev_lbuttonup)(hwnd, wMsg, wParam, lParam);
- }
-
- long my_mousemove(HWND hwnd, WORD wMsg, WORD wParam,
- DWORD lParam)
- {
- if (bDrag)
- {
- // Avoid 'reentrancy'
- bDrag = FALSE;
- if (do_DragObject())
- do_31Protocol();
- }
- return (*prev_mousemove)(hwnd, wMsg, wParam, lParam);
- }
-
- int main(int argc, char *argv[])
- {
- int i;
- char *sz;
-
- if (! CheckOrdName("DragObject", "USER", 464))
- return 0;
-
- winio_settitle(__hMainWnd, "Drag'n'Drop Server");
- winio_about("DDSERVER"
- "\nDemonstrates server end of Drag and Drop protocol"
- "\nin both 3.0 and 3.1 using DragObject"
- "\n\nFrom Chapter 6 of"
- "\n\"Undocumented Windows\" (Addison-Wesley, 1992)"
- "\nby Andrew Schulman, David Maxey and Matt Pietrek"
- );
-
- winio_setmenufunc(__hMainWnd, ID_HELP, (MENU_FUNC) usage_help);
-
- InsertMenu(winio_hmenuhelp(__hMainWnd),
- 0, MF_STRING | MF_ENABLED | MF_BYPOSITION,
- ID_HELP, "&Usage");
-
- // for later WinFile emulation (!)
- szArgv0 = argv[0];
-
- prev_lbuttondown = wmhandler_set(__hMainWnd, WM_LBUTTONDOWN,
- (WMHANDLER) my_lbuttondown);
- prev_lbuttonup = wmhandler_set(__hMainWnd, WM_LBUTTONUP,
- (WMHANDLER) my_lbuttonup);
- prev_mousemove = wmhandler_set(__hMainWnd, WM_MOUSEMOVE,
- (WMHANDLER) my_mousemove);
- winio_onclose(__hMainWnd, (DESTROY_FUNC) free_sel);
-
- // Use the class icon for the drag cursor
- hDragCursor = GetClassWord(__hMainWnd, GCW_HICON);
-
-
- while (TRUE)
- {
- printf("Enter file(s) and/or dir(s)\n"
- "separated by a single space:\n");
- gets(filelist);
- strupr(filelist);
-
- // Ensure it is space char terminated
- if (filelist[strlen(filelist) - 1] != ' ')
- strcat(filelist, " ");
- printf("List is <%s>\n", filelist);
- for (i = 0, cObjs = 0; filelist[i]; i++)
- if (filelist[i] == ' ') cObjs++;
-
- // Free up the last allocation if necessary
- if (hOfstruct)
- {
- GlobalFree(hOfstruct);
- hOfstruct = 0;
- }
-
- // Detect the 'object' type
- if (cObjs > 1)
- wDragType = DRAGOBJ_MULTIPLE;
- else
- if (filelist[strlen(filelist) - 2] == '\\')
- wDragType = DRAGOBJ_DIRECTORY;
- else
- {
- // Allocate ourselves a global block for a single file
- hOfstruct = GlobalAlloc(GMEM_DDESHARE, sizeof(OFSTRUCT));
- lpof = (LPOFSTRUCT) GlobalLock(hOfstruct);
- OpenFile((LPSTR) &filelist, lpof, OF_PARSE);
- printf("Filename parsed to: %Fs\n",
- (LPSTR) &lpof->szPathName);
- if (((sz = strchr(filelist, '.')) != NULL) &&
- ((strncmp((char *) (sz+1), "EXE", 3) == 0) ||
- (strncmp((char *) (sz+1), "BAT", 3) == 0) ||
- (strncmp((char *) (sz+1), "COM", 3) == 0)))
- wDragType = DRAGOBJ_PROGRAM;
- else
- wDragType = DRAGOBJ_DATA;
- wDragType |= DRAGOBJ_EXTERNAL;
- GlobalUnlock(hOfstruct);
- }
- }
- return 0;
- }
-