platform_drag_and_drop_data.hpp
Go to the documentation of this file.
00001 /* 00002 Copyright 2007 Adobe Systems Incorporated 00003 Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt 00004 or a copy at http://stlab.adobe.com/licenses.html) 00005 */ 00006 00007 /**************************************************************************************************/ 00008 00009 #ifndef ADOBE_DRAG_AND_DROP_PLATFORM_DATA_HPP 00010 #define ADOBE_DRAG_AND_DROP_PLATFORM_DATA_HPP 00011 00012 /**************************************************************************************************/ 00013 00014 #define WINDOWS_LEAN_AND_MEAN 1 00015 00016 #include <windows.h> 00017 #include <commctrl.h> 00018 00019 #include <adobe/config.hpp> 00020 00021 #include <boost/cstdint.hpp> 00022 #include <boost/function.hpp> 00023 #include <boost/noncopyable.hpp> 00024 00025 #include <adobe/algorithm/find.hpp> 00026 #include <adobe/future/windows_cast.hpp> 00027 #include <adobe/future/drag_and_drop_fwd.hpp> 00028 00029 #include <vector> 00030 00031 /**************************************************************************************************/ 00032 00033 namespace adobe { 00034 00035 /**************************************************************************************************/ 00036 00037 namespace implementation { 00038 00039 /**************************************************************************************************/ 00040 00041 template <typename SourceType, typename TargetType> 00042 LRESULT CALLBACK drag_and_drop_subclass(HWND widget, UINT message, WPARAM wParam, 00043 LPARAM lParam, UINT_PTR ptr, DWORD_PTR ref); 00044 00045 /**************************************************************************************************/ 00046 00047 } // namespace implementation 00048 00049 /**************************************************************************************************/ 00050 00051 template <typename SourceType, typename TargetType> 00052 class drag_and_drop_handler_platform_data : boost::noncopyable 00053 { 00054 public: 00055 typedef SourceType source_type; 00056 typedef TargetType target_type; 00057 typedef boost::function<void (const target_type&)> client_callback_proc_t; 00058 00059 drag_and_drop_handler_platform_data() : 00060 chosen_flavor_m(flavor_invalid), 00061 widget_m(0) 00062 { } 00063 00064 template <typename InputIterator> 00065 drag_and_drop_handler_platform_data(InputIterator first, InputIterator last) : 00066 flavor_set_m(first, last), 00067 chosen_flavor_m(flavor_invalid), 00068 widget_m(0) 00069 { } 00070 00071 void init() 00072 { } 00073 00074 template <typename Client> 00075 void attach(const Client& control, const client_callback_proc_t& proc) 00076 { 00077 set_callback(proc); 00078 00079 install(control); 00080 } 00081 00082 void detach() 00083 { 00084 uninstall(); 00085 } 00086 00087 void insert_flavor(boost::uint32_t flavor) 00088 { 00089 if (adobe::find(flavor_set_m, flavor) == flavor_set_m.end()) 00090 flavor_set_m.push_back(flavor); 00091 } 00092 00093 void erase_flavor(boost::uint32_t flavor) 00094 { flavor_set_m.erase(adobe::find(flavor_set_m, flavor)); } 00095 00096 void set_callback(const client_callback_proc_t& proc) 00097 { callback_m = proc; } 00098 00099 void set_accepts_files(bool does_accept) 00100 { 00101 if (widget_m) 00102 ::DragAcceptFiles(widget_m, does_accept); 00103 } 00104 00105 private: 00106 friend LRESULT CALLBACK implementation::drag_and_drop_subclass<source_type, target_type>(HWND widget, UINT message, WPARAM wParam, 00107 LPARAM lParam, UINT_PTR ptr, DWORD_PTR ref); 00108 00109 bool install(HWND widget) 00110 { 00111 assert (widget_m == 0); 00112 00113 widget_m = widget; 00114 00115 BOOL success(::SetWindowSubclass(widget_m, implementation::drag_and_drop_subclass<source_type, target_type>, reinterpret_cast<UINT_PTR>(this), 0)); 00116 00117 assert(success != 0); 00118 00119 return success != 0; 00120 } 00121 00122 void uninstall() 00123 { 00124 assert (widget_m != 0); 00125 00126 set_accepts_files(false); 00127 00128 ::RemoveWindowSubclass(widget_m, implementation::drag_and_drop_subclass<source_type, target_type>, reinterpret_cast<UINT_PTR>(this)); 00129 00130 widget_m = 0; 00131 } 00132 00133 client_callback_proc_t callback_m; 00134 std::vector<boost::uint32_t> flavor_set_m; 00135 boost::uint32_t chosen_flavor_m; 00136 HWND widget_m; 00137 }; 00138 00139 /**************************************************************************************************/ 00140 00141 namespace implementation { 00142 00143 /**************************************************************************************************/ 00144 00145 template <typename SourceType, typename TargetType> 00146 LRESULT CALLBACK drag_and_drop_subclass(HWND widget, UINT message, WPARAM wParam, 00147 LPARAM lParam, UINT_PTR ptr, DWORD_PTR ref) 00148 { 00149 typedef drag_and_drop_handler_platform_data<SourceType, TargetType> dnd_type; 00150 00151 dnd_type& dnd(*hackery::cast<dnd_type*>(ptr)); 00152 00153 switch (message) 00154 { 00155 case WM_DROPFILES: 00156 { 00157 ::MessageBeep(MB_OK); 00158 00159 return 0; 00160 } 00161 break; 00162 } 00163 00164 return ::DefSubclassProc(dnd.widget_m, message, wParam, lParam); 00165 } 00166 00167 /**************************************************************************************************/ 00168 00169 } // namespace implementation 00170 00171 /**************************************************************************************************/ 00172 00173 } // namespace adobe 00174 00175 /**************************************************************************************************/ 00176 00177 // ADOBE_DRAG_AND_DROP_PLATFORM_DATA_HPP 00178 #endif 00179 00180 /**************************************************************************************************/ |