source: trunk/dll/draglist.c

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

Remove some dead code and comments source files starting with A-D

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 28.1 KB
RevLine 
[38]1
2/***********************************************************************
3
4 $Id: draglist.c 1878 2015-10-11 22:24:39Z gyoung $
5
6 Drag drop support
7
8 Copyright (c) 1993-98 M. Kimes
[1498]9 Copyright (c) 2001, 2010 Steven H.Levine
[38]10
[364]11 16 Oct 02 SHL DoFileDrag: don't free stack
12 26 Jul 06 SHL Check more run time errors
[603]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
[618]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
[628]19 21 Apr 07 SHL Avoid odd first time drag failure
[672]20 12 May 07 SHL Use dcd->ulItemsToUnHilite
[985]21 05 Jul 07 SHL FreeDragInfoData: suppress PMERR_SOURCE_SAME_AS_TARGET notices
[793]22 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
[985]23 29 Feb 08 GKY Use xmallocz where appropriate
[1402]24 08 Mar 09 GKY Additional strings move to PCSZs
[1453]25 12 Sep 09 GKY Fix (probably spurrious) error message generated on drag of
26 items from a pmmail mail message (PMERR_INVALID_PARAMETER)
[1498]27 17 JAN 10 GKY Changes to get working with Watcom 1.9 Beta (1/16/10). Mostly cast CHAR CONSTANT * as CHAR *.
[1545]28 23 Oct 10 GKY Add ForwardslashToBackslash function to streamline code
[38]29
30***********************************************************************/
31
[907]32#include <stdlib.h>
33#include <string.h>
34#include <ctype.h>
35
[2]36#define INCL_DOS
37#define INCL_WIN
[618]38#define INCL_SHLERRORS
[841]39#define INCL_LONGLONG
[2]40
[1181]41#include "fm3dll.h"
[1207]42#include "info.h" // Data declaration(s)
43#include "init.h" // Data declaration(s)
44#include "newview.h" // Data declarations
[907]45#include "errutil.h" // Dos_Error...
[1158]46#include "draglist.h"
47#include "valid.h" // IsValidDrive
[1181]48#include "misc.h" // IsFm2Window
49#include "select.h" // MarkAll
50#include "wrappers.h" // xrealloc
[1011]51#include "fortify.h"
[1545]52#include "pathutil.h" // ForwardslashToBackslash
[2]53
[1207]54// Data definitions
[364]55static PSZ pszSrcFile = __FILE__;
56
[1207]57#pragma data_seg(GLOBAL1)
58HPOINTER hptrDir;
59HPOINTER hptrFile;
60HPOINTER hptrLast;
61
62#pragma data_seg(GLOBAL2)
[1402]63PCSZ DRMDRFLIST = "<DRM_OS2FILE,DRF_UNKNOWN>," "<DRM_DISCARD,DRF_UNKNOWN>," "<DRM_PRINT,DRF_UNKNOWN>";
[1207]64
[618]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)
[603]76{
[606]77
[1461]78//# ifdef USE_FAST_FREE
[1463]79 if (!IsFm2Window(pDInfo->hwndSource, FALSE)) {
[1461]80 if (!DrgDeleteDraginfoStrHandles(pDInfo)) {
[618]81 Win_Error(hwnd, hwnd, pszSrcFile, __LINE__,
[1461]82 "DrgDeleteDraginfoStrHandles");
[618]83 }
[1461]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);
[618]98 }
[1461]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 }
[618]134 }
[1461]135 } // for
136 }
137//# endif
[618]138 if (!DrgFreeDraginfo(pDInfo)) {
[727]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");
[618]144 }
145 }
[603]146}
147
[551]148HWND DragOne(HWND hwndCnr, HWND hwndObj, CHAR * filename, BOOL moveok)
149{
[2]150
[551]151 DRAGITEM DItem;
152 HWND hDrop = 0;
153 DRAGIMAGE fakeicon;
154 PDRAGINFO pDInfo;
[847]155 FILESTATUS3 fs3;
[551]156 CHAR szDir[CCHMAXPATH], szFile[CCHMAXPATH], *p;
[2]157
[551]158 if (filename && *filename) {
159 if ((IsRoot(filename) && IsValidDrive(*filename)) ||
[847]160 !DosQueryPathInfo(filename, FIL_STANDARD, &fs3, sizeof(fs3))) {
[551]161 strcpy(szDir, filename);
[1545]162 ForwardslashToBackslash(szDir);
[551]163 p = strrchr(szDir, '\\');
164 if (p) {
165 *p = 0;
166 p++;
167 strcpy(szFile, p);
[1438]168 strcat(szDir, PCSZ_BACKSLASH);
[2]169 }
170 else {
[551]171 strcpy(szFile, filename);
172 *szDir = 0;
[2]173 }
[551]174 memset(&fakeicon, 0, sizeof(DRAGIMAGE));
[2]175 fakeicon.hImage = (IsRoot(filename) ||
[551]176 (fs3.attrFile & FILE_DIRECTORY) != 0) ?
177 hptrDir : hptrFile;
178 memset(&DItem, 0, sizeof(DRAGITEM));
[618]179 DItem.hwndItem = (hwndObj) ? hwndObj : hwndCnr; // Initialize DRAGITEM
[38]180 // DItem.hwndItem = hwndCnr;
[2]181 DItem.ulItemID = 1;
182 DItem.hstrType = DrgAddStrHandle(DRT_UNKNOWN);
[1498]183 DItem.hstrRMF = DrgAddStrHandle((CHAR *) DRMDRFLIST);
[2]184 DItem.hstrContainerName = DrgAddStrHandle(szDir);
185 DItem.hstrSourceName = DrgAddStrHandle(szFile);
[606]186 if (!DItem.hstrSourceName)
[618]187 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
188 "DrgQueryStrName");
[2]189 DItem.hstrTargetName = DrgAddStrHandle(szFile);
190 DItem.fsControl = 0;
[551]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;
[2]196 DItem.fsSupportedOps = DO_COPYABLE | DO_LINKABLE;
[551]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;
[2]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;
[618]209 pDInfo = DrgAllocDraginfo(1);
[551]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;
[618]220 DrgSetDragitem(pDInfo, &DItem, sizeof(DRAGITEM), 0);
[551]221 WinSetFocus(HWND_DESKTOP, HWND_DESKTOP);
[618]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);
[551]230 WinSetWindowPos(hwndCnr, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE);
[2]231 }
232 }
233 }
234 return hDrop;
235}
236
[551]237HWND DoFileDrag(HWND hwndCnr, HWND hwndObj, PCNRDRAGINIT pcd, CHAR * arcfile,
238 CHAR * directory, BOOL moveok)
[38]239{
[618]240 // Drag files from a container
[2]241
[551]242 BOOL isdir, rooting = FALSE;
243 PCNRITEM pci;
[618]244 CHAR *p;
[551]245 INT attribute = CRA_CURSORED;
246 PDRAGINFO pDInfo = NULL;
[618]247 DRAGITEM **ppDItem = NULL, **ppDITest;
248 DRAGITEM *pDItem;
[551]249 PCNRITEM pciRec = (PCNRITEM) pcd->pRecord;
[618]250 HWND hDrop = NULLHANDLE;
251 ULONG ulNumfiles = 0, ulNumDIAlloc = 0, ulSelect, ulNumIcon = 0;
[551]252 CHAR szFile[CCHMAXPATH], szBuffer[CCHMAXPATH];
[618]253 DRAGIMAGE *paDImgIcons = NULL, *pDImg, dimgFakeIcon;
254 BOOL ok;
[628]255 UINT c;
[672]256 DIRCNRDATA *dcd;
[2]257
[628]258 static BOOL first_drag = TRUE;
259
[672]260 // Count items to unhilite, pass to UnHilite when partial unhilite required
261 dcd = INSTDATA(hwndCnr);
[1641]262 if (!dcd)
263 return hDrop;
[672]264 dcd->ulItemsToUnHilite = 0;
[551]265 if (!pciRec && directory && *directory)
266 return DragOne(hwndCnr, hwndObj, directory, moveok);
[2]267
[551]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));
[2]278 }
279 }
280 }
281 else {
[38]282 pci = pciRec;
[2]283 attribute = (pci->rc.flRecordAttr & CRA_SELECTED) ? CRA_SELECTED : 0;
[551]284 if (attribute) {
285 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
286 MPFROMSHORT(attribute));
[2]287 }
288 }
289
[618]290 ulSelect = 0;
[551]291 while (pci && (INT) pci > -1) {
292 if (!(pci->rc.flRecordAttr & CRA_FILTERED)) {
[730]293 if (IsRoot(pci->pszFileName) && !IsValidDrive(*pci->pszFileName))
[551]294 goto Continuing;
295 if (!arcfile) {
[730]296 strcpy(szBuffer, pci->pszFileName);
[551]297 p = strrchr(szBuffer, '\\');
298 if (p) {
299 p++;
300 strcpy(szFile, p);
301 *p = 0;
302 }
303 else
304 goto Continuing;
[2]305 }
306 else
[730]307 strcpy(szFile, pci->pszFileName);
[2]308 }
[551]309 if (!arcfile) {
[38]310 // Filesystem object
[618]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),
[551]318 pszSrcFile, __LINE__);
[618]319 if (!pDImg)
[551]320 break;
[618]321 paDImgIcons = pDImg;
[551]322 }
323 else if (!ulNumIcon) {
[618]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;
[1533]331 pDImg->cxOffset = -16 + ((SHORT) ulNumfiles * 4);
332 pDImg->cyOffset = 0 + ((SHORT) ulNumfiles * 7);
[551]333 ulNumIcon = ulNumfiles + 1;
334 }
[618]335 ppDITest =
336 xrealloc(ppDItem, sizeof(DRAGITEM *) * (ulNumDIAlloc + 4L),
[551]337 pszSrcFile, __LINE__);
[618]338 if (!ppDITest)
[551]339 break;
[618]340 ppDItem = ppDITest;
341 ulNumDIAlloc += 4L;
[2]342 }
[985]343 // Create & Initialize DRAGITEM
344 pDItem = xmallocz(sizeof(DRAGITEM), pszSrcFile, __LINE__);
[618]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;
[1533]358 pDImg->cxOffset = -16 + ((SHORT) ulNumfiles * 3);
359 pDImg->cyOffset = 0 + ((SHORT) ulNumfiles * 6);
[2]360 }
[618]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;
[1498]366 pDItem->hstrRMF = DrgAddStrHandle((CHAR *) DRMDRFLIST);
[618]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) {
[628]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);
[1039]391 free(pDItem);
[628]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
[672]400 dcd->ulItemsToUnHilite = ulNumfiles + 1;
[551]401 break;
[618]402 }
403 pDItem->fsControl = isdir ? DC_CONTAINER : 0;
[730]404 if (IsFullName(pci->pszFileName) &&
405 (driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_REMOVABLE))
[618]406 pDItem->fsControl |= DC_REMOVEABLEMEDIA;
407 pDItem->fsSupportedOps = DO_COPYABLE | DO_LINKABLE;
[730]408 if (moveok && IsFullName(pci->pszFileName) &&
409 !(driveflags[toupper(*pci->pszFileName) - 'A'] &
[618]410 DRIVE_NOTWRITEABLE))
411 pDItem->fsSupportedOps |= DO_MOVEABLE;
[730]412 if (IsRoot(pci->pszFileName)) {
[618]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?
[628]418 } // if filesystem object
[2]419 else {
[38]420 // Archive object
[618]421 if (ulNumfiles + 3L > ulNumDIAlloc) {
422 ppDITest =
423 xrealloc(ppDItem, sizeof(DRAGITEM *) * (ulNumDIAlloc + 5L),
[551]424 pszSrcFile, __LINE__);
[618]425 if (!ppDITest)
[551]426 break;
[618]427 ppDItem = ppDITest;
428 ulNumDIAlloc += 5L;
[2]429 }
[985]430 // Create & Initialize DRAGITEM
431 pDItem = xmallocz(sizeof(DRAGITEM), pszSrcFile, __LINE__);
[618]432 if (!pDItem)
[551]433 break;
[618]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;
[1498]441 pDItem->hstrRMF = DrgAddStrHandle((CHAR *) DRMDRFOS2FILE);
[618]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);
[1039]460 free(pDItem);
[672]461 dcd->ulItemsToUnHilite = ulNumfiles + 1; // +1 to ensure non-zero
[618]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++;
[985]470 // Create & Initialize DRAGITEM
471 pDItem = xmallocz(sizeof(DRAGITEM), pszSrcFile, __LINE__);
[618]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;
[1498]480 pDItem->hstrRMF = DrgAddStrHandle((CHAR *) DRMDRFFM2ARC);
[618]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) {
[628]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);
[1039]505 free(pDItem);
[628]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
[672]514 dcd->ulItemsToUnHilite = ulNumfiles + 1;
[618]515 break;
516 }
517 pDItem->fsControl = 0;
[551]518 if (IsFullName(arcfile) &&
519 (driveflags[toupper(*arcfile) - 'A'] & DRIVE_REMOVABLE))
[618]520 pDItem->fsControl |= DC_REMOVEABLEMEDIA;
521 pDItem->fsSupportedOps = DO_COPYABLE;
[551]522 ulNumfiles++;
[2]523 }
[618]524 // ppDItem[ulNumfiles] = NULL; // Why bother - fixme to be gone?
[628]525 } // if archive object
[551]526 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
527 MPFROM2SHORT(TRUE, CRA_SOURCE));
[2]528
[551]529 Continuing:
[2]530
[551]531 if (!attribute)
[2]532 break;
[551]533 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMP(pci),
534 MPFROMSHORT(attribute));
[618]535 } // while
536
[551]537 if (ulNumfiles) {
[618]538 pDInfo = DrgAllocDraginfo(ulNumfiles);
[551]539 if (pDInfo) {
540 if ((arcfile && *arcfile) || (IsFullName(szBuffer) &&
541 (driveflags[toupper(*szBuffer) - 'A'] &
542 DRIVE_NOTWRITEABLE)))
543 pDInfo->usOperation = DO_COPY;
[2]544 else
[551]545 pDInfo->usOperation = DO_DEFAULT;
546 if ((!arcfile || !*arcfile) && rooting)
547 pDInfo->usOperation = DO_LINK;
[2]548 pDInfo->hwndSource = (hwndObj) ? hwndObj : hwndCnr;
[38]549 // pDInfo->hwndSource = hwndCnr;
[618]550 for (ulSelect = 0; ulSelect < ulNumfiles; ulSelect++) {
551 DrgSetDragitem(pDInfo, ppDItem[ulSelect], sizeof(DRAGITEM), ulSelect);
[1009]552 xfree(ppDItem[ulSelect], pszSrcFile, __LINE__);
[2]553 }
554#ifdef __DEBUG_ALLOC__
555 _heap_check();
556#endif
[1009]557 xfree(ppDItem, pszSrcFile, __LINE__);
[618]558 ppDItem = NULL; // Remember gone
[2]559 DosPostEventSem(CompactSem);
560
[551]561 if (arcfile) {
[618]562 dimgFakeIcon.cb = sizeof(DRAGIMAGE);
563 dimgFakeIcon.cptl = 0;
[551]564 if (ulNumfiles > 1)
[618]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;
[2]572 }
[551]573 if (!arcfile) {
574 if (!ulNumIcon)
575 ulNumIcon = ulNumfiles;
[2]576 }
577 else
[618]578 ulNumIcon = 1;
[2]579
[551]580 WinSetFocus(HWND_DESKTOP, HWND_DESKTOP);
[618]581 hDrop = DrgDrag(hwndCnr,
582 pDInfo,
583 paDImgIcons,
584 ulNumIcon,
585 VK_ENDDRAG, // Drag end button
586 NULL);
[551]587 WinSetWindowPos(hwndCnr, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE);
[2]588 }
589 }
[618]590
591 if (hDrop == NULLHANDLE ) {
[672]592 dcd->ulItemsToUnHilite = 0;
[618]593 if (pDInfo)
594 FreeDragInfoData(hwndCnr, pDInfo);
595 }
[1039]596 xfree(ppDItem, pszSrcFile, __LINE__);
[618]597 if (paDImgIcons && paDImgIcons != &dimgFakeIcon)
[1039]598 free(paDImgIcons);
[618]599 DosPostEventSem(CompactSem);
[551]600 MarkAll(hwndCnr, TRUE, FALSE, TRUE);
[2]601 return hDrop;
602}
603
[551]604HWND DragList(HWND hwnd, HWND hwndObj, CHAR ** list, BOOL moveok)
605{
[618]606 // Drag a linked list of files
[2]607
[551]608 BOOL isdir;
609 register CHAR *p;
610 PDRAGINFO pDInfo = NULL;
[618]611 DRAGITEM **ppDItem = NULL, **ppDITest;
612 DRAGITEM *pDItem;
[551]613 HWND hDrop = (HWND) 0;
[618]614 ULONG ulNumfiles = 0, ulNumDIAlloc = 0, ulSelect, ulNumIcon = 0;
[551]615 CHAR szFile[CCHMAXPATH], szBuffer[CCHMAXPATH];
[618]616 DRAGIMAGE *paDImgIcons = NULL, *pDImg;
[847]617 FILESTATUS3 fs3;
[618]618 BOOL ok;
[672]619 DIRCNRDATA *dcd;
[2]620
[551]621 if (!list || !list[0])
[2]622 return hDrop;
[672]623
624 dcd = INSTDATA(hwnd);
625
[618]626 for (ulSelect = 0; list[ulSelect]; ulSelect++) {
627 if ((!IsRoot(list[ulSelect]) || !IsValidDrive(*list[ulSelect])) &&
[847]628 DosQueryPathInfo(list[ulSelect], FIL_STANDARD, &fs3, sizeof(fs3)))
[2]629 continue;
[618]630 strcpy(szBuffer, list[ulSelect]);
[551]631 p = strrchr(szBuffer, '\\');
632 if (p) {
[2]633 p++;
[551]634 strcpy(szFile, p);
[2]635 *p = 0;
636 }
637 else
638 continue;
[551]639 if (*szFile) {
[618]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),
[551]646 pszSrcFile, __LINE__);
[618]647 if (!pDImg)
[551]648 break;
[618]649 paDImgIcons = pDImg;
[551]650 }
651 else if (!ulNumIcon) {
[618]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;
[1533]659 pDImg->cxOffset = -16 + ((SHORT) ulNumfiles * 4);
660 pDImg->cyOffset = 0 + ((SHORT) ulNumfiles * 7);
[551]661 ulNumIcon = ulNumfiles + 1;
662 }
[618]663 ppDITest =
664 xrealloc(ppDItem, sizeof(DRAGITEM *) * (ulNumDIAlloc + 4L),
[551]665 pszSrcFile, __LINE__);
[618]666 if (!ppDITest)
[551]667 break;
[618]668 ppDItem = ppDITest;
669 ulNumDIAlloc += 4L;
[2]670 }
[985]671 // Create & Initialize DRAGITEM
672 pDItem = xmallocz(sizeof(DRAGITEM), pszSrcFile, __LINE__);
[618]673 if (!pDItem)
[551]674 break;
[618]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;
[1533]684 pDImg->cxOffset = -16 + ((SHORT) ulNumfiles * 3);
685 pDImg->cyOffset = 0 + ((SHORT) ulNumfiles * 6);
[2]686 }
[618]687 pDItem->hwndItem = (hwndObj) ? hwndObj : hwnd;
688 pDItem->ulItemID = (ULONG) ulSelect;
689 pDItem->hstrType = DrgAddStrHandle(DRT_UNKNOWN);
690 ok = pDItem->hstrType;
[1498]691 pDItem->hstrRMF = DrgAddStrHandle((CHAR *) DRMDRFLIST);
[618]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);
[1039]710 free(pDItem);
[672]711 dcd->ulItemsToUnHilite = ulNumfiles + 1;
[618]712 break;
713 }
714 pDItem->fsControl = isdir ? DC_CONTAINER : 0;
715 if (IsFullName(list[ulSelect]) &&
716 (driveflags[toupper(*list[ulSelect]) - 'A'] & DRIVE_REMOVABLE))
717 pDItem->fsControl |= DC_REMOVEABLEMEDIA;
718 pDItem->fsSupportedOps = DO_COPYABLE | DO_LINKABLE;
719 if (moveok && IsFullName(list[ulSelect]) &&
720 !(driveflags[toupper(*list[ulSelect]) - 'A'] & DRIVE_NOTWRITEABLE))
721 pDItem->fsSupportedOps |= DO_MOVEABLE;
722 if (IsRoot(list[ulSelect]))
723 pDItem->fsControl = DO_LINKABLE;
724 ulNumfiles++;
[2]725 }
[618]726 } // for
[364]727 if (ulNumfiles) {
[618]728 pDInfo = DrgAllocDraginfo(ulNumfiles);
[364]729 if (pDInfo) {
730 if ((IsFullName(szBuffer) &&
[551]731 (driveflags[toupper(*szBuffer) - 'A'] & DRIVE_NOTWRITEABLE)))
732 pDInfo->usOperation = DO_COPY;
[2]733 else
[551]734 pDInfo->usOperation = DO_DEFAULT;
[364]735 if (IsRoot(list[0]))
[551]736 pDInfo->usOperation = DO_LINK;
[618]737 pDInfo->hwndSource = hwndObj ? hwndObj : hwnd;
738 for (ulSelect = 0; ulSelect < ulNumfiles; ulSelect++) {
739 if (!DrgSetDragitem(pDInfo, ppDItem[ulSelect], sizeof(DRAGITEM), ulSelect)) {
740 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
741 "DrgSetDragitem");
742 }
[1032]743 xfree(ppDItem[ulSelect], pszSrcFile, __LINE__);
[618]744 } // for
[2]745#ifdef __DEBUG_ALLOC__
746 _heap_check();
747#endif
[1009]748 xfree(ppDItem, pszSrcFile, __LINE__);
[618]749 ppDItem = NULL; // Remember gone
[2]750 DosPostEventSem(CompactSem);
751
[551]752 if (!ulNumIcon)
753 ulNumIcon = ulNumfiles;
[2]754
[551]755 WinSetFocus(HWND_DESKTOP, HWND_DESKTOP);
[618]756 hDrop = DrgDrag(hwnd,
757 pDInfo,
758 paDImgIcons,
759 ulNumIcon,
760 VK_ENDDRAG, // Drag end button
761 (PVOID) NULL);
762 if (hDrop == NULLHANDLE) {
[672]763 dcd->ulItemsToUnHilite = 0;
[618]764 FreeDragInfoData(hwnd, pDInfo);
765 }
[1009]766 xfree(paDImgIcons, pszSrcFile, __LINE__);
[618]767 paDImgIcons = NULL; // Remember gone
[551]768 WinSetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE);
[2]769 DosPostEventSem(CompactSem);
770 }
771 }
[1009]772 xfree(ppDItem, pszSrcFile, __LINE__);
773 xfree(paDImgIcons, pszSrcFile, __LINE__);
[2]774 return hDrop;
775}
776
[618]777#ifdef NEVER // fixme to be enabled someday?
[2]778
[551]779BOOL PickUp(HWND hwndCnr, HWND hwndObj, PCNRDRAGINIT pcd)
780{
[2]781
[551]782 PCNRITEM pci;
783 BOOL loop = TRUE;
784 PDRAGINFO pdinfoOld = NULL, pdinfoCurrent = NULL;
785 ULONG cditem = 0;
786 DRAGITEM ditem;
[618]787 DRAGIMAGE dimgFakeIcon;
[551]788 CHAR szDir[CCHMAXPATH], szFile[CCHMAXPATH], *p;
[2]789
[551]790 pci = (PCNRITEM) pcd->pRecord;
791 if (pci && (INT) pci != -1) {
792 if (pci->rc.flRecordAttr & CRA_SELECTED) {
[2]793 loop = TRUE;
[551]794 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS,
795 MPFROMLONG(CMA_FIRST), MPFROMSHORT(CRA_SELECTED));
[2]796 }
[730]797 while (pci && (INT) pci != -1 && *pci->pszFileName) {
[551]798 if (pdinfoOld || DrgQueryDragStatus() & DGS_LAZYDRAGINPROGRESS) {
799 if (!pdinfoOld)
800 pdinfoOld = DrgQueryDraginfoPtr(NULL);
801 if (pdinfoOld) {
802 cditem = pdinfoOld->cditem + 1;
803 pdinfoCurrent = DrgReallocDraginfo(pdinfoOld, cditem);
804 pdinfoOld = pdinfoCurrent;
805 }
[2]806 }
807 else
[551]808 pdinfoCurrent = pdinfoOld = DrgAllocDraginfo(1);
809 if (pdinfoCurrent) {
[1545]810 strcpy(szDir, pci->pszFileName);
811 ForwardslashToBackslash(szDir);
[551]812 p = strrchr(szDir, '\\');
813 if (p) {
814 *p = 0;
815 p++;
816 strcpy(szFile, p);
[1438]817 strcat(szDir, PCSZ_BACKSLASH);
[551]818 }
819 else {
[730]820 strcpy(szFile, pci->pszFileName);
[551]821 *szDir = 0;
822 }
823 ditem.ulItemID = (ULONG) pci;
824 ditem.hwndItem = (hwndObj) ? hwndObj : hwndCnr;
825 ditem.hstrType = DrgAddStrHandle(DRT_UNKNOWN);
826 ditem.hstrRMF = DrgAddStrHandle(DRMDRFLIST);
827 ditem.hstrContainerName = DrgAddStrHandle(szDir);
828 ditem.hstrSourceName = DrgAddStrHandle(szFile);
[618]829 // fixme to check better if code ever enabled
830 if (!ditem.hstrSourceName) {
831 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
832 "DrgAddStrHandle");
833 }
[551]834 ditem.hstrTargetName = DrgAddStrHandle(szFile);
835 ditem.fsControl = 0;
[730]836 if (IsRoot(pci->pszFileName) || (pci->attrFile & FILE_DIRECTORY) != 0)
[551]837 ditem.fsControl |= DC_CONTAINER;
[730]838 if (IsFullName(pci->pszFileName) &&
839 (driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_REMOVABLE))
[551]840 ditem.fsControl |= DC_REMOVEABLEMEDIA;
841 ditem.fsSupportedOps = DO_COPYABLE | DO_LINKABLE;
[730]842 if (IsFullName(pci->pszFileName) &&
843 !(driveflags[toupper(*pci->pszFileName) - 'A'] &
[551]844 DRIVE_NOTWRITEABLE))
845 ditem.fsSupportedOps |= DO_MOVEABLE;
[730]846 if (IsRoot(pci->pszFileName))
[551]847 ditem.fsSupportedOps = DO_LINKABLE;
[618]848 memset(&dimgFakeIcon, 0, sizeof(DRAGIMAGE));
849 dimgFakeIcon.hImage = pci->rc.hptrIcon;
850 dimgFakeIcon.cb = sizeof(DRAGIMAGE);
851 dimgFakeIcon.cptl = 0;
852 dimgFakeIcon.fl = DRG_ICON;
853 dimgFakeIcon.sizlStretch.cx = 32;
854 dimgFakeIcon.sizlStretch.cy = 32;
855 dimgFakeIcon.cxOffset = -16;
856 dimgFakeIcon.cyOffset = 0;
[730]857 if (IsFullName(pci->pszFileName) &&
858 (driveflags[toupper(*pci->pszFileName) - 'A'] &
[551]859 DRIVE_NOTWRITEABLE))
860 pdinfoCurrent->usOperation = DO_COPY;
861 else
862 pdinfoCurrent->usOperation = DO_DEFAULT;
[730]863 if (IsRoot(pci->pszFileName))
[551]864 pdinfoCurrent->usOperation = DO_LINK;
865 pdinfoCurrent->hwndSource = (hwndObj) ? hwndObj : hwndCnr;
866 DrgSetDragitem(pdinfoCurrent, &ditem, sizeof(DRAGITEM), cditem);
[2]867 }
[551]868 if (!loop)
869 break;
870 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS,
871 MPFROMP(pci), MPFROMSHORT(CRA_SELECTED));
[618]872 } // while
[551]873 if (pdinfoCurrent)
[618]874 return DrgLazyDrag(hwndCnr, pdinfoCurrent, &dimgFakeIcon, 1, NULL);
[2]875 }
876 return FALSE;
877}
878
[38]879#endif // NEVER
[793]880
881#pragma alloc_text(DRAGLIST,DragOne,DoFileDrag,DragList,PickUp,FreeDragInfoData)
Note: See TracBrowser for help on using the repository browser.