15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Drag n'Drop on desktop

Noel DANJOU -- NoelD@msn.com
Sunday, February 16, 1997

Hello,

Environment : VC++ 4.2-flat, Win 95

In one application I would like to be able to drag one or more items from a 
CListView to one or more text files on the desktop. I found out that I need to 
register the CFSTR_FILECONTENTS & CFSTR_FILEGROUPDESCRIPTOR clipboard formats 
and use COleDataSource but that does not work with the code I wrote and I 
can't figure out where I am wrong. Please could you help me debug my code I 
attached it below :

Thanks for your time,

Noel

-- S O U R C E    C O D E --

in View :

// refdbView.cpp : implementation of the CRefdbView class
//

#include "stdafx.h"
#include "afxole.h"
#include "refdb.h"

#include "DataSrc.h"	// OLE Drag n'Drop source
#include "shlobj.h"		// CFSTR_* definitions

#include "reflectr.h"
#include "refdbDoc.h"
#include "refdbVw.h"
#include "tools.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

[...]

UINT	gcfFileContents = 0;
UINT	gcfFileGroupDescriptor = 0;


[...]

/////////////////////////////////////////////////////////////////////////////
// CRefdbView message handlers

int CRefdbView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	lpCreateStruct->style |= LVS_REPORT | LVS_OWNERDRAWFIXED;
	if (CListView::OnCreate(lpCreateStruct) == -1)
		return -1;

	// Give the document a pointer to this view
	GetDocument()->m_pListView = this;

	CreateColumns();

	gcfFileContents = RegisterClipboardFormat(CFSTR_FILECONTENTS);
	gcfFileGroupDescriptor = RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR);

	return 0;
}

[...]

/////////////////////////////////////////////////////////////////////////////
// Drag n'Drop

[...]

void CRefdbView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	CListView::OnLButtonDown(nFlags, point);

	CListCtrlEx& ctlList = (CListCtrlEx&)GetListCtrl();

	// Create an OLE data source on the heap
	CReflectorDataSource* pDataSource = NULL;

	pDataSource = new CReflectorDataSource;

	pDataSource->SetListCtrl(&ctlList);

	// default FORMATETC is NULL -> tymed = TYMED_HGLOBAL
	pDataSource->DelayRenderData(CF_TEXT);					// e.g. target is WordPad
	pDataSource->DelayRenderData(gcfFileContents);			// e.g. target is Desktop
	pDataSource->DelayRenderData(gcfFileGroupDescriptor);	// required by 
FileContents

	// Uses default COleDropSource implementation.
	if (DROPEFFECT_MOVE == 
		pDataSource->DoDragDrop(DROPEFFECT_COPY | DROPEFFECT_MOVE))
	{
		// TODO: remove items
	}

	delete pDataSource;
}

void CRefdbView::OnEditCopy() 
{
	CReflectorDataSource* pDataSource = NULL; 
	CListCtrlEx& ctlList = (CListCtrlEx&)GetListCtrl();

	pDataSource = new CReflectorDataSource;

	pDataSource->SetListCtrl(&ctlList);
	
	// default FORMATETC is NULL -> tymed = TYMED_HGLOBAL
	pDataSource->DelayRenderData(CF_TEXT);	// e.g. target is WordPad

	// The Clipboard now owns the allocated memory and will delete this 
	// data object when new data is put on the Clipboard
	pDataSource->SetClipboard();

	delete pDataSource;
}

void CRefdbView::OnUpdateEditCopy(CCmdUI* pCmdUI) 
{
	CListCtrl& ctlList = (CListCtrl&)GetListCtrl();

	pCmdUI->Enable(ctlList.GetSelectedCount() > 0);
}

[...]


in DataSrc.cpp :
---------------------

// DataSrc.cpp : implementation file
//

#include "stdafx.h"
#include "refdb.h"
#include "reflectr.h"
#include "DataSrc.h"
#include "shlobj.h"	// FILEGROUPDESCRIPTOR structure definition

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define CU_FILE_SIZE	215
#define CU_DATA_SIZE	1024

extern UINT gcfFileContents;
extern UINT gcfFileGroupDescriptor;

/////////////////////////////////////////////////////////////////////////////
// CReflectorDataSource

CReflectorDataSource::CReflectorDataSource()
{
	m_pCtlList = NULL;
}

CReflectorDataSource::~CReflectorDataSource()
{
}


BEGIN_MESSAGE_MAP(CReflectorDataSource, COleDataSource)
	//{{AFX_MSG_MAP(CReflectorDataSource)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CReflectorDataSource message handlers

BOOL CReflectorDataSource::OnRenderGlobalData(LPFORMATETC lpFormatEtc, 
HGLOBAL* phGlobal) 
{
	ASSERT(gcfFileContents);
	ASSERT(gcfFileGroupDescriptor);

	if (lpFormatEtc->cfFormat == CF_TEXT)
	{
		CreateText(phGlobal);
	}
	else
	if (lpFormatEtc->cfFormat == gcfFileContents)
	{
		CreateFileContents(phGlobal);
	}
	else
	if (lpFormatEtc->cfFormat == gcfFileGroupDescriptor)
	{
		CreateFileDescriptor(phGlobal);
	}
	else
	{
		TRACE("OnRenderGlobalData() : Format not supported !\n");
		return FALSE;
	}

	if (*phGlobal == NULL)
		return FALSE;
	
	return TRUE;
}

void CReflectorDataSource::CreateText(HGLOBAL* phData)
{
	TRACE("CreateText()\n");

	HGLOBAL hData = *phData;

	ASSERT(m_pCtlList != NULL);

	int count = m_pCtlList->GetSelectedCount();

	// allocate space for the number of reflector items
	if (hData == NULL)
		hData = GlobalAlloc(GHND | GMEM_SHARE, (DWORD)(sizeof(TCHAR) * CU_DATA_SIZE 
* count));

	// Failure ?
	if (hData == NULL) 
		return;	

	CString strYes;
	CString strNo;
	CString strCountry;
	CString strLetters;
	CString strFullName;
	CString strShortName;
	CString strIPAddress;
	CString strContactName;
	CString strContactEmail;
	CString strConferenceID;
	CString strAddToMenu;
	CString strSendVideo;
	CString strReceiveVideo;
	CString strIsRunning;

	strYes.LoadString(IDS_YES);
	strNo.LoadString(IDS_NO);
	strCountry.LoadString(IDS_COUNTRY);
	strLetters.LoadString(IDS_LETTERS);
	strFullName.LoadString(IDS_FULLNAME);
	strShortName.LoadString(IDS_SHORTNAME);
	strIPAddress.LoadString(IDS_IPADDRESS);
	strContactName.LoadString(IDS_CONTACT_NAME);
	strContactEmail.LoadString(IDS_CONTACT_EMAIL);
	strConferenceID.LoadString(IDS_CONFERENCE_ID);
	strAddToMenu.LoadString(IDS_ADD_TO_MENU);
	strSendVideo.LoadString(IDS_SEND_VIDEO);
	strReceiveVideo.LoadString(IDS_RECEIVE_VIDEO);
	strIsRunning.LoadString(IDS_IS_RUNNING);

	CReflector* pReflector;

	LPSTR lpData = (LPSTR)GlobalLock(hData);

	*lpData = 0;

	int iItem = m_pCtlList->GetNextItem(-1, LVNI_SELECTED);

	while (iItem != -1)
	{
		if ((pReflector = m_pCtlList->GetReflector(iItem)) == NULL)
			break;

		strcat(lpData, strCountry);
		strcat(lpData, pReflector->m_strCountry);
		strcat(lpData, strLetters);
		strcat(lpData, pReflector->m_strLetters);
		strcat(lpData, strFullName);
		strcat(lpData, pReflector->m_strFullName);
		strcat(lpData, strShortName);
		strcat(lpData, pReflector->m_strShortName);
		strcat(lpData, strIPAddress);
		strcat(lpData, pReflector->m_strIPAddress);
		strcat(lpData, strContactName);
		strcat(lpData, pReflector->m_strContactName);
		strcat(lpData, strContactEmail);
		strcat(lpData, pReflector->m_strContactEmail);
		strcat(lpData, strConferenceID);
		strcat(lpData, pReflector->m_strConferenceID);
		strcat(lpData, strAddToMenu);
		strcat(lpData, pReflector->m_bAddToMenu		? strYes : strNo);
		strcat(lpData, strSendVideo);
		strcat(lpData, pReflector->m_bSendVideo		? strYes : strNo);
		strcat(lpData, strReceiveVideo);
		strcat(lpData, pReflector->m_bReceiveVideo	? strYes : strNo);
		strcat(lpData, strIsRunning);
		strcat(lpData, pReflector->m_bIsRunning		? strYes : strNo);
		strcat(lpData, _T("\n\n"));

		// Move to next item
		iItem = m_pCtlList->GetNextItem(iItem, LVNI_SELECTED);
	}

	GlobalUnlock(hData);

	*phData = hData;
}

void CReflectorDataSource::CreateFileContents(HGLOBAL* phData)
{
	TRACE("CreateFileContents()\n");

	HGLOBAL hData = *phData;

	ASSERT(m_pCtlList != NULL);

	int count = m_pCtlList->GetSelectedCount();

	// allocate space for the number of files
	if (hData == NULL)
		hData = GlobalAlloc(GHND | GMEM_SHARE, (DWORD)(CU_FILE_SIZE * count));

	// Failure ?
	if (hData == NULL) 
		return;	

	LPTSTR lpData = (LPTSTR)GlobalLock(hData);

	CReflector* pReflector;
	CString strOptions;
	strOptions.LoadString(IDS_OPTIONS_TEXT);

	int iItem = m_pCtlList->GetNextItem(-1, LVNI_SELECTED);

	while (iItem != -1)
	{
		if ((pReflector = m_pCtlList->GetReflector(iItem)) == NULL)
			break;

		strcpy(lpData, pReflector->m_strIPAddress);
		strcat(lpData, _T("\r\n"));
		strcat(lpData, pReflector->m_strConferenceID);
		strcat(lpData, strOptions);
		TRACE1("content : %s\n", lpData);

		lpData += CU_FILE_SIZE;

		// Move to next item
		iItem = m_pCtlList->GetNextItem(iItem, LVNI_SELECTED);
	}

	GlobalUnlock(hData);

	*phData = hData;
}

static TCHAR BASED_CODE szExt[] = _T(".cu");

void CReflectorDataSource::CreateFileDescriptor(HGLOBAL* phData)
{
	TRACE("CreateFileDescriptor()\n");

	HGLOBAL hData = *phData;

	ASSERT(m_pCtlList != NULL);

	int count = m_pCtlList->GetSelectedCount();
	ASSERT(count);

	// allocate space for FILEGROUPDESCRIPTOR structure plus the number of file
	// Note: FILEGROUPDESCRIPTOR holds one FILEDESCRIPTOR that's why "count-1"
	if (hData == NULL)
		hData = GlobalAlloc(GHND | GMEM_SHARE, (DWORD)(sizeof(FILEGROUPDESCRIPTOR) +
													  (sizeof(FILEDESCRIPTOR) * (count-1))));
	
	// Failure ?
	if (hData == NULL)
		return;	

	LPFILEGROUPDESCRIPTOR pfgd = (LPFILEGROUPDESCRIPTOR)GlobalLock(hData);

	pfgd->cItems = count;

	CReflector* pReflector;

	LPFILEDESCRIPTOR pfd = &pfgd->fgd[0];
	CString strFileName;

	int iItem = m_pCtlList->GetNextItem(-1, LVNI_SELECTED);

	while (iItem != -1)
	{
		if ((pReflector = m_pCtlList->GetReflector(iItem)) == NULL)
			break;

		strFileName = pReflector->m_strFullName + szExt;

		pfd->dwFlags = FD_FILESIZE;	// Only the file name and size fields are valid
		pfd->nFileSizeLow = CU_FILE_SIZE;
		lstrcpy(pfd->cFileName, strFileName);

		TRACE1("filename : %s\n", pfd->cFileName);

		pfd++; // point to next FILEDESCRIPTOR structure

		// Move to next item
		iItem = m_pCtlList->GetNextItem(iItem, LVNI_SELECTED);
	}

	GlobalUnlock(hData);

	*phData = hData;
}

=====================================================
Noel DANJOU 						12/21/1968
Village Paillette						Software Engineer @ PalmCom
50320 Saint Jean des Champs		Email: noeld@msn.com
France								UIN : 187712

NetMeeting 2.0 B2:   callto:uls.microsoft.com/noeld@msn.com

Home Pages:
http://ourworld.compuserve.com/homepages/noeld/       (personal)
http://ourworld.compuserve.com/homepages/gil_mic/    (company)
=====================================================





Noel DANJOU -- NoelD@msn.com
Wednesday, February 19, 1997

Hello,

Environment : VC++ 4.2-flat, Win 95

In one application I would like to be able to drag one or more items from a 
CListView to one or more text files on the desktop. I found out that I need to 
register the CFSTR_FILECONTENTS & CFSTR_FILEGROUPDESCRIPTOR clipboard formats 
and use COleDataSource but that does not work with the code I wrote and I 
can't figure out where I am wrong. Please could you help me debug my code I 
attached it below :

Thanks for your time,

Noel

-- S O U R C E    C O D E --

in View :

// refdbView.cpp : implementation of the CRefdbView class
//

#include "stdafx.h"
#include "afxole.h"
#include "refdb.h"

#include "DataSrc.h"	// OLE Drag n'Drop source
#include "shlobj.h"		// CFSTR_* definitions

#include "reflectr.h"
#include "refdbDoc.h"
#include "refdbVw.h"
#include "tools.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

[...]

UINT	gcfFileContents = 0;
UINT	gcfFileGroupDescriptor = 0;


[...]

/////////////////////////////////////////////////////////////////////////////
// CRefdbView message handlers

int CRefdbView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	lpCreateStruct->style |= LVS_REPORT | LVS_OWNERDRAWFIXED;
	if (CListView::OnCreate(lpCreateStruct) == -1)
		return -1;

	// Give the document a pointer to this view
	GetDocument()->m_pListView = this;

	CreateColumns();

	gcfFileContents = RegisterClipboardFormat(CFSTR_FILECONTENTS);
	gcfFileGroupDescriptor = RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR);

	return 0;
}

[...]

/////////////////////////////////////////////////////////////////////////////
// Drag n'Drop

[...]

void CRefdbView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	CListView::OnLButtonDown(nFlags, point);

	CListCtrlEx& ctlList = (CListCtrlEx&)GetListCtrl();

	// Create an OLE data source on the heap
	CReflectorDataSource* pDataSource = NULL;

	pDataSource = new CReflectorDataSource;

	pDataSource->SetListCtrl(&ctlList);

	// default FORMATETC is NULL -> tymed = TYMED_HGLOBAL
	pDataSource->DelayRenderData(CF_TEXT);					// e.g. target is WordPad
	pDataSource->DelayRenderData(gcfFileContents);			// e.g. target is Desktop
	pDataSource->DelayRenderData(gcfFileGroupDescriptor);	// required by 
FileContents

	// Uses default COleDropSource implementation.
	if (DROPEFFECT_MOVE == 
		pDataSource->DoDragDrop(DROPEFFECT_COPY | DROPEFFECT_MOVE))
	{
		// TODO: remove items
	}

	delete pDataSource;
}

void CRefdbView::OnEditCopy() 
{
	CReflectorDataSource* pDataSource = NULL; 
	CListCtrlEx& ctlList = (CListCtrlEx&)GetListCtrl();

	pDataSource = new CReflectorDataSource;

	pDataSource->SetListCtrl(&ctlList);
	
	// default FORMATETC is NULL -> tymed = TYMED_HGLOBAL
	pDataSource->DelayRenderData(CF_TEXT);	// e.g. target is WordPad

	// The Clipboard now owns the allocated memory and will delete this 
	// data object when new data is put on the Clipboard
	pDataSource->SetClipboard();

	delete pDataSource;
}

void CRefdbView::OnUpdateEditCopy(CCmdUI* pCmdUI) 
{
	CListCtrl& ctlList = (CListCtrl&)GetListCtrl();

	pCmdUI->Enable(ctlList.GetSelectedCount() > 0);
}

[...]


in DataSrc.cpp :
---------------------

// DataSrc.cpp : implementation file
//

#include "stdafx.h"
#include "refdb.h"
#include "reflectr.h"
#include "DataSrc.h"
#include "shlobj.h"	// FILEGROUPDESCRIPTOR structure definition

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define CU_FILE_SIZE	215
#define CU_DATA_SIZE	1024

extern UINT gcfFileContents;
extern UINT gcfFileGroupDescriptor;


/////////////////////////////////////////////////////////////////////////////
// CReflectorDataSource

CReflectorDataSource::CReflectorDataSource()
{
	m_pCtlList = NULL;
}

CReflectorDataSource::~CReflectorDataSource()
{
}


BEGIN_MESSAGE_MAP(CReflectorDataSource, COleDataSource)
	//{{AFX_MSG_MAP(CReflectorDataSource)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CReflectorDataSource message handlers

BOOL CReflectorDataSource::OnRenderGlobalData(LPFORMATETC lpFormatEtc, 
HGLOBAL* phGlobal) 
{
	ASSERT(gcfFileContents);
	ASSERT(gcfFileGroupDescriptor);

	if (lpFormatEtc->cfFormat == CF_TEXT)
	{
		CreateText(phGlobal);
	}
	else
	if (lpFormatEtc->cfFormat == gcfFileContents)
	{
		CreateFileContents(phGlobal);
	}
	else
	if (lpFormatEtc->cfFormat == gcfFileGroupDescriptor)
	{
		CreateFileDescriptor(phGlobal);
	}
	else
	{
		TRACE("OnRenderGlobalData() : Format not supported !\n");
		return FALSE;
	}

	if (*phGlobal == NULL)
		return FALSE;
	
	return TRUE;
}

void CReflectorDataSource::CreateText(HGLOBAL* phData)
{
	TRACE("CreateText()\n");

	HGLOBAL hData = *phData;

	ASSERT(m_pCtlList != NULL);

	int count = m_pCtlList->GetSelectedCount();

	// allocate space for the number of reflector items
	if (hData == NULL)
		hData = GlobalAlloc(GHND | GMEM_SHARE, (DWORD)(sizeof(TCHAR) * CU_DATA_SIZE 
* count));

	// Failure ?
	if (hData == NULL) 
		return;	

	CString strYes;
	CString strNo;
	CString strCountry;
	CString strLetters;
	CString strFullName;
	CString strShortName;
	CString strIPAddress;
	CString strContactName;
	CString strContactEmail;
	CString strConferenceID;
	CString strAddToMenu;
	CString strSendVideo;
	CString strReceiveVideo;
	CString strIsRunning;

	strYes.LoadString(IDS_YES);
	strNo.LoadString(IDS_NO);
	strCountry.LoadString(IDS_COUNTRY);
	strLetters.LoadString(IDS_LETTERS);
	strFullName.LoadString(IDS_FULLNAME);
	strShortName.LoadString(IDS_SHORTNAME);
	strIPAddress.LoadString(IDS_IPADDRESS);
	strContactName.LoadString(IDS_CONTACT_NAME);
	strContactEmail.LoadString(IDS_CONTACT_EMAIL);
	strConferenceID.LoadString(IDS_CONFERENCE_ID);
	strAddToMenu.LoadString(IDS_ADD_TO_MENU);
	strSendVideo.LoadString(IDS_SEND_VIDEO);
	strReceiveVideo.LoadString(IDS_RECEIVE_VIDEO);
	strIsRunning.LoadString(IDS_IS_RUNNING);

	CReflector* pReflector;

	LPSTR lpData = (LPSTR)GlobalLock(hData);

	*lpData = 0;

	int iItem = m_pCtlList->GetNextItem(-1, LVNI_SELECTED);

	while (iItem != -1)
	{
		if ((pReflector = m_pCtlList->GetReflector(iItem)) == NULL)
			break;

		strcat(lpData, strCountry);
		strcat(lpData, pReflector->m_strCountry);
		strcat(lpData, strLetters);
		strcat(lpData, pReflector->m_strLetters);
		strcat(lpData, strFullName);
		strcat(lpData, pReflector->m_strFullName);
		strcat(lpData, strShortName);
		strcat(lpData, pReflector->m_strShortName);
		strcat(lpData, strIPAddress);
		strcat(lpData, pReflector->m_strIPAddress);
		strcat(lpData, strContactName);
		strcat(lpData, pReflector->m_strContactName);
		strcat(lpData, strContactEmail);
		strcat(lpData, pReflector->m_strContactEmail);
		strcat(lpData, strConferenceID);
		strcat(lpData, pReflector->m_strConferenceID);
		strcat(lpData, strAddToMenu);
		strcat(lpData, pReflector->m_bAddToMenu		? strYes : strNo);
		strcat(lpData, strSendVideo);
		strcat(lpData, pReflector->m_bSendVideo		? strYes : strNo);
		strcat(lpData, strReceiveVideo);
		strcat(lpData, pReflector->m_bReceiveVideo	? strYes : strNo);
		strcat(lpData, strIsRunning);
		strcat(lpData, pReflector->m_bIsRunning		? strYes : strNo);
		strcat(lpData, _T("\n\n"));

		// Move to next item
		iItem = m_pCtlList->GetNextItem(iItem, LVNI_SELECTED);
	}

	GlobalUnlock(hData);

	*phData = hData;
}

void CReflectorDataSource::CreateFileContents(HGLOBAL* phData)
{
	TRACE("CreateFileContents()\n");

	HGLOBAL hData = *phData;

	ASSERT(m_pCtlList != NULL);

	int count = m_pCtlList->GetSelectedCount();

	// allocate space for the number of files
	if (hData == NULL)
		hData = GlobalAlloc(GHND | GMEM_SHARE, (DWORD)(CU_FILE_SIZE * count));

	// Failure ?
	if (hData == NULL) 
		return;	

	LPTSTR lpData = (LPTSTR)GlobalLock(hData);

	CReflector* pReflector;
	CString strOptions;
	strOptions.LoadString(IDS_OPTIONS_TEXT);

	int iItem = m_pCtlList->GetNextItem(-1, LVNI_SELECTED);

	while (iItem != -1)
	{
		if ((pReflector = m_pCtlList->GetReflector(iItem)) == NULL)
			break;

		strcpy(lpData, pReflector->m_strIPAddress);
		strcat(lpData, _T("\r\n"));
		strcat(lpData, pReflector->m_strConferenceID);
		strcat(lpData, strOptions);
		TRACE1("content : %s\n", lpData);

		lpData += CU_FILE_SIZE;

		// Move to next item
		iItem = m_pCtlList->GetNextItem(iItem, LVNI_SELECTED);
	}

	GlobalUnlock(hData);

	*phData = hData;
}

static TCHAR BASED_CODE szExt[] = _T(".cu");

void CReflectorDataSource::CreateFileDescriptor(HGLOBAL* phData)
{
	TRACE("CreateFileDescriptor()\n");

	HGLOBAL hData = *phData;

	ASSERT(m_pCtlList != NULL);

	int count = m_pCtlList->GetSelectedCount();
	ASSERT(count);

	// allocate space for FILEGROUPDESCRIPTOR structure plus the number of file
	// Note: FILEGROUPDESCRIPTOR holds one FILEDESCRIPTOR that's why "count-1"
	if (hData == NULL)
		hData = GlobalAlloc(GHND | GMEM_SHARE, (DWORD)(sizeof(FILEGROUPDESCRIPTOR) +
													  (sizeof(FILEDESCRIPTOR) * (count-1))));
	
	// Failure ?
	if (hData == NULL)
		return;	

	LPFILEGROUPDESCRIPTOR pfgd = (LPFILEGROUPDESCRIPTOR)GlobalLock(hData);

	pfgd->cItems = count;

	CReflector* pReflector;

	LPFILEDESCRIPTOR pfd = &pfgd->fgd[0];
	CString strFileName;

	int iItem = m_pCtlList->GetNextItem(-1, LVNI_SELECTED);

	while (iItem != -1)
	{
		if ((pReflector = m_pCtlList->GetReflector(iItem)) == NULL)
			break;

		strFileName = pReflector->m_strFullName + szExt;

		pfd->dwFlags = FD_FILESIZE;	// Only the file name and size fields are valid
		pfd->nFileSizeLow = CU_FILE_SIZE;
		lstrcpy(pfd->cFileName, strFileName);

		TRACE1("filename : %s\n", pfd->cFileName);

		pfd++; // point to next FILEDESCRIPTOR structure

		// Move to next item
		iItem = m_pCtlList->GetNextItem(iItem, LVNI_SELECTED);
	}

	GlobalUnlock(hData);

	*phData = hData;
}

=====================================================
Noel DANJOU 						12/21/1968
Village Paillette						Software Engineer @ PalmCom
50320 Saint Jean des Champs		Email: noeld@msn.com
France								UIN : 187712

NetMeeting 2.0 B2:   callto:uls.microsoft.com/noeld@msn.com

Home Pages:
http://ourworld.compuserve.com/homepages/noeld/       (personal)
http://ourworld.compuserve.com/homepages/gil_mic/    (company)
=====================================================






Become an MFC-L member | Вернуться в корень Архива |