블로그

  • 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

  • CDockablePane에 Dialog 등록

    http://cafe.naver.com/ssua/517

    CDockablePanel에 Dialog를 등록하여 사용할경우 컨트롤러를 직접 생성하는것보다 편리하다.

    처리해야할 부분

    기본적으로 CDockablePanel를 상속받아 Panel을 만들고 OnCreate 에서 다이얼로그를 생성하여 등록 하면

    되지만 부가적으로 해야할 처리들이 몇가지 존재한다.

    1. 페널의 사이즈가 변경될시 다이얼로그의 사이즈도 변경해 줘야 한다.

    2. 페널이 포커스되면 다이얼로그에  포커스를 설정해 줘야 한다.

    3. 페널위 다이얼로그에서 마우스 오른쪽 클릭시에도 DockablePane Context menu (도킹관련 팝업메뉴)가 떠버려

    다이얼로그를 가리게 되며 다이얼로그 위에서 마우스 왼쪽 클릭을 해도 사라지지 않는 문제점이 발생한다

    이를 위해 Context Menu를 차단 해줘야 한다.

    세부 작업 설명

    1. 다이얼로그 생성한후 아래와 같이 셋팅하자.

    Dialog.Properties.Border = None

    Dialog.Properties.Style = Child

    2. 페널 생성.

    클래스 위자드->MFC클래스-> Base Class(상속받을 클래스)에 CDockablePane 설정후 페널 생성.

    3. 페널에 다이얼로그 등록.

    페널에 WM_CREATE 메시지 핸들러 등록.

    int DockingPane::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    if (CDockablePane::OnCreate(lpCreateStruct) == -1)
    return -1;

    // TODO:  Add your specialized creation code here
    BOOL bRet = m_Dialog.Create(IDD_TEST_DOCKING, this);
    ASSERT( bRet );
    m_Dialog.ShowWindow(SW_SHOW);

    return 0;
    }

    4. 사이즈 변화에 대한 다이얼로그 적용.

    페널에  WM_SIZE 메시지 핸들러 등록.

    void DockingPane::OnSize(UINT nType, int cx, int cy)
    {
    CDockablePane::OnSize(nType, cx, cy);

    // TODO: Add your message handler code here
    m_Dialog.MoveWindow( 0, 0, cx, cy );
     //m_Dialog.SetWindowPos (NULL, -1, -1, cx, cy, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
    }

    5. 페널이 포커스시 다이얼로그포커스 설정.

    페널에 WM_SETFOCUS 메시지 핸들러 등록.

    void DockingPane::OnSetFocus(CWnd* pOldWnd)
    {
    CDockablePane::OnSetFocus(pOldWnd);

    // TODO: Add your message handler code here
     m_Dialog.SetFocus();
    }

    6. DockablePane Context menu 차단.

    OnShowControlBarMenu 함수를 오버라이딩하여 Base클래스에서의 처리를 막아버린다.

    //: h

    virtual BOOL OnShowControlBarMenu(CPoint point);

    //: cpp

    BOOL DockingPane::OnShowControlBarMenu( CPoint point )
    {
    return FALSE;
    }

    기타

    ! vs2010 에서는 다이얼로그 페널(CPaneDialog)을 자체적으로 지원하는 걸로 알고 있다.

  • Drag & Drop기능

    [참조사이트]http://blog.naver.com/iperfume/100048381739

    1. 파일 드래그앤 드롭했을때 파일명과 경로를 입력하는방법

    http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=278&MAEULNo=20&no=21664&ref=21664

    2. codeproject 자료

    http://www.codeproject.com/clipboard/ddmgr.asp

    3. Devpia 자료

    3-1. http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=50&MAEULNo=20&no=494120&ref=494120

    3-2. http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=50&MAEULNo=20&no=466864&ref=466864

    4. 탐색기에서 응용프로그램으로 드래그 앤 드롭

    http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=50&MAEULNo=20&no=469642&ref=469609

    Drag & Drop은 주로 두개의 서로 다른 프로그램 사이에서 일어나는 과정이므로 COM 인터페이스를 이용해 표준화 되어있다.

    IDropSource, IDropTarger, IDataObject 인터페이스를 통해 구현하도록 되어 있으며 RegisterDragDrop, DoDragDrop이라는 API함수를 호출하여 Drap&Drop을 시작한다.

    DoDragDrop함수가 호출된 이후의 나머지 과정(DragEnter, DragOver, Drop, DragLeave)은 운영체제가 맡아서 처리해준다.

    MFC에서는 Drag&Drop을 쉽게 구현할 수 있도록 COleDropSource, COleDropTarget, COleDataObject클래스를 제공하고 있다.

    5. Drag&Drop 으로 URL얻어오기(소스포함)

      – 인터넷 익스플로우에서 응용프로그램으로 Drag&Drop을 했을때 URL얻어오는 방법

    http://www.codeguru.com/Cpp/I-N/internet/article.php/c3363

    6. ListCtrl간 드래그앤 드롭

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