Somthing confused with ole drag and drop implementation [closed] - drag-and-drop
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I wish to finish a little demo to implement OLE drag and drop(drag a file from my application to windows explorer).
But here comes a problem:DoDragDrop return DRAGDROP_S_DROP which means the ole drag and drop operation has successfully done,but also get DROPEFFECT_NONE which means drop target cannot accept the data.
I debug into it but I get a mess with them,help me,please:(
Here is the gui:
Critical code comes:
1.MainWindow.h
#ifndef MainWindowH
#define MainWindowH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Ole2.h>
#include "MyDataObject.h"
#include "MyDropSource.h"
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TLabel *Label1;
void __fastcall Label1StartDrag(TObject *Sender, TDragObject *&DragObject);
void __fastcall Label1EndDrag(TObject *Sender, TObject *Target, int X, int Y);
void __fastcall FormCreate(TObject *Sender);
void __fastcall FormDestroy(TObject *Sender);
private: // User declarations
//准备两个接口实例
IDataObject *pDataObject;
IDropSource *pDropSource;
//
STGMEDIUM stgmed;
FORMATETC fmtetc;
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
2.DoDragDrop invoke in MainWindow.cpp
void __fastcall TForm1::Label1StartDrag(TObject *Sender, TDragObject *&DragObject)
{
Label1->Caption = "Start drag";
//Source file
char tFileName[256] = "D:\\119.dat";
//Prepare FOTMATETC
fmtetc.cfFormat = CF_HDROP;
fmtetc.dwAspect = DVASPECT_CONTENT;
fmtetc.lindex = -1;
fmtetc.ptd = (void*)0;
fmtetc.tymed = TYMED_HGLOBAL;
//Prepare DROPFILES
DROPFILES* tDropFiles;
//Fill the filename
HGLOBAL hGblFiles;
LPSTR lpData;
stgmed.hGlobal = GlobalAlloc(GHND, sizeof(DROPFILES)+strlen(tFileName)+ 2);
if(0 == stgmed.hGlobal)
MessageBoxA(NULL, "OUT_OF_MEMORY!!!", "OUT_OF_MEMORY", 0);
tDropFiles = (DROPFILES*)GlobalLock(stgmed.hGlobal);
ZeroMemory(tDropFiles, sizeof(DROPFILES)+strlen(tFileName)+2);
strcpy(((char*)tDropFiles)+sizeof(DROPFILES), tFileName);
GlobalUnlock(stgmed.hGlobal);
tDropFiles->fNC = true;
tDropFiles->fWide = false;
tDropFiles->pFiles = sizeof(DROPFILES);
tDropFiles->pt.x = 0;
tDropFiles->pt.y = 0;
//set hGlobal
stgmed.tymed = TYMED_HGLOBAL;
stgmed.hGlobal = tDropFiles;
stgmed.pUnkForRelease = 0;
//Create Instance of IDropSource and IDataObject
pDropSource = new MyDropSource();
pDropSource->AddRef();
pDataObject = new MyDataObject();
pDataObject->AddRef();
//SetData
pDataObject->SetData(&fmtetc, &stgmed, true);
OleInitialize(0);
//Invoke DoDragDrop
DWORD dwEffect;
HRESULT tResult = DoDragDrop((IDataObject*)pDataObject, (IDropSource*)pDropSource, DROPEFFECT_MOVE, &dwEffect);
//Ckeck drag&drop result
if(tResult != DRAGDROP_S_DROP)
{
if(tResult == DRAGDROP_S_CANCEL)
MessageBoxA(NULL, "DRAGDROP_S_CANCEL!", "DRAGDROP_S_DROP", 0);
else
MessageBoxA(NULL, "E_UNSPEC!", "DRAGDROP_S_DROP", 0);
return;
}
if((dwEffect & DROPEFFECT_MOVE) == DROPEFFECT_MOVE)
MessageBoxA(NULL, "Ole drag&drop OK!!", "DRAGDROP_S_DROP", 0);
else
{
if((dwEffect & DROPEFFECT_NONE) == DROPEFFECT_NONE)
MessageBoxA(NULL, "DROPEFFECT_NONE!!", "DRAGDROP_S_DROP", 0);
}
//Clean
pDropSource->Release();
pDataObject->Release();
OleUninitialize();
return;
}
3.MyDataObject.h
#ifndef _MYDATAOBJECT_H_
#define _MYDATAOBJECT_H_
#include <stdio.h>
#include "IDragDemo.h"
#include "MyDropSource.h"
#ifndef SAFE_DELETE
#define SAFE_DELETE(p) { if(p){delete(p); (p)=NULL;} }
#endif
HRESULT CreateEnumFormatEtc(UINT cfmt, FORMATETC *afmt, IEnumFORMATETC **ppEnumFormatEtc);
class MyDataObject : public IDataObject
{
public:
//IUnknown implementation
ULONG __stdcall AddRef();
ULONG __stdcall Release();
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject);
//IDataObject members
STDMETHODIMP GetData (FORMATETC *pformatetcIn, STGMEDIUM *pmedium);
STDMETHODIMP GetDataHere (FORMATETC *pformatetc, STGMEDIUM *pmedium);
STDMETHODIMP QueryGetData (FORMATETC *pformatetc);
STDMETHODIMP GetCanonicalFormatEtc (FORMATETC *pformatectIn, FORMATETC *pformatetcOut);
STDMETHODIMP SetData (FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease);
STDMETHODIMP EnumFormatEtc (DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc);
STDMETHODIMP DAdvise (FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection);
STDMETHODIMP DUnadvise (DWORD dwConnection);
STDMETHODIMP EnumDAdvise (IEnumSTATDATA **ppenumAdvise);
public:
MyDataObject();
~MyDataObject();
private:
LONG refcount;
FORMATETC* m_AcceptFormat;
STGMEDIUM* m_StorageMedium;
HGLOBAL DupGlobalMem(HGLOBAL hMem);
//Helper function
HRESULT CopyMedium(STGMEDIUM* pMedDest, STGMEDIUM* pMedSrc, FORMATETC* pFmtSrc);
HRESULT SetBlob(CLIPFORMAT cf, const void *pvBlob, UINT cbBlob);
LONG m_RefCount;
};
//----------------MyEnumFormatEtc-----------------------------------------------------------
class MyEnumFormatEtc : public IEnumFORMATETC
{
public:
// IUnknown members
HRESULT __stdcall QueryInterface (REFIID iid, void ** ppv)
{
if((iid==IID_IUnknown)||(iid==IID_IEnumFORMATETC))
{
*ppv=this;
AddRef();
return S_OK;
}
else
{
*ppv=NULL;
return E_NOINTERFACE;
}
}
ULONG __stdcall AddRef (void) { return ++_iRefCount; }
ULONG __stdcall Release (void) { if(--_iRefCount==0){delete this; return 0;} return _iRefCount; }
// IEnumFormatEtc members
HRESULT __stdcall Next (ULONG celt, FORMATETC * rgelt, ULONG * pceltFetched);
HRESULT __stdcall Skip (ULONG celt)
{
_nIndex += celt;
return (_nIndex <= _nNumFormats) ? S_OK : S_FALSE;
}
HRESULT __stdcall Reset (void)
{
_nIndex = 0;
return S_OK;
}
HRESULT __stdcall Clone (IEnumFORMATETC ** ppEnumFormatEtc)
{
HRESULT hResult;
hResult = CreateEnumFormatEtc(_nNumFormats, _pFormatEtc, ppEnumFormatEtc);
if(hResult == S_OK)
{
((MyEnumFormatEtc *)*ppEnumFormatEtc)->_nIndex = _nIndex;
}
return hResult;
}
// Construction / Destruction
MyEnumFormatEtc(FORMATETC *pFormatEtc, ULONG nNumFormats);
~MyEnumFormatEtc();
private:
LONG _iRefCount;
ULONG _nIndex;
ULONG _nNumFormats;
FORMATETC * _pFormatEtc;
};
//---------------------------------------------------------------------------
#endif
4.MyDataObject.cpp
#include "MyDataObject.h"
#include "MyDropSource.h"
#include <Urlmon.h>
MyDataObject::MyDataObject(MyDropSource* vDropSource)
{
m_RefCount = 0;
m_DropSource = vDropSource;
}
MyDataObject::~MyDataObject()
{
refcount = 0;
SAFE_DELETE(m_StorageMedium);
SAFE_DELETE(m_AcceptFormat);
}
ULONG __stdcall MyDataObject::AddRef()
{
return InterlockedIncrement(&m_RefCount);
}
ULONG __stdcall MyDataObject::Release()
{
ULONG nRefCount = InterlockedDecrement(&m_RefCount);
if (nRefCount == 0)
delete this;
return nRefCount;
}
STDMETHODIMP MyDataObject::QueryInterface(REFIID riid, void **ppvObject) {
if (!ppvObject)
return E_POINTER;
if (riid == IID_IDataObject)
*ppvObject = (IDataObject*)this;
else if (riid == IID_IUnknown)
*ppvObject = (IUnknown*)this;
else
{
*ppvObject = 0;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
STDMETHODIMP MyDataObject::GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
{
if ( (NULL == pformatetcIn) || (NULL == pmedium) )
{
return E_INVALIDARG;
}
pmedium->hGlobal = NULL;
if( (pformatetcIn->tymed & m_AcceptFormat->tymed) &&
(pformatetcIn->dwAspect == m_AcceptFormat->dwAspect) &&
(pformatetcIn->cfFormat == m_AcceptFormat->cfFormat) )
{
return CopyMedium(pmedium, m_StorageMedium, m_AcceptFormat);
}
return DV_E_FORMATETC;
}
STDMETHODIMP MyDataObject::GetDataHere(FORMATETC *pformatetc, STGMEDIUM *pmedium)
{
return E_NOTIMPL;
}
STDMETHODIMP MyDataObject::QueryGetData(FORMATETC *pformatetc)
{
if(NULL == pformatetc )
{
return E_INVALIDARG;
}
if(!(DVASPECT_CONTENT & pformatetc->dwAspect))
{
return DV_E_DVASPECT;
}
HRESULT hr = DV_E_TYMED;
if(m_AcceptFormat->tymed & pformatetc->tymed )
{
if(m_AcceptFormat->cfFormat == pformatetc->cfFormat )
{
return S_OK;
}
else
{
hr = DV_E_CLIPFORMAT;
}
}
else
{
hr = DV_E_TYMED;
}
return hr;
}
STDMETHODIMP MyDataObject::GetCanonicalFormatEtc(FORMATETC *pformatectIn, FORMATETC *pformatetcOut)
{
pformatetcOut->ptd = NULL;
return E_NOTIMPL;
}
STDMETHODIMP MyDataObject::SetData(FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease)
{
if ( (NULL == pformatetc) || (NULL == pmedium) )
return E_INVALIDARG;
if ( pformatetc->tymed != pmedium->tymed )
return E_FAIL;
m_AcceptFormat = new FORMATETC;
m_StorageMedium = new STGMEDIUM;
ZeroMemory(m_AcceptFormat, sizeof(FORMATETC));
ZeroMemory(m_StorageMedium, sizeof(STGMEDIUM));
if ( TRUE == fRelease )
{
*m_StorageMedium = *pmedium;
}
else
{
CopyMedium(m_StorageMedium, pmedium, pformatetc);
}
return S_OK;
}
STDMETHODIMP MyDataObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc)
{
if(NULL == ppenumFormatEtc)
{
return E_INVALIDARG;
}
*ppenumFormatEtc = NULL;
HRESULT hr = E_NOTIMPL;
if (DATADIR_GET == dwDirection )
{
FORMATETC rgfmtetc[] =
{
{ CF_HDROP, NULL, DVASPECT_CONTENT, 0, TYMED_HGLOBAL },
};
hr = CreateEnumFormatEtc(ARRAYSIZE(rgfmtetc), rgfmtetc, ppenumFormatEtc);
}
return hr;
}
//Advises:OLE_E_ADVISENOTSUPPORTED
STDMETHODIMP MyDataObject::DAdvise(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
{
UNREFERENCED_PARAMETER(pformatetc);
UNREFERENCED_PARAMETER(advf);
UNREFERENCED_PARAMETER(pAdvSink);
UNREFERENCED_PARAMETER(pdwConnection);
return E_NOTIMPL;
}
STDMETHODIMP MyDataObject::DUnadvise(DWORD dwConnection)
{
UNREFERENCED_PARAMETER(dwConnection);
return E_NOTIMPL;
}
STDMETHODIMP MyDataObject::EnumDAdvise(IEnumSTATDATA **ppenumAdvise)
{
UNREFERENCED_PARAMETER(ppenumAdvise);
return E_NOTIMPL;
}
//Advises:OLE_E_ADVISENOTSUPPORTED
HGLOBAL MyDataObject::DupGlobalMem(HGLOBAL hMem)
{
DWORD len = GlobalSize(hMem);
PVOID source = GlobalLock(hMem);
PVOID dest = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, len);
memcpy(dest, source, len);
GlobalUnlock(hMem);
return dest;
}
HRESULT MyDataObject::CopyMedium(STGMEDIUM* pMedDest, STGMEDIUM* pMedSrc, FORMATETC* pFmtSrc)
{
if ( (NULL == pMedDest) || (NULL ==pMedSrc) || (NULL == pFmtSrc) )
{
return E_INVALIDARG;
}
switch(pMedSrc->tymed)
{
case TYMED_HGLOBAL:
pMedDest->hGlobal = (HGLOBAL)OleDuplicateData(pMedSrc->hGlobal, pFmtSrc->cfFormat, NULL);
break;
case TYMED_GDI:
pMedDest->hBitmap = (HBITMAP)OleDuplicateData(pMedSrc->hBitmap, pFmtSrc->cfFormat, NULL);
break;
case TYMED_MFPICT:
pMedDest->hMetaFilePict = (HMETAFILEPICT)OleDuplicateData(pMedSrc->hMetaFilePict, pFmtSrc->cfFormat, NULL);
break;
case TYMED_ENHMF:
pMedDest->hEnhMetaFile = (HENHMETAFILE)OleDuplicateData(pMedSrc->hEnhMetaFile, pFmtSrc->cfFormat, NULL);
break;
case TYMED_FILE:
pMedSrc->lpszFileName = (LPOLESTR)OleDuplicateData(pMedSrc->lpszFileName, pFmtSrc->cfFormat, NULL);
break;
case TYMED_ISTREAM:
pMedDest->pstm = pMedSrc->pstm;
pMedSrc->pstm->AddRef();
break;
case TYMED_ISTORAGE:
pMedDest->pstg = pMedSrc->pstg;
pMedSrc->pstg->AddRef();
break;
case TYMED_NULL:
default:
break;
}
pMedDest->tymed = pMedSrc->tymed;
pMedDest->pUnkForRelease = NULL;
if(pMedSrc->pUnkForRelease != NULL)
{
pMedDest->pUnkForRelease = pMedSrc->pUnkForRelease;
pMedSrc->pUnkForRelease->AddRef();
}
return S_OK;
}
HRESULT MyDataObject::SetBlob(CLIPFORMAT cf, const void *pvBlob, UINT cbBlob)
{
void *pv = GlobalAlloc(GPTR, cbBlob);
HRESULT hr = pv ? S_OK : E_OUTOFMEMORY;
if ( SUCCEEDED(hr) )
{
CopyMemory(pv, pvBlob, cbBlob);
FORMATETC fmte = {cf, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
STGMEDIUM medium = {};
medium.tymed = TYMED_HGLOBAL;
medium.hGlobal = pv;
hr = this->SetData(&fmte, &medium, TRUE);
if (FAILED(hr))
{
GlobalFree(pv);
}
}
return hr;
}
HRESULT CreateEnumFormatEtc(UINT cfmt, FORMATETC *afmt, IEnumFORMATETC **ppEnumFormatEtc)
{
if (cfmt == 0 || afmt == 0 || ppEnumFormatEtc == 0)
return E_INVALIDARG;
*ppEnumFormatEtc = new MyEnumFormatEtc(afmt, cfmt);
return (*ppEnumFormatEtc) ? S_OK: E_OUTOFMEMORY;
}
void DeepCopyFormatEtc(FORMATETC *dest, FORMATETC *source)
{
*dest = *source;
if(source->ptd)
{
dest->ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE));
*(dest->ptd) = *(source->ptd);
}
}
MyEnumFormatEtc::MyEnumFormatEtc(FORMATETC *pFormatEtc, ULONG nNumFormats)
:_iRefCount(1),_nIndex(0),_nNumFormats(nNumFormats)
{
_pFormatEtc = new FORMATETC[nNumFormats];
// make a new copy of each FORMATETC structure
for(ULONG i = 0; i < nNumFormats; i++)
{
DeepCopyFormatEtc (&_pFormatEtc[i], &pFormatEtc[i]);
}
}
MyEnumFormatEtc::~MyEnumFormatEtc()
{
// first free any DVTARGETDEVICE structures
for(ULONG i = 0; i < _nNumFormats; i++)
{
if(_pFormatEtc[i].ptd)
CoTaskMemFree(_pFormatEtc[i].ptd);
}
// now free the main array
delete[] _pFormatEtc;
}
HRESULT __stdcall MyEnumFormatEtc::Next(ULONG celt, FORMATETC *pFormatEtc, ULONG *pceltFetched)
{
ULONG copied = 0;
// copy the FORMATETC structures into the caller's buffer
while (_nIndex < _nNumFormats && copied < celt)
{
DeepCopyFormatEtc (&pFormatEtc [copied], &_pFormatEtc [_nIndex]);
copied++;
_nIndex++;
}
// store result
if(pceltFetched != 0)
*pceltFetched = copied;
// did we copy all that was requested?
return (copied == celt) ? S_OK : S_FALSE;
}
5.MyDropSource.h
#ifndef _MYDROPSOURCE_H_
#define _MYDROPSOURCE_H_
#include <stdio.h>
#include "IDragDemo.h"
class MyDropSource : public IDropSource
{
public:
//IUnknown implementation
ULONG __stdcall AddRef();
ULONG __stdcall Release();
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject);
//IDropSource members
STDMETHODIMP QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState);
STDMETHODIMP GiveFeedback(DWORD dwEffect);
//Cons/Destructors
MyDropSource();
~MyDropSource();
private:
LONG refcount;
};
#endif
6.MyDropSource.cpp
#include "MyDataObject.h"
#include "MyDropSource.h"
#include <Urlmon.h>
//Constructors
MyDataObject::MyDataObject(MyDropSource* vDropSource)
{
m_RefCount = 0;
m_DropSource = vDropSource;
}
//Destructors
MyDataObject::~MyDataObject()
{
refcount = 0;
SAFE_DELETE(m_StorageMedium);
SAFE_DELETE(m_AcceptFormat);
}
//IUnkown implementation
ULONG __stdcall MyDataObject::AddRef()
{
return InterlockedIncrement(&m_RefCount);
}
ULONG __stdcall MyDataObject::Release()
{
ULONG nRefCount = InterlockedDecrement(&m_RefCount);
if (nRefCount == 0)
delete this;
return nRefCount;
}
STDMETHODIMP MyDataObject::QueryInterface(REFIID riid, void **ppvObject) {
if (!ppvObject)
return E_POINTER;
if (riid == IID_IDataObject)
*ppvObject = (IDataObject*)this;
else if (riid == IID_IUnknown)
*ppvObject = (IUnknown*)this;
else
{
*ppvObject = 0;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
STDMETHODIMP MyDataObject::GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
{
//入参检查
if ( (NULL == pformatetcIn) || (NULL == pmedium) )
{
return E_INVALIDARG;
}
pmedium->hGlobal = NULL;
if( (pformatetcIn->tymed & m_AcceptFormat->tymed) &&
(pformatetcIn->dwAspect == m_AcceptFormat->dwAspect) &&
(pformatetcIn->cfFormat == m_AcceptFormat->cfFormat) )
{
return CopyMedium(pmedium, m_StorageMedium, m_AcceptFormat);
}
return DV_E_FORMATETC;
}
STDMETHODIMP MyDataObject::GetDataHere(FORMATETC *pformatetc, STGMEDIUM *pmedium)
{
return E_NOTIMPL;
}
STDMETHODIMP MyDataObject::QueryGetData(FORMATETC *pformatetc)
{
if(NULL == pformatetc )
{
return E_INVALIDARG;
}
if(!(DVASPECT_CONTENT & pformatetc->dwAspect))
{
return DV_E_DVASPECT;
}
HRESULT hr = DV_E_TYMED;
if(m_AcceptFormat->tymed & pformatetc->tymed )
{
if(m_AcceptFormat->cfFormat == pformatetc->cfFormat )
{
return S_OK;
}
else
{
hr = DV_E_CLIPFORMAT;
}
}
else
{
hr = DV_E_TYMED;
}
return hr;
}
STDMETHODIMP MyDataObject::GetCanonicalFormatEtc(FORMATETC *pformatectIn, FORMATETC *pformatetcOut)
{
pformatetcOut->ptd = NULL;
return E_NOTIMPL;
}
STDMETHODIMP MyDataObject::SetData(FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease)
{
if ( (NULL == pformatetc) || (NULL == pmedium) )
return E_INVALIDARG;
if ( pformatetc->tymed != pmedium->tymed )
return E_FAIL;
m_AcceptFormat = new FORMATETC;
m_StorageMedium = new STGMEDIUM;
ZeroMemory(m_AcceptFormat, sizeof(FORMATETC));
ZeroMemory(m_StorageMedium, sizeof(STGMEDIUM));
if ( TRUE == fRelease )
{
*m_StorageMedium = *pmedium;
}
else
{
CopyMedium(m_StorageMedium, pmedium, pformatetc);
}
return S_OK;
}
STDMETHODIMP MyDataObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc)
{
if(NULL == ppenumFormatEtc)
{
return E_INVALIDARG;
}
*ppenumFormatEtc = NULL;
HRESULT hr = E_NOTIMPL;
if (DATADIR_GET == dwDirection )
{
FORMATETC rgfmtetc[] =
{
{ CF_HDROP, NULL, DVASPECT_CONTENT, 0, TYMED_HGLOBAL },
};
hr = CreateEnumFormatEtc(ARRAYSIZE(rgfmtetc), rgfmtetc, ppenumFormatEtc);
}
return hr;
}
//Advises:OLE_E_ADVISENOTSUPPORTED
STDMETHODIMP MyDataObject::DAdvise(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
{
UNREFERENCED_PARAMETER(pformatetc);
UNREFERENCED_PARAMETER(advf);
UNREFERENCED_PARAMETER(pAdvSink);
UNREFERENCED_PARAMETER(pdwConnection);
return E_NOTIMPL;
}
STDMETHODIMP MyDataObject::DUnadvise(DWORD dwConnection)
{
UNREFERENCED_PARAMETER(dwConnection);
return E_NOTIMPL;
}
STDMETHODIMP MyDataObject::EnumDAdvise(IEnumSTATDATA **ppenumAdvise)
{
UNREFERENCED_PARAMETER(ppenumAdvise);
return E_NOTIMPL;
}
//Advises:OLE_E_ADVISENOTSUPPORTED
HGLOBAL MyDataObject::DupGlobalMem(HGLOBAL hMem)
{
DWORD len = GlobalSize(hMem);
PVOID source = GlobalLock(hMem);
PVOID dest = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, len);
memcpy(dest, source, len);
GlobalUnlock(hMem);
return dest;
}
HRESULT MyDataObject::CopyMedium(STGMEDIUM* pMedDest, STGMEDIUM* pMedSrc, FORMATETC* pFmtSrc)
{
if ( (NULL == pMedDest) || (NULL ==pMedSrc) || (NULL == pFmtSrc) )
{
return E_INVALIDARG;
}
switch(pMedSrc->tymed)
{
case TYMED_HGLOBAL:
pMedDest->hGlobal = (HGLOBAL)OleDuplicateData(pMedSrc->hGlobal, pFmtSrc->cfFormat, NULL);
break;
case TYMED_GDI:
pMedDest->hBitmap = (HBITMAP)OleDuplicateData(pMedSrc->hBitmap, pFmtSrc->cfFormat, NULL);
break;
case TYMED_MFPICT:
pMedDest->hMetaFilePict = (HMETAFILEPICT)OleDuplicateData(pMedSrc->hMetaFilePict, pFmtSrc->cfFormat, NULL);
break;
case TYMED_ENHMF:
pMedDest->hEnhMetaFile = (HENHMETAFILE)OleDuplicateData(pMedSrc->hEnhMetaFile, pFmtSrc->cfFormat, NULL);
break;
case TYMED_FILE:
pMedSrc->lpszFileName = (LPOLESTR)OleDuplicateData(pMedSrc->lpszFileName, pFmtSrc->cfFormat, NULL);
break;
case TYMED_ISTREAM:
pMedDest->pstm = pMedSrc->pstm;
pMedSrc->pstm->AddRef();
break;
case TYMED_ISTORAGE:
pMedDest->pstg = pMedSrc->pstg;
pMedSrc->pstg->AddRef();
break;
case TYMED_NULL:
default:
break;
}
pMedDest->tymed = pMedSrc->tymed;
pMedDest->pUnkForRelease = NULL;
if(pMedSrc->pUnkForRelease != NULL)
{
pMedDest->pUnkForRelease = pMedSrc->pUnkForRelease;
pMedSrc->pUnkForRelease->AddRef();
}
return S_OK;
}
HRESULT MyDataObject::SetBlob(CLIPFORMAT cf, const void *pvBlob, UINT cbBlob)
{
void *pv = GlobalAlloc(GPTR, cbBlob);
HRESULT hr = pv ? S_OK : E_OUTOFMEMORY;
if ( SUCCEEDED(hr) )
{
CopyMemory(pv, pvBlob, cbBlob);
FORMATETC fmte = {cf, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
STGMEDIUM medium = {};
medium.tymed = TYMED_HGLOBAL;
medium.hGlobal = pv;
hr = this->SetData(&fmte, &medium, TRUE);
if (FAILED(hr))
{
GlobalFree(pv);
}
}
return hr;
}
HRESULT CreateEnumFormatEtc(UINT cfmt, FORMATETC *afmt, IEnumFORMATETC **ppEnumFormatEtc)
{
if (cfmt == 0 || afmt == 0 || ppEnumFormatEtc == 0)
return E_INVALIDARG;
*ppEnumFormatEtc = new MyEnumFormatEtc(afmt, cfmt);
return (*ppEnumFormatEtc) ? S_OK: E_OUTOFMEMORY;
}
void DeepCopyFormatEtc(FORMATETC *dest, FORMATETC *source)
{
// copy the source FORMATETC into dest
*dest = *source;
if(source->ptd)
{
// allocate memory for the DVTARGETDEVICE if necessary
dest->ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE));
// copy the contents of the source DVTARGETDEVICE into dest->ptd
*(dest->ptd) = *(source->ptd);
}
}
MyEnumFormatEtc::MyEnumFormatEtc(FORMATETC *pFormatEtc, ULONG nNumFormats)
:_iRefCount(1),_nIndex(0),_nNumFormats(nNumFormats)
{
_pFormatEtc = new FORMATETC[nNumFormats];
// make a new copy of each FORMATETC structure
for(ULONG i = 0; i < nNumFormats; i++)
{
DeepCopyFormatEtc (&_pFormatEtc[i], &pFormatEtc[i]);
}
}
MyEnumFormatEtc::~MyEnumFormatEtc()
{
// first free any DVTARGETDEVICE structures
for(ULONG i = 0; i < _nNumFormats; i++)
{
if(_pFormatEtc[i].ptd)
CoTaskMemFree(_pFormatEtc[i].ptd);
}
// now free the main array
delete[] _pFormatEtc;
}
HRESULT __stdcall MyEnumFormatEtc::Next(ULONG celt, FORMATETC *pFormatEtc, ULONG *pceltFetched)
{
ULONG copied = 0;
// copy the FORMATETC structures into the caller's buffer
while (_nIndex < _nNumFormats && copied < celt)
{
DeepCopyFormatEtc (&pFormatEtc [copied], &_pFormatEtc [_nIndex]);
copied++;
_nIndex++;
}
// store result
if(pceltFetched != 0)
*pceltFetched = copied;
// did we copy all that was requested?
return (copied == celt) ? S_OK : S_FALSE;
}
7.IDragDemo.h
#ifndef _DRAGDROP_H_
#define _DRAGDROP_H_
#include <windows.h>
#include <ole2.h>
#include <Shlobj.h>
#endif //_DRAGDROP_H_
Complete Code can be get here:https://github.com/cyfingm/cb_ole_dragdrop
OleIsCurrentClipboard() is returning S_FALSE because you are calling OleFlushClipboard() beforehand. Read the documentation:
OleFlushClipboard function
Carries out the clipboard shutdown sequence. It also releases the IDataObject pointer that was placed on the clipboard by the OleSetClipboard function.
...
OleFlushClipboard renders the data from a data object onto the clipboard and releases the IDataObject pointer to the data object.
...
Before calling OleFlushClipboard, you can easily determine if your data is still on the clipboard with a call to the OleIsCurrentClipboard function.
Basically, once you call OleFlushClipboard(), the clipboard no longer contains a pointer to your IDataObject. The CF_HDROP data gets copied directly onto the clipboard, and the IDataObject is removed.
Why are you involving the clipboard at all? You do not need to put the IDataObject on the clipboard in order to use DoDragDrop(), so stop doing that. You pass the IDataObject directly to DoDragDrop(), that is all you need to do.
There are other problems with this code as well.
This line is wrong:
strcpy((char*)(tDropFiles+sizeof(DROPFILES)), tFileName);
It should be this instead:
strcpy(((char*)tDropFiles)+sizeof(DROPFILES), tFileName);
Or this:
strcpy((char*)(tDropFiles+1), tFileName);
You are also not maintaining the IDataObject and IDropSource reference counts correctly. When you create those objects, their reference counts are 0. OleSetClipboard() will increment the IDataObject reference count, then OleFlushClipboard() will decrement it, freeing that object before DoDragDrop() is called. Label1EndDrag() needs to call AddRef() on both objects after creating them (it has a reference to them, afterall), and then call Release() when it is done using them.
pDropSource = new MyDropSource();
pDropSource->AddRef();
pDataObject = new MyDataObject((MyDropSource*)pDropSource);//(&fmtetc, &stgmed, 1);
pDataObject->AddRef();
...
pDropSource->Release();
pDataObject->Release();
Also, this will not work:
(MyDropSource*)pDropSource
You cannot create a MyDropSource instance, assign it to an IDropSource* pointer, and then type-cast it back to MyDropSource*. And besides, there is no good reason to have MyDataObject contain a pointer to MyDropSource (especially since it is not actually using it for anything, nor is it incrementing/decrementing the reference count), so you need to remove that altogether.
Lastly, your QueryInterface() implementations are not returning the correct output pointer address. It is not taking polymorphic vtables into account correctly. The implementation need to look more like this instead:
STDMETHODIMP MyDataObject::QueryInterface(REFIID riid, void **ppvObject)
{
if (!ppvObject)
return E_POINTER;
if (riid == IID_IDataObject)
*ppvObject = (IDataObject*)this;
else if (riid == IID_IUnknown)
*ppvObject = (IUnknown*)this;
else
{
*ppvObject = 0;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
I'm sure there are other flaws and leaks in this code, but I stopped reviewing after seeing these big flaws. It is not a very clean implementation in general.
Update: DROPEFFECT_NONE is defined as 0, so the statement
if((dwEffect & DROPEFFECT_NONE) == DROPEFFECT_NONE)
Will always evaluate as true, regardless of the value of dwEffect. Don't use the bitwise & operator to test for DROPEFFECT_NONE, use the == operator instead. Use & for all other values.
if(dwEffect == DROPEFFECT_NONE)
MessageBoxA(NULL, "Ole data not accepted!!", "DRAGDROP_S_DROP", 0);
else if((dwEffect & DROPEFFECT_MOVE) == DROPEFFECT_MOVE)
MessageBoxA(NULL, "Ole data moved!!", "DRAGDROP_S_DROP", 0);
else if((dwEffect & DROPEFFECT_COPY) == DROPEFFECT_COPY)
MessageBoxA(NULL, "Ole data copied!!", "DRAGDROP_S_DROP", 0);
...
Related
Send TCP or UDP packets from efi application
I want to develop an application to be automatically executed from startup.nsh in EFI shell. This application should send raw bytes to an ip address and receive some back. I looked everywhere for explanation and example for the implementation of simple network protocol in my code but found nothin. Can someone explain and show a code example using gnu_efi libaries?
Here is a sample how to send and receive UDP packets with EDK2, porting it to gnu-efi should be an easy task, wrap all gBS->, gRT-> and protocolXY calls with the uefi_call_wrapper. Change the global values to match your client and server. #include <Uefi.h> #include <Library\UefiLib.h> #include <Protocol\ServiceBinding.h> #include <Protocol\Udp4.h> #include <Protocol\SimpleNetwork.h> #include <Protocol\ManagedNetwork.h> #include <Protocol\Ip4.h> #ifndef LOG #define LOG(fmt, ...) AsciiPrint(fmt, __VA_ARGS__) #endif #ifndef TRACE #define TRACE(status) LOG("Status: '%r', Function: '%a', File: '%a', Line: '%d'\r\n", status, __FUNCTION__, __FILE__, __LINE__) #endif static EFI_GUID gEfiUdp4ServiceBindingProtocolGuid = EFI_UDP4_SERVICE_BINDING_PROTOCOL_GUID; static EFI_GUID gEfiUdp4ProtocolGuid = EFI_UDP4_PROTOCOL_GUID; extern EFI_BOOT_SERVICES *gBS; extern EFI_RUNTIME_SERVICES *gRT; static BOOLEAN gTransmitCompleteFlag = FALSE; static BOOLEAN gReceiveCompleteFlag = FALSE; /* Configuration */ static EFI_IPv4_ADDRESS gLocalAddress = { 10, 0, 2, 200 }; static EFI_IPv4_ADDRESS gSubnetMask = { 255, 255, 255, 0 }; static UINT16 gLocalPort = 0; static EFI_IPv4_ADDRESS gRemoteAddress = { 10, 0, 2, 180 }; static UINT16 gRemotePort = 4444; static VOID EFIAPI TransmitEventCallback( IN EFI_EVENT Event, IN void *UserData) { gTransmitCompleteFlag = TRUE; } static VOID EFIAPI ReceiveEventCallback( IN EFI_EVENT Event, IN void *UserData) { gReceiveCompleteFlag = TRUE; } static EFI_STATUS EFIAPI WaitForFlag( IN BOOLEAN *Flag, IN EFI_UDP4_PROTOCOL *Udp4Protocol OPTIONAL, IN UINTN Timeout) { EFI_STATUS Status; UINT8 LastSecond = MAX_UINT8; UINT8 Timer = 0; EFI_TIME CurrentTime; while (!*Flag && (Timeout == 0 || Timer < Timeout)) { if (Udp4Protocol) { Udp4Protocol->Poll( Udp4Protocol); } // use gRT->GetTime to exit this loop Status = gRT->GetTime(&CurrentTime, NULL); if (EFI_ERROR(Status)) { TRACE(Status); // Error handling return Status; } if (LastSecond != CurrentTime.Second) { LastSecond = CurrentTime.Second; Timer++; } } return *Flag ? EFI_SUCCESS : EFI_TIMEOUT; } EFI_STATUS EFIAPI UefiMain( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) { EFI_STATUS Status; EFI_UDP4_CONFIG_DATA Udp4ConfigData; EFI_UDP4_COMPLETION_TOKEN Udp4ReceiveCompletionToken; EFI_UDP4_COMPLETION_TOKEN Udp4TansmitCompletionToken; EFI_UDP4_TRANSMIT_DATA Udp4TransmitData; EFI_HANDLE Udp4ChildHandle = NULL; EFI_UDP4_PROTOCOL *Udp4Protocol = NULL; EFI_SERVICE_BINDING_PROTOCOL *Udp4ServiceBindingProtocol = NULL; CHAR8 TxBuffer[] = "Hello Server!"; /* Step 1: Locate the corresponding Service Binding Protocol, if there is more then 1 network interface gBS->LocateHandleBuffer should be used */ Status = gBS->LocateProtocol( &gEfiUdp4ServiceBindingProtocolGuid, NULL, &Udp4ServiceBindingProtocol); if (EFI_ERROR(Status)) { TRACE(Status); // Error handling return Status; } /* Step 2: Create a new UDP4 instance */ Status = Udp4ServiceBindingProtocol->CreateChild( Udp4ServiceBindingProtocol, &Udp4ChildHandle); if (EFI_ERROR(Status)) { TRACE(Status); // Error handling return Status; } Status = gBS->HandleProtocol( Udp4ChildHandle, &gEfiUdp4ProtocolGuid, &Udp4Protocol); if (EFI_ERROR(Status)) { TRACE(Status); // Error handling return Status; } /* Step 3: Prepare the UDP4 instance */ Udp4ConfigData.AcceptBroadcast = FALSE; Udp4ConfigData.AcceptPromiscuous = FALSE; Udp4ConfigData.AcceptAnyPort = FALSE; Udp4ConfigData.AllowDuplicatePort = FALSE; Udp4ConfigData.TimeToLive = 16; Udp4ConfigData.TypeOfService = 0; Udp4ConfigData.DoNotFragment = TRUE; Udp4ConfigData.ReceiveTimeout = 0; Udp4ConfigData.TransmitTimeout = 0; // Change to TRUE and set the following fields to zero if DHCP is used Udp4ConfigData.UseDefaultAddress = FALSE; gBS->CopyMem(&Udp4ConfigData.StationAddress, &gLocalAddress, sizeof(Udp4ConfigData.StationAddress)); gBS->CopyMem(&Udp4ConfigData.SubnetMask, &gSubnetMask, sizeof(Udp4ConfigData.SubnetMask)); Udp4ConfigData.StationPort = gLocalPort; gBS->CopyMem(&Udp4ConfigData.RemoteAddress, &gRemoteAddress, sizeof(Udp4ConfigData.RemoteAddress)); Udp4ConfigData.RemotePort = gRemotePort; Status = Udp4Protocol->Configure( Udp4Protocol, &Udp4ConfigData); if (EFI_ERROR(Status)) { TRACE(Status); // Error handling return Status; } /* Step 4: Send data and wait for completion */ Udp4TansmitCompletionToken.Status = EFI_SUCCESS; Udp4TansmitCompletionToken.Event = NULL; Status = gBS->CreateEvent( EVT_NOTIFY_SIGNAL, TPL_CALLBACK, TransmitEventCallback, NULL, &(Udp4TansmitCompletionToken.Event)); if (EFI_ERROR(Status)) { TRACE(Status); // Error handling return Status; } Udp4TansmitCompletionToken.Packet.TxData = &Udp4TransmitData; Udp4TransmitData.UdpSessionData = NULL; gBS->SetMem(&Udp4TransmitData.GatewayAddress, sizeof(Udp4TransmitData.GatewayAddress), 0x00); Udp4TransmitData.DataLength = sizeof(TxBuffer); Udp4TransmitData.FragmentCount = 1; Udp4TransmitData.FragmentTable[0].FragmentLength = Udp4TransmitData.DataLength; Udp4TransmitData.FragmentTable[0].FragmentBuffer = TxBuffer; gTransmitCompleteFlag = FALSE; LOG("Sending data...\r\n"); Status = Udp4Protocol->Transmit( Udp4Protocol, &Udp4TansmitCompletionToken); if (EFI_ERROR(Status)) { TRACE(Status); // Error handling return Status; } Status = WaitForFlag( &gTransmitCompleteFlag, Udp4Protocol, 10); if (EFI_ERROR(Status)) { TRACE(EFI_TIMEOUT); // Error handling return EFI_TIMEOUT; } if (EFI_ERROR(Udp4TansmitCompletionToken.Status)) { TRACE(Status); // Error handling return Status; } LOG("Data sent.\r\n"); /* Step 5: Receive data */ Udp4ReceiveCompletionToken.Status = EFI_SUCCESS; Udp4ReceiveCompletionToken.Event = NULL; Status = gBS->CreateEvent( EVT_NOTIFY_SIGNAL, TPL_CALLBACK, ReceiveEventCallback, NULL, &(Udp4ReceiveCompletionToken.Event)); if (EFI_ERROR(Status)) { TRACE(Status); // Error handling return Status; } Udp4ReceiveCompletionToken.Packet.RxData = NULL; gReceiveCompleteFlag = FALSE; LOG("Receiving data...\r\n"); Status = Udp4Protocol->Receive( Udp4Protocol, &Udp4ReceiveCompletionToken); if (EFI_ERROR(Status)) { TRACE(Status); // Error handling return Status; } Status = WaitForFlag( &gReceiveCompleteFlag, Udp4Protocol, 10); if (EFI_ERROR(Status)) { TRACE(EFI_TIMEOUT); // Error handling return EFI_TIMEOUT; } if (EFI_ERROR(Udp4ReceiveCompletionToken.Status)) { TRACE(Status); // Error handling return Status; } /* Step 6: Process received data */ if ( Udp4ReceiveCompletionToken.Packet.RxData && Udp4ReceiveCompletionToken.Packet.RxData->FragmentCount > 0 && Udp4ReceiveCompletionToken.Packet.RxData->DataLength > 0) { LOG("Received '%a'.\r\n", Udp4ReceiveCompletionToken.Packet.RxData->FragmentTable[0].FragmentBuffer); } else { LOG("Received an empty package.\r\n"); } /* Step 7: Cleanup */ if ( Udp4ReceiveCompletionToken.Packet.RxData && Udp4ReceiveCompletionToken.Packet.RxData->RecycleSignal) { Status = gBS->SignalEvent(Udp4ReceiveCompletionToken.Packet.RxData->RecycleSignal); if (EFI_ERROR(Udp4ReceiveCompletionToken.Status)) { TRACE(Status); // Error handling return Status; } } Status = Udp4ServiceBindingProtocol->DestroyChild( Udp4ServiceBindingProtocol, Udp4ChildHandle); if (EFI_ERROR(Udp4ReceiveCompletionToken.Status)) { TRACE(Status); // Error handling return Status; } return EFI_SUCCESS; }
How to overlay a picture over a video stream with Gstreamer in C?
I want to overlay a ".png" picture over a stream coming from an IP Camera using Gstreamer. A working pipeline for my hardware is: gst-launch-1.0 rtspsrc location=rtsp://user:pass#IP:port/channel latency=400 ! rtph264depay ! vpudec use-vpu-memory=false ! imxvideoconvert_ipu ! video/x-raw,format=I420 ! gdkpixbufoverlay location=/home/user/folder/image.png offset-x=100 offset-y=100 ! overlaysink The problem comes when I try to translate this pipeline in C. The code I wrote for this pipeline runs, but there is no video playback on the display. The player stuck itself before setting the pipeline on "playing" state. Here, there is a simple version of my C implementation: #include <gst/gst.h> #include <glib.h> #include <iostream> typedef struct _CustomData { GstElement *source; GstElement *rtp; GstElement *sink; GstElement *vpudec; GstElement *converter, *gdkpixbufoverlay, *capsfilter ; GstBus *bus; GstElement *pipeline; GMainLoop *loop; } CustomData; static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data) { GMainLoop *loop = (GMainLoop *) data; switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_EOS:{ g_print ("End of stream\n"); g_main_loop_quit (loop); break; } case GST_MESSAGE_ERROR: { gchar *debug; GError *error; gst_message_parse_error (msg, &error, &debug); g_free (debug); g_printerr ("Error: %s\n", error->message); g_error_free (error); g_main_loop_quit (loop); break; } default: break; } return TRUE; } static void pad_added_handler (GstElement *src, GstPad *new_pad, CustomData *data) { GstPad *sink_pad = gst_element_get_static_pad (data->rtp, "sink"); GstPadLinkReturn ret; GstCaps *new_pad_caps = NULL; GstStructure *new_pad_struct = NULL; const gchar *new_pad_type = NULL; if (gst_pad_is_linked (sink_pad)) { goto exit; } new_pad_caps = gst_pad_query_caps (new_pad, NULL); new_pad_struct = gst_caps_get_structure (new_pad_caps, 0); new_pad_type = gst_structure_get_name (new_pad_struct); if (!g_str_has_prefix (new_pad_type, "application/x-rtp")) { g_print (" It has type '%s' which is not x-rtp . Ignoring.\n", new_pad_type); goto exit; } ret = gst_pad_link (new_pad, sink_pad); if (GST_PAD_LINK_FAILED (ret)) { g_print(" Type is '%s' but link failed.\n", new_pad_type); } else { g_print (" Link succeeded (type '%s').\n", new_pad_type); } exit: if (new_pad_caps != NULL) gst_caps_unref (new_pad_caps); gst_object_unref (sink_pad); } int main (int argc, char *argv[]){ CustomData data; gst_init (NULL, NULL); data.loop = g_main_loop_new (NULL, FALSE); // Create gstreamer elements data.pipeline = gst_pipeline_new ("player"); data.source = gst_element_factory_make ("rtspsrc", "source"); data.rtp = gst_element_factory_make ("rtph264depay","rtp"); data.vpudec = gst_element_factory_make ("vpudec","vpudec"); data.converter = gst_element_factory_make ("imxcompositor_ipu","converter"); data.capsfilter = gst_element_factory_make ("capsfilter", "video- rate"); data.gdkpixbufoverlay = gst_element_factory_make ("gdkpixbufoverlay","overlaytool"); data.sink = gst_element_factory_make ("overlaysink", "videoSink"); if (!data.pipeline || !data.source || !data.rtp || !data.vpudec || !data.converter || !data.capsfilter || !data.gdkpixbufoverlay || !data.sink) { g_printerr ("One element could not be created. Exiting.\n"); return -1; } g_object_set (data.source, "location","rtsp://user:pass#IP:port/channel", NULL); g_object_set (data.source,"latency", 400 , NULL); g_object_set (data.vpudec, "use-vpu-memory", false, NULL); g_object_set (data.gdkpixbufoverlay, "location","/home/user/folder/image.png", NULL); g_object_set (data.gdkpixbufoverlay, "offset-x", 100 , NULL); g_object_set (data.gdkpixbufoverlay, "offset-y", 100 , NULL); GstCaps *capsFormat = gst_caps_from_string ("video/x-raw,format=I420"); g_object_set ( data.capsfilter, "caps", capsFormat, NULL); gst_caps_unref(capsFormat); //add all elements into the pipeline gst_bin_add_many (GST_BIN (data.pipeline), data.source, data.rtp, data.vpudec, data.converter, data.capsfilter, data.gdkpixbufoverlay, data.sink, NULL); // link all elements gst_element_link_many ( data.rtp, data.vpudec , data.converter , data.capsfilter, data.gdkpixbufoverlay, data.sink, NULL); g_signal_connect (data.source, "pad-added", G_CALLBACK (pad_added_handler), &data); // Set the pipeline to "playing" state GstStateChangeReturn ret; ret = gst_element_set_state (data.pipeline, GST_STATE_PLAYING); if (ret == GST_STATE_CHANGE_FAILURE) { g_printerr("Unable to set the pipeline to the playing state.\n"); gst_object_unref (data.pipeline); return -1; } // Iterate g_main_loop_run (data.loop); // Out of the main loop, clean g_print ("Returned, stopping playback\n"); gst_element_set_state (data.pipeline, GST_STATE_NULL); g_print ("Deleting pipeline\n"); gst_object_unref (GST_OBJECT (data.pipeline)); return 0; } Does anyone see the problem? Thank you
After many tries, I did figure out that in the C code I posted I have selected the wrong element, therefore the data.converter element is: data.converter = gst_element_factory_make("imxvideoconvert_ipu ","converter"); and not imxcompositor_ipu .
I am getting error while importing Policymanager?
I am writing code for my own media-controller for VideoView. and my code is as follows public class FMediaController extends FrameLayout { private MediaPlayerControl mPlayer; private Context mContext; private View mAnchor; private View mRoot; private WindowManager mWindowManager; private Window mWindow; private View mDecor; private ProgressBar mProgress; private TextView mEndTime, mCurrentTime; private boolean mShowing; private boolean mDragging; private static final int sDefaultTimeout = 3000; private static final int FADE_OUT = 1; private static final int SHOW_PROGRESS = 2; private boolean mUseFastForward; private boolean mFromXml; private boolean mListenersSet; private View.OnClickListener mNextListener, mPrevListener; StringBuilder mFormatBuilder; Formatter mFormatter; private ImageButton mPauseButton; private ImageButton mFfwdButton; private ImageButton mRewButton; private ImageButton mNextButton; private ImageButton mPrevButton; public FMediaController(Context context, AttributeSet attrs) { super(context, attrs); mRoot = this; mContext = context; mUseFastForward = true; mFromXml = true; } #Override public void onFinishInflate() { if (mRoot != null) initControllerView(mRoot); } public FMediaController(Context context, boolean useFastForward) { super(context); mContext = context; mUseFastForward = useFastForward; initFloatingWindow(); } public FMediaController(Context context) { super(context); mContext = context; mUseFastForward = true; initFloatingWindow(); } private void initFloatingWindow() { mWindowManager = (WindowManager)mContext.getSystemService("window"); mWindow = PolicyManager.makeNewWindow(mContext); mWindow.setWindowManager(mWindowManager, null, null); mWindow.requestFeature(Window.FEATURE_NO_TITLE); mDecor = mWindow.getDecorView(); mDecor.setOnTouchListener(mTouchListener); mWindow.setContentView(this); mWindow.setBackgroundDrawableResource(android.R.color.transparent); // While the media controller is up, the volume control keys should // affect the media stream type mWindow.setVolumeControlStream(AudioManager.STREAM_MUSIC); setFocusable(true); setFocusableInTouchMode(true); setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); requestFocus(); } private OnTouchListener mTouchListener = new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { if (mShowing) { hide(); } } return false; } }; public void setMediaPlayer(MediaPlayerControl player) { mPlayer = player; updatePausePlay(); } /** * Set the view that acts as the anchor for the control view. * This can for example be a VideoView, or your Activity's main view. * #param view The view to which to anchor the controller when it is visible. */ public void setAnchorView(View view) { mAnchor = view; FrameLayout.LayoutParams frameParams = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT ); removeAllViews(); View v = makeControllerView(); addView(v, frameParams); } /** * Create the view that holds the widgets that control playback. * Derived classes can override this to create their own. * #return The controller view. * #hide This doesn't work as advertised */ protected View makeControllerView() { LayoutInflater inflate = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mRoot = inflate.inflate(R.layout.media_controller, null); initControllerView(mRoot); return mRoot; } private void initControllerView(View v) { mPauseButton = (ImageButton) v.findViewById(R.id.pause); if (mPauseButton != null) { mPauseButton.requestFocus(); mPauseButton.setOnClickListener(mPauseListener); } mFfwdButton = (ImageButton) v.findViewById(R.id.ffwd); if (mFfwdButton != null) { mFfwdButton.setOnClickListener(mFfwdListener); if (!mFromXml) { mFfwdButton.setVisibility(mUseFastForward ? View.VISIBLE : View.GONE); } } mRewButton = (ImageButton) v.findViewById(R.id.rew); if (mRewButton != null) { mRewButton.setOnClickListener(mRewListener); if (!mFromXml) { mRewButton.setVisibility(mUseFastForward ? View.VISIBLE : View.GONE); } } // By default these are hidden. They will be enabled when setPrevNextListeners() is called mNextButton = (ImageButton) v.findViewById(R.id.next); if (mNextButton != null && !mFromXml && !mListenersSet) { mNextButton.setVisibility(View.GONE); } mPrevButton = (ImageButton) v.findViewById(R.id.prev); if (mPrevButton != null && !mFromXml && !mListenersSet) { mPrevButton.setVisibility(View.GONE); } mProgress = (ProgressBar) v.findViewById(R.id.mediacontroller_progress); if (mProgress != null) { if (mProgress instanceof SeekBar) { SeekBar seeker = (SeekBar) mProgress; seeker.setOnSeekBarChangeListener(mSeekListener); } mProgress.setMax(1000); } mEndTime = (TextView) v.findViewById(R.id.time); mCurrentTime = (TextView) v.findViewById(R.id.time_current); mFormatBuilder = new StringBuilder(); mFormatter = new Formatter(mFormatBuilder, Locale.getDefault()); installPrevNextListeners(); } /** * Show the controller on screen. It will go away * automatically after 3 seconds of inactivity. */ public void show() { show(sDefaultTimeout); } /** * Show the controller on screen. It will go away * automatically after 'timeout' milliseconds of inactivity. * #param timeout The timeout in milliseconds. Use 0 to show * the controller until hide() is called. */ public void show(int timeout) { if (!mShowing && mAnchor != null) { setProgress(); int [] anchorpos = new int[2]; mAnchor.getLocationOnScreen(anchorpos); WindowManager.LayoutParams p = new WindowManager.LayoutParams(); p.gravity = Gravity.TOP; p.width = mAnchor.getWidth(); p.height = LayoutParams.WRAP_CONTENT; p.x = 0; p.y = anchorpos[1] + mAnchor.getHeight() - p.height; p.format = PixelFormat.TRANSLUCENT; p.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; p.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; p.token = null; p.windowAnimations = 0; // android.R.style.DropDownAnimationDown; mWindowManager.addView(mDecor, p); mShowing = true; } updatePausePlay(); // cause the progress bar to be updated even if mShowing // was already true. This happens, for example, if we're // paused with the progress bar showing the user hits play. mHandler.sendEmptyMessage(SHOW_PROGRESS); Message msg = mHandler.obtainMessage(FADE_OUT); if (timeout != 0) { mHandler.removeMessages(FADE_OUT); mHandler.sendMessageDelayed(msg, timeout); } } public boolean isShowing() { return mShowing; } /** * Remove the controller from the screen. */ public void hide() { if (mAnchor == null) return; if (mShowing) { try { mHandler.removeMessages(SHOW_PROGRESS); mWindowManager.removeView(mDecor); } catch (IllegalArgumentException ex) { Log.w("MediaController", "already removed"); } mShowing = false; } } private Handler mHandler = new Handler() { #Override public void handleMessage(Message msg) { int pos; switch (msg.what) { case FADE_OUT: hide(); break; case SHOW_PROGRESS: pos = setProgress(); if (!mDragging && mShowing && mPlayer.isPlaying()) { msg = obtainMessage(SHOW_PROGRESS); sendMessageDelayed(msg, 1000 - (pos % 1000)); } break; } } }; private String stringForTime(int timeMs) { int totalSeconds = timeMs / 1000; int seconds = totalSeconds % 60; int minutes = (totalSeconds / 60) % 60; int hours = totalSeconds / 3600; mFormatBuilder.setLength(0); if (hours > 0) { return mFormatter.format("%d:%02d:%02d", hours, minutes, seconds).toString(); } else { return mFormatter.format("%02d:%02d", minutes, seconds).toString(); } } private int setProgress() { if (mPlayer == null || mDragging) { return 0; } int position = mPlayer.getCurrentPosition(); int duration = mPlayer.getDuration(); if (mProgress != null) { if (duration > 0) { // use long to avoid overflow long pos = 1000L * position / duration; mProgress.setProgress( (int) pos); } int percent = mPlayer.getBufferPercentage(); mProgress.setSecondaryProgress(percent * 10); } if (mEndTime != null) mEndTime.setText(stringForTime(duration)); if (mCurrentTime != null) mCurrentTime.setText(stringForTime(position)); return position; } #Override public boolean onTouchEvent(MotionEvent event) { show(sDefaultTimeout); return true; } #Override public boolean onTrackballEvent(MotionEvent ev) { show(sDefaultTimeout); return false; } #Override public boolean dispatchKeyEvent(KeyEvent event) { int keyCode = event.getKeyCode(); if (event.getRepeatCount() == 0 && event.isLongPress() && ( keyCode == KeyEvent.KEYCODE_HEADSETHOOK || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE || keyCode == KeyEvent.KEYCODE_SPACE)) { doPauseResume(); show(sDefaultTimeout); return true; } else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP) { if (mPlayer.isPlaying()) { mPlayer.pause(); updatePausePlay(); } return true; } else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) { // don't show the controls for volume adjustment return super.dispatchKeyEvent(event); } else if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU) { hide(); return true; } else { show(sDefaultTimeout); } return super.dispatchKeyEvent(event); } private View.OnClickListener mPauseListener = new View.OnClickListener() { public void onClick(View v) { doPauseResume(); show(sDefaultTimeout); } }; private void updatePausePlay() { if (mRoot == null) return; ImageButton button = (ImageButton) mRoot.findViewById(R.id.pause); if (button == null) return; if (mPlayer.isPlaying()) { button.setImageResource(android.R.drawable.ic_media_pause); } else { button.setImageResource(android.R.drawable.ic_media_play); } } private void doPauseResume() { if (mPlayer.isPlaying()) { mPlayer.pause(); } else { mPlayer.start(); } updatePausePlay(); } private OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() { long duration; public void onStartTrackingTouch(SeekBar bar) { show(3600000); duration = mPlayer.getDuration(); } public void onProgressChanged(SeekBar bar, int progress, boolean fromtouch) { if (fromtouch) { mDragging = true; duration = mPlayer.getDuration(); long newposition = (duration * progress) / 1000L; mPlayer.seekTo( (int) newposition); if (mCurrentTime != null) mCurrentTime.setText(stringForTime( (int) newposition)); } } public void onStopTrackingTouch(SeekBar bar) { mDragging = false; setProgress(); updatePausePlay(); show(sDefaultTimeout); } }; #Override public void setEnabled(boolean enabled) { if (mPauseButton != null) { mPauseButton.setEnabled(enabled); } if (mFfwdButton != null) { mFfwdButton.setEnabled(enabled); } if (mRewButton != null) { mRewButton.setEnabled(enabled); } if (mNextButton != null) { mNextButton.setEnabled(enabled && mNextListener != null); } if (mPrevButton != null) { mPrevButton.setEnabled(enabled && mPrevListener != null); } if (mProgress != null) { mProgress.setEnabled(enabled); } super.setEnabled(enabled); } private View.OnClickListener mRewListener = new View.OnClickListener() { public void onClick(View v) { int pos = mPlayer.getCurrentPosition(); pos -= 5000; // milliseconds mPlayer.seekTo(pos); setProgress(); show(sDefaultTimeout); } }; private View.OnClickListener mFfwdListener = new View.OnClickListener() { public void onClick(View v) { int pos = mPlayer.getCurrentPosition(); pos += 15000; // milliseconds mPlayer.seekTo(pos); setProgress(); show(sDefaultTimeout); } }; private void installPrevNextListeners() { if (mNextButton != null) { mNextButton.setOnClickListener(mNextListener); mNextButton.setEnabled(mNextListener != null); } if (mPrevButton != null) { mPrevButton.setOnClickListener(mPrevListener); mPrevButton.setEnabled(mPrevListener != null); } } public void setPrevNextListeners(View.OnClickListener next, View.OnClickListener prev) { mNextListener = next; mPrevListener = prev; mListenersSet = true; if (mRoot != null) { installPrevNextListeners(); if (mNextButton != null && !mFromXml) { mNextButton.setVisibility(View.VISIBLE); } if (mPrevButton != null && !mFromXml) { mPrevButton.setVisibility(View.VISIBLE); } } } public interface MediaPlayerControl { void start(); void pause(); int getDuration(); int getCurrentPosition(); void seekTo(int pos); boolean isPlaying(); int getBufferPercentage(); }; } and I am getting error at "Policy manager" at initfloatwindow method and I have imported import com.android.internal.policy.PolicyManager private void initFloatingWindow() { mWindowManager = (WindowManager)mContext.getSystemService("window"); mWindow = PolicyManager.makeNewWindow(mContext);//I got error here mWindow.setWindowManager(mWindowManager, null, null); mWindow.requestFeature(Window.FEATURE_NO_TITLE); mDecor = mWindow.getDecorView(); mDecor.setOnTouchListener(mTouchListener); mWindow.setContentView(this); mWindow.setBackgroundDrawableResource(android.R.color.transparent); // While the media controller is up, the volume control keys should // affect the media stream type mWindow.setVolumeControlStream(AudioManager.STREAM_MUSIC); setFocusable(true); setFocusableInTouchMode(true); setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); requestFocus(); } Please anyone can help me please.Thanks in advance
PolicyManager is an internal class, not in puplic API so you cannot use it.
How to get the keycode for different mobiles using j2me
I am developing application for Nokia using Netbeans platform. Now I am in idea to make this application to work on any java enabled mobile. So for that I have to get the platform of the devices, how can I get it(specifically for micromax, blackberry) mobiles? Also the left and right softkey code.
I found one answer which is given this link. the KeyCodeAdapter class provided by above link is like below import javax.microedition.lcdui.Canvas; /** * Class redefines codes of mobile phone to our constant values. * Class can give to developers following information: * <ul> * <li/><i>defined platform name</i><br> * In case if device vendor not defined we'll recieve <code>PLATFORM_NOT_DEFINED</code> like platform name. * Same in this case keyCodes will be setted like for Nokia and SE. It's done for work on emulators, * because on some of them it's impossible to define platform name. * <li/><i>adopted to our constants key code value</i> * <li/><i>for test returns defined real code of left softkey</i> * </ul> */ public final class KeyCodeAdapter { /** * instance on this class */ private static final KeyCodeAdapter instance = new KeyCodeAdapter(); /** * canvas used for definig codes */ private final Canvas adaptorCanvas; /** * constants for platforms names */ public static final String PLATFORM_MOTOROLA = "motorola"; public static final String PLATFORM_NOKIA = "nokia"; public static final String PLATFORM_SONY_ERICSSON = "SE"; public static final String PLATFORM_SIEMENS = "siemens"; public static final String PLATFORM_SAMSUNG = "samsung"; public static final String PLATFORM_LG = "LG"; public static final String PLATFORM_NOT_DEFINED = "NA"; /** * constants for keycodes */ public static final int SOFT_KEY_LEFT = -201; public static final int SOFT_KEY_RIGHT = -202; public static final int SOFT_KEY_MIDDLE_INTERNET = -203; /** * this key is present on Nokia s60 */ public static final int PENCIL_KEY = -207; public static final int DELETE_KEY = -204; public static final int BACK_KEY = -205; // public static final int SEND_KEY = -206; //constant will be used in future for green key start dialling public static final int KEY_1 = 201; public static final int KEY_2 = 202; public static final int KEY_3 = 203; public static final int KEY_4 = 204; public static final int KEY_5 = 205; public static final int KEY_6 = 206; public static final int KEY_7 = 207; public static final int KEY_8 = 208; public static final int KEY_9 = 209; public static final int KEY_0 = 200; public static final int KEY__POUND = 211; public static final int KEY__STAR = 212; /** * KEYS on JOISTICK */ public static final int UP_KEY = 221; public static final int DOWN_KEY = 222; public static final int LEFT_KEY = 223; public static final int RIGHT_KEY = 224; public static final int CENTER_KEY = 225; public static final int NOT_DEFINED_KEY = 254; /** * current platform name */ private final String PLATFORM_NAME; /** * current platform codeofSoftkey */ private final int SOFTKEY_LEFT; private final int SOFTKEY_RIGHT; private final int SOFTKEY_MIDDLE_INTERNET; private final int SOFTKEY_DELETE; private final int SOFTKEY_BACK; /** * standart values for softkeys of different platforms * used only in predefining */ private static final int SOFT_KEY_LEFT_SE = -6; private static final int SOFT_KEY_RIGHT_SE = -7; private static final int DELETE_KEY_SE = -8; private static final int INTERNET_KEY_SE = -10; private static final int BACK_KEY_SE = -11; private static final int SOFT_KEY_LEFT_SAMSUNG = -6; private static final int SOFT_KEY_RIGHT_SAMSUNG = -7; private static final int DELETE_KEY_SAMSUNG = -8; private static final int SOFT_KEY_LEFT_SIEMENS = -1; private static final int SOFT_KEY_RIGHT_SIEMENS = -4; private static final int SOFT_KEY_LEFT_NOKIA = -6; private static final int SOFT_KEY_RIGHT_NOKIA = -7; private static final int DELETE_KEY_NOKIA = -8; private static final int PENCIL_KEY_NOKIA = -50; private static final int SOFT_KEY_LEFT_MOTOROLA = -21; private static final int SOFT_KEY_RIGHT_MOTOROLA = -22; private static final int SOFT_KEY_LEFT_MOTOROLA2 = -20; private static final int SOFT_KEY_LEFT_MOTOROLA1 = 21; private static final int SOFT_KEY_RIGHT_MOTOROLA1 = 22; private static final int SOFT_KEY_MIDLE_MOTOROLA = -23; private static final int SOFT_KEY_MIDLE_NOKIA = -5; private static final String SOFT_WORD = "SOFT"; /** * constructor. * here is predefining of spesial keys and platform made */ private KeyCodeAdapter() { adaptorCanvas = MainCanvas.getInstance(); PLATFORM_NAME = getPlatform(); SOFTKEY_LEFT = getLeftSoftkeyCode(); SOFTKEY_RIGHT = getRightSoftkeyCode(); SOFTKEY_MIDDLE_INTERNET = getMidleORInternetSoftkeyCode(); SOFTKEY_DELETE = getDeleteKeyCode(); SOFTKEY_BACK = getBackKeyCode(); } /** * return platform keycode of left softkey * if it's defined * default value -6 * * #return SOFTKEY_LEFT */ public int getPlatformSoftkeyLeftCode() { return SOFTKEY_LEFT; } /** * Returns mobile phone platform * * #return name mobile phone platform */ private String getPlatform() { // detecting NOKIA or SonyEricsson try { final String currentPlatform = System.getProperty("microedition.platform"); if (currentPlatform.indexOf("Nokia") != -1) { return PLATFORM_NOKIA; } else if (currentPlatform.indexOf("SonyEricsson") != -1) { return PLATFORM_SONY_ERICSSON; } } catch (Throwable ex) { } // detecting SAMSUNG try { Class.forName("com.samsung.util.Vibration"); return PLATFORM_SAMSUNG; } catch (Throwable ex) { } // detecting MOTOROLA try { Class.forName("com.motorola.multimedia.Vibrator"); return PLATFORM_MOTOROLA; } catch (Throwable ex) { try { Class.forName("com.motorola.graphics.j3d.Effect3D"); return PLATFORM_MOTOROLA; } catch (Throwable ex2) { try { Class.forName("com.motorola.multimedia.Lighting"); return PLATFORM_MOTOROLA; } catch (Throwable ex3) { try { Class.forName("com.motorola.multimedia.FunLight"); return PLATFORM_MOTOROLA; } catch (Throwable ex4) { } } } } try { if (adaptorCanvas.getKeyName(SOFT_KEY_LEFT_MOTOROLA).toUpperCase().indexOf(SOFT_WORD) > -1) { return PLATFORM_MOTOROLA; } } catch (Throwable e) { try { if (adaptorCanvas.getKeyName(SOFT_KEY_LEFT_MOTOROLA1).toUpperCase().indexOf(SOFT_WORD) > -1) { return PLATFORM_MOTOROLA; } } catch (Throwable e1) { try { if (adaptorCanvas.getKeyName(SOFT_KEY_LEFT_MOTOROLA2).toUpperCase().indexOf(SOFT_WORD) > -1) { return PLATFORM_MOTOROLA; } } catch (Throwable e2) { } } } // detecting SIEMENS try { Class.forName("com.siemens.mp.io.File"); return PLATFORM_SIEMENS; } catch (Throwable ex) { } // detecting LG try { Class.forName("mmpp.media.MediaPlayer"); return PLATFORM_LG; } catch (Throwable ex) { try { Class.forName("mmpp.phone.Phone"); return PLATFORM_LG; } catch (Throwable ex1) { try { Class.forName("mmpp.lang.MathFP"); return PLATFORM_LG; } catch (Throwable ex2) { try { Class.forName("mmpp.media.BackLight"); return PLATFORM_LG; } catch (Throwable ex3) { } } } } return PLATFORM_NOT_DEFINED; } /** * define real left soft key code by platform * * #return code */ private int getLeftSoftkeyCode() { int keyCode = 0; try { if (PLATFORM_NAME.equals(PLATFORM_MOTOROLA)) { String softkeyLeftMoto = ""; try { softkeyLeftMoto = adaptorCanvas.getKeyName(SOFT_KEY_LEFT_MOTOROLA).toUpperCase(); } catch (IllegalArgumentException ilae) { // ilae.printStackTrace(); } String softkeyLeftMoto1 = ""; try { softkeyLeftMoto1 = adaptorCanvas.getKeyName(SOFT_KEY_LEFT_MOTOROLA1).toUpperCase(); } catch (IllegalArgumentException ilae) { // ilae.printStackTrace(); } String softkeyLeftMoto2 = ""; try { softkeyLeftMoto2 = adaptorCanvas.getKeyName(SOFT_KEY_LEFT_MOTOROLA2).toUpperCase(); } catch (IllegalArgumentException ilae) { // ilae.printStackTrace(); } if (softkeyLeftMoto.indexOf(SOFT_WORD) >= 0 && softkeyLeftMoto.indexOf("1") >= 0) { return SOFT_KEY_LEFT_MOTOROLA; } else if (softkeyLeftMoto1.indexOf(SOFT_WORD) >= 0 && softkeyLeftMoto1.indexOf("1") >= 0) { return SOFT_KEY_LEFT_MOTOROLA1; } else if (softkeyLeftMoto2.indexOf(SOFT_WORD) >= 0 && softkeyLeftMoto2.indexOf("1") >= 0) { return SOFT_KEY_LEFT_MOTOROLA2; } else if (softkeyLeftMoto.indexOf(SOFT_WORD) >= 0 && softkeyLeftMoto.indexOf("LEFT") >= 0) { return SOFT_KEY_LEFT_MOTOROLA; } else if (softkeyLeftMoto1.indexOf(SOFT_WORD) >= 0 && softkeyLeftMoto1.indexOf("LEFT") >= 0) { return SOFT_KEY_LEFT_MOTOROLA1; } else if (softkeyLeftMoto2.indexOf(SOFT_WORD) >= 0 && softkeyLeftMoto2.indexOf("LEFT") >= 0) { return SOFT_KEY_LEFT_MOTOROLA2; } } else if (PLATFORM_NAME.equals(PLATFORM_NOKIA)) { return SOFT_KEY_LEFT_NOKIA; } else if (PLATFORM_NAME.equals(PLATFORM_SAMSUNG)) { // String leftkeySamsungName = adaptorCanvas.getKeyName(SOFT_KEY_LEFT_SAMSUNG).toUpperCase(); // if (leftkeySamsungName.indexOf(SOFT_WORD) >= 0) { // if (leftkeySamsungName.indexOf("1") >= 0) { return SOFT_KEY_LEFT_SAMSUNG; // } else if (leftkeySamsungName.indexOf("LEFT") >= 0) { // return SOFT_KEY_LEFT_SAMSUNG; // } // } } else if (PLATFORM_NAME.equals(PLATFORM_SIEMENS)) { String leftKeySiemensName = adaptorCanvas.getKeyName(SOFT_KEY_LEFT_SIEMENS).toUpperCase(); if (leftKeySiemensName.indexOf(SOFT_WORD) >= 0) { if (leftKeySiemensName.indexOf("1") >= 0) { return SOFT_KEY_LEFT_SIEMENS; } else if (leftKeySiemensName.indexOf("LEFT") >= 0) { return SOFT_KEY_LEFT_SIEMENS; } } } else if (PLATFORM_NAME.equals(PLATFORM_SONY_ERICSSON)) { return SOFT_KEY_LEFT_SE; } else if (PLATFORM_NAME.equals(PLATFORM_NOT_DEFINED)) { // for (int i = -125; i <= 125; i++) { if (i == 0) { i++; } // System.out.println(getKeyName(i).toUpperCase()); final String s = adaptorCanvas.getKeyName(i).toUpperCase(); if (s.indexOf(SOFT_WORD) >= 0) { if (s.indexOf("1") >= 0) { keyCode = i; break; } if (s.indexOf("LEFT") >= 0) { keyCode = i; break; } } } } if (keyCode == 0) { //#if emulator return SOFT_KEY_LEFT_NOKIA; //#endif } } catch (Throwable iaEx) { //#if emulator return SOFT_KEY_LEFT_NOKIA; //#endif } return keyCode; } /** * define real right soft key code for current platform * * #return code */ private int getRightSoftkeyCode() { int keyCode = 0; try { if (PLATFORM_NAME.equals(PLATFORM_MOTOROLA)) { String rightSoftMoto1 = ""; try { rightSoftMoto1 = adaptorCanvas.getKeyName(SOFT_KEY_LEFT_MOTOROLA1).toUpperCase(); } catch (IllegalArgumentException ilae) { // ilae.printStackTrace(); } String rightSoftMoto = ""; try { rightSoftMoto = adaptorCanvas.getKeyName(SOFT_KEY_RIGHT_MOTOROLA).toUpperCase(); } catch (IllegalArgumentException ilae) { // ilae.printStackTrace(); } String rightSoftMoto2 = ""; try { rightSoftMoto2 = adaptorCanvas.getKeyName(SOFT_KEY_RIGHT_MOTOROLA1).toUpperCase(); } catch (IllegalArgumentException ilae) { // ilae.printStackTrace(); } if (rightSoftMoto.indexOf(SOFT_WORD) >= 0 && rightSoftMoto.indexOf("2") >= 0) { return SOFT_KEY_RIGHT_MOTOROLA; } else if (rightSoftMoto1.indexOf(SOFT_WORD) >= 0 && rightSoftMoto1.indexOf("2") >= 0) { return SOFT_KEY_RIGHT_MOTOROLA; } else if (rightSoftMoto2.indexOf(SOFT_WORD) >= 0 && rightSoftMoto2.indexOf("2") >= 0) { return SOFT_KEY_RIGHT_MOTOROLA1; } else if (rightSoftMoto.indexOf(SOFT_WORD) >= 0 && rightSoftMoto.indexOf("RIGHT") >= 0) { return SOFT_KEY_LEFT_MOTOROLA; } else if (rightSoftMoto1.indexOf(SOFT_WORD) >= 0 && rightSoftMoto1.indexOf("RIGHT") >= 0) { return SOFT_KEY_RIGHT_MOTOROLA1; } else if (rightSoftMoto2.indexOf(SOFT_WORD) >= 0 && rightSoftMoto2.indexOf("RIGHT") >= 0) { return SOFT_KEY_RIGHT_MOTOROLA; } } else if (PLATFORM_NAME.equals(PLATFORM_NOKIA)) { return SOFT_KEY_RIGHT_NOKIA; } else if (PLATFORM_NAME.equals(PLATFORM_SAMSUNG)) { // String rightSoftSamsung = adaptorCanvas.getKeyName(SOFT_KEY_RIGHT_SAMSUNG).toUpperCase(); // if (rightSoftSamsung.indexOf(SOFT_WORD) >= 0) { // if (rightSoftSamsung.indexOf("2") >= 0) { return SOFT_KEY_RIGHT_SAMSUNG; // } else if (rightSoftSamsung.indexOf("RIGHT") >= 0) { // return SOFT_KEY_RIGHT_SAMSUNG; // } // } } else if (PLATFORM_NAME.equals(PLATFORM_SIEMENS)) { String rightSoftSiemens = adaptorCanvas.getKeyName(SOFT_KEY_RIGHT_SIEMENS).toUpperCase(); if (rightSoftSiemens.indexOf(SOFT_WORD) >= 0) { if (rightSoftSiemens.indexOf("4") >= 0) { return SOFT_KEY_RIGHT_SIEMENS; } else if (rightSoftSiemens.indexOf("RIGHT") >= 0) { return SOFT_KEY_RIGHT_SIEMENS; } } } else if (PLATFORM_NAME.equals(PLATFORM_SONY_ERICSSON)) { return SOFT_KEY_RIGHT_SE; } else if (PLATFORM_NAME.equals(PLATFORM_NOT_DEFINED)) { for (int i = -125; i <= 125; i++) { if (i == 0) { i++; } String keyName = adaptorCanvas.getKeyName(i).toUpperCase(); if (keyName.indexOf(SOFT_WORD) >= 0) { if (keyName.indexOf("2") >= 0) { keyCode = i; break; } else if (keyName.indexOf("4") >= 0) { keyCode = i; break; } else if (keyName.indexOf("RIGHT") >= 0) { keyCode = i; break; } } } } } catch (Throwable iaEx) { //#if emulator return SOFT_KEY_RIGHT_NOKIA; //#endif } return keyCode; } /** * define real middle soft key code for current platform * * #return code */ private int getMidleORInternetSoftkeyCode() { try { if (PLATFORM_NAME.equals(PLATFORM_MOTOROLA)) { if (adaptorCanvas.getKeyName(SOFT_KEY_MIDLE_MOTOROLA).toUpperCase().indexOf("SOFT") >= 0) { return SOFT_KEY_MIDLE_MOTOROLA; } } else if (PLATFORM_NAME.equals(PLATFORM_NOKIA)) { if (adaptorCanvas.getKeyName(SOFT_KEY_MIDLE_NOKIA).toUpperCase().indexOf("SOFT") >= 0) { return SOFT_KEY_MIDLE_NOKIA; } } else if (PLATFORM_NAME.equals(PLATFORM_SAMSUNG)) { } else if (PLATFORM_NAME.equals(PLATFORM_SIEMENS)) { } else if (PLATFORM_NAME.equals(PLATFORM_SONY_ERICSSON)) { return INTERNET_KEY_SE; } } catch (Throwable e) { } return 0; } /** * define real key's C or DELETE code for current platform * * #return code */ private int getDeleteKeyCode() { try { if (PLATFORM_NAME.equals(PLATFORM_MOTOROLA)) { } else if (PLATFORM_NAME.equals(PLATFORM_NOKIA)) { if (adaptorCanvas.getKeyName(DELETE_KEY_SE).toUpperCase().indexOf("CLEAR") >= 0) { return DELETE_KEY_NOKIA; } else { return DELETE_KEY_NOKIA; } } else if (PLATFORM_NAME.equals(PLATFORM_SAMSUNG)) { if (adaptorCanvas.getKeyName(DELETE_KEY_SAMSUNG).toUpperCase().indexOf("CLEAR") >= 0) { return DELETE_KEY_SAMSUNG; } } else if (PLATFORM_NAME.equals(PLATFORM_SIEMENS)) { } else if (PLATFORM_NAME.equals(PLATFORM_SONY_ERICSSON)) { if (adaptorCanvas.getKeyName(DELETE_KEY_SE).toUpperCase().indexOf("CLEAR") >= 0) { return DELETE_KEY_SE; } else if (adaptorCanvas.getKeyName(DELETE_KEY_SE).toUpperCase().indexOf("C") >= 0) { return DELETE_KEY_SE; } else { return DELETE_KEY_SE; } } } catch (Throwable e) { return DELETE_KEY_SE; } return 0; } /** * define real key's BACK code for current platform * * #return code */ private int getBackKeyCode() { try { if (PLATFORM_NAME.equals(PLATFORM_MOTOROLA)) { } else if (PLATFORM_NAME.equals(PLATFORM_NOKIA)) { } else if (PLATFORM_NAME.equals(PLATFORM_SAMSUNG)) { } else if (PLATFORM_NAME.equals(PLATFORM_SIEMENS)) { } else if (PLATFORM_NAME.equals(PLATFORM_SONY_ERICSSON)) { return BACK_KEY_SE; } } catch (Throwable e) { } return 0; } /** * name of curent platform * * #return PLATFORM_NAME */ public String getPlatformName() { return PLATFORM_NAME; } /** * Used to adopt key kode to predefined constances, which are platform independent. * <p/> * You can use this method in any kind of canvas, but better at first time to call * <code>getInstance()</code> method at the beginning of midlet work, because initialisation takes time. * <p/> * Best variant for usage is calling <code>adoptKeyCode()</code> to use <code>keyPressed()</code> method in Canvas: * <pre> * protected void keyPressed(int keyCode) { * keyCode = KeyCodeAdapter.getInstance().adoptKeyCode(keyCode); * } * </pre> * and then you can use it: * <pre> * switch (keyCode) { * case KeyCodeAdapter.UP_KEY: * break; * case KeyCodeAdapter.SOFT_KEY_LEFT: * break; * }</pre> * or send this code to any other clesses. * * #param keycode This code is sent by platform to canvas and redirected here * #return this keycode is equal to one of our constants declared in this class */ public int adoptKeyCode(int keycode) { switch (keycode) { case Canvas.KEY_NUM0: return KEY_0; case Canvas.KEY_NUM1: return KEY_1; case Canvas.KEY_NUM2: return KEY_2; case Canvas.KEY_NUM3: return KEY_3; case Canvas.KEY_NUM4: return KEY_4; case Canvas.KEY_NUM5: return KEY_5; case Canvas.KEY_NUM6: return KEY_6; case Canvas.KEY_NUM7: return KEY_7; case Canvas.KEY_NUM8: return KEY_8; case Canvas.KEY_NUM9: return KEY_9; case Canvas.KEY_STAR: return KEY__STAR; case Canvas.KEY_POUND: return KEY__POUND; default: if (keycode == SOFTKEY_LEFT) { return SOFT_KEY_LEFT; } else if (keycode == SOFTKEY_RIGHT) { return SOFT_KEY_RIGHT; } else if (keycode == SOFTKEY_DELETE) { return DELETE_KEY; } else if (keycode == SOFTKEY_BACK) { return BACK_KEY; } else if (keycode == SOFTKEY_MIDDLE_INTERNET) { return SOFT_KEY_MIDDLE_INTERNET; } else if (keycode == PENCIL_KEY_NOKIA) { return PENCIL_KEY; } else { try { final int gameAction; gameAction = adaptorCanvas.getGameAction(keycode); if (gameAction == Canvas.UP) { return UP_KEY; } else if (gameAction == Canvas.DOWN) { return DOWN_KEY; } else if (gameAction == Canvas.LEFT) { return LEFT_KEY; } else if (gameAction == Canvas.RIGHT) { return RIGHT_KEY; } else if (gameAction == Canvas.FIRE) { return CENTER_KEY; } } catch (IllegalArgumentException e) { // e.printStackTrace(); } } break; } //#if debug //# return keycode; //#else return NOT_DEFINED_KEY; //#endif } /** * return instance of class * * #return instance */ public static KeyCodeAdapter getInstance() { return instance; } } You have to use like this in your code:::- protected void keyPressed(int keyCode) { int internalKeyCode = KeyCodeAdapter.getInstance().adoptKeyCode(keyCode); switch (keyCode) { case KeyCodeAdapter.SOFT_KEY_LEFT: // some processing break; case KeyCodeAdapter.BACK_KEY: // some processing break; default: } ... } Hope this will help you. Thanks
SWT StyledText - How To Indent/Un-Indent Selected Text With Tab Or Shift+Tab Keys
Using the Eclipse SWT StyledText widget, how can you indent/un-indent a selected block of text with the tab or shift+tab keys?
This seems to do the trick... protected Control createContents(Composite parent){ ...... //add the listeners... text_code_impl.addVerifyKeyListener(new VerifyKeyListener() { public void verifyKey(VerifyEvent e) { if (e.keyCode == SWT.TAB) { if ((e.stateMask & SWT.SHIFT) != 0){ e.doit = text_code_impl_shift_tab_pressed(); } else { e.doit = text_code_impl_tab_pressed(); } } } }); text_code_impl.addTraverseListener(new TraverseListener() { public void keyTraversed(TraverseEvent e) { if (e.detail == SWT.TRAVERSE_TAB_PREVIOUS) { e.doit = false; //allows verifyKey listener to fire } } }); } boolean text_code_impl_tab_pressed() { if (text_code_impl.getSelectionText().equals("")){ return true; } Point range = text_code_impl.getSelectionRange(); int start = range.x; int length = text_code_impl.getSelectionCount(); String txt = text_code_impl.getText(); while (start > 0 && txt.charAt(start-1) != '\n') { start--; length++; } int replace_length = length; text_code_impl.setSelectionRange(start, length); text_code_impl.showSelection(); String sel_text = text_code_impl.getSelectionText(); String[] lines = sel_text.split("\n"); String new_text = ""; for (int x=0; x < lines.length; x++){ if (x > 0){ new_text += '\n'; } new_text += '\t'; length++; new_text += lines[x]; } text_code_impl.replaceTextRange(start, replace_length, new_text); text_code_impl.setSelectionRange(start, length); text_code_impl.showSelection(); return false; } boolean text_code_impl_shift_tab_pressed() { if (text_code_impl.getSelectionText().equals("")){ return true; } Point range = text_code_impl.getSelectionRange(); int start = range.x; int length = text_code_impl.getSelectionCount(); String txt = text_code_impl.getText(); while (start > 0 && txt.charAt(start-1) != '\n') { --start; ++length; } int replace_length = length; text_code_impl.setSelectionRange(start, length); text_code_impl.showSelection(); String sel_text = text_code_impl.getSelectionText(); String[] lines = sel_text.split("\n"); String new_text = ""; for (int x=0; x < lines.length; x++){ if (x > 0){ new_text += '\n'; } if (lines[x].charAt(0) == '\t'){ new_text += lines[x].substring(1); length--; } else if (lines[x].startsWith(" ")){ new_text += lines[x].substring(1); length--; } else { new_text += lines[x]; } } text_code_impl.replaceTextRange(start, replace_length, new_text); text_code_impl.setSelectionRange(start, length); text_code_impl.showSelection(); return false; }