source: trunk/dll/draglist.c@ 1877

Last change on this file since 1877 was 1877, checked in by Gregg Young, 10 years ago

Remove debug code

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 28.2 KB
Line 
1
2/***********************************************************************
3
4 $Id: draglist.c 1877 2015-10-11 21:43:27Z gyoung $
5
6 Drag drop support
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2001, 2010 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 19 Apr 07 SHL Rework DeleteDragitemStrHandles to be FreeDragInfoData
17 19 Apr 07 SHL Add more drag/drop error checking
18 19 Apr 07 SHL Optimize DRAGITEM DRAGIMAGE array access
19 21 Apr 07 SHL Avoid odd first time drag failure
20 12 May 07 SHL Use dcd->ulItemsToUnHilite
21 05 Jul 07 SHL FreeDragInfoData: suppress PMERR_SOURCE_SAME_AS_TARGET notices
22 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
23 29 Feb 08 GKY Use xmallocz where appropriate
24 08 Mar 09 GKY Additional strings move to PCSZs
25 12 Sep 09 GKY Fix (probably spurrious) error message generated on drag of
26 items from a pmmail mail message (PMERR_INVALID_PARAMETER)
27 17 JAN 10 GKY Changes to get working with Watcom 1.9 Beta (1/16/10). Mostly cast CHAR CONSTANT * as CHAR *.
28 23 Oct 10 GKY Add ForwardslashToBackslash function to streamline code
29
30***********************************************************************/
31
32#include <stdlib.h>
33#include <string.h>
34#include <ctype.h>
35
36#define INCL_DOS
37#define INCL_WIN
38#define INCL_SHLERRORS
39#define INCL_LONGLONG
40
41#include "fm3dll.h"
42#include "info.h" // Data declaration(s)
43#include "init.h" // Data declaration(s)
44#include "newview.h" // Data declarations
45#include "errutil.h" // Dos_Error...
46#include "draglist.h"
47#include "valid.h" // IsValidDrive
48#include "misc.h" // IsFm2Window
49#include "select.h" // MarkAll
50#include "wrappers.h" // xrealloc
51#include "fortify.h"
52#include "pathutil.h" // ForwardslashToBackslash
53
54// Data definitions
55static PSZ pszSrcFile = __FILE__;
56
57#pragma data_seg(GLOBAL1)
58HPOINTER hptrDir;
59HPOINTER hptrFile;
60HPOINTER hptrLast;
61
62#pragma data_seg(GLOBAL2)
63PCSZ DRMDRFLIST = "<DRM_OS2FILE,DRF_UNKNOWN>," "<DRM_DISCARD,DRF_UNKNOWN>," "<DRM_PRINT,DRF_UNKNOWN>";
64
65/**
66 * Delete drag item string handles.
67 * Work around for DrgDeleteDraginfoStrHandles
68 * which seems to fail with a large number of strings
69 * Assume called after successful DrgAccessDraginfo
70 */
71
72
73// #define USE_FAST_FREE // Define to let PM do free
74
75VOID FreeDragInfoData (HWND hwnd, PDRAGINFO pDInfo)
76{
77
78//# ifdef USE_FAST_FREE
79 if (!IsFm2Window(pDInfo->hwndSource, FALSE)) {
80 if (!DrgDeleteDraginfoStrHandles(pDInfo)) {
81 Win_Error(hwnd, hwnd, pszSrcFile, __LINE__,
82 "DrgDeleteDraginfoStrHandles");
83 }
84 }
85 //# else // The slow way
86 else {
87 PDRAGITEM pDItem;
88 ULONG cDitem;
89 ULONG curitem;
90 APIRET ok;
91
92 cDitem = DrgQueryDragitemCount(pDInfo);
93 for (curitem = 0; curitem < cDitem; curitem++) {
94 pDItem = DrgQueryDragitemPtr(pDInfo, curitem);
95 if (!pDItem) {
96 Win_Error(hwnd, hwnd, pszSrcFile, __LINE__,
97 "DrgQueryDragitemPtr(%u)", curitem);
98 }
99 else {
100 ok = DrgDeleteStrHandle(pDItem->hstrType);
101 if (!ok) {
102 HAB hab = WinQueryAnchorBlock(hwnd);
103 PERRINFO pErrInfoBlk = WinGetErrorInfo(hab);
104 if (ERRORIDERROR(pErrInfoBlk->idError) != PMERR_INVALID_PARAMETER)
105 Win_Error(hwnd, hwnd, pszSrcFile, __LINE__,
106 "DrgDeleteStrHandle(0x%x) hstrType",pDItem->hstrType);
107 }
108 ok = DrgDeleteStrHandle(pDItem->hstrRMF);
109 if (!ok) {
110 HAB hab = WinQueryAnchorBlock(hwnd);
111 PERRINFO pErrInfoBlk = WinGetErrorInfo(hab);
112 if (ERRORIDERROR(pErrInfoBlk->idError) != PMERR_INVALID_PARAMETER)
113 Win_Error(hwnd, hwnd, pszSrcFile, __LINE__,
114 "DrgDeleteStrHandle(0x%x) hstrRMF",pDItem->hstrRMF);
115 }
116 ok = DrgDeleteStrHandle(pDItem->hstrContainerName);
117 if (!ok) {
118 HAB hab = WinQueryAnchorBlock(hwnd);
119 PERRINFO pErrInfoBlk = WinGetErrorInfo(hab);
120 if (ERRORIDERROR(pErrInfoBlk->idError) != PMERR_INVALID_PARAMETER)
121 Win_Error(hwnd, hwnd, pszSrcFile, __LINE__,
122 "DrgDeleteStrHandle(0x%x) hstrContainerName",pDItem->hstrContainerName);
123 }
124 ok = DrgDeleteStrHandle(pDItem->hstrSourceName);
125 if (!ok) {
126 Win_Error(hwnd, hwnd, pszSrcFile, __LINE__,
127 "DrgDeleteStrHandle(0x%x) hstrSourceName",pDItem->hstrSourceName);
128 }
129 ok = DrgDeleteStrHandle(pDItem->hstrTargetName);
130 if (!ok) {
131 Win_Error(hwnd, hwnd, pszSrcFile, __LINE__,
132 "DrgDeleteStrHandle(0x%x) hstrTargetName",pDItem->hstrTargetName);
133 }
134 }
135 } // for
136 }
137//# endif
138 if (!DrgFreeDraginfo(pDInfo)) {
139 // PMERR_SOURCE_SAME_AS_TARGET is not an error if dragging within same fm/2 process
140 if (!IsFm2Window(pDInfo->hwndSource, FALSE) ||
141 (WinGetLastError(WinQueryAnchorBlock(hwnd)) & 0xffff) != PMERR_SOURCE_SAME_AS_TARGET)
142 {
143 Win_Error(hwnd, hwnd, pszSrcFile, __LINE__, "DrgFreeDraginfo");
144 }
145 }
146}
147
148HWND DragOne(HWND hwndCnr, HWND hwndObj, CHAR * filename, BOOL moveok)
149{
150
151 DRAGITEM DItem;
152 HWND hDrop = 0;
153 DRAGIMAGE fakeicon;
154 PDRAGINFO pDInfo;
155 FILESTATUS3 fs3;
156 CHAR szDir[CCHMAXPATH], szFile[CCHMAXPATH], *p;
157
158 if (filename && *filename) {
159 if ((IsRoot(filename) && IsValidDrive(*filename)) ||
160 !DosQueryPathInfo(filename, FIL_STANDARD, &fs3, sizeof(fs3))) {
161 strcpy(szDir, filename);
162 ForwardslashToBackslash(szDir);
163 p = strrchr(szDir, '\\');
164 if (p) {
165 *p = 0;
166 p++;
167 strcpy(szFile, p);
168 strcat(szDir, PCSZ_BACKSLASH);
169 }
170 else {
171 strcpy(szFile, filename);
172 *szDir = 0;
173 }
174 memset(&fakeicon, 0, sizeof(DRAGIMAGE));
175 fakeicon.hImage = (IsRoot(filename) ||
176 (fs3.attrFile & FILE_DIRECTORY) != 0) ?
177 hptrDir : hptrFile;
178 memset(&DItem, 0, sizeof(DRAGITEM));
179 DItem.hwndItem = (hwndObj) ? hwndObj : hwndCnr; // Initialize DRAGITEM
180 // DItem.hwndItem = hwndCnr;
181 DItem.ulItemID = 1;
182 DItem.hstrType = DrgAddStrHandle(DRT_UNKNOWN);
183 DItem.hstrRMF = DrgAddStrHandle((CHAR *) DRMDRFLIST);
184 DItem.hstrContainerName = DrgAddStrHandle(szDir);
185 DItem.hstrSourceName = DrgAddStrHandle(szFile);
186 if (!DItem.hstrSourceName)
187 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
188 "DrgQueryStrName");
189 DItem.hstrTargetName = DrgAddStrHandle(szFile);
190 DItem.fsControl = 0;
191 if (IsRoot(filename) || (fs3.attrFile & FILE_DIRECTORY) != 0)
192 DItem.fsControl |= DC_CONTAINER;
193 if (IsFullName(filename) &&
194 (driveflags[toupper(*filename) - 'A'] & DRIVE_REMOVABLE))
195 DItem.fsControl |= DC_REMOVEABLEMEDIA;
196 DItem.fsSupportedOps = DO_COPYABLE | DO_LINKABLE;
197 if (moveok && IsFullName(filename) &&
198 !(driveflags[toupper(*filename) - 'A'] & DRIVE_NOTWRITEABLE))
199 DItem.fsSupportedOps |= DO_MOVEABLE;
200 if (IsRoot(filename))
201 DItem.fsSupportedOps = DO_LINKABLE;
202 fakeicon.cb = sizeof(DRAGIMAGE);
203 fakeicon.cptl = 0;
204 fakeicon.fl = DRG_ICON;
205 fakeicon.sizlStretch.cx = 32;
206 fakeicon.sizlStretch.cy = 32;
207 fakeicon.cxOffset = -16;
208 fakeicon.cyOffset = 0;
209 pDInfo = DrgAllocDraginfo(1);
210 if (pDInfo) {
211 if (IsFullName(filename) &&
212 (driveflags[toupper(*filename) - 'A'] & DRIVE_NOTWRITEABLE))
213 pDInfo->usOperation = DO_COPY;
214 else
215 pDInfo->usOperation = DO_DEFAULT;
216 if (IsRoot(filename))
217 pDInfo->usOperation = DO_LINK;
218 pDInfo->hwndSource = (hwndObj) ? hwndObj : hwndCnr;
219 // pDInfo->hwndSource = hwndCnr;
220 DrgSetDragitem(pDInfo, &DItem, sizeof(DRAGITEM), 0);
221 WinSetFocus(HWND_DESKTOP, HWND_DESKTOP);
222 hDrop = DrgDrag(hwndCnr,
223 pDInfo,
224 &fakeicon,
225 1, // DragImage count
226 VK_ENDDRAG, // Drag end button
227 NULL);
228 if (hDrop == NULLHANDLE)
229 FreeDragInfoData(hwndCnr, pDInfo);
230 WinSetWindowPos(hwndCnr, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE);
231 }
232 }
233 }
234 return hDrop;
235}
236
237HWND DoFileDrag(HWND hwndCnr, HWND hwndObj, PCNRDRAGINIT pcd, CHAR * arcfile,
238 CHAR * directory, BOOL moveok)
239{
240 // Drag files from a container
241
242 BOOL isdir, rooting = FALSE;
243 PCNRITEM pci;
244 CHAR *p;
245 INT attribute = CRA_CURSORED;
246 PDRAGINFO pDInfo = NULL;
247 DRAGITEM **ppDItem = NULL, **ppDITest;
248 DRAGITEM *pDItem;
249 PCNRITEM pciRec = (PCNRITEM) pcd->pRecord;
250 HWND hDrop = NULLHANDLE;
251 ULONG ulNumfiles = 0, ulNumDIAlloc = 0, ulSelect, ulNumIcon = 0;
252 CHAR szFile[CCHMAXPATH], szBuffer[CCHMAXPATH];
253 DRAGIMAGE *paDImgIcons = NULL, *pDImg, dimgFakeIcon;
254 BOOL ok;
255 UINT c;
256 DIRCNRDATA *dcd;
257
258 static BOOL first_drag = TRUE;
259
260 // Count items to unhilite, pass to UnHilite when partial unhilite required
261 dcd = INSTDATA(hwndCnr);
262 if (!dcd)
263 return hDrop;
264 dcd->ulItemsToUnHilite = 0;
265 if (!pciRec && directory && *directory)
266 return DragOne(hwndCnr, hwndObj, directory, moveok);
267
268 if (!pciRec) {
269 pci = (PCNRITEM) WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS,
270 MPFROMLONG(CMA_FIRST),
271 MPFROMSHORT(attribute));
272 if (pci && (INT) pci > -1) {
273 if (pci->rc.flRecordAttr & CRA_SELECTED) {
274 attribute = CRA_SELECTED;
275 pci =
276 WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
277 MPFROMSHORT(attribute));
278 }
279 }
280 }
281 else {
282 pci = pciRec;
283 attribute = (pci->rc.flRecordAttr & CRA_SELECTED) ? CRA_SELECTED : 0;
284 if (attribute) {
285 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
286 MPFROMSHORT(attribute));
287 }
288 }
289
290 ulSelect = 0;
291 while (pci && (INT) pci > -1) {
292 if (!(pci->rc.flRecordAttr & CRA_FILTERED)) {
293 if (IsRoot(pci->pszFileName) && !IsValidDrive(*pci->pszFileName))
294 goto Continuing;
295 if (!arcfile) {
296 strcpy(szBuffer, pci->pszFileName);
297 p = strrchr(szBuffer, '\\');
298 if (p) {
299 p++;
300 strcpy(szFile, p);
301 *p = 0;
302 }
303 else
304 goto Continuing;
305 }
306 else
307 strcpy(szFile, pci->pszFileName);
308 }
309 if (!arcfile) {
310 // Filesystem object
311 isdir = pci->attrFile & FILE_DIRECTORY;
312 // fixme to expand smarter - expand fast at first - do same for similar code
313 if (ulNumfiles + 2 > ulNumDIAlloc) {
314 // Expand
315 if (!paDImgIcons) {
316 pDImg =
317 xrealloc(paDImgIcons, sizeof(DRAGIMAGE) * (ulNumDIAlloc + 4L),
318 pszSrcFile, __LINE__);
319 if (!pDImg)
320 break;
321 paDImgIcons = pDImg;
322 }
323 else if (!ulNumIcon) {
324 pDImg = &paDImgIcons[ulNumfiles];
325 pDImg->cb = sizeof(DRAGIMAGE);
326 pDImg->cptl = 0;
327 pDImg->hImage = hptrLast;
328 pDImg->fl = DRG_ICON;
329 pDImg->sizlStretch.cx = 32;
330 pDImg->sizlStretch.cy = 32;
331 pDImg->cxOffset = -16 + ((SHORT) ulNumfiles * 4);
332 pDImg->cyOffset = 0 + ((SHORT) ulNumfiles * 7);
333 ulNumIcon = ulNumfiles + 1;
334 }
335 ppDITest =
336 xrealloc(ppDItem, sizeof(DRAGITEM *) * (ulNumDIAlloc + 4L),
337 pszSrcFile, __LINE__);
338 if (!ppDITest)
339 break;
340 ppDItem = ppDITest;
341 ulNumDIAlloc += 4L;
342 }
343 // Create & Initialize DRAGITEM
344 pDItem = xmallocz(sizeof(DRAGITEM), pszSrcFile, __LINE__);
345 if (!pDItem)
346 break; // Already complained
347 ppDItem[ulNumfiles] = pDItem;
348 if (!ulNumIcon) {
349 pDImg = &paDImgIcons[ulNumfiles];
350 pDImg->cb = sizeof(DRAGIMAGE);
351 pDImg->cptl = 0;
352 pDImg->hImage = pci->rc.hptrIcon;
353 if (!pDImg->hImage)
354 pDImg->hImage = isdir ? hptrDir : hptrFile;
355 pDImg->fl = DRG_ICON;
356 pDImg->sizlStretch.cx = 32;
357 pDImg->sizlStretch.cy = 32;
358 pDImg->cxOffset = -16 + ((SHORT) ulNumfiles * 3);
359 pDImg->cyOffset = 0 + ((SHORT) ulNumfiles * 6);
360 }
361 pDItem->hwndItem = (hwndObj) ? hwndObj : hwndCnr;
362 pDItem->hwndItem = hwndCnr;
363 pDItem->ulItemID = (ULONG) pci;
364 pDItem->hstrType = DrgAddStrHandle(DRT_UNKNOWN);
365 ok = pDItem->hstrType;
366 pDItem->hstrRMF = DrgAddStrHandle((CHAR *) DRMDRFLIST);
367 ok = ok && pDItem->hstrRMF;
368 pDItem->hstrContainerName = DrgAddStrHandle(szBuffer);
369 ok = ok && pDItem->hstrContainerName;
370 pDItem->hstrSourceName = DrgAddStrHandle(szFile);
371 ok = ok && pDItem->hstrSourceName;
372 pDItem->hstrTargetName = DrgAddStrHandle(szFile);
373 ok = ok && pDItem->hstrTargetName;
374 if (!ok) {
375 // If we have string handle add overflow, release corrupt DragItem
376 // We release 3 more to work around 1st time drag failure reported by Gregg
377 // fixme to know why this happens - PM may need to create a handle?
378 c = first_drag ? 4 : 1;
379 first_drag = FALSE;
380 for (; c > 0 && ulNumfiles > 0; c--) {
381 if (pDItem->hstrType)
382 DrgDeleteStrHandle(pDItem->hstrType);
383 if (pDItem->hstrRMF)
384 DrgDeleteStrHandle(pDItem->hstrRMF);
385 if (pDItem->hstrContainerName)
386 DrgDeleteStrHandle(pDItem->hstrContainerName);
387 if (pDItem->hstrSourceName)
388 DrgDeleteStrHandle(pDItem->hstrSourceName);
389 if (pDItem->hstrTargetName)
390 DrgDeleteStrHandle(pDItem->hstrTargetName);
391 free(pDItem);
392 // Last item not yet count so only decrement by one less than loop count
393 // Unhilite code will adjust this when unhighliting
394 if (c > 1) {
395 ulNumfiles--;
396 pDItem = ppDItem[ulNumfiles];
397 }
398 }
399 // Set count to actual count + 1 to ensure count non-zero on any failure
400 dcd->ulItemsToUnHilite = ulNumfiles + 1;
401 break;
402 }
403 pDItem->fsControl = isdir ? DC_CONTAINER : 0;
404 if (IsFullName(pci->pszFileName) &&
405 (driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_REMOVABLE))
406 pDItem->fsControl |= DC_REMOVEABLEMEDIA;
407 pDItem->fsSupportedOps = DO_COPYABLE | DO_LINKABLE;
408 if (moveok && IsFullName(pci->pszFileName) &&
409 !(driveflags[toupper(*pci->pszFileName) - 'A'] &
410 DRIVE_NOTWRITEABLE))
411 pDItem->fsSupportedOps |= DO_MOVEABLE;
412 if (IsRoot(pci->pszFileName)) {
413 pDItem->fsSupportedOps = DO_LINKABLE;
414 rooting = TRUE;
415 }
416 ulNumfiles++;
417 // ppDItem[ulNumfiles] = NULL; // Why bother - can't we count - fixme to be gone?
418 } // if filesystem object
419 else {
420 // Archive object
421 if (ulNumfiles + 3L > ulNumDIAlloc) {
422 ppDITest =
423 xrealloc(ppDItem, sizeof(DRAGITEM *) * (ulNumDIAlloc + 5L),
424 pszSrcFile, __LINE__);
425 if (!ppDITest)
426 break;
427 ppDItem = ppDITest;
428 ulNumDIAlloc += 5L;
429 }
430 // Create & Initialize DRAGITEM
431 pDItem = xmallocz(sizeof(DRAGITEM), pszSrcFile, __LINE__);
432 if (!pDItem)
433 break;
434 ppDItem[ulNumfiles] = pDItem;
435 dimgFakeIcon.hImage = hptrFile;
436 pDItem->hwndItem = (hwndObj) ? hwndObj : hwndCnr;
437 pDItem->hwndItem = hwndCnr;
438 pDItem->ulItemID = (ULONG) pci;
439 pDItem->hstrType = DrgAddStrHandle(DRT_UNKNOWN);
440 ok = pDItem->hstrType;
441 pDItem->hstrRMF = DrgAddStrHandle((CHAR *) DRMDRFOS2FILE);
442 ok = ok && pDItem->hstrRMF;
443 pDItem->hstrContainerName = DrgAddStrHandle(arcfile);
444 ok = ok && pDItem->hstrContainerName;
445 pDItem->hstrSourceName = DrgAddStrHandle(szFile);
446 ok = ok && pDItem->hstrSourceName;
447 pDItem->hstrTargetName = DrgAddStrHandle(szFile);
448 ok = ok && pDItem->hstrTargetName;
449 if (!ok){
450 if (pDItem->hstrType)
451 DrgDeleteStrHandle(pDItem->hstrType);
452 if (pDItem->hstrRMF)
453 DrgDeleteStrHandle(pDItem->hstrRMF);
454 if (pDItem->hstrContainerName)
455 DrgDeleteStrHandle(pDItem->hstrContainerName);
456 if (pDItem->hstrSourceName)
457 DrgDeleteStrHandle(pDItem->hstrSourceName);
458 if (pDItem->hstrTargetName)
459 DrgDeleteStrHandle(pDItem->hstrTargetName);
460 free(pDItem);
461 dcd->ulItemsToUnHilite = ulNumfiles + 1; // +1 to ensure non-zero
462 break;
463 }
464 pDItem->fsControl = DC_PREPARE;
465 if (IsFullName(arcfile) &&
466 (driveflags[toupper(*arcfile) - 'A'] & DRIVE_REMOVABLE))
467 pDItem->fsControl |= DC_REMOVEABLEMEDIA;
468 pDItem->fsSupportedOps = DO_COPYABLE;
469 ulNumfiles++;
470 // Create & Initialize DRAGITEM
471 pDItem = xmallocz(sizeof(DRAGITEM), pszSrcFile, __LINE__);
472 if (pDItem) {
473 ppDItem[ulNumfiles] = pDItem;
474 dimgFakeIcon.hImage = hptrFile;
475 pDItem->hwndItem = (hwndObj) ? hwndObj : hwndCnr;
476 pDItem->hwndItem = hwndCnr;
477 pDItem->ulItemID = ulSelect++;
478 pDItem->hstrType = DrgAddStrHandle(DRT_UNKNOWN);
479 ok = ok && pDItem->hstrType;
480 pDItem->hstrRMF = DrgAddStrHandle((CHAR *) DRMDRFFM2ARC);
481 ok = ok && pDItem->hstrRMF;
482 pDItem->hstrContainerName = DrgAddStrHandle(arcfile);
483 ok = ok && pDItem->hstrContainerName;
484 pDItem->hstrSourceName = DrgAddStrHandle(szFile);
485 ok = ok && pDItem->hstrSourceName;
486 pDItem->hstrTargetName = DrgAddStrHandle(szFile);
487 ok = ok && pDItem->hstrTargetName;
488 if (!ok) {
489 // If we have string handle add overflow, release corrupt DragItem
490 // We release 3 more to work around 1st time drag failure reported by Gregg
491 // fixme to know why this happens - PM may need to create a handle?
492 c = first_drag ? 4 : 1;
493 first_drag = FALSE;
494 for (; c > 0 && ulNumfiles > 0; c--) {
495 if (pDItem->hstrType)
496 DrgDeleteStrHandle(pDItem->hstrType);
497 if (pDItem->hstrRMF)
498 DrgDeleteStrHandle(pDItem->hstrRMF);
499 if (pDItem->hstrContainerName)
500 DrgDeleteStrHandle(pDItem->hstrContainerName);
501 if (pDItem->hstrSourceName)
502 DrgDeleteStrHandle(pDItem->hstrSourceName);
503 if (pDItem->hstrTargetName)
504 DrgDeleteStrHandle(pDItem->hstrTargetName);
505 free(pDItem);
506 // Last item not yet count so only decrement by one less than loop count
507 if (c > 1) {
508 ulNumfiles--;
509 pDItem = ppDItem[ulNumfiles];
510 }
511 }
512 // Set count to actual count + 1 to ensure count non-zero on any failure
513 // Unhilite code will adjust this when unhighliting
514 dcd->ulItemsToUnHilite = ulNumfiles + 1;
515 break;
516 }
517 pDItem->fsControl = 0;
518 if (IsFullName(arcfile) &&
519 (driveflags[toupper(*arcfile) - 'A'] & DRIVE_REMOVABLE))
520 pDItem->fsControl |= DC_REMOVEABLEMEDIA;
521 pDItem->fsSupportedOps = DO_COPYABLE;
522 ulNumfiles++;
523 }
524 // ppDItem[ulNumfiles] = NULL; // Why bother - fixme to be gone?
525 } // if archive object
526 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
527 MPFROM2SHORT(TRUE, CRA_SOURCE));
528
529 Continuing:
530
531 if (!attribute)
532 break;
533 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMP(pci),
534 MPFROMSHORT(attribute));
535 } // while
536
537 if (ulNumfiles) {
538 pDInfo = DrgAllocDraginfo(ulNumfiles);
539 if (pDInfo) {
540 if ((arcfile && *arcfile) || (IsFullName(szBuffer) &&
541 (driveflags[toupper(*szBuffer) - 'A'] &
542 DRIVE_NOTWRITEABLE)))
543 pDInfo->usOperation = DO_COPY;
544 else
545 pDInfo->usOperation = DO_DEFAULT;
546 if ((!arcfile || !*arcfile) && rooting)
547 pDInfo->usOperation = DO_LINK;
548 pDInfo->hwndSource = (hwndObj) ? hwndObj : hwndCnr;
549 // pDInfo->hwndSource = hwndCnr;
550 for (ulSelect = 0; ulSelect < ulNumfiles; ulSelect++) {
551 DrgSetDragitem(pDInfo, ppDItem[ulSelect], sizeof(DRAGITEM), ulSelect);
552 xfree(ppDItem[ulSelect], pszSrcFile, __LINE__);
553 }
554#ifdef __DEBUG_ALLOC__
555 _heap_check();
556#endif
557 xfree(ppDItem, pszSrcFile, __LINE__);
558 ppDItem = NULL; // Remember gone
559 DosPostEventSem(CompactSem);
560
561 if (arcfile) {
562 dimgFakeIcon.cb = sizeof(DRAGIMAGE);
563 dimgFakeIcon.cptl = 0;
564 if (ulNumfiles > 1)
565 dimgFakeIcon.hImage = hptrFile;
566 dimgFakeIcon.fl = DRG_ICON;
567 dimgFakeIcon.sizlStretch.cx = 32;
568 dimgFakeIcon.sizlStretch.cy = 32;
569 dimgFakeIcon.cxOffset = -16;
570 dimgFakeIcon.cyOffset = 0;
571 paDImgIcons = &dimgFakeIcon;
572 }
573 if (!arcfile) {
574 if (!ulNumIcon)
575 ulNumIcon = ulNumfiles;
576 }
577 else
578 ulNumIcon = 1;
579
580 WinSetFocus(HWND_DESKTOP, HWND_DESKTOP);
581 hDrop = DrgDrag(hwndCnr,
582 pDInfo,
583 paDImgIcons,
584 ulNumIcon,
585 VK_ENDDRAG, // Drag end button
586 NULL);
587 WinSetWindowPos(hwndCnr, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE);
588 }
589 }
590
591 if (hDrop == NULLHANDLE ) {
592 dcd->ulItemsToUnHilite = 0;
593 if (pDInfo)
594 FreeDragInfoData(hwndCnr, pDInfo);
595 }
596 xfree(ppDItem, pszSrcFile, __LINE__);
597 if (paDImgIcons && paDImgIcons != &dimgFakeIcon)
598 free(paDImgIcons);
599 DosPostEventSem(CompactSem);
600 MarkAll(hwndCnr, TRUE, FALSE, TRUE);
601 return hDrop;
602}
603
604HWND DragList(HWND hwnd, HWND hwndObj, CHAR ** list, BOOL moveok)
605{
606 // Drag a linked list of files
607
608 BOOL isdir;
609 register CHAR *p;
610 PDRAGINFO pDInfo = NULL;
611 DRAGITEM **ppDItem = NULL, **ppDITest;
612 DRAGITEM *pDItem;
613 HWND hDrop = (HWND) 0;
614 ULONG ulNumfiles = 0, ulNumDIAlloc = 0, ulSelect, ulNumIcon = 0;
615 CHAR szFile[CCHMAXPATH], szBuffer[CCHMAXPATH];
616 DRAGIMAGE *paDImgIcons = NULL, *pDImg;
617 FILESTATUS3 fs3;
618 BOOL ok;
619 DIRCNRDATA *dcd;
620
621 if (!list || !list[0])
622 return hDrop;
623
624 dcd = INSTDATA(hwnd);
625
626 for (ulSelect = 0; list[ulSelect]; ulSelect++) {
627 if ((!IsRoot(list[ulSelect]) || !IsValidDrive(*list[ulSelect])) &&
628 DosQueryPathInfo(list[ulSelect], FIL_STANDARD, &fs3, sizeof(fs3)))
629 continue;
630 strcpy(szBuffer, list[ulSelect]);
631 p = strrchr(szBuffer, '\\');
632 if (p) {
633 p++;
634 strcpy(szFile, p);
635 *p = 0;
636 }
637 else
638 continue;
639 if (*szFile) {
640 isdir = IsRoot(list[ulSelect]) || fs3.attrFile & FILE_DIRECTORY;
641 // fixme to expand smarter - expand fast at first - do same for similar code
642 if (ulNumfiles + 2 > ulNumDIAlloc) {
643 if (!paDImgIcons) {
644 pDImg =
645 xrealloc(paDImgIcons, sizeof(DRAGIMAGE) * (ulNumDIAlloc + 4L),
646 pszSrcFile, __LINE__);
647 if (!pDImg)
648 break;
649 paDImgIcons = pDImg;
650 }
651 else if (!ulNumIcon) {
652 pDImg = &paDImgIcons[ulNumfiles];
653 pDImg->cb = sizeof(DRAGIMAGE);
654 pDImg->cptl = 0;
655 pDImg->hImage = hptrLast;
656 pDImg->fl = DRG_ICON;
657 pDImg->sizlStretch.cx = 32;
658 pDImg->sizlStretch.cy = 32;
659 pDImg->cxOffset = -16 + ((SHORT) ulNumfiles * 4);
660 pDImg->cyOffset = 0 + ((SHORT) ulNumfiles * 7);
661 ulNumIcon = ulNumfiles + 1;
662 }
663 ppDITest =
664 xrealloc(ppDItem, sizeof(DRAGITEM *) * (ulNumDIAlloc + 4L),
665 pszSrcFile, __LINE__);
666 if (!ppDITest)
667 break;
668 ppDItem = ppDITest;
669 ulNumDIAlloc += 4L;
670 }
671 // Create & Initialize DRAGITEM
672 pDItem = xmallocz(sizeof(DRAGITEM), pszSrcFile, __LINE__);
673 if (!pDItem)
674 break;
675 ppDItem[ulNumfiles] = pDItem;
676 if (!ulNumIcon) {
677 pDImg = &paDImgIcons[ulNumfiles];
678 pDImg->cb = sizeof(DRAGIMAGE);
679 pDImg->cptl = 0;
680 pDImg->hImage = isdir ? hptrDir : hptrFile;
681 pDImg->fl = DRG_ICON;
682 pDImg->sizlStretch.cx = 32;
683 pDImg->sizlStretch.cy = 32;
684 pDImg->cxOffset = -16 + ((SHORT) ulNumfiles * 3);
685 pDImg->cyOffset = 0 + ((SHORT) ulNumfiles * 6);
686 }
687 pDItem->hwndItem = (hwndObj) ? hwndObj : hwnd;
688 pDItem->ulItemID = (ULONG) ulSelect;
689 pDItem->hstrType = DrgAddStrHandle(DRT_UNKNOWN);
690 ok = pDItem->hstrType;
691 pDItem->hstrRMF = DrgAddStrHandle((CHAR *) DRMDRFLIST);
692 ok = ok && pDItem->hstrRMF;
693 pDItem->hstrContainerName = DrgAddStrHandle(szBuffer);
694 ok = ok && pDItem->hstrContainerName;
695 pDItem->hstrSourceName = DrgAddStrHandle(szFile);
696 ok = ok && pDItem->hstrSourceName;
697 pDItem->hstrTargetName = DrgAddStrHandle(szFile);
698 ok = ok && pDItem->hstrTargetName;
699 if (!ok) {
700 if (pDItem->hstrType)
701 DrgDeleteStrHandle(pDItem->hstrType);
702 if (pDItem->hstrRMF)
703 DrgDeleteStrHandle(pDItem->hstrRMF);
704 if (pDItem->hstrContainerName)
705 DrgDeleteStrHandle(pDItem->hstrContainerName);
706 if (pDItem->hstrSourceName)
707 DrgDeleteStrHandle(pDItem->hstrSourceName);
708 if (pDItem->hstrTargetName)
709 DrgDeleteStrHandle(pDItem->hstrTargetName);
710 free(pDItem);
711 // pDItem = NULL; // Why bother, we can count - fixme to be gone
712 dcd->ulItemsToUnHilite = ulNumfiles + 1;
713 break;
714 }
715 pDItem->fsControl = isdir ? DC_CONTAINER : 0;
716 if (IsFullName(list[ulSelect]) &&
717 (driveflags[toupper(*list[ulSelect]) - 'A'] & DRIVE_REMOVABLE))
718 pDItem->fsControl |= DC_REMOVEABLEMEDIA;
719 pDItem->fsSupportedOps = DO_COPYABLE | DO_LINKABLE;
720 if (moveok && IsFullName(list[ulSelect]) &&
721 !(driveflags[toupper(*list[ulSelect]) - 'A'] & DRIVE_NOTWRITEABLE))
722 pDItem->fsSupportedOps |= DO_MOVEABLE;
723 if (IsRoot(list[ulSelect]))
724 pDItem->fsControl = DO_LINKABLE;
725 ulNumfiles++;
726 // ppDItem[ulNumfiles] = NULL; // Why bother - fixme to be gone
727 }
728 } // for
729 if (ulNumfiles) {
730 pDInfo = DrgAllocDraginfo(ulNumfiles);
731 if (pDInfo) {
732 if ((IsFullName(szBuffer) &&
733 (driveflags[toupper(*szBuffer) - 'A'] & DRIVE_NOTWRITEABLE)))
734 pDInfo->usOperation = DO_COPY;
735 else
736 pDInfo->usOperation = DO_DEFAULT;
737 if (IsRoot(list[0]))
738 pDInfo->usOperation = DO_LINK;
739 pDInfo->hwndSource = hwndObj ? hwndObj : hwnd;
740 // pDInfo->hwndSource = hwnd;
741 for (ulSelect = 0; ulSelect < ulNumfiles; ulSelect++) {
742 if (!DrgSetDragitem(pDInfo, ppDItem[ulSelect], sizeof(DRAGITEM), ulSelect)) {
743 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
744 "DrgSetDragitem");
745 }
746 xfree(ppDItem[ulSelect], pszSrcFile, __LINE__);
747 } // for
748#ifdef __DEBUG_ALLOC__
749 _heap_check();
750#endif
751 xfree(ppDItem, pszSrcFile, __LINE__);
752 ppDItem = NULL; // Remember gone
753 DosPostEventSem(CompactSem);
754
755 if (!ulNumIcon)
756 ulNumIcon = ulNumfiles;
757
758 WinSetFocus(HWND_DESKTOP, HWND_DESKTOP);
759 hDrop = DrgDrag(hwnd,
760 pDInfo,
761 paDImgIcons,
762 ulNumIcon,
763 VK_ENDDRAG, // Drag end button
764 (PVOID) NULL);
765 if (hDrop == NULLHANDLE) {
766 dcd->ulItemsToUnHilite = 0;
767 FreeDragInfoData(hwnd, pDInfo);
768 }
769 xfree(paDImgIcons, pszSrcFile, __LINE__);
770 paDImgIcons = NULL; // Remember gone
771 WinSetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE);
772 DosPostEventSem(CompactSem);
773 }
774 }
775 xfree(ppDItem, pszSrcFile, __LINE__);
776 xfree(paDImgIcons, pszSrcFile, __LINE__);
777 return hDrop;
778}
779
780#ifdef NEVER // fixme to be enabled someday?
781
782BOOL PickUp(HWND hwndCnr, HWND hwndObj, PCNRDRAGINIT pcd)
783{
784
785 PCNRITEM pci;
786 BOOL loop = TRUE;
787 PDRAGINFO pdinfoOld = NULL, pdinfoCurrent = NULL;
788 ULONG cditem = 0;
789 DRAGITEM ditem;
790 DRAGIMAGE dimgFakeIcon;
791 CHAR szDir[CCHMAXPATH], szFile[CCHMAXPATH], *p;
792
793 pci = (PCNRITEM) pcd->pRecord;
794 if (pci && (INT) pci != -1) {
795 if (pci->rc.flRecordAttr & CRA_SELECTED) {
796 loop = TRUE;
797 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS,
798 MPFROMLONG(CMA_FIRST), MPFROMSHORT(CRA_SELECTED));
799 }
800 while (pci && (INT) pci != -1 && *pci->pszFileName) {
801 if (pdinfoOld || DrgQueryDragStatus() & DGS_LAZYDRAGINPROGRESS) {
802 if (!pdinfoOld)
803 pdinfoOld = DrgQueryDraginfoPtr(NULL);
804 if (pdinfoOld) {
805 cditem = pdinfoOld->cditem + 1;
806 pdinfoCurrent = DrgReallocDraginfo(pdinfoOld, cditem);
807 pdinfoOld = pdinfoCurrent;
808 }
809 }
810 else
811 pdinfoCurrent = pdinfoOld = DrgAllocDraginfo(1);
812 if (pdinfoCurrent) {
813 strcpy(szDir, pci->pszFileName);
814 ForwardslashToBackslash(szDir);
815 p = strrchr(szDir, '\\');
816 if (p) {
817 *p = 0;
818 p++;
819 strcpy(szFile, p);
820 strcat(szDir, PCSZ_BACKSLASH);
821 }
822 else {
823 strcpy(szFile, pci->pszFileName);
824 *szDir = 0;
825 }
826 ditem.ulItemID = (ULONG) pci;
827 ditem.hwndItem = (hwndObj) ? hwndObj : hwndCnr;
828 ditem.hstrType = DrgAddStrHandle(DRT_UNKNOWN);
829 ditem.hstrRMF = DrgAddStrHandle(DRMDRFLIST);
830 ditem.hstrContainerName = DrgAddStrHandle(szDir);
831 ditem.hstrSourceName = DrgAddStrHandle(szFile);
832 // fixme to check better if code ever enabled
833 if (!ditem.hstrSourceName) {
834 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
835 "DrgAddStrHandle");
836 }
837 ditem.hstrTargetName = DrgAddStrHandle(szFile);
838 ditem.fsControl = 0;
839 if (IsRoot(pci->pszFileName) || (pci->attrFile & FILE_DIRECTORY) != 0)
840 ditem.fsControl |= DC_CONTAINER;
841 if (IsFullName(pci->pszFileName) &&
842 (driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_REMOVABLE))
843 ditem.fsControl |= DC_REMOVEABLEMEDIA;
844 ditem.fsSupportedOps = DO_COPYABLE | DO_LINKABLE;
845 if (IsFullName(pci->pszFileName) &&
846 !(driveflags[toupper(*pci->pszFileName) - 'A'] &
847 DRIVE_NOTWRITEABLE))
848 ditem.fsSupportedOps |= DO_MOVEABLE;
849 if (IsRoot(pci->pszFileName))
850 ditem.fsSupportedOps = DO_LINKABLE;
851 memset(&dimgFakeIcon, 0, sizeof(DRAGIMAGE));
852 dimgFakeIcon.hImage = pci->rc.hptrIcon;
853 dimgFakeIcon.cb = sizeof(DRAGIMAGE);
854 dimgFakeIcon.cptl = 0;
855 dimgFakeIcon.fl = DRG_ICON;
856 dimgFakeIcon.sizlStretch.cx = 32;
857 dimgFakeIcon.sizlStretch.cy = 32;
858 dimgFakeIcon.cxOffset = -16;
859 dimgFakeIcon.cyOffset = 0;
860 if (IsFullName(pci->pszFileName) &&
861 (driveflags[toupper(*pci->pszFileName) - 'A'] &
862 DRIVE_NOTWRITEABLE))
863 pdinfoCurrent->usOperation = DO_COPY;
864 else
865 pdinfoCurrent->usOperation = DO_DEFAULT;
866 if (IsRoot(pci->pszFileName))
867 pdinfoCurrent->usOperation = DO_LINK;
868 pdinfoCurrent->hwndSource = (hwndObj) ? hwndObj : hwndCnr;
869 DrgSetDragitem(pdinfoCurrent, &ditem, sizeof(DRAGITEM), cditem);
870 }
871 if (!loop)
872 break;
873 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS,
874 MPFROMP(pci), MPFROMSHORT(CRA_SELECTED));
875 } // while
876 if (pdinfoCurrent)
877 return DrgLazyDrag(hwndCnr, pdinfoCurrent, &dimgFakeIcon, 1, NULL);
878 }
879 return FALSE;
880}
881
882#endif // NEVER
883
884#pragma alloc_text(DRAGLIST,DragOne,DoFileDrag,DragList,PickUp,FreeDragInfoData)
Note: See TracBrowser for help on using the repository browser.