📄 pkidropsource.cpp
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
PKIDropSource.cpp - implements OLE IDropSource for drag and drop
$Id: PKIDropSource.cpp,v 1.7 2002/09/23 20:18:43 sdas Exp $
____________________________________________________________________________*/
#include "pgpPFLConfig.h"
// system header files
#include <windows.h>
#include <commctrl.h>
// project header files
#include "PKIDropSource.h"
#include "resource.h"
#include "TreeList.h"
extern "C" {
typedef struct _PK *PPGPKEYSSTRUCT;
extern HINSTANCE g_hinst;
BOOL PKFindWindowFromPoint (POINT* ppt, HWND* phwnd);
}
// ________________________________________
//
// IUnknown Methods
STDMETHODIMP CDropSource::QueryInterface (
REFIID iid,
void FAR* FAR* ppv)
{
if ((iid == IID_IUnknown) || (iid == IID_IDropSource))
{
*ppv = this;
++m_refs;
return NOERROR;
}
*ppv = NULL;
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) CDropSource::AddRef (void)
{
return ++m_refs;
}
STDMETHODIMP_(ULONG) CDropSource::Release (void)
{
if (--m_refs == 0)
{
delete this;
return 0;
}
return m_refs;
}
// ________________________________________
//
// calculate cursor offsets
static VOID
sCalcOffsets (
HWND hwnd,
ULONG* pulXOff,
ULONG* pulYOff)
{
NONCLIENTMETRICS ncm;
// get offset number to convert client to window coordinates
ncm.cbSize = sizeof(NONCLIENTMETRICS);
SystemParametersInfo (SPI_GETNONCLIENTMETRICS,
sizeof(NONCLIENTMETRICS), &ncm, 0);
*pulXOff = ncm.iBorderWidth;
*pulYOff = ncm.iBorderWidth + ncm.iCaptionHeight;
if (GetMenu (hwnd))
*pulYOff += ncm.iMenuHeight;
}
// ________________________________________
//
// CDropSource Constructor
CDropSource::CDropSource (
VOID* pKeysStruct,
HWND hwnd,
HWND hwndTree,
BOOL bRenderAll)
{
HIMAGELIST hIml;
TL_DRAGBITMAP tldb;
DWORD dwPos;
POINTS pts;
m_refs = 1;
m_hwnd = hwnd;
m_pKeysStruct = pKeysStruct;
sCalcOffsets (hwnd, &m_ncxoffset, &m_ncyoffset);
dwPos = GetMessagePos ();
pts = MAKEPOINTS (dwPos);
tldb.ptCursorPos.x = pts.x;
tldb.ptCursorPos.y = pts.y;
ScreenToClient (hwndTree, &tldb.ptCursorPos);
if (!bRenderAll)
tldb.ulFlags = TLRB_TOPLEVELONLY;
else
tldb.ulFlags = 0;
TreeList_RenderDragBitmap (hwndTree, &tldb);
hIml = ImageList_Create (tldb.sizeDrag.cx, tldb.sizeDrag.cy,
ILC_MASK|ILC_COLORDDB, 1, 1);
ImageList_AddMasked (hIml, tldb.hbmDrag, GetSysColor (COLOR_WINDOW));
DeleteObject (tldb.hbmDrag);
ImageList_BeginDrag (hIml, 0, tldb.ptHotSpot.x, tldb.ptHotSpot.y);
ImageList_Destroy (hIml);
tldb.ptCursorPos.x = pts.x;
tldb.ptCursorPos.y = pts.y;
ScreenToClient (hwnd, &tldb.ptCursorPos);
ImageList_DragEnter (hwnd, tldb.ptCursorPos.x + m_ncxoffset,
tldb.ptCursorPos.y + m_ncyoffset);
}
CDropSource::~CDropSource()
{
if (m_hwnd)
ImageList_DragLeave (m_hwnd);
ImageList_EndDrag ();
}
// ________________________________________
//
// IDropSource Methods
STDMETHODIMP CDropSource::QueryContinueDrag (
BOOL fEscapePressed,
DWORD grfKeyState)
{
if (fEscapePressed)
return DRAGDROP_S_CANCEL;
else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
return DRAGDROP_S_DROP;
else
return NOERROR;
}
//enables application to give visual feedback to end-user during drag and
//drop operation by providing IDataObject::DoDragDrop() with an enumeration
//value specifying the visual effect
STDMETHODIMP CDropSource::GiveFeedback (DWORD dwEffect)
{
BOOL bInWindow = FALSE;
BOOL bInvalidate = FALSE;
HWND hwnd = NULL;
HWND hwndSys;
BOOL bDragLeave;
POINT pt;
GetCursorPos (&pt);
//check if the point is within any of pgp main windows
bDragLeave = PKFindWindowFromPoint (&pt, &hwnd);
//get the window at the point as reported by the system
hwndSys = WindowFromPoint (pt);
//if(GetParent (hwndSys) != hwnd)
if ((hwndSys != hwnd) && !IsChild(hwnd, hwndSys))
{
//WFP reports a window that is not one of pgp's main windows nor
//is a child or descendant of any of the pgp main windows
hwnd = NULL;
bDragLeave = FALSE;
}
if (hwnd != m_hwnd)
{
if (m_hwnd)
{
ImageList_DragLeave (m_hwnd);
if (!bDragLeave)
{
bInvalidate = TRUE;
if (m_hwnd)
InvalidateRect (m_hwnd, NULL, FALSE);
}
}
m_hwnd = hwnd;
if (m_hwnd)
{
sCalcOffsets (m_hwnd, &m_ncxoffset, &m_ncyoffset);
ScreenToClient (m_hwnd, &pt);
ImageList_DragEnter (m_hwnd,
pt.x + m_ncxoffset, pt.y + m_ncyoffset);
}
}
if (!(dwEffect & DROPEFFECT_SCROLL))
{
if (m_hwnd)
{
ScreenToClient (m_hwnd, &pt);
ImageList_DragMove (pt.x + m_ncxoffset, pt.y + m_ncyoffset);
}
}
if (bInvalidate)
{
InvalidateRect (hwndSys, NULL, TRUE);
UpdateWindow (hwndSys);
}
return DRAGDROP_S_USEDEFAULTCURSORS;//use standard OLE cursors to show the drop effect
}
// ________________________________________
//
// Interface to C code
extern "C" {
LPDROPSOURCE PKCreateDropSource (
VOID* pKeysStruct,
HWND hwnd,
HWND hwndTree,
BOOL bRenderAll)
{
return ((LPDROPSOURCE) new CDropSource (
pKeysStruct, hwnd, hwndTree, bRenderAll));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -