📄 droptarget.cpp
字号:
/*____________________________________________________________________________
FreeAmp - The Free MP3 Player
Portions Copyright (C) 1999 EMusic.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: DropTarget.cpp,v 1.10 2000/09/11 22:14:04 ijr Exp $
____________________________________________________________________________*/
// The debugger can't handle symbols more than 255 characters long.
// STL often creates symbols longer than that.
// When symbols are longer than 255 characters, the warning is disabled.
#ifdef WIN32
#pragma warning(disable:4786)
#endif
// system header files
#include <windows.h>
#include <commctrl.h>
#include <shlobj.h>
// project header files
#include "DropTarget.h"
#include "DropObject.h"
DropTarget* g_me = NULL;
// IUnknown Methods
STDMETHODIMP DropTarget::QueryInterface(REFIID iid, void FAR* FAR* ppv)
{
if((iid == IID_IUnknown) ||(iid == IID_IDropTarget))
{
*ppv = this;
++m_refs;
return NOERROR;
}
*ppv = NULL;
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) DropTarget::AddRef(void)
{
return ++m_refs;
}
STDMETHODIMP_(ULONG) DropTarget::Release(void)
{
if(--m_refs == 0)
{
delete this;
return 0;
}
return m_refs;
}
// DropTarget Constructor
DropTarget::DropTarget(HWND hwnd)
{
m_refs = 1;
m_hwnd = hwnd;
m_acceptFormat = false;
m_allowMove = false;
m_enabled = true;
m_targetIsSource = false;
m_scrolling = true;
g_me = this;
short pattern[8];
HBITMAP bmp;
for (int i = 0; i < 8; i++)
pattern[i] = (WORD)(0x5555 << (i & 1));
bmp = CreateBitmap(8, 8, 1, 1, &pattern);
m_insertBrush = CreatePatternBrush(bmp);
DeleteObject(bmp);
}
DropTarget::~DropTarget()
{
DeleteObject(m_insertBrush);
}
// Enable/disable dropping
void DropTarget::Enable(bool enable)
{
m_enabled = enable;
}
void DropTarget::TargetIsSource(bool isSrc)
{
m_targetIsSource = isSrc;
}
#define SCROLL_OFF 0
#define SCROLL_UP 1
#define SCROLL_DOWN -1
#define SCROLL_TIMER 92173
void DropTarget::CheckAutoScroll(POINT pt)
{
SCROLLINFO si;
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_RANGE;
BOOL hasScroll = GetScrollInfo(m_hwnd, SB_VERT, &si);
if(hasScroll && si.nMin != si.nMax)
{
RECT rect;
GetClientRect(m_hwnd, &rect);
//char buf[256];
//sprintf(buf, "%d, %d\r\n", pt.x, pt.y);
//sprintf(buf, "%d, %d, %d, %d\r\n",
// itemRect.top, itemRect.left, itemRect.bottom, itemRect.right);
//OutputDebugString(buf);
if(PtInRect(&rect, pt))
{
if(pt.y < rect.top + 2*GetSystemMetrics(SM_CYHSCROLL))
{
//OutputDebugString("scroll up\r\n");
// scroll up
AutoScroll(SCROLL_UP);
}
else if(pt.y > rect.bottom - GetSystemMetrics(SM_CYHSCROLL))
{
// scroll down
//OutputDebugString("scroll down\r\n");
AutoScroll(SCROLL_DOWN);
}
else
{
//OutputDebugString("scroll off\r\n");
AutoScroll(SCROLL_OFF);
}
}
}
}
void DropTarget::ScrollFunction()
{
ImageList_DragShowNolock(FALSE);
//OutputDebugString("scrolling\r\n");
HDC hdc = GetDC(m_hwnd);
HBRUSH oldBrush = (HBRUSH)SelectObject(hdc, m_insertBrush);
//OutputDebugString("erase old - scrolling\r\n");
// erase old
PatBlt(hdc,
m_scrollRect.left,
m_scrollRect.top,
m_scrollRect.right - m_scrollRect.left,
m_scrollRect.bottom - m_scrollRect.top,
PATINVERT);
SendMessage(m_hwnd, WM_VSCROLL, MAKELONG(m_scrollCode, 0), NULL);
// draw new
PatBlt(hdc,
m_scrollRect.left,
m_scrollRect.top,
m_scrollRect.right - m_scrollRect.left,
m_scrollRect.bottom - m_scrollRect.top,
PATINVERT);
SelectObject(hdc, oldBrush);
ReleaseDC(m_hwnd, hdc);
ImageList_DragShowNolock(TRUE);
}
static void CALLBACK ScrollProc(HWND hwnd, UINT msg, UINT id, DWORD ticks)
{
g_me->ScrollFunction();
}
void DropTarget::AutoScroll(int scrollCode)
{
m_scrollCode = (scrollCode == SCROLL_UP ? SB_LINEUP : SB_LINEDOWN);
if(scrollCode == SCROLL_OFF)
{
//OutputDebugString("KillTimer\r\n");
KillTimer(GetParent(m_hwnd), SCROLL_TIMER);
m_scrolling = false;
}
else if(!m_scrolling)
{
m_scrolling = true;
m_scrollRect = m_insertRect;
m_timer = SetTimer(GetParent(m_hwnd), SCROLL_TIMER, 250, ScrollProc);
}
}
// ________________________________________
//
// IDropTarget Methods
STDMETHODIMP DropTarget::DragEnter(LPDATAOBJECT pDataObj,
DWORD dwKeyState,
POINTL pt,
LPDWORD pdwEffect)
{
FORMATETC fmtetc;
// default to not allowing drop
m_acceptFormat = false;
m_allowMove = false;
*pdwEffect = DROPEFFECT_NONE;
if(!m_enabled)
{
return NOERROR;
}
/*IEnumFORMATETC* ief;
if(S_OK == pDataObj->EnumFormatEtc(DATADIR_GET, &ief))
{
FORMATETC e;
ULONG i;
while (S_OK == ief->Next(1, &e, &i))
{
ief->Skip(1);
}
}*/
// Does the drag source provide our private format?
fmtetc.cfFormat = RegisterClipboardFormat(CFSTR_FREEAMP_CATALOGITEM);
fmtetc.ptd = NULL;
fmtetc.dwAspect = DVASPECT_CONTENT;
fmtetc.lindex = -1;
fmtetc.tymed = TYMED_HGLOBAL;
if(pDataObj->QueryGetData(&fmtetc) == NOERROR)
{
m_acceptFormat = true;
*pdwEffect = DROPEFFECT_COPY;
}
fmtetc.cfFormat = RegisterClipboardFormat(CFSTR_FREEAMP_PLAYLISTITEM);
fmtetc.ptd = NULL;
fmtetc.dwAspect = DVASPECT_CONTENT;
fmtetc.lindex = -1;
fmtetc.tymed = TYMED_HGLOBAL;
if(pDataObj->QueryGetData(&fmtetc) == NOERROR)
{
m_acceptFormat = true;
m_allowMove = true;
if(dwKeyState & MK_CONTROL)
*pdwEffect = DROPEFFECT_COPY;
else
*pdwEffect = DROPEFFECT_COPY;
}
// Does the drag source provide CF_HDROP?
fmtetc.cfFormat = CF_HDROP;
fmtetc.ptd = NULL;
fmtetc.dwAspect = DVASPECT_CONTENT;
fmtetc.lindex = -1;
fmtetc.tymed = TYMED_HGLOBAL;
if(pDataObj->QueryGetData(&fmtetc) == NOERROR)
{
m_acceptFormat = true;
*pdwEffect = DROPEFFECT_COPY;
}
if(m_acceptFormat)
{
// draw a line to indicate insertion point in list
LV_HITTESTINFO hti;
RECT itemRect;
hti.pt.x = pt.x;
hti.pt.y = pt.y;
MapWindowPoints(NULL, m_hwnd, (LPPOINT)&hti.pt, 1);
m_oldItem = ListView_HitTest(m_hwnd, &hti);
if(m_oldItem < 0)
{
itemRect.top = 0;
itemRect.bottom = 0;
itemRect.left = 0;
itemRect.right = 0;
}
else
{
int middle;
ListView_GetItemRect(m_hwnd, hti.iItem, &itemRect, LVIR_BOUNDS);
middle = itemRect.top + (itemRect.bottom - itemRect.top)/2;
if(pt.y < middle)
{
//itemRect.top -= 2;
itemRect.bottom = itemRect.top;
itemRect.top -= 2;
}
else
{
//itemRect.bottom += 2;
itemRect.top = itemRect.bottom - 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -