「Windowsのクリップボードを用いた選択コンテンツの取得」の版間の差分
Notion-MW |
Notion-MW |
||
47行目: | 47行目: | ||
コード例は以下である。 | コード例は以下である。 | ||
< | <syntaxhighlight lang="c#">class CBSample | ||
{ | { | ||
static string[] unsupported_formats = new string[] { | static string[] unsupported_formats = new string[] {"Object Descriptor"}; | ||
[STAThread] | [STAThread] | ||
60行目: | 60行目: | ||
System.Windows.Forms.IDataObject cb1 = new DataObject(); | System.Windows.Forms.IDataObject cb1 = new DataObject(); | ||
System.Windows.Forms.IDataObject cb2 = new DataObject(); | System.Windows.Forms.IDataObject cb2 = new DataObject(); | ||
MessageBox.Show( | MessageBox.Show("This app will save clipboard two times and then restore two times."); | ||
this.backupCBto(ref cb1); | this.backupCBto(ref cb1); | ||
MessageBox.Show( | MessageBox.Show("clipboard 1 is saved."); | ||
this.backupCBto(ref cb2); | this.backupCBto(ref cb2); | ||
MessageBox.Show( | MessageBox.Show("clipboard 2 is saved."); | ||
this.restoreCBfrom(ref cb1); | this.restoreCBfrom(ref cb1); | ||
MessageBox.Show( | MessageBox.Show("clipboard 1 is restored."); | ||
this.restoreCBfrom(ref cb2); | this.restoreCBfrom(ref cb2); | ||
MessageBox.Show( | MessageBox.Show("clipboard 2 is restored."); | ||
} | } | ||
private void backupCBto(ref System.Windows.Forms.IDataObject cb) | private void backupCBto(ref System.Windows.Forms.IDataObject cb) | ||
77行目: | 77行目: | ||
foreach (string fmt in cb_raw.GetFormats(false)) | foreach (string fmt in cb_raw.GetFormats(false)) | ||
{ | { | ||
if (!Array.Exists(unsupported_formats, s = | if (!Array.Exists(unsupported_formats, s => s == fmt)) { Console.WriteLine(fmt); cb.SetData(fmt, cb_raw.GetData(fmt)); } | ||
} | } | ||
} | } | ||
85行目: | 85行目: | ||
Clipboard.SetDataObject(cb, true); | Clipboard.SetDataObject(cb, true); | ||
} | } | ||
}</ | }</syntaxhighlight> | ||
このサンプルでは、クリップボードを2回にわたって別々の変数に格納し、それを再び復元することができる。 | このサンプルでは、クリップボードを2回にわたって別々の変数に格納し、それを再び復元することができる。 | ||
167行目: | 167行目: | ||
に従い、コンストラクタの冒頭に | に従い、コンストラクタの冒頭に | ||
< | <syntaxhighlight lang="visual basic">this.Visible = false; | ||
this.WindowState = FormWindowState.Minimized; | this.WindowState = FormWindowState.Minimized; | ||
this.ShowInTaskbar = false;</ | this.ShowInTaskbar = false;</syntaxhighlight> | ||
を入れると、一見消えているように見えるが、Alt+Tabなどをすると表示されているのが見えてしまうので、自分のHWNDを対象にSW_HIDEを指定してShowWindowをすると完全に消える。 | を入れると、一見消えているように見えるが、Alt+Tabなどをすると表示されているのが見えてしまうので、自分のHWNDを対象にSW_HIDEを指定してShowWindowをすると完全に消える。 | ||
< | <syntaxhighlight lang="visual basic">case WM_SHOWWINDOW: | ||
this.CenterToScreen(); | this.CenterToScreen(); | ||
if ((int)message.WParam == 1) | if ((int)message.WParam == 1) | ||
178行目: | 178行目: | ||
if (!window_init_done) | if (!window_init_done) | ||
{//being shown | {//being shown | ||
Console.WriteLine( | Console.WriteLine("Hiding"); | ||
window_init_done = true; | window_init_done = true; | ||
ShowWindow(this.Handle, SW_HIDE); | ShowWindow(this.Handle, SW_HIDE); | ||
} | } | ||
} | } | ||
break;</ | break;</syntaxhighlight> | ||
==== conhostでの実行 ==== | ==== conhostでの実行 ==== | ||
215行目: | 215行目: | ||
C#の<code>NamedPipeClientStream</code>ではパイプの名前を<code>"."</code> <code>"test"</code>とコンピュータ名/パイプ名で分けているのに対して(AutoHotkeyで呼び出されている)Win32 APIの関数<code>CreateNamedPipe</code>では<code>"\\.\</code><strong><code>pipe\</code></strong><code>test"</code>と書く必要があるようなので注意。 | C#の<code>NamedPipeClientStream</code>ではパイプの名前を<code>"."</code> <code>"test"</code>とコンピュータ名/パイプ名で分けているのに対して(AutoHotkeyで呼び出されている)Win32 APIの関数<code>CreateNamedPipe</code>では<code>"\\.\</code><strong><code>pipe\</code></strong><code>test"</code>と書く必要があるようなので注意。 | ||
< | <syntaxhighlight lang="visual basic">using System; | ||
using System.IO.Pipes; | using System.IO.Pipes; | ||
226行目: | 226行目: | ||
public static void Main(string[] args) | public static void Main(string[] args) | ||
{ | { | ||
NamedPipeClientStream npcs = new NamedPipeClientStream( | NamedPipeClientStream npcs = new NamedPipeClientStream(".", "test", PipeDirection.InOut); | ||
npcs.Connect(); | npcs.Connect(); | ||
byte[] dat = System.Text.Encoding.Unicode.GetBytes( | byte[] dat = System.Text.Encoding.Unicode.GetBytes("XYZ"); | ||
byte[] buf = new byte[6]; | byte[] buf = new byte[6]; | ||
if (npcs.IsConnected == true) { | if (npcs.IsConnected == true) { | ||
240行目: | 240行目: | ||
} | } | ||
} | } | ||
}</ | }</syntaxhighlight> | ||
< | <syntaxhighlight lang="visual basic">ptr := A_PtrSize ? "Ptr" : "UInt" | ||
char_size := A_IsUnicode ? 2 : 1 | char_size := A_IsUnicode ? 2 : 1 | ||
pipe := DllCall( | pipe := DllCall("CreateNamedPipe", "str", "\\.\pipe\test", "uint", 3, "uint", 4, "uint", 10, "uint", 100, "uint", 100, "uint", 0, ptr, 0, ptr) | ||
DllCall( | DllCall("ConnectNamedPipe", ptr, pipe, ptr, 0) | ||
MsgBox ConnectNamedPipe(0 is OK): %ErrorLevel%/%A_LastError% | MsgBox ConnectNamedPipe(0 is OK): %ErrorLevel%/%A_LastError% | ||
VarSetCapacity(Buffer, char_size * 3) | VarSetCapacity(Buffer, char_size * 3) | ||
DllCall( | DllCall("WriteFile", ptr, pipe, "str", "345", "uint", char_size * 3, "uint*", 0, ptr, 0) | ||
DllCall( | DllCall("ReadFile", "UInt", pipe, "Str", Buffer, "UInt", char_size * 3, "UIntP", BytesRead, "UInt", 0) | ||
MsgBox, 64, %BytesRead%, %Buffer%</ | MsgBox, 64, %BytesRead%, %Buffer%</syntaxhighlight> | ||
なお、これは一応(Windows11で)動いた例というだけで、使用されている関数の細かいパラメータやエラーハンドリング、Closeの仕方、Unicode/非Unicodeや32bit/64bitの扱い、バイト数の計算の仕方など、不完全な部分がいくつもあると思われる。 | なお、これは一応(Windows11で)動いた例というだけで、使用されている関数の細かいパラメータやエラーハンドリング、Closeの仕方、Unicode/非Unicodeや32bit/64bitの扱い、バイト数の計算の仕方など、不完全な部分がいくつもあると思われる。 | ||