Anonymous
C ++ WIN32 API DRAG and Drop Preview Image не работает
Сообщение
Anonymous » 02 июн 2025, 04:35
Я работаю над индивидуальной структурой пользовательского интерфейса и пытаюсь реализовать API Drag and Drop Win32 для текста. Пока что перетаскивание текст работает, однако я потратил много времени, пытаясь получить предварительное изображение для отображения, и ничего не работает.
Код: Выделить всё
class DragSource : public IDropSource {
UINT m_refCount;
HWND m_hwnd;
DragSource() {
m_refCount = 0;
}
virtual ~DragSource() {}
public:
static HRESULT STDMETHODCALLTYPE CreateInstance(IDropSource** pDropSource) {
HRESULT hr = E_OUTOFMEMORY;
if (pDropSource != NULL) {
DragSource* pCDropSrc = new DragSource();
hr = pCDropSrc->QueryInterface(IID_IDropSource, reinterpret_cast(pDropSource));
if (SUCCEEDED(hr))
return S_OK;
}
return hr;
}
HRESULT STDMETHODCALLTYPE QueryInterface(_In_ REFIID riid, _Out_ void** ppvObject) {
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDropSource)) {
*ppvObject = static_cast(this);
}
else {
*ppvObject = NULL; return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE AddRef() {
return InterlockedIncrement(&m_refCount);
}
ULONG STDMETHODCALLTYPE Release() {
ULONG refCount = InterlockedDecrement(&m_refCount);
if (refCount == 0) {
delete this;
return 0;
}
return refCount;
}
HRESULT GiveFeedback(DWORD dwEffect) override {
return DRAGDROP_S_USEDEFAULTCURSORS;
}
HRESULT QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState) override {
if (fEscapePressed)
return DRAGDROP_S_CANCEL;
if (!(grfKeyState & MK_LBUTTON))
return DRAGDROP_S_DROP;
return S_OK;
}
};
< /code>
И это код, который запускает операцию перетаскивания: < /p>
void DragNDropManager::startDragText(HWND windowHandle, std::string text) {
HRESULT hr;
const wchar_t* testText = L"Hello from drag!";
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, (wcslen(testText) + 1) * sizeof(wchar_t));
memcpy(GlobalLock(hGlobal), testText, (wcslen(testText) + 1) * sizeof(wchar_t));
GlobalUnlock(hGlobal);
FORMATETC fmt = { CF_UNICODETEXT, nullptr, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM stg = { TYMED_HGLOBAL };
stg.hGlobal = hGlobal;
SIZE imageSize = { 100, 30 };
HDC hdc = GetDC(nullptr);
HDC memDC = CreateCompatibleDC(hdc);
HBITMAP hBitmap = CreateCompatibleBitmap(hdc, imageSize.cx, imageSize.cy);
SelectObject(memDC, hBitmap);
HBRUSH bg = CreateSolidBrush(RGB(255, 0, 255));
RECT rc = { 0, 0, imageSize.cx, imageSize.cy };
FillRect(memDC, &rc, bg);
DeleteObject(bg);
SetTextColor(memDC, RGB(0, 0, 0));
DrawTextW(memDC, L"Drag text", -1, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
DeleteDC(memDC);
ReleaseDC(nullptr, hdc);
SHDRAGIMAGE dragImage = {};
dragImage.sizeDragImage.cx = imageSize.cx;
dragImage.sizeDragImage.cy = imageSize.cy;
dragImage.hbmpDragImage = hBitmap;
dragImage.crColorKey = RGB(255, 255, 255);
dragImage.ptOffset = { 0, 0 };
hr = SHCreateDataObject(NULL, NULL, NULL, NULL, IID_PPV_ARGS(&textObject));
textObject->SetData(&fmt, &stg, TRUE);
// Set drag image
IDragSourceHelper* pHelper = nullptr;
if (SUCCEEDED(CoCreateInstance(CLSID_DragDropHelper, NULL, CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pHelper)))) {
hr = pHelper->InitializeFromBitmap(&dragImage, textObject);
std::cout
Подробнее здесь: [url]https://stackoverflow.com/questions/79648095/c-win32-api-drag-and-drop-image-preview-not-working[/url]
1748828112
Anonymous
Я работаю над индивидуальной структурой пользовательского интерфейса и пытаюсь реализовать API Drag and Drop Win32 для текста. Пока что перетаскивание текст работает, однако я потратил много времени, пытаясь получить предварительное изображение для отображения, и ничего не работает.[code]class DragSource : public IDropSource { UINT m_refCount; HWND m_hwnd; DragSource() { m_refCount = 0; } virtual ~DragSource() {} public: static HRESULT STDMETHODCALLTYPE CreateInstance(IDropSource** pDropSource) { HRESULT hr = E_OUTOFMEMORY; if (pDropSource != NULL) { DragSource* pCDropSrc = new DragSource(); hr = pCDropSrc->QueryInterface(IID_IDropSource, reinterpret_cast(pDropSource)); if (SUCCEEDED(hr)) return S_OK; } return hr; } HRESULT STDMETHODCALLTYPE QueryInterface(_In_ REFIID riid, _Out_ void** ppvObject) { if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDropSource)) { *ppvObject = static_cast(this); } else { *ppvObject = NULL; return E_NOINTERFACE; } AddRef(); return S_OK; } ULONG STDMETHODCALLTYPE AddRef() { return InterlockedIncrement(&m_refCount); } ULONG STDMETHODCALLTYPE Release() { ULONG refCount = InterlockedDecrement(&m_refCount); if (refCount == 0) { delete this; return 0; } return refCount; } HRESULT GiveFeedback(DWORD dwEffect) override { return DRAGDROP_S_USEDEFAULTCURSORS; } HRESULT QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState) override { if (fEscapePressed) return DRAGDROP_S_CANCEL; if (!(grfKeyState & MK_LBUTTON)) return DRAGDROP_S_DROP; return S_OK; } }; < /code> И это код, который запускает операцию перетаскивания: < /p> void DragNDropManager::startDragText(HWND windowHandle, std::string text) { HRESULT hr; const wchar_t* testText = L"Hello from drag!"; HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, (wcslen(testText) + 1) * sizeof(wchar_t)); memcpy(GlobalLock(hGlobal), testText, (wcslen(testText) + 1) * sizeof(wchar_t)); GlobalUnlock(hGlobal); FORMATETC fmt = { CF_UNICODETEXT, nullptr, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; STGMEDIUM stg = { TYMED_HGLOBAL }; stg.hGlobal = hGlobal; SIZE imageSize = { 100, 30 }; HDC hdc = GetDC(nullptr); HDC memDC = CreateCompatibleDC(hdc); HBITMAP hBitmap = CreateCompatibleBitmap(hdc, imageSize.cx, imageSize.cy); SelectObject(memDC, hBitmap); HBRUSH bg = CreateSolidBrush(RGB(255, 0, 255)); RECT rc = { 0, 0, imageSize.cx, imageSize.cy }; FillRect(memDC, &rc, bg); DeleteObject(bg); SetTextColor(memDC, RGB(0, 0, 0)); DrawTextW(memDC, L"Drag text", -1, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE); DeleteDC(memDC); ReleaseDC(nullptr, hdc); SHDRAGIMAGE dragImage = {}; dragImage.sizeDragImage.cx = imageSize.cx; dragImage.sizeDragImage.cy = imageSize.cy; dragImage.hbmpDragImage = hBitmap; dragImage.crColorKey = RGB(255, 255, 255); dragImage.ptOffset = { 0, 0 }; hr = SHCreateDataObject(NULL, NULL, NULL, NULL, IID_PPV_ARGS(&textObject)); textObject->SetData(&fmt, &stg, TRUE); // Set drag image IDragSourceHelper* pHelper = nullptr; if (SUCCEEDED(CoCreateInstance(CLSID_DragDropHelper, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pHelper)))) { hr = pHelper->InitializeFromBitmap(&dragImage, textObject); std::cout Подробнее здесь: [url]https://stackoverflow.com/questions/79648095/c-win32-api-drag-and-drop-image-preview-not-working[/url]