Czy da się jakoś zrealizować obsługę drag & drop elementów w PopupMenu ? Chodzi mi o taki myk, jaki jest np. w menu Start, że łapiemy za jakiś element i przenosimy go w inne miejsce.
Pozdrawiam
Zacznj od obslużenia WM_MENUGETOBJECT. Pamiętam że w 2005 roku zajmowałem się tym i miałem problem z niewymazującym się systemowym insertmarkiem, ale drag-drop dzialał jak powinien.
Bo nie napisałem, że programuję w C++ Builder wykorzystując VCL. Czy muszę przechwycić ten komunikat w jakiś sposób, np. poprzez takie cuś ?
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_MENUGETOBJECT, TMessage, TestowaFunkcja)
END_MESSAGE_MAP(TForm)
Powinieneś wiedzieć jak tak to zrobić w builderze, skoro go używasz. Może ktoś inny odpowie jak odbierać w nim komunikaty.
-
Zacznij od OleInitialize(0), dodaj bit stylu MNS_DRAGDROP do swojego menu (SetMenuInfo) i zaimplementuj IDropSource, IDropTarget oraz IDataObject.
-
Przechwyć WM_MENUDRAG (początek drag-drop z Twojego menu) i zapisz wParam jako pozycja itemu, lParam jako HMENU - oba parametry to źródło drag-dropu. Użyj teraz DoDragDrop() podstawiając własne implementacje IDataObject and IDropSource. Zwróć MND_CONTINUE.
-
Przechwyć WM_MENUGETOBJECT, tutaj lParam wskazuje na strukturę MENUGETOBJECTINFO gdzie znajdziesz docelowe HMENU i pozycję, oraz pvObj które powinieneś ustawić na na (swój) obiekt opisany identyfikatorem riid - najważniejszy tu będzie IID_IDropTarget. Zwróć MNGO_NOERROR, lub w razie błędu MNGO_NOINTERFACE (gdy riid != IID_IDropTarget)
W implementacji CDropSource::QueryContinueDrag sprawdź czy (!(grfKeyState & VK_LBUTTON)) i jeśli tak, to zwróć DRAGDROP_S_DROP.
Przykładowy (kompletny) kod znajdziesz tu http://pastebin.4programmers.net/3480
Gdyby kod dotyczył zwykłego okna nie dialogowego, to zamiast SetWindowLong - zmienną hr zwracaj bezpośrednio.
Ok, dzięki sapero za odpowiedź. Będę kombinował ...
Zarejestruj się i dołącz do największej społeczności programistów w Polsce.
Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.