source: trunk/dll/draglist.c@ 606

Last change on this file since 606 was 606, checked in by Gregg Young, 18 years ago

Drag drop work around for number of files limitation in PM

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.6 KB
Line 
1
2/***********************************************************************
3
4 $Id: draglist.c 606 2007-04-13 21:30:27Z gyoung $
5
6 Drag drop support
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2001, 2002 Steven H.Levine
10
11 16 Oct 02 SHL DoFileDrag: don't free stack
12 26 Jul 06 SHL Check more run time errors
13 06 Apr 07 GKY Work around PM DragInfo and DrgFreeDISH limits
14 06 Apr 07 GKY Add DeleteDragitemStrHandles
15 06 Apr 07 GKY Add some error checking in drag/drop
16
17***********************************************************************/
18
19#define INCL_DOS
20#define INCL_WIN
21#include <os2.h>
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <ctype.h>
27
28#include "fm3dll.h"
29
30static PSZ pszSrcFile = __FILE__;
31
32#pragma alloc_text(DRAGLIST,DragOne,DoFileDrag,DragList,PickUp,DeleteDragitemStrHandles)
33/* work around for DrgDeleteDraginfoStrHandles
34which seems to fail with a large number of strings */
35BOOL DeleteDragitemStrHandles (PDRAGINFO pDInfo)
36{
37 PDRAGITEM pDItem;
38 ULONG cDitem;
39 UINT i = 0;
40 APIRET rc;
41
42 cDitem = DrgQueryDragitemCount(pDInfo);
43 for (; i < (UINT)cDitem; i++){
44 pDItem = DrgQueryDragitemPtr(pDInfo, i);
45 if (!pDItem)
46 return FALSE;
47 else {
48 DrgDeleteStrHandle(pDItem->hstrType);
49 DrgDeleteStrHandle(pDItem->hstrRMF);
50 DrgDeleteStrHandle(pDItem->hstrContainerName);
51 rc = DrgDeleteStrHandle(pDItem->hstrSourceName);
52 if (!rc)
53 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
54 "DrgDeleteStrHandle");
55 DrgDeleteStrHandle(pDItem->hstrTargetName);
56 }
57 } // for
58 return TRUE;
59}
60
61HWND DragOne(HWND hwndCnr, HWND hwndObj, CHAR * filename, BOOL moveok)
62{
63
64 DRAGITEM DItem;
65 HWND hDrop = 0;
66 DRAGIMAGE fakeicon;
67 PDRAGINFO pDInfo;
68 FILESTATUS3 fs3;
69 CHAR szDir[CCHMAXPATH], szFile[CCHMAXPATH], *p;
70
71 if (filename && *filename) {
72 if ((IsRoot(filename) && IsValidDrive(*filename)) ||
73 !DosQueryPathInfo(filename, FIL_STANDARD, &fs3, sizeof(fs3))) {
74 strcpy(szDir, filename);
75 p = szDir;
76 while (*p) {
77 if (*p == '/')
78 *p = '\\';
79 p++;
80 }
81 p = strrchr(szDir, '\\');
82 if (p) {
83 *p = 0;
84 p++;
85 strcpy(szFile, p);
86 strcat(szDir, "\\");
87 }
88 else {
89 strcpy(szFile, filename);
90 *szDir = 0;
91 }
92 memset(&fakeicon, 0, sizeof(DRAGIMAGE));
93 fakeicon.hImage = (IsRoot(filename) ||
94 (fs3.attrFile & FILE_DIRECTORY) != 0) ?
95 hptrDir : hptrFile;
96 memset(&DItem, 0, sizeof(DRAGITEM));
97 DItem.hwndItem = (hwndObj) ? hwndObj : hwndCnr; /* Initialize DRAGITEM */
98 // DItem.hwndItem = hwndCnr;
99 DItem.ulItemID = 1;
100 DItem.hstrType = DrgAddStrHandle(DRT_UNKNOWN);
101 DItem.hstrRMF = DrgAddStrHandle(DRMDRFLIST);
102 DItem.hstrContainerName = DrgAddStrHandle(szDir);
103 DItem.hstrSourceName = DrgAddStrHandle(szFile);
104 if (!DItem.hstrSourceName)
105 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
106 "DrgQueryStrName");
107 DItem.hstrTargetName = DrgAddStrHandle(szFile);
108 DItem.fsControl = 0;
109 if (IsRoot(filename) || (fs3.attrFile & FILE_DIRECTORY) != 0)
110 DItem.fsControl |= DC_CONTAINER;
111 if (IsFullName(filename) &&
112 (driveflags[toupper(*filename) - 'A'] & DRIVE_REMOVABLE))
113 DItem.fsControl |= DC_REMOVEABLEMEDIA;
114 DItem.fsSupportedOps = DO_COPYABLE | DO_LINKABLE;
115 if (moveok && IsFullName(filename) &&
116 !(driveflags[toupper(*filename) - 'A'] & DRIVE_NOTWRITEABLE))
117 DItem.fsSupportedOps |= DO_MOVEABLE;
118 if (IsRoot(filename))
119 DItem.fsSupportedOps = DO_LINKABLE;
120 fakeicon.cb = sizeof(DRAGIMAGE);
121 fakeicon.cptl = 0;
122 fakeicon.fl = DRG_ICON;
123 fakeicon.sizlStretch.cx = 32;
124 fakeicon.sizlStretch.cy = 32;
125 fakeicon.cxOffset = -16;
126 fakeicon.cyOffset = 0;
127 pDInfo = DrgAllocDraginfo(1); /* Allocate DRAGINFO */
128 if (pDInfo) {
129 if (IsFullName(filename) &&
130 (driveflags[toupper(*filename) - 'A'] & DRIVE_NOTWRITEABLE))
131 pDInfo->usOperation = DO_COPY;
132 else
133 pDInfo->usOperation = DO_DEFAULT;
134 if (IsRoot(filename))
135 pDInfo->usOperation = DO_LINK;
136 pDInfo->hwndSource = (hwndObj) ? hwndObj : hwndCnr;
137 // pDInfo->hwndSource = hwndCnr;
138 DrgSetDragitem(pDInfo, /* Set item in DRAGINFO */
139 &DItem, /* Pointer to DRAGITEM */
140 sizeof(DRAGITEM), /* Size of DRAGITEM */
141 0); /* Index of DRAGITEM */
142 WinSetFocus(HWND_DESKTOP, HWND_DESKTOP);
143 hDrop = DrgDrag(hwndCnr, /* Initiate drag */
144 pDInfo, /* DRAGINFO structure */
145 &fakeicon, 1L, VK_ENDDRAG, /* End of drag indicator */
146 (PVOID) NULL); /* Reserved */
147 //if (hDrop == NULLHANDLE)
148 if (!DeleteDragitemStrHandles(pDInfo)) //)
149 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
150 "DeleteDragistr");
151 DrgDeleteDraginfoStrHandles (pDInfo);
152 DrgFreeDraginfo(pDInfo); /* Free DRAGINFO struct */
153 WinSetWindowPos(hwndCnr, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE);
154 }
155 }
156 }
157 return hDrop;
158}
159
160HWND DoFileDrag(HWND hwndCnr, HWND hwndObj, PCNRDRAGINIT pcd, CHAR * arcfile,
161 CHAR * directory, BOOL moveok)
162{
163 /* drag files from a container */
164
165 BOOL isdir, rooting = FALSE;
166 PCNRITEM pci;
167 register CHAR *p;
168 INT attribute = CRA_CURSORED;
169 PDRAGINFO pDInfo = NULL;
170 DRAGITEM **ppDItem = NULL, **ppTest;
171 PCNRITEM pciRec = (PCNRITEM) pcd->pRecord;
172 HWND hDrop = 0;
173 register ULONG ulNumfiles = 0L, numdragalloc = 0L, Select, ulNumIcon = 0;
174 CHAR szFile[CCHMAXPATH], szBuffer[CCHMAXPATH];
175 DRAGIMAGE *padiIcon = NULL, *padiTest, diFakeIcon;
176 APIRET rc;
177
178 fExceedPMDrgLimit = 0;
179 if (!pciRec && directory && *directory)
180 return DragOne(hwndCnr, hwndObj, directory, moveok);
181
182 if (!pciRec) {
183 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS,
184 MPFROMLONG(CMA_FIRST),
185 MPFROMSHORT(attribute));
186 if (pci && (INT) pci > -1) {
187 if (pci->rc.flRecordAttr & CRA_SELECTED) {
188 attribute = CRA_SELECTED;
189 pci =
190 WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
191 MPFROMSHORT(attribute));
192 }
193 }
194 }
195 else {
196 pci = pciRec;
197 attribute = (pci->rc.flRecordAttr & CRA_SELECTED) ? CRA_SELECTED : 0;
198 if (attribute) {
199 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
200 MPFROMSHORT(attribute));
201 }
202 }
203
204 Select = 0L;
205 while (pci && (INT) pci > -1) {
206 if (!(pci->rc.flRecordAttr & CRA_FILTERED)) {
207 if (IsRoot(pci->szFileName) && !IsValidDrive(*pci->szFileName))
208 goto Continuing;
209 if (!arcfile) {
210 strcpy(szBuffer, pci->szFileName);
211 p = strrchr(szBuffer, '\\');
212 if (p) {
213 p++;
214 strcpy(szFile, p);
215 *p = 0;
216 }
217 else
218 goto Continuing;
219 }
220 else
221 strcpy(szFile, pci->szFileName);
222 }
223 if (!arcfile) {
224 // Filesystem object
225 isdir = ((pci->attrFile & FILE_DIRECTORY) != 0);
226 if (ulNumfiles + 2L > numdragalloc) {
227 if (!padiIcon) {
228 padiTest =
229 xrealloc(padiIcon, sizeof(DRAGIMAGE) * (numdragalloc + 4L),
230 pszSrcFile, __LINE__);
231 if (padiTest)
232 padiIcon = padiTest;
233 else
234 break;
235 }
236 else if (!ulNumIcon) {
237 padiIcon[ulNumfiles].cb = sizeof(DRAGIMAGE);
238 padiIcon[ulNumfiles].cptl = 0;
239 padiIcon[ulNumfiles].hImage = hptrLast;
240 padiIcon[ulNumfiles].fl = DRG_ICON;
241 padiIcon[ulNumfiles].sizlStretch.cx = 32;
242 padiIcon[ulNumfiles].sizlStretch.cy = 32;
243 padiIcon[ulNumfiles].cxOffset = -16 + (ulNumfiles * 4);
244 padiIcon[ulNumfiles].cyOffset = 0 + (ulNumfiles * 7);
245 ulNumIcon = ulNumfiles + 1;
246 }
247 ppTest =
248 xrealloc(ppDItem, sizeof(DRAGITEM *) * (numdragalloc + 4L),
249 pszSrcFile, __LINE__);
250 if (ppTest) {
251 ppDItem = ppTest;
252 numdragalloc += 4L;
253 }
254 else
255 break;
256 }
257 ppDItem[ulNumfiles] = xmalloc(sizeof(DRAGITEM), pszSrcFile, __LINE__);
258 if (ppDItem[ulNumfiles]) {
259 if (!ulNumIcon) {
260 padiIcon[ulNumfiles].cb = sizeof(DRAGIMAGE);
261 padiIcon[ulNumfiles].cptl = 0;
262 padiIcon[ulNumfiles].hImage = pci->rc.hptrIcon;
263 if (!padiIcon[ulNumfiles].hImage)
264 padiIcon[ulNumfiles].hImage = (isdir) ? hptrDir : hptrFile;
265 padiIcon[ulNumfiles].fl = DRG_ICON;
266 padiIcon[ulNumfiles].sizlStretch.cx = 32;
267 padiIcon[ulNumfiles].sizlStretch.cy = 32;
268 padiIcon[ulNumfiles].cxOffset = -16 + (ulNumfiles * 3);
269 padiIcon[ulNumfiles].cyOffset = 0 + (ulNumfiles * 6);
270 }
271 memset(ppDItem[ulNumfiles], 0, sizeof(DRAGITEM));
272 ppDItem[ulNumfiles]->hwndItem = (hwndObj) ? hwndObj : hwndCnr; /* Initialize DRAGITEM */
273 ppDItem[ulNumfiles]->hwndItem = hwndCnr;
274 ppDItem[ulNumfiles]->ulItemID = (ULONG) pci;
275 ppDItem[ulNumfiles]->hstrType = DrgAddStrHandle(DRT_UNKNOWN);
276 ppDItem[ulNumfiles]->hstrRMF = DrgAddStrHandle(DRMDRFLIST);
277 ppDItem[ulNumfiles]->hstrContainerName = DrgAddStrHandle(szBuffer);
278 ppDItem[ulNumfiles]->hstrSourceName = DrgAddStrHandle(szFile);
279 if (!ppDItem[ulNumfiles]->hstrSourceName){
280 DrgDeleteStrHandle(ppDItem[ulNumfiles]->hstrType);
281 DrgDeleteStrHandle(ppDItem[ulNumfiles]->hstrRMF);
282 DrgDeleteStrHandle(ppDItem[ulNumfiles]->hstrContainerName);
283 DrgDeleteStrHandle(ppDItem[ulNumfiles]->hstrSourceName);
284 xfree(ppDItem[ulNumfiles]);
285 fExceedPMDrgLimit = ulNumfiles - 1;
286 break;
287 }
288 /*Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
289 "DrgAddStrHandle");*/
290 ppDItem[ulNumfiles]->hstrTargetName = DrgAddStrHandle(szFile);
291 ppDItem[ulNumfiles]->fsControl = (isdir) ? DC_CONTAINER : 0;
292 if (IsFullName(pci->szFileName) &&
293 (driveflags[toupper(*pci->szFileName) - 'A'] & DRIVE_REMOVABLE))
294 ppDItem[ulNumfiles]->fsControl |= DC_REMOVEABLEMEDIA;
295 ppDItem[ulNumfiles]->fsSupportedOps = DO_COPYABLE | DO_LINKABLE;
296 if (moveok && IsFullName(pci->szFileName) &&
297 !(driveflags[toupper(*pci->szFileName) - 'A'] &
298 DRIVE_NOTWRITEABLE))
299 ppDItem[ulNumfiles]->fsSupportedOps |= DO_MOVEABLE;
300 if (IsRoot(pci->szFileName)) {
301 ppDItem[ulNumfiles]->fsSupportedOps = DO_LINKABLE;
302 rooting = TRUE;
303 }
304 //if (ulNumfiles >= 2000){
305 // pDInfo = DrgAllocDraginfo(ulNumfiles);
306 // fExceedPMDrgLimit = TRUE;
307 // goto Thatsall;
308 // }
309 ulNumfiles++;
310 ppDItem[ulNumfiles] = NULL;
311 }
312 else
313 break;
314 }
315 else {
316 // Archive object
317 if (ulNumfiles + 3L > numdragalloc) {
318 ppTest =
319 xrealloc(ppDItem, sizeof(DRAGITEM *) * (numdragalloc + 5L),
320 pszSrcFile, __LINE__);
321 if (!ppTest)
322 break;
323 else {
324 ppDItem = ppTest;
325 numdragalloc += 5L;
326 }
327 }
328 ppDItem[ulNumfiles] = xmalloc(sizeof(DRAGITEM), pszSrcFile, __LINE__);
329 if (!ppDItem[ulNumfiles])
330 break;
331 else {
332 diFakeIcon.hImage = hptrFile;
333 memset(ppDItem[ulNumfiles], 0, sizeof(DRAGITEM));
334 ppDItem[ulNumfiles]->hwndItem = (hwndObj) ? hwndObj : hwndCnr; /* Initialize DRAGITEM */
335 ppDItem[ulNumfiles]->hwndItem = hwndCnr;
336 ppDItem[ulNumfiles]->ulItemID = (ULONG) pci;
337 ppDItem[ulNumfiles]->hstrType = DrgAddStrHandle(DRT_UNKNOWN);
338 ppDItem[ulNumfiles]->hstrRMF = DrgAddStrHandle(DRMDRFOS2FILE);
339 ppDItem[ulNumfiles]->hstrContainerName = DrgAddStrHandle(arcfile);
340 ppDItem[ulNumfiles]->hstrSourceName = DrgAddStrHandle(szFile);
341 if (!ppDItem[ulNumfiles]->hstrSourceName){
342 DrgDeleteStrHandle(ppDItem[ulNumfiles]->hstrType);
343 DrgDeleteStrHandle(ppDItem[ulNumfiles]->hstrRMF);
344 DrgDeleteStrHandle(ppDItem[ulNumfiles]->hstrContainerName);
345 DrgDeleteStrHandle(ppDItem[ulNumfiles]->hstrSourceName);
346 xfree(ppDItem[ulNumfiles]);
347 fExceedPMDrgLimit = ulNumfiles - 1;
348 break;
349 }
350 ppDItem[ulNumfiles]->hstrTargetName = DrgAddStrHandle(szFile);
351 ppDItem[ulNumfiles]->fsControl = DC_PREPARE;
352 if (IsFullName(arcfile) &&
353 (driveflags[toupper(*arcfile) - 'A'] & DRIVE_REMOVABLE))
354 ppDItem[ulNumfiles]->fsControl |= DC_REMOVEABLEMEDIA;
355 ppDItem[ulNumfiles]->fsSupportedOps = DO_COPYABLE;
356 ulNumfiles++;
357 ppDItem[ulNumfiles] = xmalloc(sizeof(DRAGITEM), pszSrcFile, __LINE__);
358 if (ppDItem[ulNumfiles]) {
359 diFakeIcon.hImage = hptrFile;
360 memset(ppDItem[ulNumfiles], 0, sizeof(DRAGITEM));
361 ppDItem[ulNumfiles]->hwndItem = (hwndObj) ? hwndObj : hwndCnr; /* Initialize DRAGITEM */
362 ppDItem[ulNumfiles]->hwndItem = hwndCnr;
363 ppDItem[ulNumfiles]->ulItemID = Select++;
364 ppDItem[ulNumfiles]->hstrType = DrgAddStrHandle(DRT_UNKNOWN);
365 ppDItem[ulNumfiles]->hstrRMF = DrgAddStrHandle(DRMDRFFM2ARC);
366 ppDItem[ulNumfiles]->hstrContainerName = DrgAddStrHandle(arcfile);
367 ppDItem[ulNumfiles]->hstrSourceName = DrgAddStrHandle(szFile);
368 if (!ppDItem[ulNumfiles]->hstrSourceName){
369 DrgDeleteStrHandle(ppDItem[ulNumfiles]->hstrType);
370 DrgDeleteStrHandle(ppDItem[ulNumfiles]->hstrRMF);
371 DrgDeleteStrHandle(ppDItem[ulNumfiles]->hstrContainerName);
372 DrgDeleteStrHandle(ppDItem[ulNumfiles]->hstrSourceName);
373 xfree(ppDItem[ulNumfiles]);
374 fExceedPMDrgLimit = ulNumfiles - 1;
375 break;
376 }
377 ppDItem[ulNumfiles]->hstrTargetName = DrgAddStrHandle(szFile);
378 ppDItem[ulNumfiles]->fsControl = 0;
379 if (IsFullName(arcfile) &&
380 (driveflags[toupper(*arcfile) - 'A'] & DRIVE_REMOVABLE))
381 ppDItem[ulNumfiles]->fsControl |= DC_REMOVEABLEMEDIA;
382 ppDItem[ulNumfiles]->fsSupportedOps = DO_COPYABLE;
383 //if (ulNumfiles >= 1000){
384 // pDInfo = DrgAllocDraginfo(ulNumfiles);
385 // fexceedpmdrglimit = TRUE;
386 // goto Thatsall;
387 // }
388 ulNumfiles++;
389 }
390 ppDItem[ulNumfiles] = NULL;
391 }
392 }
393 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
394 MPFROM2SHORT(TRUE, CRA_SOURCE));
395
396 Continuing:
397
398 if (!attribute)
399 break;
400 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMP(pci),
401 MPFROMSHORT(attribute));
402 } // while
403 if (fExceedPMDrgLimit)
404 ulNumfiles = ulNumfiles - 1;
405 if (ulNumfiles) {
406 pDInfo = DrgAllocDraginfo(ulNumfiles); /* Allocate DRAGINFO */
407 if (pDInfo) {
408 if ((arcfile && *arcfile) || (IsFullName(szBuffer) &&
409 (driveflags[toupper(*szBuffer) - 'A'] &
410 DRIVE_NOTWRITEABLE)))
411 pDInfo->usOperation = DO_COPY;
412 else
413 pDInfo->usOperation = DO_DEFAULT;
414 if ((!arcfile || !*arcfile) && rooting)
415 pDInfo->usOperation = DO_LINK;
416 pDInfo->hwndSource = (hwndObj) ? hwndObj : hwndCnr;
417 // pDInfo->hwndSource = hwndCnr;
418 for (Select = 0L; Select < ulNumfiles; Select++) {
419 DrgSetDragitem(pDInfo, /* Set item in DRAGINFO */
420 ppDItem[Select], /* Pointer to DRAGITEM */
421 sizeof(DRAGITEM), /* Size of DRAGITEM */
422 Select); /* Index of DRAGITEM */
423 xfree(ppDItem[Select]);
424 }
425#ifdef __DEBUG_ALLOC__
426 _heap_check();
427#endif
428 xfree(ppDItem);
429 ppDItem = NULL;
430 DosPostEventSem(CompactSem);
431
432 if (arcfile) {
433 diFakeIcon.cb = sizeof(DRAGIMAGE);
434 diFakeIcon.cptl = 0;
435 if (ulNumfiles > 1)
436 diFakeIcon.hImage = hptrFile;
437 diFakeIcon.fl = DRG_ICON;
438 diFakeIcon.sizlStretch.cx = 32;
439 diFakeIcon.sizlStretch.cy = 32;
440 diFakeIcon.cxOffset = -16;
441 diFakeIcon.cyOffset = 0;
442 padiIcon = &diFakeIcon;
443 }
444 if (!arcfile) {
445 if (!ulNumIcon)
446 ulNumIcon = ulNumfiles;
447 }
448 else
449 ulNumIcon = 1L;
450
451 WinSetFocus(HWND_DESKTOP, HWND_DESKTOP);
452 hDrop = DrgDrag(hwndCnr, /* Initiate drag */
453 pDInfo, /* DRAGINFO structure */
454 padiIcon, ulNumIcon, VK_ENDDRAG, /* End of drag indicator */
455 (PVOID) NULL); /* Reserved */
456 rc = DeleteDragitemStrHandles(pDInfo);
457 if (!rc)
458 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
459 "DeleteDragistr");
460 DrgDeleteDraginfoStrHandles (pDInfo);
461 rc = DrgFreeDraginfo(pDInfo); /* Free DRAGINFO struct */
462 if (!rc)
463 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
464 "DrgFreeDraginfo");
465 if (padiIcon && padiIcon != &diFakeIcon)
466 xfree(padiIcon);
467 padiIcon = NULL;
468 WinSetWindowPos(hwndCnr, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE);
469 DosPostEventSem(CompactSem);
470 }
471 }
472 if (ppDItem)
473 xfree(ppDItem);
474 if (padiIcon && padiIcon != &diFakeIcon)
475 xfree(padiIcon);
476 MarkAll(hwndCnr, TRUE, FALSE, TRUE);
477 return hDrop;
478}
479
480HWND DragList(HWND hwnd, HWND hwndObj, CHAR ** list, BOOL moveok)
481{
482
483 /* drag a linked list of files */
484
485 BOOL isdir;
486 register CHAR *p;
487 PDRAGINFO pDInfo = NULL;
488 DRAGITEM **ppDItem = NULL, **ppTest;
489 HWND hDrop = (HWND) 0;
490 register ULONG ulNumfiles = 0L, numdragalloc = 0L, Select, ulNumIcon = 0;
491 CHAR szFile[CCHMAXPATH], szBuffer[CCHMAXPATH];
492 DRAGIMAGE *padiIcon = NULL, *padiTest;
493 FILESTATUS3 fs3;
494
495 if (!list || !list[0])
496 return hDrop;
497 for (Select = 0; list[Select]; Select++) {
498 if ((!IsRoot(list[Select]) || !IsValidDrive(*list[Select])) &&
499 DosQueryPathInfo(list[Select], FIL_STANDARD, &fs3, sizeof(fs3)))
500 continue;
501 strcpy(szBuffer, list[Select]);
502 p = strrchr(szBuffer, '\\');
503 if (p) {
504 p++;
505 strcpy(szFile, p);
506 *p = 0;
507 }
508 else
509 continue;
510 if (*szFile) {
511 isdir = (IsRoot(list[Select])) ? TRUE :
512 ((fs3.attrFile & FILE_DIRECTORY) != 0);
513 if (ulNumfiles + 2L > numdragalloc) {
514 if (!padiIcon) {
515 padiTest =
516 xrealloc(padiIcon, sizeof(DRAGIMAGE) * (numdragalloc + 4L),
517 pszSrcFile, __LINE__);
518 if (!padiTest)
519 break;
520 else
521 padiIcon = padiTest;
522 }
523 else if (!ulNumIcon) {
524 padiIcon[ulNumfiles].cb = sizeof(DRAGIMAGE);
525 padiIcon[ulNumfiles].cptl = 0;
526 padiIcon[ulNumfiles].hImage = hptrLast;
527 padiIcon[ulNumfiles].fl = DRG_ICON;
528 padiIcon[ulNumfiles].sizlStretch.cx = 32;
529 padiIcon[ulNumfiles].sizlStretch.cy = 32;
530 padiIcon[ulNumfiles].cxOffset = -16 + (ulNumfiles * 4);
531 padiIcon[ulNumfiles].cyOffset = 0 + (ulNumfiles * 7);
532 ulNumIcon = ulNumfiles + 1;
533 }
534 ppTest =
535 xrealloc(ppDItem, sizeof(DRAGITEM *) * (numdragalloc + 4L),
536 pszSrcFile, __LINE__);
537 if (!ppTest)
538 break;
539 else {
540 ppDItem = ppTest;
541 numdragalloc += 4L;
542 }
543 }
544 ppDItem[ulNumfiles] = xmalloc(sizeof(DRAGITEM), pszSrcFile, __LINE__);
545 if (!ppDItem[ulNumfiles])
546 break;
547 else {
548 if (!ulNumIcon) {
549 padiIcon[ulNumfiles].cb = sizeof(DRAGIMAGE);
550 padiIcon[ulNumfiles].cptl = 0;
551 padiIcon[ulNumfiles].hImage = (isdir) ? hptrDir : hptrFile;
552 padiIcon[ulNumfiles].fl = DRG_ICON;
553 padiIcon[ulNumfiles].sizlStretch.cx = 32;
554 padiIcon[ulNumfiles].sizlStretch.cy = 32;
555 padiIcon[ulNumfiles].cxOffset = -16 + (ulNumfiles * 3);
556 padiIcon[ulNumfiles].cyOffset = 0 + (ulNumfiles * 6);
557 }
558 memset(ppDItem[ulNumfiles], 0, sizeof(DRAGITEM));
559 ppDItem[ulNumfiles]->hwndItem = (hwndObj) ? hwndObj : hwnd; /* Initialize DRAGITEM */
560 // ppDItem[ulNumfiles]->hwndItem = hwnd;
561 ppDItem[ulNumfiles]->ulItemID = (ULONG) Select;
562 ppDItem[ulNumfiles]->hstrType = DrgAddStrHandle(DRT_UNKNOWN);
563 ppDItem[ulNumfiles]->hstrRMF = DrgAddStrHandle(DRMDRFLIST);
564 ppDItem[ulNumfiles]->hstrContainerName = DrgAddStrHandle(szBuffer);
565 ppDItem[ulNumfiles]->hstrSourceName = DrgAddStrHandle(szFile);
566 if (!ppDItem[ulNumfiles]->hstrSourceName){
567 DrgDeleteStrHandle(ppDItem[ulNumfiles]->hstrType);
568 DrgDeleteStrHandle(ppDItem[ulNumfiles]->hstrRMF);
569 DrgDeleteStrHandle(ppDItem[ulNumfiles]->hstrContainerName);
570 DrgDeleteStrHandle(ppDItem[ulNumfiles]->hstrSourceName);
571 xfree(ppDItem[ulNumfiles]);
572 fExceedPMDrgLimit = ulNumfiles - 1;
573 break;
574 }
575 ppDItem[ulNumfiles]->hstrTargetName = DrgAddStrHandle(szFile);
576 ppDItem[ulNumfiles]->fsControl = (isdir) ? DC_CONTAINER : 0;
577 if (IsFullName(list[Select]) &&
578 (driveflags[toupper(*list[Select]) - 'A'] & DRIVE_REMOVABLE))
579 ppDItem[ulNumfiles]->fsControl |= DC_REMOVEABLEMEDIA;
580 ppDItem[ulNumfiles]->fsSupportedOps = DO_COPYABLE | DO_LINKABLE;
581 if (moveok && IsFullName(list[Select]) &&
582 !(driveflags[toupper(*list[Select]) - 'A'] & DRIVE_NOTWRITEABLE))
583 ppDItem[ulNumfiles]->fsSupportedOps |= DO_MOVEABLE;
584 if (IsRoot(list[Select]))
585 ppDItem[ulNumfiles]->fsControl = DO_LINKABLE;
586 ulNumfiles++;
587 ppDItem[ulNumfiles] = NULL;
588 }
589 }
590 } // for
591 if (fExceedPMDrgLimit)
592 ulNumfiles = ulNumfiles - 1;
593 if (ulNumfiles) {
594 pDInfo = DrgAllocDraginfo(ulNumfiles); /* Allocate DRAGINFO */
595 if (pDInfo) {
596 if ((IsFullName(szBuffer) &&
597 (driveflags[toupper(*szBuffer) - 'A'] & DRIVE_NOTWRITEABLE)))
598 pDInfo->usOperation = DO_COPY;
599 else
600 pDInfo->usOperation = DO_DEFAULT;
601 if (IsRoot(list[0]))
602 pDInfo->usOperation = DO_LINK;
603 pDInfo->hwndSource = (hwndObj) ? hwndObj : hwnd;
604 // pDInfo->hwndSource = hwnd;
605 for (Select = 0L; Select < ulNumfiles; Select++) {
606 DrgSetDragitem(pDInfo, /* Set item in DRAGINFO */
607 ppDItem[Select], /* Pointer to DRAGITEM */
608 sizeof(DRAGITEM), /* Size of DRAGITEM */
609 Select); /* Index of DRAGITEM */
610 free(ppDItem[Select]);
611 } // for
612#ifdef __DEBUG_ALLOC__
613 _heap_check();
614#endif
615 free(ppDItem);
616 ppDItem = NULL;
617 DosPostEventSem(CompactSem);
618
619 if (!ulNumIcon)
620 ulNumIcon = ulNumfiles;
621
622 WinSetFocus(HWND_DESKTOP, HWND_DESKTOP);
623 hDrop = DrgDrag(hwnd, /* Initiate drag */
624 pDInfo, /* DRAGINFO structure */
625 padiIcon, ulNumIcon, VK_ENDDRAG, /* End of drag indicator */
626 (PVOID) NULL); /* Reserved */
627 if (!DeleteDragitemStrHandles(pDInfo))
628 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
629 "DeleteDragistr");
630 DrgDeleteDraginfoStrHandles (pDInfo);
631 if (!DrgFreeDraginfo(pDInfo)); /* Free DRAGINFO struct */
632 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
633 "DrgFreeDraginfo");
634 xfree(padiIcon);
635 padiIcon = NULL;
636 WinSetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE);
637 DosPostEventSem(CompactSem);
638 }
639 }
640 if (ppDItem)
641 free(ppDItem);
642 if (padiIcon)
643 free(padiIcon);
644 return hDrop;
645}
646
647#ifdef NEVER
648
649BOOL PickUp(HWND hwndCnr, HWND hwndObj, PCNRDRAGINIT pcd)
650{
651
652 PCNRITEM pci;
653 BOOL loop = TRUE;
654 PDRAGINFO pdinfoOld = NULL, pdinfoCurrent = NULL;
655 ULONG cditem = 0;
656 DRAGITEM ditem;
657 DRAGIMAGE diFakeIcon;
658 CHAR szDir[CCHMAXPATH], szFile[CCHMAXPATH], *p;
659
660 pci = (PCNRITEM) pcd->pRecord;
661 if (pci && (INT) pci != -1) {
662 if (pci->rc.flRecordAttr & CRA_SELECTED) {
663 loop = TRUE;
664 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS,
665 MPFROMLONG(CMA_FIRST), MPFROMSHORT(CRA_SELECTED));
666 }
667 while (pci && (INT) pci != -1 && *pci->szFileName) {
668 if (pdinfoOld || DrgQueryDragStatus() & DGS_LAZYDRAGINPROGRESS) {
669 if (!pdinfoOld)
670 pdinfoOld = DrgQueryDraginfoPtr(NULL);
671 if (pdinfoOld) {
672 cditem = pdinfoOld->cditem + 1;
673 pdinfoCurrent = DrgReallocDraginfo(pdinfoOld, cditem);
674 pdinfoOld = pdinfoCurrent;
675 }
676 }
677 else
678 pdinfoCurrent = pdinfoOld = DrgAllocDraginfo(1);
679 if (pdinfoCurrent) {
680 strcpy(szDir, pci->szFileName);
681 p = szDir;
682 while (*p) {
683 if (*p == '/')
684 *p = '\\';
685 p++;
686 }
687 p = strrchr(szDir, '\\');
688 if (p) {
689 *p = 0;
690 p++;
691 strcpy(szFile, p);
692 strcat(szDir, "\\");
693 }
694 else {
695 strcpy(szFile, pci->szFileName);
696 *szDir = 0;
697 }
698 ditem.ulItemID = (ULONG) pci;
699 ditem.hwndItem = (hwndObj) ? hwndObj : hwndCnr;
700 ditem.hstrType = DrgAddStrHandle(DRT_UNKNOWN);
701 ditem.hstrRMF = DrgAddStrHandle(DRMDRFLIST);
702 ditem.hstrContainerName = DrgAddStrHandle(szDir);
703 ditem.hstrSourceName = DrgAddStrHandle(szFile);
704 if (!ditem.hstrSourceName)
705 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
706 "DrgAddStrHandle");
707 ditem.hstrTargetName = DrgAddStrHandle(szFile);
708 ditem.fsControl = 0;
709 if (IsRoot(pci->szFileName) || (pci->attrFile & FILE_DIRECTORY) != 0)
710 ditem.fsControl |= DC_CONTAINER;
711 if (IsFullName(pci->szFileName) &&
712 (driveflags[toupper(*pci->szFileName) - 'A'] & DRIVE_REMOVABLE))
713 ditem.fsControl |= DC_REMOVEABLEMEDIA;
714 ditem.fsSupportedOps = DO_COPYABLE | DO_LINKABLE;
715 if (IsFullName(pci->szFileName) &&
716 !(driveflags[toupper(*pci->szFileName) - 'A'] &
717 DRIVE_NOTWRITEABLE))
718 ditem.fsSupportedOps |= DO_MOVEABLE;
719 if (IsRoot(pci->szFileName))
720 ditem.fsSupportedOps = DO_LINKABLE;
721 memset(&diFakeIcon, 0, sizeof(DRAGIMAGE));
722 diFakeIcon.hImage = pci->rc.hptrIcon;
723 diFakeIcon.cb = sizeof(DRAGIMAGE);
724 diFakeIcon.cptl = 0;
725 diFakeIcon.fl = DRG_ICON;
726 diFakeIcon.sizlStretch.cx = 32;
727 diFakeIcon.sizlStretch.cy = 32;
728 diFakeIcon.cxOffset = -16;
729 diFakeIcon.cyOffset = 0;
730 if (IsFullName(pci->szFileName) &&
731 (driveflags[toupper(*pci->szFileName) - 'A'] &
732 DRIVE_NOTWRITEABLE))
733 pdinfoCurrent->usOperation = DO_COPY;
734 else
735 pdinfoCurrent->usOperation = DO_DEFAULT;
736 if (IsRoot(pci->szFileName))
737 pdinfoCurrent->usOperation = DO_LINK;
738 pdinfoCurrent->hwndSource = (hwndObj) ? hwndObj : hwndCnr;
739 DrgSetDragitem(pdinfoCurrent, &ditem, sizeof(DRAGITEM), cditem);
740 }
741 if (!loop)
742 break;
743 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS,
744 MPFROMP(pci), MPFROMSHORT(CRA_SELECTED));
745 }
746 if (pdinfoCurrent)
747 return DrgLazyDrag(hwndCnr, pdinfoCurrent, &diFakeIcon, 1, NULL);
748 }
749 return FALSE;
750}
751
752#endif // NEVER
Note: See TracBrowser for help on using the repository browser.