OSDN Git Service

Change the platform toolset to v140
[xkeymacs/xkeymacs.git] / xkeymacsdll / ClipboardFormatSnap.cpp
1 // ClipboardFormatSnap.cpp: CClipboardFormatSnap \83N\83\89\83X\82Ì\83C\83\93\83v\83\8a\83\81\83\93\83e\81[\83V\83\87\83\93\r
2 //\r
3 //////////////////////////////////////////////////////////////////////\r
4 \r
5 #include "ClipboardFormatSnap.h"\r
6 #include "Utils.h"\r
7 \r
8 #ifdef _DEBUG\r
9 #undef THIS_FILE\r
10 static char THIS_FILE[]=__FILE__;\r
11 #define new DEBUG_NEW\r
12 #endif\r
13 \r
14 //////////////////////////////////////////////////////////////////////\r
15 // \8d\\92z/\8fÁ\96Å\r
16 //////////////////////////////////////////////////////////////////////\r
17 \r
18 CClipboardFormatSnap::CClipboardFormatSnap() :\r
19 m_nFormat( 0 ), m_oData()\r
20 {\r
21 }\r
22 \r
23 CClipboardFormatSnap::~CClipboardFormatSnap()\r
24 {\r
25 }\r
26 \r
27 //////////////////////////////////////////////////////////////////////\r
28 // \83R\83s\81[\r
29 //////////////////////////////////////////////////////////////////////\r
30 \r
31 CClipboardFormatSnap::CClipboardFormatSnap( const CClipboardFormatSnap& rhs ) :\r
32 m_nFormat( 0 ), m_oData()\r
33 {\r
34         m_nFormat = rhs.m_nFormat;\r
35 \r
36         int nLen = rhs.m_oData.GetSize();\r
37         m_oData.RemoveAll();\r
38         m_oData.SetSize( nLen );\r
39 \r
40         for( int i = 0; i < nLen; ++i )\r
41         {\r
42                 m_oData[ i ] = rhs.m_oData[ i ];\r
43         }\r
44 }\r
45 \r
46 const BOOL CClipboardFormatSnap::operator==( const CClipboardFormatSnap& rhs )\r
47 {\r
48         if( m_nFormat != rhs.m_nFormat ) return FALSE;\r
49 \r
50         if( m_oData.GetSize() != rhs.m_oData.GetSize() ) return FALSE;\r
51 \r
52         for( int i = 0; i < m_oData.GetSize(); ++i )\r
53         {\r
54                 if( m_oData[ i ] != rhs.m_oData[ i ] ) return FALSE;\r
55         }\r
56 \r
57         return TRUE;\r
58 }\r
59 \r
60 const BOOL CClipboardFormatSnap::operator!=( const CClipboardFormatSnap& rhs )\r
61 {\r
62         return !( *this == rhs );\r
63 }\r
64 \r
65 const CClipboardFormatSnap& CClipboardFormatSnap::operator=( const CClipboardFormatSnap& rhs )\r
66 {\r
67         m_nFormat = rhs.m_nFormat;\r
68 \r
69         int nLen = rhs.m_oData.GetSize();\r
70         m_oData.RemoveAll();\r
71         m_oData.SetSize( nLen );\r
72 \r
73         for( int i = 0; i < nLen; ++i )\r
74         {\r
75                 m_oData[ i ] = rhs.m_oData[ i ];\r
76         }\r
77 \r
78         return *this;\r
79 }\r
80 \r
81 void CClipboardFormatSnap::MergeText( const CClipboardFormatSnap &rhs, const int nSizeOfNullTerminator )\r
82 {\r
83         const int nOriginalTextLength = GetTextLength( nSizeOfNullTerminator );\r
84         if( 0 < nOriginalTextLength )\r
85         {\r
86                 m_oData.SetSize( nOriginalTextLength + rhs.m_oData.GetSize() );\r
87                 for( int i = 0; i < rhs.m_oData.GetSize(); ++i )\r
88                 {\r
89                         m_oData[ nOriginalTextLength + i ] = rhs.m_oData[ i ];\r
90                 }\r
91         }\r
92         else\r
93         {\r
94                 *this = rhs;\r
95         }\r
96 }\r
97 \r
98 void CClipboardFormatSnap::MergeRTF( const CClipboardFormatSnap& rhs )\r
99 {\r
100         const int nOriginalHead = GetRTFBodyHead();\r
101         const int nOriginalLength = GetRTFBodyLength();\r
102         const int nRHSHead = rhs.GetRTFBodyHead();\r
103         const int nRHSLength = rhs.GetRTFBodyLength();\r
104 \r
105         if( nRHSLength )\r
106         {\r
107                 m_oData.SetSize( m_oData.GetSize() + nRHSLength );\r
108                 for( int i = m_oData.GetSize() - 1; nOriginalHead + nOriginalLength <= i ; --i )\r
109                 {\r
110                         m_oData[ i ] = m_oData[ i - nRHSLength ];\r
111                 }\r
112                 for( int j = 0; j < nRHSLength; ++j )\r
113                 {\r
114                         m_oData[ nOriginalHead + nOriginalLength + j ] = rhs.m_oData[ nRHSHead + j ];\r
115                 }\r
116         }\r
117 }\r
118 \r
119 const CClipboardFormatSnap& CClipboardFormatSnap::operator+( const CClipboardFormatSnap& rhs )\r
120 {\r
121         if( !rhs.m_oData.GetSize() ) return *this;\r
122 \r
123         ASSERT( m_nFormat == rhs.m_nFormat );\r
124         m_nFormat = rhs.m_nFormat;\r
125 \r
126         switch( m_nFormat )\r
127         {\r
128         case CF_TEXT:\r
129         case CF_OEMTEXT:\r
130                 MergeText( rhs, 1 );\r
131                 break;\r
132         case CF_UNICODETEXT:\r
133                 MergeText( rhs, 2 );\r
134                 break;\r
135         case CF_LOCALE:\r
136                 *this = rhs;\r
137                 break;\r
138         case 49310:     // Rich Text Format\r
139                 MergeRTF( rhs );\r
140                 break;\r
141         default:\r
142                 ASSERT( 0 );\r
143                 *this = rhs;\r
144                 break;\r
145         }\r
146 \r
147         return *this;\r
148 }\r
149 \r
150 /*\r
151 const CClipboardFormatSnap& CClipboardFormatSnap::Merge( CClipboardFormatSnap& lhs, CClipboardFormatSnap& rhs )\r
152 {\r
153         ASSERT( m_nFormat == rhs.m_nFormat );\r
154         m_nFormat = lhs.m_nFormat;\r
155         m_oData.RemoveAll();\r
156 \r
157         switch( m_nFormat )\r
158         {\r
159         case CF_TEXT:\r
160         case CF_OEMTEXT:\r
161                 {\r
162                         const int nSizeOfNullTerminator = 1;\r
163                         if( lhs.m_oData.GetSize() && rhs.m_oData.GetSize() )\r
164                         {\r
165                                 m_oData.SetSize( lhs.m_oData.GetSize() - nSizeOfNullTerminator + rhs.m_oData.GetSize() );\r
166 \r
167                                 int nLHS = 0;\r
168                                 for( nLHS = 0; nLHS < lhs.m_oData.GetSize() - nSizeOfNullTerminator; ++nLHS )\r
169                                 {\r
170                                         m_oData[ nLHS ] = lhs.m_oData[ nLHS ];\r
171                                 }\r
172                                 for( int nRHS = 0; nRHS < rhs.m_oData.GetSize(); ++nRHS )\r
173                                 {\r
174                                         m_oData[ nLHS + nRHS ] = rhs.m_oData[ nRHS ];\r
175                                 }\r
176                         }\r
177                         else if( lhs.m_oData.GetSize() )\r
178                         {\r
179                                 *this = lhs;\r
180                         }\r
181                         else if( rhs.m_oData.GetSize() )\r
182                         {\r
183                                 *this = rhs;\r
184                         }\r
185                         else\r
186                         {\r
187                                 ASSERT( 0 );\r
188                         }\r
189                 }\r
190                 break;\r
191         case CF_UNICODETEXT:\r
192                 {\r
193                         const int nSizeOfNullTerminator = 2;\r
194                         if( lhs.m_oData.GetSize() && rhs.m_oData.GetSize() )\r
195                         {\r
196                                 m_oData.SetSize( lhs.m_oData.GetSize() - nSizeOfNullTerminator + rhs.m_oData.GetSize() );\r
197 \r
198                                 int nLHS = 0;\r
199                                 for( nLHS = 0; nLHS < lhs.m_oData.GetSize() - nSizeOfNullTerminator; ++nLHS )\r
200                                 {\r
201                                         m_oData[ nLHS ] = lhs.m_oData[ nLHS ];\r
202                                 }\r
203                                 for( int nRHS = 0; nRHS < rhs.m_oData.GetSize(); ++nRHS )\r
204                                 {\r
205                                         m_oData[ nLHS + nRHS ] = rhs.m_oData[ nRHS ];\r
206                                 }\r
207                         }\r
208                         else if( lhs.m_oData.GetSize() )\r
209                         {\r
210                                 *this = lhs;\r
211                         }\r
212                         else if( rhs.m_oData.GetSize() )\r
213                         {\r
214                                 *this = rhs;\r
215                         }\r
216                         else\r
217                         {\r
218                                 ASSERT( 0 );\r
219                         }\r
220                 }\r
221                 break;\r
222         case CF_LOCALE:\r
223                 *this = lhs;\r
224                 break;\r
225         default:\r
226                 ASSERT( 0 );\r
227                 *this = lhs;\r
228                 break;\r
229         }\r
230 \r
231         return *this;\r
232 }\r
233 */\r
234 \r
235 //////////////////////////////////////////////////////////////////////\r
236 // \91\80\8dì\r
237 //////////////////////////////////////////////////////////////////////\r
238 \r
239 BOOL CClipboardFormatSnap::Capture( int nFormat )\r
240 {\r
241 //      CUtils::Log("CClipboardFormatSnap::Capture: 0");\r
242         m_nFormat = nFormat;\r
243 \r
244         //\r
245         // (0) DataObject\82Í\8eæ\82è\8f\9c\82­(4byte\82Ì\83|\83C\83\93\83^\82µ\82©\93¾\82ç\82ê\82È\82¢\82½\82ß)\r
246         //\r
247         if( GetFormatName( nFormat ) == _T("DataObject") ) return FALSE;\r
248 \r
249         //\r
250         // (0.5) Excel \8fã\82Å CF_METAFILEPICT/CF_ENHMETAFILE \82É GetClipboardData \82·\82é\82Æ "\90}\82ª\91å\82«\82·\82¬\82Ü\82·\81B" \82Æ\82¢\82¤\83G\83\89\81[\82ª\95\\8e¦\82³\82ê\82é\81B\r
251         //\r
252 //      CUtils::Log("CClipboardFormatSnap::Capture: 0.5");\r
253         if( CUtils::IsExcel() && ( nFormat == CF_METAFILEPICT || nFormat == CF_ENHMETAFILE ) ) return FALSE;\r
254 \r
255         //\r
256         // (1) Clipboard\93à\82Ì\83\81\83\82\83\8a\83u\83\8d\83b\83N\8eæ\93¾\r
257         //\r
258 //      CUtils::Log("CClipboardFormatSnap::Capture: 1");\r
259         HANDLE hData    = GetClipboardData( nFormat ); if( hData == NULL ) return FALSE;\r
260 //      CUtils::Log("CClipboardFormatSnap::Capture: 1.1");\r
261         void *pData     = GlobalLock( hData );         if( pData == NULL ) return FALSE;\r
262 //      CUtils::Log("CClipboardFormatSnap::Capture: 1.2");\r
263         size_t nLenData = GlobalSize( hData );         if( nLenData == 0 ) return FALSE;\r
264 \r
265         //\r
266         // (2) \83\8d\81[\83J\83\8b\83I\83u\83W\83F\83N\83g\82Ö\83f\81[\83^\83R\83s\81[\r
267         //\r
268 //      CUtils::Log("CClipboardFormatSnap::Capture: 2");\r
269         m_oData.RemoveAll();\r
270 //      CUtils::Log("CClipboardFormatSnap::Capture: 2.1");\r
271         m_oData.SetSize( nLenData );\r
272 //      CUtils::Log("CClipboardFormatSnap::Capture: 2.2");\r
273         CopyMemory( &m_oData[ 0 ], pData, nLenData );\r
274 //      CUtils::Log("CClipboardFormatSnap::Capture: 2.3");\r
275         GlobalUnlock( hData );\r
276 \r
277         // for debug\r
278 //      CUtils::Log( "nFormat: %d (%s)", nFormat, GetFormatName( nFormat ) );\r
279 ///     if( nFormat == CF_OEMTEXT )\r
280 //      if( nFormat == 49310 )  // Rich Text Format\r
281 ///     if( nFormat == 49360 )  // HTML Format\r
282 ///     if( nFormat == 49669 )  // Notes Editor Internal\r
283 ///     if( nFormat == 49742 )  // HPB HTML Format\r
284 //      {\r
285 ///             for( int i = 0; i < m_oData.GetSize(); ++i )\r
286 ///             {\r
287 ///                     CUtils::Log( "%02x (%c)", m_oData[i], m_oData[ i ] );\r
288 ///             }\r
289 ///\r
290 ///             CUtils::Log( "size = %d", m_oData.GetSize() );\r
291 //              char *sz = new char[ m_oData.GetSize() + 1 ];\r
292 //              memset( sz, 0, m_oData.GetSize() + 1 );\r
293 //              for( int i = 0; i < m_oData.GetSize(); ++i )\r
294 //              {\r
295 //                      *(sz + i) = m_oData[ i ];\r
296 //              }\r
297 //              CUtils::Log( "%s", sz );\r
298 //              CUtils::Log( "length = %d", GetRTFBodyLength());\r
299 //              delete[] sz;\r
300 //      }\r
301 \r
302 //      CUtils::Log("CClipboardFormatSnap::Capture: 3");\r
303         return TRUE;\r
304 }\r
305 \r
306 BOOL CClipboardFormatSnap::Restore()\r
307 {\r
308         int nLenData = m_oData.GetSize() * sizeof(BYTE);\r
309         HANDLE hClip = GlobalAlloc( GMEM_MOVEABLE, nLenData );\r
310         void *pClip = GlobalLock( hClip );\r
311         CopyMemory( pClip, &m_oData[ 0 ], nLenData );\r
312 \r
313         GlobalUnlock( hClip );\r
314         SetClipboardData( m_nFormat, hClip );\r
315         return TRUE;\r
316 }\r
317 \r
318 BOOL CClipboardFormatSnap::IsSameFormat( const CClipboardFormatSnap *const pFormatSnap )\r
319 {\r
320         return m_nFormat == pFormatSnap->m_nFormat;\r
321 }\r
322 \r
323 BOOL CClipboardFormatSnap::IsMergeableFormat()\r
324 {\r
325         return IsMergeableFormat( m_nFormat );\r
326 }\r
327 \r
328 BOOL CClipboardFormatSnap::IsMergeableFormat( const int nFormat )\r
329 {\r
330         switch( nFormat )\r
331         {\r
332         case CF_TEXT:\r
333         case CF_OEMTEXT:\r
334         case CF_UNICODETEXT:\r
335         case CF_LOCALE:\r
336 //      case 49310:     // Rich Text Format\r
337                 return TRUE;\r
338                 break;\r
339         default:\r
340                 break;\r
341         }\r
342 \r
343         return FALSE;\r
344 }\r
345 \r
346 int CClipboardFormatSnap::FindReturn()\r
347 {\r
348 //      CUtils::Log( "%s", GetFormatName( m_nFormat ) );\r
349         switch( m_nFormat )\r
350         {\r
351         case CF_TEXT:\r
352         case CF_OEMTEXT:\r
353                 {\r
354                         for( int i = 0; i < m_oData.GetSize(); ++i )\r
355                         {\r
356 //                              CUtils::Log( "%#02x (%c)", m_oData[ i ], m_oData[ i ] );\r
357                                 if( m_oData[ i ] == VK_RETURN ) return i;       // CR\r
358                                 if( !m_oData[ i ] ) break;                                      // NULL Terminator\r
359                         }\r
360                 }\r
361                 break;\r
362         case CF_UNICODETEXT:\r
363                 {\r
364 //                      for( int i = 0; i < m_oData.GetSize(); ++i )\r
365 //                      {\r
366 //                              CUtils::Log( "%#02x (%c)", m_oData[ i ], m_oData[ i ] );\r
367 //                      }\r
368                 }\r
369                 break;\r
370         default:\r
371                 break;\r
372         }\r
373 \r
374         return -1;\r
375 }\r
376 \r
377 const int CClipboardFormatSnap::GetTextLength( const int nSizeOfNullTerminator )\r
378 {\r
379         try {\r
380                 char *pNullTerminator = new char[ nSizeOfNullTerminator ];\r
381 \r
382                 if( !pNullTerminator ) return -1;\r
383                 memset( pNullTerminator, 0, nSizeOfNullTerminator );\r
384 \r
385                 char *pCurrentCharactor = new char[ nSizeOfNullTerminator ];\r
386                 if( !pCurrentCharactor )\r
387                 {\r
388                         delete [] pNullTerminator;\r
389                         pNullTerminator = NULL;\r
390                         return -1;\r
391                 }\r
392 \r
393                 for( int i = 0; i < m_oData.GetSize() - nSizeOfNullTerminator + 1; i += nSizeOfNullTerminator )\r
394                 {\r
395                         for( int j = 0; j < nSizeOfNullTerminator; ++j ) pCurrentCharactor[ j ] = m_oData[ i + j ];\r
396 \r
397                         if( !memcmp( pCurrentCharactor, pNullTerminator, nSizeOfNullTerminator ) )\r
398                         {\r
399                                 delete [] pNullTerminator;\r
400                                 pNullTerminator = NULL;\r
401                                 delete [] pCurrentCharactor;\r
402                                 pCurrentCharactor = NULL;\r
403                                 return i;\r
404                         }\r
405                 }\r
406 \r
407                 delete [] pNullTerminator;\r
408                 pNullTerminator = NULL;\r
409                 delete [] pCurrentCharactor;\r
410                 pCurrentCharactor = NULL;\r
411         }\r
412         catch (CMemoryException* e) {\r
413                 e->Delete();\r
414 //              CUtils::Log("CClipboardFormatSnap::GetTextLength: 'new' threw an exception");\r
415         }\r
416 \r
417         return -1;\r
418 }\r
419 \r
420 const int CClipboardFormatSnap::GetRTFBodyHead() const\r
421 {\r
422         int nBra = 0;\r
423         int i;\r
424         for( i = 0; i < m_oData.GetSize(); ++i )\r
425         {\r
426                 BOOL bBody = FALSE;\r
427 \r
428                 switch( m_oData[ i ] )\r
429                 {\r
430                 case '{':\r
431                         if( nBra++ )\r
432                         {\r
433                                 for( ++i ; i < m_oData.GetSize(); ++i )\r
434                                 {\r
435                                         switch( m_oData[ i ] )\r
436                                         {\r
437                                         case '{':\r
438                                                 ++nBra;\r
439                                                 break;\r
440                                         case '}':\r
441                                                 --nBra;\r
442                                                 break;\r
443                                         case '\\':\r
444 //                                              // for Microsoft Word\r
445 //                                              if( i < m_oData.GetSize() + 7 &&\r
446 //                                                      m_oData[ i + 1 ] == 'i' &&\r
447 //                                                      m_oData[ i + 2 ] == 'n' &&\r
448 //                                                      m_oData[ i + 3 ] == 's' &&\r
449 //                                                      m_oData[ i + 4 ] == 'r' &&\r
450 //                                                      m_oData[ i + 5 ] == 's' &&\r
451 //                                                      m_oData[ i + 6 ] == 'i' &&\r
452 //                                                      m_oData[ i + 7 ] == 'd' )\r
453 //                                              {\r
454 //                                                      --i;\r
455 //                                                      nBra = 1;\r
456 //                                              }\r
457                                                 break;\r
458                                         default:\r
459                                                 break;\r
460                                         }\r
461 \r
462                                         if( nBra == 1 ) break;\r
463                                 }\r
464                         }\r
465                         break;\r
466 \r
467                 case '}':\r
468                         if( --nBra == 0 ) {\r
469                                 i = m_oData.GetSize();\r
470                                 bBody = TRUE;\r
471                         }\r
472                         break;\r
473 \r
474                 case '\\':      // tag\r
475                         for( ; i < m_oData.GetSize(); ++i )\r
476                         {\r
477                                 BOOL bTagEnd = FALSE;\r
478                                 switch( m_oData[ i ] )\r
479                                 {\r
480                                 case '{':\r
481                                 case '}':\r
482                                         --i;\r
483                                         bTagEnd = TRUE;\r
484                                         break;\r
485                                 case ' ':\r
486                                         bTagEnd = TRUE;\r
487                                         break;\r
488                                 case '\\':\r
489                                         if( i < m_oData.GetSize() + 5 &&\r
490                                                 m_oData[ i + 1 ] == 'p' &&\r
491                                                 m_oData[ i + 2 ] == 'a' &&\r
492                                                 m_oData[ i + 3 ] == 'r' &&\r
493                                                 m_oData[ i + 4 ] == 0x0d &&\r
494                                                 m_oData[ i + 5 ] == 0x0a )\r
495                                         {\r
496                                                 bTagEnd = TRUE;\r
497                                                 bBody = TRUE;\r
498                                         }\r
499                                         if( i < m_oData.GetSize() + 1 &&\r
500                                                 ( m_oData[ i + 1 ] == '\\' ||\r
501                                                   m_oData[ i + 1 ] == '{' ||\r
502                                                   m_oData[ i + 1 ] == '}' ) )\r
503                                         {\r
504                                                 bTagEnd = TRUE;\r
505                                                 bBody = TRUE;\r
506                                         }\r
507                                         break;\r
508                                 default:\r
509                                         break;\r
510                                 }\r
511 \r
512                                 if( bTagEnd ) break;\r
513                         }\r
514                         break;\r
515 \r
516                 case 0x0d:\r
517                         if( i < m_oData.GetSize() + 5 &&\r
518                                         m_oData[ i + 1 ] == 0x0a &&\r
519                                         m_oData[ i + 2 ] == '\\' &&\r
520                                         m_oData[ i + 3 ] == 'p' &&\r
521                                         m_oData[ i + 4 ] == 'a' &&\r
522                                         m_oData[ i + 5 ] == 'r' )\r
523                         {\r
524                                 bBody = TRUE;\r
525                         }\r
526                         break;\r
527                 case 0x0a:\r
528                         break;\r
529 \r
530                 default:        // body\r
531                         bBody = TRUE;\r
532                         break;\r
533                 }\r
534 \r
535                 if( bBody ) break;\r
536         }\r
537 \r
538         return i;\r
539 }\r
540 \r
541 const int CClipboardFormatSnap::GetRTFBodyLength() const\r
542 {\r
543 //      CUtils::Log("const int CClipboardFormatSnap::GetRTFBodyLength() const: GetRTFBodyHead() = %d, m_oData.GetSize() = %d", GetRTFBodyHead(), m_oData.GetSize());\r
544         int nLength  = 0;\r
545 \r
546         for( int i = GetRTFBodyHead(); i < m_oData.GetSize(); ++i )\r
547         {\r
548                 if( m_oData[ i ] == '}' ) break;\r
549                 else if( m_oData[ i ] == '\\' )\r
550                 {\r
551 //                      CUtils::Log( "Body: %#04x (%c)", m_oData[ i ], m_oData[ i ] );\r
552 //                      CUtils::Log( "Body: %#04x (%c)", m_oData[ i + 1 ], m_oData[ i + 1 ] );\r
553                         nLength += 2;\r
554                         ++i;\r
555                 }\r
556                 else\r
557                 {\r
558 //                      CUtils::Log( "Body: %#04x (%c)", m_oData[ i ], m_oData[ i ] );\r
559                         ++nLength;\r
560                 }\r
561         }\r
562 \r
563         return nLength;\r
564 }\r
565 \r
566 BOOL CClipboardFormatSnap::IsEmpty()\r
567 {\r
568         BOOL rc = TRUE;\r
569         switch( m_nFormat )\r
570         {\r
571         case CF_TEXT:\r
572         case CF_OEMTEXT:\r
573                 if( ( 1 < m_oData.GetSize() ) && m_oData[ 0 ] ) rc = FALSE;\r
574                 break;\r
575         case CF_UNICODETEXT:\r
576                 if( ( 2 < m_oData.GetSize() ) && m_oData[ 0 ] && m_oData[ 1 ] ) rc = FALSE;\r
577                 break;\r
578         default:\r
579                 break;\r
580         }\r
581         return rc;\r
582 }\r
583 \r
584 void CClipboardFormatSnap::Add( const char *const pAddedString, const BOOL bTop )\r
585 {\r
586         switch( m_nFormat )\r
587         {\r
588         case CF_TEXT:\r
589         case CF_OEMTEXT:\r
590                 Add( pAddedString, bTop, 1 );\r
591                 break;\r
592         case CF_UNICODETEXT:\r
593                 Add( pAddedString, bTop, 2 );\r
594                 break;\r
595         default:\r
596                 break;\r
597         }\r
598 }\r
599 \r
600 void CClipboardFormatSnap::Add( const char *const pAddedString, const BOOL bTop, const int nSizeOfNullTerminator )\r
601 {\r
602         int nOffset = GetTextLength( nSizeOfNullTerminator );\r
603         if( nOffset < 0 ) nOffset = 0;\r
604 \r
605         if( m_oData.GetSize() < ( nOffset + nSizeOfNullTerminator * ( (int)strlen( pAddedString ) + 1 ) ) )\r
606         {\r
607                 m_oData.SetSize( nOffset + nSizeOfNullTerminator * ( strlen( pAddedString ) + 1 ) );\r
608         }\r
609 \r
610         if( bTop )\r
611         {\r
612                 int i;\r
613                 for( i = nOffset + nSizeOfNullTerminator - 1; 0 <= i ; --i )\r
614                 {\r
615                         m_oData[ nSizeOfNullTerminator * strlen(pAddedString) + i ] = m_oData[ i ];\r
616                 }\r
617                 for( i = 0; i < ( int )strlen( pAddedString ); ++i )\r
618                 {\r
619                         for ( int j = 0; j < nSizeOfNullTerminator; ++j ) {\r
620                                 if( j ) m_oData[ i * nSizeOfNullTerminator + j ] = 0;\r
621                                 else    m_oData[ i * nSizeOfNullTerminator + j ] = *( pAddedString + i );\r
622                         }\r
623                 }\r
624         }\r
625         else\r
626         {\r
627                 unsigned int i;\r
628                 for( i = 0; i < strlen( pAddedString ); ++i )\r
629                 {\r
630                         for( int j = 0; j < nSizeOfNullTerminator; ++j )\r
631                         {\r
632                                 if( j ) m_oData[ nOffset + i * nSizeOfNullTerminator + j ] = 0;\r
633                                 else    m_oData[ nOffset + i * nSizeOfNullTerminator + j ] = *( pAddedString + i );\r
634                         }\r
635                 }\r
636 \r
637                 for( int j = 0; j < nSizeOfNullTerminator; ++j )\r
638                 {\r
639                         m_oData[ nOffset + i * nSizeOfNullTerminator + j ] = 0;\r
640                 }\r
641         }\r
642 }\r
643 \r
644 void CClipboardFormatSnap::DeleteLastReturn()\r
645 {\r
646         switch( m_nFormat )\r
647         {\r
648         case CF_TEXT:\r
649         case CF_OEMTEXT:\r
650                 DeleteLastReturn( 1 );\r
651                 break;\r
652         case CF_UNICODETEXT:\r
653                 DeleteLastReturn( 2 );\r
654                 break;\r
655         default:\r
656                 break;\r
657         }\r
658 }\r
659 \r
660 void CClipboardFormatSnap::DeleteLastReturn(const int nSizeOfNullTerminator)\r
661 {\r
662         if( GetTextLength( nSizeOfNullTerminator ) - nSizeOfNullTerminator * 2 < 0 ) return;\r
663 \r
664         try {\r
665                 char *pCRLF = new char[ nSizeOfNullTerminator * 2 ];\r
666                 if( !pCRLF ) return;\r
667                 memset( pCRLF, 0, nSizeOfNullTerminator * 2 );\r
668                 *pCRLF = '\r';\r
669                 *(pCRLF + nSizeOfNullTerminator) = '\n';\r
670 \r
671                 BOOL bDelete = TRUE;\r
672                 for( int i = 0; i < nSizeOfNullTerminator * 2; ++i )\r
673                 {\r
674 //                      CUtils::Log( "%#02x (%c) AA _%#02x_", m_oData[ GetTextLength( nSizeOfNullTerminator ) - nSizeOfNullTerminator * 2 + i ], m_oData[ GetTextLength( nSizeOfNullTerminator ) - nSizeOfNullTerminator * 2 + i ], *( pCRLF + i ) );\r
675                         if( m_oData[ GetTextLength( nSizeOfNullTerminator ) - nSizeOfNullTerminator * 2 + i ] != *( pCRLF + i ) )\r
676                         {\r
677                                 bDelete = FALSE;\r
678                                 break;\r
679                         }\r
680                 }\r
681 \r
682                 if( bDelete )\r
683                 {\r
684                         const int nOffset = GetTextLength( nSizeOfNullTerminator );\r
685                         for( int i = 0; i < nSizeOfNullTerminator * 2; ++i )\r
686                         {\r
687 //                              CUtils::Log( "%#02x (%c) BB", m_oData[ GetTextLength( nSizeOfNullTerminator ) - nSizeOfNullTerminator * 2 + i ], m_oData[ GetTextLength( nSizeOfNullTerminator ) - nSizeOfNullTerminator * 2 + i ] );\r
688                                 m_oData[ nOffset - nSizeOfNullTerminator * 2 + i ] = 0;\r
689                         }\r
690                 }\r
691         }\r
692         catch (CMemoryException* e) {\r
693                 e->Delete();\r
694 //              CUtils::Log("CClipboardFormatSnap::DeleteLastReturn: 'new' threw an exception");\r
695         }\r
696 }\r