TNB Library
TnbClipboard.h
[詳解]
1#pragma once
14#ifdef _TnbCLIPBOARD_OtherType_ENABLE
15 #include "TnbDntStr.h"
16 #include "TnbMap.h"
17#else
18 #include "TnbStr.h"
19#endif
20#include "TnbBitmapHandle.h"
21#include <shlobj.h>
22#include <wingdi.h>
23#ifndef _WIN32_WCE
24 #pragma comment(lib,"gdi32.lib")
25#endif
26
27
28
29//TNB Library
30namespace TNB
31{
32
33
34
49{
50public:
51
60 explicit CClipboard(HWND hWnd = NULL, DWORD dwOpenTimeout = 500, bool boHasErrBox = false)
61 : m_hWnd(hWnd), m_dwOpenTimeout(dwOpenTimeout), m_boHasErrBox(boHasErrBox)
62 {
63 }
64
69 void SetHandle(HWND hWnd)
70 {
71 m_hWnd = hWnd;
72 }
73
80 bool Empty(void)
81 {
82 bool boRc = false;
83 if ( m_Open(true) )
84 {
85 m_Close();
86 boRc = true;
87 }
88 return boRc;
89 }
90
98 bool IsAvailable(UINT uFormat = 0) const
99 {
100 bool boRc = false;
101 if ( uFormat == 0 )
102 {
103 uFormat = CBFMT_TEXT;
104 }
105 if ( m_Open() )
106 {
107 boRc = !! ::IsClipboardFormatAvailable(uFormat);
108 m_Close();
109 }
110 return boRc;
111 }
112
119 static CStr GetFormatName(UINT uFormat)
120 {
121 CStr str;
122 int r = ::GetClipboardFormatName(uFormat, str.GetBuffer(1024), 1024);
123 _GetLastError("GetClipboardFormatName");
124 str.ReleaseBuffer();
125 if ( r == 0 )
126 {
127 str.Empty();
128 }
129 return str;
130 }
131
137 static UINT RegisterUserDataType(LPCTSTR lpszDataTypeName)
138 {
139 return ::RegisterClipboardFormat(lpszDataTypeName);
140 }
141
147 CStr GetString(void) const
148 {
149 CStr strRc;
150 if ( m_Open() )
151 {
152 if ( ::IsClipboardFormatAvailable(CBFMT_TEXT) )
153 {
154 HANDLE hMem = ::GetClipboardData(CBFMT_TEXT);
155 if ( hMem != NULL )
156 {
157 strRc = static_cast<LPCTSTR>(GlobalLock(hMem));
158 GlobalUnlock(hMem);
159 }
160 }
161 m_Close();
162 }
163 return strRc;
164 }
165
174 bool SetString(LPCTSTR lpszText, bool isAdd = false)
175 {
176 if ( ! m_Open(! isAdd) )
177 {
178 return false;
179 }
180 size_t iStrLen = STRLIB::GetLen(lpszText);
181 HGLOBAL hMem = m_AllocAndCopy((iStrLen + 1) * sizeof(TCHAR), lpszText);
182 bool boRc = m_SetData(CBFMT_TEXT, hMem);
183 m_Close();
184 return boRc;
185 }
186
196 bool GetUserData(CWorkMem& _data, UINT dataTypeId) const
197 {
198 bool r = false;
199 if ( m_Open() )
200 {
201 if ( ::IsClipboardFormatAvailable(dataTypeId) )
202 {
203 HGLOBAL h = ::GetClipboardData(dataTypeId);
204 size_t len = ::GlobalSize(h);
205 _data.Reset(len, static_cast<BYTE*>(GlobalLock(h)));
206 r = true;
207 GlobalUnlock(h);
208 }
209 m_Close();
210 }
211 return r;
212 }
213
225 bool SetUserData(UINT dataTypeId, size_t dataSize, LPCVOID pData, bool isAdd = false)
226 {
227 if ( ! m_Open(! isAdd) )
228 {
229 return false;
230 }
231 HGLOBAL h = m_AllocAndCopy(dataSize, pData);
232 bool r = m_SetData(dataTypeId, h);
233 m_Close();
234 return r;
235 }
236
237 #ifndef _WIN32_WCE
238
245 HBITMAP GetBitmap(void) const
246 {
247 HBITMAP rc = NULL;
248 if ( m_Open() )
249 {
250 if ( ::IsClipboardFormatAvailable(CF_BITMAP) )
251 {
252 HBITMAP hBmp = static_cast<HBITMAP>(::GetClipboardData(CF_BITMAP));
253 if ( hBmp != NULL )
254 {
255 rc = static_cast<HBITMAP>(::CopyImage(hBmp, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION));
256 }
257 }
258 m_Close();
259 }
260 return rc;
261 }
262
271 bool SetBitmap(HBITMAP bmp, bool isAdd = false)
272 {
273 if ( ! m_Open(! isAdd) )
274 {
275 return false;
276 }
277 BITMAPINFOHEADER bmi;
278 RGBQUAD* pRgb = NULL;
279 HBITMAP hBmp = CBitmapHandle::Create32bitDibSection(bmp, pRgb, &bmi);
280 if ( hBmp == NULL )
281 {
282 return false;
283 }
284 HGLOBAL h = ::GlobalAlloc(GHND, sizeof(bmi) + bmi.biWidth * bmi.biHeight * sizeof(RGBQUAD));
285 BYTE* B = static_cast<BYTE*>(::GlobalLock(h));
286 MemCopy(B, &bmi, sizeof(bmi));
287 MemCopy(&B[sizeof(bmi)], pRgb, bmi.biWidth * bmi.biHeight * sizeof(RGBQUAD));
288 ::GlobalUnlock(h);
289 bool boRc = m_SetData(CF_DIB, h);
290 _DeleteObject(hBmp);
291 m_Close();
292 return boRc;
293 }
294
295 #endif // _WIN32_WCE
296
297 #ifdef _TnbCLIPBOARD_OtherType_ENABLE
298
299 #ifndef _WIN32_WCE
300
310 bool GetDropInfo(CStrVector& _vstrFiles, DWORD& _dwEffect) const
311 {
312 bool boRc = false;
313 _vstrFiles.RemoveAll();
314 _dwEffect = 0;
315 if ( m_Open() )
316 {
317 if ( ::IsClipboardFormatAvailable(CF_HDROP) )
318 {
319 HDROP hDrop = static_cast<HDROP>(::GetClipboardData(CF_HDROP));
320 TCHAR atcBuf[MAX_PATH];
321 int iCount = ToInt(::DragQueryFile(hDrop, 0xFFFFFFFF, NULL, NULL));
322 for ( int i = 0; i < iCount; i++ )
323 {
324 ::DragQueryFile(hDrop, i, atcBuf, MAX_PATH);
325 _vstrFiles.Add(atcBuf);
326 }
327 //
328 UINT uFmt = ::RegisterClipboardFormat(CFSTR_PREFERREDDROPEFFECT);
329 HANDLE hDropEffect = ::GetClipboardData(uFmt);
330 if ( hDropEffect != NULL )
331 {
332 _dwEffect = *static_cast<DWORD*>(::GlobalLock(hDropEffect));
333 ::GlobalUnlock(hDropEffect);
334 boRc = true;
335 }
336 }
337 m_Close();
338 }
339 return boRc;
340 }
341
352 bool SetDropInfo(const CStrVector& vstrFiles, DWORD dwEffect = DROPEFFECT_COPY)
353 {
354 if ( ! m_Open(true) )
355 {
356 return false;
357 }
358 bool boRc = false;
359 //Double Null Term Str 作成
361 dnt.Set(vstrFiles);
362 //CF_HDROPを作成
363 DROPFILES dfs = { sizeof(dfs) };
364 #ifdef _UNICODE
365 dfs.fWide = 1;
366 #endif
367 size_t size = dnt.GetSize() * sizeof(TCHAR);
368 HGLOBAL hDrop = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, sizeof(DROPFILES) + size);
369 BYTE* B = static_cast<BYTE*>(::GlobalLock(hDrop));
370 MemCopy(B, reinterpret_cast<const BYTE*>(&dfs), sizeof(DROPFILES));
371 B += sizeof(DROPFILES);
372 MemCopy(B, reinterpret_cast<const BYTE*>(LPCTSTR(dnt)), size);
373 ::GlobalUnlock(hDrop);
374 //Preferred DropEffectを作成
375 HGLOBAL hDropEffect = m_AllocAndCopy(sizeof(DWORD), &dwEffect);
376 //クリップボードにデータをセット
377 UINT uFmt = ::RegisterClipboardFormat(CFSTR_PREFERREDDROPEFFECT);
378 if ( ::SetClipboardData(CF_HDROP, hDrop) == NULL )
379 {
380 ::GlobalFree(hDropEffect);
381 ::GlobalFree(hDrop);
382 }
383 else if ( ::SetClipboardData(uFmt, hDropEffect) == NULL )
384 {
385 ::GlobalFree(hDropEffect);
386 }
387 else
388 {
389 boRc = true;
390 }
391 m_Close();
392 return boRc;
393 }
394
395 #endif // _WIN32_WCE
396
398 typedef CMapT< UINT, CVectorT<BYTE> > CDataMap;
399
409 bool GetAll(CDataMap& _data, bool boIsWithMetafile = false, bool boIsWithRegData = false) const
410 {
411 bool boRc = false;
412 _data.RemoveAll();
413 if ( ! m_Open() )
414 {
415 return false;
416 }
417 UINT uFormat = 0;
418 while ( true )
419 {
420 UINT r = ::EnumClipboardFormats(uFormat);
421 if ( r == 0 )
422 {
423 DWORD dwError = _GetLastError("EnumClipboardFormats");
424 if ( dwError == NO_ERROR )
425 {
426 boRc = true;
427 }
428 else
429 {
430 _data.RemoveAll();
431 }
432 break;
433 }
434 //
435 bool boIsValid = false;
436 switch ( r )
437 {
438 case CBFMT_TEXT: //CF_TEXT CF_UNICODETEXT CF_OEMTEXT と同期
439 case CF_DIB: //CF_BITMAP CF_PALETTE CF_DIBV5 と同期
440 boIsValid = true;
441 break;
442#ifndef _WIN32_WCE
443 case CF_ENHMETAFILE: //CF_METAFILEPICT と同期
444 boIsValid = boIsWithMetafile;
445 break;
446#endif
447 default:
448 if ( boIsWithRegData )
449 {
450 boIsValid = (r >= 0x8000);
451 }
452 break;
453 }
454 //
455 if ( boIsValid )
456 {
458 HANDLE hMem = ::GetClipboardData(r);
459#ifndef _WIN32_WCE
460 if ( r == CF_ENHMETAFILE )
461 {
462 HENHMETAFILE h = (HENHMETAFILE)hMem;
463 UINT l = ::GetEnhMetaFileBits(h, 0, NULL);
464 ::GetEnhMetaFileBits(h, l, v.GetBuffer(l));
465 v.ReleaseBuffer();
466 }
467 else
468#endif
469 {
470 v.SetElements(static_cast<size_t>(::GlobalSize(hMem)), static_cast<BYTE*>(GlobalLock(hMem)));
471 GlobalUnlock(hMem);
472 }
473 _data[r] = v;
474 TRACE3(" Found Clip = 0x%04X[%s] len=%d \n", r, GetFormatName(r), v.GetSize());
475 }
476 else
477 {
478 TRACE2(" Drop Clip = 0x%04X[%s]\n", r, GetFormatName(r));
479 }
480 uFormat = r;
481 }
482 m_Close();
483 return boRc;
484 }
485
493 bool SetAll(const CDataMap& data)
494 {
495 if ( ! m_Open(true) )
496 {
497 return false;
498 }
499 bool boRc = true;
500 UINT uFormat;
502 loop ( i, data.GetSize() )
503 {
504 VERIFYLIB(data.Get(i, uFormat, v));
505 bool boIsValid = false;
506 switch ( uFormat )
507 {
508 case CF_TEXT:
509 case CF_UNICODETEXT:
510 case CF_OEMTEXT:
511 case CF_DIB: //CF_BITMAP CF_PALETTE CF_DIBV5 と同期
512 boIsValid = true;
513 break;
514#ifndef _WIN32_WCE
515 case CF_ENHMETAFILE: //CF_METAFILEPICT と同期
516 {
517 HENHMETAFILE h = ::SetEnhMetaFileBits(ToDword(v.GetSize()), v.ReferBuffer());
518 boRc &= m_SetData(uFormat, h);
519 }
520 break;
521#endif
522 default:
523 break;
524 }
525 if ( uFormat >= 0x8000 || boIsValid )
526 {
527
528#ifdef _WIN32_WCE
529 if ( uFormat == CF_TEXT )
530 {
531 LPCSTR P = reinterpret_cast<LPCSTR>(v.ReferBuffer());
532 CUnicode u = P;
533 size_t l = u.GetLength() * 2;
534 LPCWSTR lpsz = u;
535 MemCopy(v.GetBuffer(l), lpsz, l);
536 v.ReleaseBuffer();
537 uFormat = CF_UNICODETEXT;
538 }
539#endif
540 HGLOBAL hMem = m_AllocAndCopy(v.GetSize(), v.ReferBuffer());
541 boRc &= m_SetData(uFormat, hMem);
542 }
543 }
544 m_Close();
545 return boRc;
546 }
547
548 #endif // _TnbCLIPBOARD_OtherType_ENABLE
549
550private:
551
552 #ifdef _UNICODE
553 enum { CBFMT_TEXT = CF_UNICODETEXT };
554 #else
555 enum { CBFMT_TEXT = CF_TEXT };
556 #endif
557
558 HWND m_hWnd;
559 DWORD m_dwOpenTimeout;
560 bool m_boHasErrBox;
561
563 void m_MsgBox(LPCTSTR lpsz) const
564 {
565 if ( m_boHasErrBox )
566 {
567 TRACE1("%s\n", lpsz);
568 ::MessageBox(NULL, lpsz, _T("TNB::CClipboard"), MB_OK);
569 }
570 }
571
578 bool m_Open(bool boWithEmpty = false) const
579 {
580 DWORD dwTick = ::GetTickCount();
581 do
582 {
583 if ( ::OpenClipboard(m_hWnd) )
584 {
585 if ( boWithEmpty && ! ::EmptyClipboard() )
586 {
587 ::CloseClipboard();
588 m_MsgBox(_T("クリップ・ボードが一杯です"));
589 return false;
590 }
591 return true;
592 }
593 ::Sleep(1);
594 }
595 while ( (::GetTickCount() - dwTick) < m_dwOpenTimeout );
596 m_MsgBox(_T("クリップ・ボードが利用できません。"));
597 return false;
598 }
599
601 void m_Close(void) const
602 {
603 ::CloseClipboard();
604 }
605
612 HGLOBAL m_AllocAndCopy(size_t size, LPCVOID P)
613 {
614 HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, size);
615 if ( hMem == NULL )
616 {
617 m_MsgBox(_T("メモリが一杯です"));
618 }
619 else
620 {
621 ::CopyMemory(GlobalLock(hMem), P, size);
622 GlobalUnlock(hMem);
623 }
624 return hMem;
625 }
626
634 bool m_SetData(UINT uFormat, HGLOBAL hMem)
635 {
636 if ( hMem == NULL )
637 {
638 return false;
639 }
640 if ( ::SetClipboardData(uFormat, hMem) == NULL )
641 {
642 ::GlobalFree(hMem);
643 return false;
644 }
645 return true;
646 }
647};
648
649
650
651}; // TNB
ビットマップハンドル関係のヘッダ
#define loop(VAR, CNT)
loop構文.
Definition: TnbDef.h:343
Double Null Terminate(DNT)型文字列操作関係のヘッダ
マップ型情報管理関係のヘッダ
文字列管理関係のヘッダ
static HBITMAP Create32bitDibSection(HBITMAP hbm, RGBQUAD *&_pRgb, BITMAPINFOHEADER *pHeader=NULL)
[作成] 32bitビットマップ作成.
クリップボードアクセスクラス
Definition: TnbClipboard.h:49
bool IsAvailable(UINT uFormat=0) const
[確認] 存在確認.
Definition: TnbClipboard.h:98
bool SetBitmap(HBITMAP bmp, bool isAdd=false)
[設定] ビットマップ登録.
Definition: TnbClipboard.h:271
bool SetUserData(UINT dataTypeId, size_t dataSize, LPCVOID pData, bool isAdd=false)
[設定] ユーザ定義データ設定.
Definition: TnbClipboard.h:225
static UINT RegisterUserDataType(LPCTSTR lpszDataTypeName)
[登録] ユーザ定義データ型登録.
Definition: TnbClipboard.h:137
CStr GetString(void) const
[取得] 文字列取得.
Definition: TnbClipboard.h:147
CClipboard(HWND hWnd=NULL, DWORD dwOpenTimeout=500, bool boHasErrBox=false)
コンストラクタ
Definition: TnbClipboard.h:60
bool GetUserData(CWorkMem &_data, UINT dataTypeId) const
[取得] ユーザ定義データ取得.
Definition: TnbClipboard.h:196
static CStr GetFormatName(UINT uFormat)
[取得] データ型名取得
Definition: TnbClipboard.h:119
void SetHandle(HWND hWnd)
[登録] ウィンドウハンドル設定
Definition: TnbClipboard.h:69
bool SetString(LPCTSTR lpszText, bool isAdd=false)
[設定] 文字列登録.
Definition: TnbClipboard.h:174
bool Empty(void)
[操作] 空化.
Definition: TnbClipboard.h:80
HBITMAP GetBitmap(void) const
[取得] ビットマップ取得.
Definition: TnbClipboard.h:245
[ETC] コピー不可能スーパークラス.
Definition: TnbDef.h:599
Double Null Terminate(DNT)型文字列管理
Definition: TnbDntStr.h:61
void Set(LPCTSTR lpszStr)
[設定] 代入
Definition: TnbDntStr.h:141
size_t GetSize(void) const
[取得] DNT型文字列数種特
Definition: TnbDntStr.h:213
マップ型情報管理テンプレート
Definition: TnbMap.h:66
virtual bool RemoveAll(void)
[削除] すべてのキーと値を削除
Definition: TnbMap.h:434
void ReleaseBuffer(void)
[操作] 割り当てたバッファを開放.
Definition: TnbStr.h:954
size_t GetLength(void) const
[取得] 文字列長
Definition: TnbStr.h:518
void Empty(void)
[削除] 空化
Definition: TnbStr.h:197
TYP * GetBuffer(size_t iLength=0)
[操作] 書き込みバッファ要求.
Definition: TnbStr.h:914
virtual size_t GetSize(void) const
[取得] サイズ取得
Definition: TnbVector.h:368
TYP * GetBuffer(size_t size=0)
[操作] データアドレス取得
Definition: TnbVector.h:745
void ReleaseBuffer(void)
[操作] データの管理を元に戻す.
Definition: TnbVector.h:805
virtual bool RemoveAll(void)
[削除] 空化
Definition: TnbVector.h:565
virtual const TYP * ReferBuffer(void) const
[取得] データアドレス取得
Definition: TnbVector.h:664
virtual INDEX Add(const TYP &t)
[追加] 要素一つ追加.
Definition: TnbVector.h:383
virtual size_t SetElements(size_t size, const TYP *P=NULL)
[設定] 複数要素設定.
Definition: TnbVector.h:526
void Reset(size_t l, const TYP *P)
[設定] 再設定
Definition: TnbDef.h:690
size_t GetLen(LPCSTR lpsz)
[計算] 文字列長計算(ASCII/SJIS用)
Definition: TnbStrLib.h:44
DWORD ToDword(LPCSTR lpsz, int iBase=10)
[変換] INT変換(ASCII/SJIS用).
Definition: TnbStrLib.h:395
int ToInt(LPCSTR lpsz, int iBase=10)
[変換] INT変換(ASCII/SJIS用).
Definition: TnbStrLib.h:367
TNB Library
Definition: TnbDoxyTitle.txt:2
void MemCopy(T *_pDst, const void *pSrc, size_t len)
[複製] メモリコピー
Definition: TnbDef.h:376