[Windows Programming] ドキュメントの内容をクリップボードへ (MFC版)

SyntaxHighlighter を使って C++ のソースコードに色を付けてみる実験。

// MFC版
// ドキュメントの内容を:
// ・クリップボードへメタファイルと独自形式でコピー
// ・クリップボードから独自形式でペースト
// ※ MyDocument::Serialize と MyView::OnDraw でのドキュメントの描画を実装しておくこと
// MyView.h
class MyView : public CView
{
DECLARE_DYNCREATE(MyView)
DECLARE_MESSAGE_MAP()
HGLOBAL globalMemoryHandle;
protected:
MyView() : globalMemoryHandle(NULL)
{}
MyDocument* GetDocument() const
{ return reinterpret_cast<MyDocument*>(m_pDocument); }
virtual void OnDraw(CDC* pDC)
{
if (GetDocument() != NULL)
/* ドキュメントの描画 */ ;
}
afx_msg void OnEditCopy()
{
if (GetDocument() == NULL)
return;
// ドキュメントが空なら何もしない
// 例.
// if (GetDocument()->IsEmpty())
//     return;
// 拡張メタファイルの作成
CClientDC   clientDC(this);
CMetaFileDC metaDC;
metaDC.CreateEnhanced(&clientDC, NULL, NULL, NULL);
OnDraw(&metaDC);
const HENHMETAFILE enhancedMetaFileHandle = metaDC.CloseEnhanced();
// メモリへのシリアライズ
CSharedFile sharedFile;
{
CArchive ar(&sharedFile, CArchive::store);
GetDocument()->Serialize(ar);
}
globalMemoryHandle = sharedFile.Detach();
// クリップボードへの書き込み
if (OpenClipboard()) {
::EmptyClipboard();
::SetClipboardData(CF_ENHMETAFILE, CopyEnhMetaFile(enhancedMetaFileHandle, NULL));
::SetClipboardData(CF_PRIVATEFIRST, globalMemoryHandle);
::CloseClipboard();
}
::DeleteEnhMetaFile(enhancedMetaFileHandle);
}
afx_msg void OnEditPaste()
{
if (GetDocument() == NULL)
return;
if (OpenClipboard()) {
const HANDLE clipboardData = ::GetClipboardData(CF_PRIVATEFIRST);
if (clipboardData != NULL) {
CSharedFile sharedFile;
sharedFile.SetHandle(clipboardData);
{
CArchive ar(&sharedFile, CArchive::load);
GetDocument()->Serialize(ar);
}
sharedFile.Detach();
GetDocument()->SetModifiedFlag();
Invalidate();
}
::CloseClipboard();
}
}
afx_msg void OnDestroyClipboard()
{
CView::OnDestroyClipboard();
// WM_DESTROYCLIPBOARD 時に CF_PRIVATEFIRST で確保したメモリを開放する必要がある
if (globalMemoryHandle != NULL) {
::GlobalUnlock(globalMemoryHandle);
::GlobalFree  (globalMemoryHandle);
globalMemoryHandle = NULL;
}
}
};
// MyView.cpp
#include "MyView.h"
IMPLEMENT_DYNCREATE(MyView, CView)
BEGIN_MESSAGE_MAP(MyView, CView)
ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
ON_WM_DESTROYCLIPBOARD()
END_MESSAGE_MAP()