Visual Studioでコピーした文字列を、文字色を保持してExcelに貼り付けるアドインを作ってみた
Visual Studioでコピーしたソースコードを、文字色を保持してExcelに貼り付けたい場面があると思います。ですが、標準の機能ではできません。テキストだけ貼り付けられてしまいます。ということでExcelアドインを作りました。
ネットで調べると「Productivity Power Tools extension」というVisual Studio拡張機能の「HTMLコピー」を使えばいいらしいのですが、Express Editionでは使えないので今回は作ることにしました。
さらに、Visual Studio 2010 Expressあたりで、コピーした文字列をWordに貼り付けると文字化けするという不具合があったので、それも修正した状態で貼り付けるようになってます。
なお、セルではなくオートシェイプに貼り付けた場合は文字色が保持されるようです。
インストール方法
- 下記のリンクから「RichTextPaste_***.zip」をダウンロードします。
- ダウンロードしたファイルを解凍します。
- 全てのファイルに対して「ブロックの解除」を行います。
やり方は、ファイルを右クリックしてプロパティを開き、「ブロックの解除」をクリックして「OK」をクリックします。面倒ですが1ファイルずつ行ってください。まとめて行うソフトもあるようなので、それを使っても大丈夫です。 - 「setup.exe」を実行します。
動作原理
Visual Studioでコピーすると、クリップボードに複数の形式でコピーされます。その形式に「Rich Text」はありますが「HTML」はありません。Excelは、貼り付け時に「HTML」形式のテキストがあれば文字色を保持して貼り付けますが、その形式が無い場合はテキストのみ貼り付けます。(動作を見てみての推測。)
ということで、アドインの動作は、Excelがアクティブになった時にクリップボードをチェックして、「Rich Text」形式があって「HTML」形式が無い場合、「Rich Text」からコンバードして生成した「HTML」形式の情報をクリップボードに追加します。
動作メモ
Excelのアクティブの検知
Excelのアクティブの検知は、以下のようにSetWinEventHookで行っています。
この関数だと、C#でもフックができるようです。
public class ExcelWindow : IDisposable { delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime); [DllImport("user32.dll", SetLastError = true)] static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags); [DllImport("user32.dll")] static extern bool UnhookWinEvent(IntPtr hWinEventHook); private Excel.Application m_excel; private WinEventDelegate m_eventProc; private IntPtr m_WinEventHook; public event EventHandler Activate; public ExcelWindow(Excel.Application excel) { const uint EVENT_SYSTEM_FOREGROUND = 3; m_excel = excel; m_eventProc = new WinEventDelegate(winEventProc); // メンバ変数にコピーしないとガベコレに解放されてエラー m_WinEventHook = SetWinEventHook((uint) EVENT_SYSTEM_FOREGROUND, (uint) EVENT_SYSTEM_FOREGROUND, (IntPtr) 0, m_eventProc, (uint) 0, (uint) 0, (uint) 0); } void winEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) { if (hwnd.ToInt32() == m_excel.Hwnd) { if (Activate != null) { Activate(this, new EventArgs()); } } } #region IDisposable public void Dispose() { m_excel = null; UnhookWinEvent(m_WinEventHook); } #endregion }
Rich Text→HTMLの変換
RTF Converter
http://www.codeproject.com/Articles/27431/Writing-Your-Own-RTF-Converter
C#でクリップボードにデータを追加 (新規セットではなく追加)
クリップボードにHTMLデータを貼り付ける
http://azumaya.s101.xrea.com/wiki/index.php?%B3%D0%BD%F1%2FC%A2%F4%2F%A5%AF%A5%EA%A5%C3%A5%D7%A5%DC%A1%BC%A5%C9%A4%CBHTML%A5%C7%A1%BC%A5%BF%A4%F2%C5%BD%A4%EA%C9%D5%A4%B1%A4%EB
HTMLテキストをクリップボード用テキストに変換
Copying an HTML-fragment to the Clipboard
http://blog.tcx.be/2005/08/copying-html-fragment-to-clipboard.html
Visual Studio 2010の不具合での文字化け問題
Visual Studio 2010 からソースコードを PowerPoint にコピーすると文字化けする
http://ufcpp.wordpress.com/2010/05/11/
Click Once用の証明書の作成
makecert -r -pe -n "CN=mantarou" -sv RichTextPaste.pvk RichTextPaste.cer pvk2pfx -pvk RichTextPaste.pvk -spc RichTextPaste.cer -pfx RichTextPaste.pfx -po "*********"
ClickOnceのマニフェストに署名するためのテスト用の証明書を作成する
http://quickprogram.blogspot.jp/2010/03/vc-clickonce.html
クリップボードの状態の確認
デバッグでクリップボードの中身を見たくなったので使いました。
Free Clipboard Viewer
http://www.freeclipboardviewer.com/