00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "CMSWindowsClipboard.h"
00020 #include "CMSWindowsClipboardTextConverter.h"
00021 #include "CMSWindowsClipboardUTF16Converter.h"
00022 #include "CMSWindowsClipboardBitmapConverter.h"
00023 #include "CMSWindowsClipboardHTMLConverter.h"
00024 #include "CLog.h"
00025 #include "CArchMiscWindows.h"
00026 #include "CMSWindowsClipboardFacade.h"
00027
00028
00029
00030
00031
00032 UINT CMSWindowsClipboard::s_ownershipFormat = 0;
00033
00034 CMSWindowsClipboard::CMSWindowsClipboard(HWND window) :
00035 m_window(window),
00036 m_time(0),
00037 m_facade(new CMSWindowsClipboardFacade()),
00038 m_deleteFacade(true)
00039 {
00040
00041 m_converters.push_back(new CMSWindowsClipboardUTF16Converter);
00042 if (CArchMiscWindows::isWindows95Family()) {
00043
00044
00045 m_converters.push_back(new CMSWindowsClipboardTextConverter);
00046 }
00047 m_converters.push_back(new CMSWindowsClipboardBitmapConverter);
00048 m_converters.push_back(new CMSWindowsClipboardHTMLConverter);
00049 }
00050
00051 CMSWindowsClipboard::~CMSWindowsClipboard()
00052 {
00053 clearConverters();
00054
00055
00056
00057
00058 if (m_deleteFacade)
00059 delete m_facade;
00060 }
00061
00062 void
00063 CMSWindowsClipboard::setFacade(IMSWindowsClipboardFacade& facade)
00064 {
00065 delete m_facade;
00066 m_facade = &facade;
00067 m_deleteFacade = false;
00068 }
00069
00070 bool
00071 CMSWindowsClipboard::emptyUnowned()
00072 {
00073 LOG((CLOG_DEBUG "empty clipboard"));
00074
00075
00076 if (!EmptyClipboard()) {
00077
00078
00079 LOG((CLOG_DEBUG "failed to grab clipboard"));
00080 return false;
00081 }
00082
00083 return true;
00084 }
00085
00086 bool
00087 CMSWindowsClipboard::empty()
00088 {
00089 if (!emptyUnowned()) {
00090 return false;
00091 }
00092
00093
00094 HGLOBAL data = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, 1);
00095 SetClipboardData(getOwnershipFormat(), data);
00096
00097 return true;
00098 }
00099
00100 void
00101 CMSWindowsClipboard::add(EFormat format, const CString& data)
00102 {
00103 LOG((CLOG_DEBUG "add %d bytes to clipboard format: %d", data.size(), format));
00104
00105
00106 for (ConverterList::const_iterator index = m_converters.begin();
00107 index != m_converters.end(); ++index) {
00108 IMSWindowsClipboardConverter* converter = *index;
00109
00110
00111 if (converter->getFormat() == format) {
00112 HANDLE win32Data = converter->fromIClipboard(data);
00113 if (win32Data != NULL) {
00114 UINT win32Format = converter->getWin32Format();
00115 m_facade->write(win32Data, win32Format);
00116 }
00117 }
00118 }
00119 }
00120
00121 bool
00122 CMSWindowsClipboard::open(Time time) const
00123 {
00124 LOG((CLOG_DEBUG "open clipboard"));
00125
00126 if (!OpenClipboard(m_window)) {
00127
00128
00129
00130
00131 LOG((CLOG_WARN "failed to open clipboard: %d", GetLastError()));
00132 return false;
00133 }
00134
00135 m_time = time;
00136
00137 return true;
00138 }
00139
00140 void
00141 CMSWindowsClipboard::close() const
00142 {
00143 LOG((CLOG_DEBUG "close clipboard"));
00144 CloseClipboard();
00145 }
00146
00147 IClipboard::Time
00148 CMSWindowsClipboard::getTime() const
00149 {
00150 return m_time;
00151 }
00152
00153 bool
00154 CMSWindowsClipboard::has(EFormat format) const
00155 {
00156 for (ConverterList::const_iterator index = m_converters.begin();
00157 index != m_converters.end(); ++index) {
00158 IMSWindowsClipboardConverter* converter = *index;
00159 if (converter->getFormat() == format) {
00160 if (IsClipboardFormatAvailable(converter->getWin32Format())) {
00161 return true;
00162 }
00163 }
00164 }
00165 return false;
00166 }
00167
00168 CString
00169 CMSWindowsClipboard::get(EFormat format) const
00170 {
00171
00172 IMSWindowsClipboardConverter* converter = NULL;
00173 UINT win32Format = EnumClipboardFormats(0);
00174 while (converter == NULL && win32Format != 0) {
00175 for (ConverterList::const_iterator index = m_converters.begin();
00176 index != m_converters.end(); ++index) {
00177 converter = *index;
00178 if (converter->getWin32Format() == win32Format &&
00179 converter->getFormat() == format) {
00180 break;
00181 }
00182 converter = NULL;
00183 }
00184 win32Format = EnumClipboardFormats(win32Format);
00185 }
00186
00187
00188 if (converter == NULL) {
00189 return CString();
00190 }
00191
00192
00193 HANDLE win32Data = GetClipboardData(converter->getWin32Format());
00194 if (win32Data == NULL) {
00195
00196
00197
00198 return CString();
00199 }
00200
00201
00202 return converter->toIClipboard(win32Data);
00203 }
00204
00205 void
00206 CMSWindowsClipboard::clearConverters()
00207 {
00208 for (ConverterList::iterator index = m_converters.begin();
00209 index != m_converters.end(); ++index) {
00210 delete *index;
00211 }
00212 m_converters.clear();
00213 }
00214
00215 bool
00216 CMSWindowsClipboard::isOwnedBySynergy()
00217 {
00218
00219 if (s_ownershipFormat == 0) {
00220 s_ownershipFormat = RegisterClipboardFormat(TEXT("SynergyOwnership"));
00221 }
00222 return (IsClipboardFormatAvailable(getOwnershipFormat()) != 0);
00223 }
00224
00225 UINT
00226 CMSWindowsClipboard::getOwnershipFormat()
00227 {
00228
00229 if (s_ownershipFormat == 0) {
00230 s_ownershipFormat = RegisterClipboardFormat(TEXT("SynergyOwnership"));
00231 }
00232
00233
00234 return s_ownershipFormat;
00235 }