OSDN Git Service

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