Drag and drop

작성자

카테고리:

http://blog.naver.com/sjhghj/140104051130

DragDemo 프로젝트를 만들고

일단 ListControl를 좌우로 2개 만듭니다..

그리고

public:

 // CListCtrl 클래스의 CreateDragIImage()메소드가 반환한 드래그 이미지의 포인터를 저장

 CImageList * m_pImgListDrag;

 // 왼쪽 리스트 컨트롤에서 드래그 하려고 선택한 항목의 인덱스
 int   m_nIndexLeftSel;

public:
 CListCtrl m_List_Left;  // 왼쪽 리스트 컨트롤러의 변수 

public:
 CListCtrl m_List_Right; // 오른쪽 리스트 컨트롤러의 변수
public:

//CDragDemoDlg
 afx_msg void OnLvnBegindragList1(NMHDR *pNMHDR, LRESULT *pResult);
public:
 afx_msg void OnMouseMove(UINT nFlags, CPoint point);
public:
 afx_msg void OnLButtonUp(UINT nFlags, CPoint point);


CDragDemoDlg::CDragDemoDlg(CWnd* pParent /*=NULL*/)
 : CDialog(CDragDemoDlg::IDD, pParent)
{
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

 // 이 항목들을 다음과 같이 초기화 합니다.

 m_pImgListDrag = NULL;
 m_nIndexLeftSel = -1;

}

OnInitDialog() 함수에 다음과 같이 작성합니다..

 CBitmap Bitmap;
 Bitmap.LoadBitmapW(IDB_ImageList);

 static CImageList ImgList;
 ImgList.Create(32, 32, ILC_COLOR32 | ILC_MASK, 5, 0);
 ImgList.Add(&Bitmap, RGB(0,0,0));//   현재 Left와 Right 리스트 컨트롤 2개가 CImageList 클래스 객체를 공유하여 사용하고 있습니다.
 m_List_Left.SetImageList(&ImgList, LVSIL_NORMAL);
 m_List_Right.SetImageList(&ImgList, LVSIL_NORMAL);

 CString strItem =_T(“”);
 for(int i=0; i<5; ++i)
 {
  strItem.Format(_T(“%dth Item”), i);
  m_List_Left.InsertItem(i, strItem, i);

 }

 DWORD dwExStyle = m_List_Left.GetExtendedStyle();

// 둘다 LVS_EX_BORDERSELECT 확장 스타일을 하고 있습니다.
 m_List_Left.SetExtendedStyle(dwExStyle | LVS_EX_BORDERSELECT);
 dwExStyle = m_List_Right.GetExtendedStyle();
 m_List_Right.SetExtendedStyle(dwExStyle | LVS_EX_BORDERSELECT);

다음은…………

void CDragDemoDlg::OnLvnBegindragList1(NMHDR *pNMHDR, LRESULT *pResult)
{
 LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
 // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
 
 CPoint ptDrag, ptAction;

// 드래그가 시작된 항목의 인덱스가 들어가 있고, WM_LBUTTONUP 메세지가 발생할 때 사용된다
 m_nIndexLeftSel = pNMLV->iItem;

//  CreateDragImage()메소드를 호출하여 새로운 이미지 목록을 만듭니다.

//   이 함수는 내부적으로 new 연산으로 새로운 CImageList 클래스 객체를 생성하기에

// 드래그가 끝날 때 delete 연산을 통해서 객체를 소멸시켜야 합니다.
 m_pImgListDrag = m_List_Left.CreateDragImage(pNMLV->iItem, &ptDrag);

 m_pImgListDrag->SetBkColor(RGB(0,0,0));
 ptAction = pNMLV->ptAction;

 SetCapture();
 m_pImgListDrag->BeginDrag(0,ptAction – ptDrag);
 m_List_Left.ClientToScreen(&ptAction);
 m_pImgListDrag->DragEnter(NULL, ptAction);

 *pResult = 0;
}

다음은………….

void CDragDemoDlg::OnMouseMove(UINT nFlags, CPoint point)
{
 // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
 if(m_pImgListDrag != NULL){
  //좌표를 반환한다
  ClientToScreen(&point);
  // 변환된 좌표가 속한 윈도우 객체의 주소를 구한다
  CWnd* pWnd = CWnd::WindowFromPoint(point);
  // 주소가 대화상자 자체나 자식 윈도우에 해당하는 주소이면 계속 드래그 상태를 유지하도록 한다
  if(pWnd != NULL)
  {
   if(this ==pWnd || IsChild(pWnd))
   {
    
    m_pImgListDrag->DragEnter(NULL, point);
    //DragMove :  인자로 전달받은 좌표에 드래그 이미지를 출력
    m_pImgListDrag->DragMove(point);
   }
   else
   {
    // DragEnter와 반대로 이미지를 지운다
    m_pImgListDrag->DragLeave(NULL);
   }
  }
  //지워진 이미지를 다시 화면에 나오게 하려면 DragEnter()함수를 다시 호출하면 된다

 }

 CDialog::OnMouseMove(nFlags, point);
}

다음은……

void CDragDemoDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
 // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
 CString strTmp = _T(“”);
 if(m_pImgListDrag != NULL)
 {
  ClientToScreen(&point);

  m_pImgListDrag->DragLeave(NULL);

// EndDrag() 함수가 호출되면 관련 객체는 드래그 앤 드랍 동작이 끝났다고 인식하게 됩니다.
  m_pImgListDrag->EndDrag();
  ReleaseCapture();

  //오른쪽 리스트에 아이템 추가

// 드롭 위치에 해당하는 윈도우 객체의 주소를 알아내고 있습니다.

// 만일 이 주소가 오른쪽 리스트 컨트롤이고 왼쪽 리스트 컨트롤에서 선택한 항목이 있다면 GetItem()함수를 통해서 오른쪽 컨트롤 리스트에 항목을 추가하게 됩니다.
  CWnd* pWnd = CWnd::WindowFromPoint(point);
  if(pWnd == &m_List_Right && m_nIndexLeftSel >= 0)
  {
   LVITEM lvItem;
   TCHAR szBuffer[256];
   ::ZeroMemory(&lvItem, sizeof(lvItem));
   ::ZeroMemory(szBuffer, sizeof(szBuffer));

   lvItem.mask = LVIF_TEXT | LVIF_IMAGE;
   lvItem.iItem = m_nIndexLeftSel;
   lvItem.pszText = szBuffer;
   lvItem.cchTextMax = 256;
   m_List_Left.GetItem(&lvItem);
   
   m_List_Right.InsertItem(0, lvItem.pszText,lvItem.iImage);

  }

// 드롭된 위치가 왼쪽 리스트 일 경우
  else
  {
   m_List_Left.ScreenToClient(&point);
   int nIndex = m_List_Left.HitTest(point);

   if(nIndex >=0)
   {
    strTmp.Format(_T(“Drop on %dth item”), nIndex);
    AfxMessageBox(strTmp);
   }
  }
  delete m_pImgListDrag;
  m_pImgListDrag = NULL;
  m_nIndexLeftSel = -1;

  
 }
 CDialog::OnLButtonUp(nFlags, point);
}

[출처] 드래그 앤 드랍(Drag and drop)|작성자 Parker Charles

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다