// @pymethod int|PyIDropTarget|DragEnter|Called when an object is initially dragged into a window // @rdesc Your implementation of this function should return a shellcon.DROPEFFECT_* value indicating if the object can be accepted PyObject *PyIDropTarget::DragEnter(PyObject *self, PyObject *args) { IDropTarget *pIDT = GetI(self); if ( pIDT == NULL ) return NULL; // @pyparm <o PyIDataObject>|pDataObj||IDataObject interface that contains the object being dragged // @pyparm int|grfKeyState||Combination of win32con.MK_* flags containing keyboard modifier state POINTL pt; PyObject *obpt; // @pyparm (int, int)|pt||(x,y) Screen coordinates of cursor PyObject *obpDataObj; IDataObject *pDataObj; DWORD grfKeyState; DWORD dwEffect; // @pyparm int|pdwEffect||shellcon.DROPEFFECT_* value if ( !PyArg_ParseTuple(args, "OlOl:DragEnter", &obpDataObj, &grfKeyState, &obpt, &dwEffect) ) return NULL; BOOL bPythonIsHappy = TRUE; if (bPythonIsHappy && !PyCom_InterfaceFromPyInstanceOrObject(obpDataObj, IID_IDataObject, (void **)&pDataObj, TRUE /* bNoneOK */)) bPythonIsHappy = FALSE; if (bPythonIsHappy && !PyObject_AsPOINTL( obpt, &pt )) bPythonIsHappy = FALSE; if (!bPythonIsHappy) return NULL; HRESULT hr; PY_INTERFACE_PRECALL; hr = pIDT->DragEnter( pDataObj, grfKeyState, pt, &dwEffect ); if (pDataObj) pDataObj->Release(); PY_INTERFACE_POSTCALL; if ( FAILED(hr) ) return PyCom_BuildPyException(hr, pIDT, IID_IDropTarget ); return PyInt_FromLong(dwEffect); }
HRESULT WinCE_DoDragDrop(LPDATAOBJECT pDataObj, LPDROPSOURCE pDropSource, DWORD dwOKEffects, LPDWORD pdwEffect) { MSG msg; POINT dest = {0,0}; POINT lastDraw = {-1,-1}; DWORD effect = DROPEFFECT_NONE; DWORD lastEffect = -1; IDropTarget * currentTarget = NULL; IWebViewPrivate * webView = NULL; IDataObject * dataObject = pDataObj; IDropSource * dropSource = pDropSource; HRESULT feedbackHR = DRAGDROP_S_USEDEFAULTCURSORS; HCURSOR startCursor = ::GetCursor(); HCURSOR noCursor = LoadCursor(NULL, IDC_NO); // If there is a change in the keyboard or mouse button state, DoDragDrop calls // IDropSource::QueryContinueDrag and determines whether to continue the drag, to // drop the data, or to cancel the operation based on the return value. BOOL escapePressed = FALSE; DWORD keyState = MK_LBUTTON; if (GetKeyState(VK_CONTROL) & HIGH_BIT_MASK_SHORT) keyState |= MK_CONTROL; if (GetKeyState(VK_SHIFT) & HIGH_BIT_MASK_SHORT) keyState |= MK_SHIFT; HRESULT result = dropSource->QueryContinueDrag(escapePressed, keyState); bool dragActive = (result == S_OK); POINTL screenPoint; while (dragActive && GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); // Filter all mouse and key events during the drag and drop: if (msg.message == WM_LBUTTONUP || msg.message == WM_LBUTTONDOWN || msg.message == WM_RBUTTONUP || msg.message == WM_RBUTTONDOWN || msg.message == WM_MOUSEMOVE || msg.message == WM_KEYDOWN || msg.message == WM_KEYUP || msg.message == WM_CHAR || msg.message == WM_SYSKEYDOWN || msg.message == WM_SYSKEYUP || msg.message == WM_SYSCHAR) { if (msg.message == WM_MOUSEMOVE) { PERFORMANCE_START(WTF::PerformanceTrace::InputEvent,"DragDropManager: Mouse Move"); } else if (msg.message == WM_LBUTTONUP) { PERFORMANCE_START(WTF::PerformanceTrace::InputEvent,"DragDropManager: Mouse Up"); } else { PERFORMANCE_START(WTF::PerformanceTrace::InputEvent,"DragDropManager: Other Input"); } bool stateChanged = false; if (msg.message == WM_MOUSEMOVE || msg.message == WM_LBUTTONUP) { POINT pt = {GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam)}; ::ClientToScreen(msg.hwnd, &pt); screenPoint.x = pt.x; screenPoint.y = pt.y; dest.x = pt.x - currentDragImage.ptOffset.x; dest.y = pt.y - currentDragImage.ptOffset.y; if (msg.message == WM_MOUSEMOVE) { // Which window is my mouse over? HWND mouseWnd = WindowFromPoint(dest); IDropTarget * newTarget = NULL; if (mouseWnd != NULL && dragMap) { DragWindowMap::iterator it = dragMap->find(mouseWnd); if (it != dragMap->end()) newTarget = it->second; } if (currentTarget && currentTarget != newTarget) { currentTarget->DragLeave(); feedbackHR = dropSource->GiveFeedback(DROPEFFECT_NONE); } if (newTarget) { effect = DROPEFFECT_NONE; //is this the correct way to set effect? if (pdwEffect) effect = *pdwEffect; if (currentTarget != newTarget) { newTarget->DragEnter(dataObject, keyState, screenPoint, &effect); feedbackHR = dropSource->GiveFeedback(effect); // Find out if the target is a webview now. if (webView) webView->Release(); newTarget->QueryInterface(IID_IWebViewPrivate, (void**) &webView); } else if (currentTarget) { currentTarget->DragOver(keyState, screenPoint, &effect); feedbackHR = dropSource->GiveFeedback(effect); } } if (webView) { dragImageVisible = true; dragAreaInvalid = true; } if (feedbackHR == DRAGDROP_S_USEDEFAULTCURSORS && effect != lastEffect) { switch (effect) { case DROPEFFECT_NONE: ::SetCursor(noCursor); break; /* MS doesn't give us these cursors!!! case DROPEFFECT_COPY: break; case DROPEFFECT_MOVE: break; case DROPEFFECT_LINK: break; */ default: ::SetCursor(startCursor); break; } lastEffect = effect; } currentTarget = newTarget; } else if (msg.message == WM_LBUTTONUP) { keyState = 0; stateChanged = true; } } else if (msg.message == WM_KEYDOWN) { if (msg.wParam == VK_ESCAPE) { escapePressed = TRUE; stateChanged = true; } } else if (msg.message == WM_KEYUP) { if (msg.wParam == VK_ESCAPE) { escapePressed = FALSE; stateChanged = true; } } if (stateChanged) { result = dropSource->QueryContinueDrag(escapePressed, keyState); if (result != S_OK) { dragImageVisible = false; dragAreaInvalid = true; if (currentTarget && effect && result == DRAGDROP_S_DROP) { effect = DROPEFFECT_NONE; //FIXME: should we reset effect or not? result = currentTarget->Drop(dataObject, keyState, screenPoint, &effect); if (SUCCEEDED(result)) { result = DRAGDROP_S_DROP; if (pdwEffect) *pdwEffect = effect; } } else { result = DRAGDROP_S_CANCEL; } dragActive = false; } } PERFORMANCE_END(WTF::PerformanceTrace::InputEvent); } else { DispatchMessage(&msg); } if (dragAreaInvalid && webView && dragImageCairo) { PERFORMANCE_START(WTF::PerformanceTrace::Paint, "DragDropManager::Paint"); HDC screenDC = ::GetDC(NULL); cairo_surface_t * screenSurface = cairo_win32_surface_create(screenDC); cairo_t *crScreen = cairo_create(screenSurface); HWND wnd; webView->viewWindow((OLE_HANDLE*) &wnd); RECT dirty; if (invalidDragRect.left != -1) { dirty = invalidDragRect; } else { POINT p = {0, 0}; ::ClientToScreen(wnd, &p); ::GetClientRect(wnd, &dirty); dirty.left += p.x; dirty.top += p.y; dirty.right += p.x; dirty.bottom += p.y; } if (dragImageVisible) { POINT * prevDraw = NULL; if (lastDraw.x != -1 && (lastDraw.x != dest.x || lastDraw.y != dest.y)) prevDraw = &lastDraw; drawDragImage(crScreen, dest, prevDraw, webView, wnd, true, &dirty); lastDraw = dest; invalidDragRect.left = -1; } else { // erase the drag image wherever we last put it: drawDragImage(crScreen, lastDraw, NULL, webView, wnd, false, &dirty); } cairo_destroy(crScreen); cairo_surface_destroy(screenSurface); ::ReleaseDC(NULL, screenDC); dragAreaInvalid = false; PERFORMANCE_END(WTF::PerformanceTrace::Paint); } } if (currentTarget && result != DRAGDROP_S_DROP) { currentTarget->DragLeave(); } ::SetCursor(startCursor); if (webView) webView->Release(); if (dragImageCairo) { cairo_surface_destroy(dragImageCairo); dragImageCairo = NULL; } return result; }
// @pymethod int|PyIDropTarget|DragOver|Called as the dragged object moves over the window // @rdesc Your implementation of this function should return a shellcon.DROPEFFECT_* value indicating if the // object can be accepted at the current position PyObject *PyIDropTarget::DragOver(PyObject *self, PyObject *args) { IDropTarget *pIDT = GetI(self); if ( pIDT == NULL ) return NULL; // @pyparm int|grfKeyState||Combination of win32con.MK_* flags containing keyboard modifier state POINTL pt; PyObject *obpt; // @pyparm (int, int)|pt||(x,y) Screen coordinates of cursor DWORD dwEffect; // @pyparm int|pdwEffect||shellcon.DROPEFFECT_* value DWORD grfKeyState; if ( !PyArg_ParseTuple(args, "lOl:DragOver", &grfKeyState, &obpt, &dwEffect) ) return NULL; BOOL bPythonIsHappy = TRUE; if (bPythonIsHappy && !PyObject_AsPOINTL( obpt, &pt )) bPythonIsHappy = FALSE; if (!bPythonIsHappy) return NULL; HRESULT hr; PY_INTERFACE_PRECALL; hr = pIDT->DragOver( grfKeyState, pt, &dwEffect ); PY_INTERFACE_POSTCALL; if ( FAILED(hr) ) return PyCom_BuildPyException(hr, pIDT, IID_IDropTarget ); return PyInt_FromLong(dwEffect); }
void CMainWindow::Init() { tstring strPath = ZYM::CPath::GetCurDir() + _T("Face\\FaceConfig.xml"); m_FaceList.LoadConfigFile(strPath.c_str()); m_pMinSysBtn = static_cast<CButtonUI*>(paint_manager_.FindControl(_T("btnMinSys"))); m_pMaxSysBtn = static_cast<CButtonUI*>(paint_manager_.FindControl(_T("btnMaxSys"))); m_pRestoreSysBtn = static_cast<CButtonUI*>(paint_manager_.FindControl(_T("btnRestoreSys"))); m_pCloseSysBtn = static_cast<CButtonUI*>(paint_manager_.FindControl(_T("btnCloseSys"))); m_pFontBtn = static_cast<CButtonUI*>(paint_manager_.FindControl(_T("btnFont"))); m_pFaceBtn = static_cast<CButtonUI*>(paint_manager_.FindControl(_T("btnFace"))); m_pImageBtn = static_cast<CButtonUI*>(paint_manager_.FindControl(_T("btnImage"))); m_pFontNameCombo = static_cast<CComboUI*>(paint_manager_.FindControl(_T("cboFontName"))); m_pFontSizeCombo = static_cast<CComboUI*>(paint_manager_.FindControl(_T("cboFontSize"))); m_pBoldBtn = static_cast<COptionUI*>(paint_manager_.FindControl(_T("btnBold"))); m_pItalicBtn = static_cast<COptionUI*>(paint_manager_.FindControl(_T("btnItalic"))); m_pUnderLineBtn = static_cast<COptionUI*>(paint_manager_.FindControl(_T("btnUnderLine"))); m_pColorBtn = static_cast<CButtonUI*>(paint_manager_.FindControl(_T("btnColor"))); m_pCloseBtn = static_cast<CButtonUI*>(paint_manager_.FindControl(_T("btnClose"))); m_pSendBtn = static_cast<CButtonUI*>(paint_manager_.FindControl(_T("btnSend"))); m_pSendEdit = static_cast<CRichEditUI*>(paint_manager_.FindControl(_T("richSend"))); m_pRecvEdit = static_cast<CRichEditUI*>(paint_manager_.FindControl(_T("richRecv"))); DragAcceptFiles(m_hWnd, true); IRichEditOleCallback2* pRichEditOleCallback2 = NULL; HRESULT hr = ::CoCreateInstance(CLSID_ImageOle, NULL, CLSCTX_INPROC_SERVER, __uuidof(IRichEditOleCallback2), (void**)&pRichEditOleCallback2); if (SUCCEEDED(hr)) { pRichEditOleCallback2->SetNotifyHwnd(m_hWnd); ITextServices * pTextServices = m_pRecvEdit->GetTextServices(); pRichEditOleCallback2->SetTextServices(pTextServices); pTextServices->Release(); m_pRecvEdit->SetOleCallback(pRichEditOleCallback2); pRichEditOleCallback2->Release(); } pRichEditOleCallback2 = NULL; hr = ::CoCreateInstance(CLSID_ImageOle, NULL, CLSCTX_INPROC_SERVER, __uuidof(IRichEditOleCallback2), (void**)&pRichEditOleCallback2); if (SUCCEEDED(hr)) { pRichEditOleCallback2->SetNotifyHwnd(m_hWnd); ITextServices * pTextServices = m_pSendEdit->GetTextServices(); pRichEditOleCallback2->SetTextServices(pTextServices); pTextServices->Release(); m_pSendEdit->SetOleCallback(pRichEditOleCallback2); pRichEditOleCallback2->Release(); } IDropTarget *pdt = m_pSendEdit->GetTxDropTarget(); hr = ::RegisterDragDrop(m_hWnd, pdt); pdt->Release(); }
void CFolderHander::OnInit( SWindow *pFolderRoot ) { m_pFolderRoot = pFolderRoot; SASSERT(m_pFolderRoot); SWindow *pEditDir = m_pFolderRoot->FindChildByName(L"edit_dir"); SASSERT(pEditDir); IDropTarget *pDT = new CDropTarget(this); m_pFolderRoot->GetContainer()->RegisterDragDrop(pEditDir->GetSwnd(),pDT); pDT->Release(); m_pDirTree = m_pFolderRoot->FindChildByName2<STreeCtrl>(L"tree_dir"); }
void CFolderScanHandler::OnInit(SWindow *pRoot) { m_pPageRoot = pRoot->FindChildByName(L"page_folderscan"); SASSERT(m_pPageRoot); SWindow *pEditDir = m_pPageRoot->FindChildByName(L"edit_dir"); SASSERT(pEditDir); IDropTarget *pDT = new CDropTarget(this); m_pPageRoot->GetContainer()->RegisterDragDrop(pEditDir->GetSwnd(),pDT); pDT->Release(); m_pTreelist = m_pPageRoot->FindChildByName2<SFolderTreeList>(L"tree_dir"); SASSERT(m_pTreelist); m_pTreelist->GetFolderTreeCtrl()->GetEventSet()->subscribeEvent(EventTCDbClick::EventID,Subscriber(&CFolderScanHandler::OnTreeDbclick,this)); }
void CDropHandler::HandleRightClickDrop(void) { IShellFolder *pDesktop = NULL; IShellFolder *pShellFolder = NULL; IDropTarget *pDrop = NULL; LPITEMIDLIST pidlDirectory = NULL; DWORD dwe; HRESULT hr; hr = GetIdlFromParsingName(m_szDestDirectory,&pidlDirectory); if(SUCCEEDED(hr)) { hr = SHGetDesktopFolder(&pDesktop); if(SUCCEEDED(hr)) { hr = pDesktop->BindToObject(pidlDirectory,0,IID_IShellFolder,(void **)&pShellFolder); if(SUCCEEDED(hr)) { dwe = *m_pdwEffect; hr = pShellFolder->CreateViewObject(m_hwndDrop,IID_IDropTarget,(void **)&pDrop); if(SUCCEEDED(hr)) { pDrop->DragEnter(m_pDataObject,MK_RBUTTON,m_ptl,&dwe); dwe = *m_pdwEffect; pDrop->Drop(m_pDataObject,m_grfKeyState,m_ptl,&dwe); pDrop->DragLeave(); pDrop->Release(); } pShellFolder->Release(); } pDesktop->Release(); } CoTaskMemFree(pidlDirectory); } }
// @pymethod |PyIDropTarget|DragLeave|Called as the object is dragged back out of the window PyObject *PyIDropTarget::DragLeave(PyObject *self, PyObject *args) { IDropTarget *pIDT = GetI(self); if ( pIDT == NULL ) return NULL; if ( !PyArg_ParseTuple(args, ":DragLeave") ) return NULL; HRESULT hr; PY_INTERFACE_PRECALL; hr = pIDT->DragLeave( ); PY_INTERFACE_POSTCALL; if ( FAILED(hr) ) return PyCom_BuildPyException(hr, pIDT, IID_IDropTarget ); Py_INCREF(Py_None); return Py_None; }
// @pymethod |PyIDocHostUIHandler|GetDropTarget|Description of GetDropTarget. PyObject *PyIDocHostUIHandler::GetDropTarget(PyObject *self, PyObject *args) { IDocHostUIHandler *pIDHUIH = GetI(self); if ( pIDHUIH == NULL ) return NULL; // @pyparm <o PyIDropTarget>|pDropTarget||Description for pDropTarget PyObject *obpDropTarget; IDropTarget * pDropTarget; IDropTarget * ppDropTarget; if ( !PyArg_ParseTuple(args, "O:GetDropTarget", &obpDropTarget) ) return NULL; BOOL bPythonIsHappy = TRUE; if (bPythonIsHappy && !PyCom_InterfaceFromPyInstanceOrObject(obpDropTarget, IID_IDropTarget, (void **)&pDropTarget, TRUE /* bNoneOK */)) bPythonIsHappy = FALSE; if (!bPythonIsHappy) return NULL; HRESULT hr; PY_INTERFACE_PRECALL; hr = pIDHUIH->GetDropTarget( pDropTarget, &ppDropTarget ); if (pDropTarget) pDropTarget->Release(); PY_INTERFACE_POSTCALL; if ( FAILED(hr) ) return PyCom_BuildPyException(hr, pIDHUIH, IID_IDocHostUIHandler ); return PyCom_PyObjectFromIUnknown(ppDropTarget, IID_IDropTarget, FALSE); }
bool tomEdit::Init() { WLDC dc(this) ; s_XPixelPerInch = dc.GetDeviceCaps(LOGPIXELSX) ; s_YPixelPerInch = dc.GetDeviceCaps(LOGPIXELSY) ; m_ref_count = 1 ; m_show_vert_scroll_bar = false ; m_show_horz_scroll_bar = false ; m_background_transparent = true ; m_use_system_background_color = true ; m_use_system_highlight_text_color = true ; m_use_system_highlight_text_background_color = true ; m_word_wrap = !(GetStyle() & (WS_HSCROLL | ES_AUTOHSCROLL)) ; HRESULT hr ; IUnknown * pUnknown ; // 由于CreateTextServices会触发TxGetCharFormat和TxGetParaFormat, // 所以要在此之前初始化CharFormat和ParaFormat // 初始化CharFormat InitDefaultCharFormat() ; // 初始化ParaFormat InitDefaultParaFormat() ; RECT bound_in_host ; GetRectInHost(&bound_in_host) ; if (FAILED(CreateBorder(IID_IRectangleBorder, (IUnknown**)&m_border))) return FALSE ; m_border->SetPos(bound_in_host.left, bound_in_host.top) ; m_border->SetSize(bound_in_host.right - bound_in_host.left, bound_in_host.bottom - bound_in_host.top) ; m_border->SetInset(m_border_inset.left, m_border_inset.top, m_border_inset.right, m_border_inset.bottom) ; if (FAILED(CreateTextServices(NULL, this, &pUnknown))) return false ; hr = pUnknown->QueryInterface(IID_ITextServices, (void**)&m_services) ; pUnknown->Release() ; if (FAILED(hr)) return false ; // 输入的客户区矩形范围似乎无用,总是会调用ITextHost::TxGetClientRect来获取区域 if (FAILED(m_services->OnTxInPlaceActivate(&bound_in_host))) return false ; LRESULT mask ; m_services->TxSendMessage(EM_GETEVENTMASK, 0, 0, &mask) ; mask |= ENM_SELCHANGE ; m_services->TxSendMessage(EM_SETEVENTMASK, 0, mask, NULL) ; m_call_back = new tomEditCallback(this) ; SetOLECallback(m_call_back) ; // 注册拖拽 IDropTarget * dt = NULL ; if (S_OK == m_services->TxGetDropTarget(&dt)) { RegisterDragDrop(dt) ; dt->Release() ; } return true ; }