• R/O
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

テンキー押下でWin32アプリのウインドウをキャプチャする。ただしUWPアプリはキャプチャできない。


Commit MetaInfo

Revision103 (tree)
Time2018-03-07 00:39:07
Authorhor931101jp

Log Message

(empty log message)

Change Summary

Incremental Difference

--- tags/TenKeyCapture_00.20-180306/ClassMyCommon.cs (nonexistent)
+++ tags/TenKeyCapture_00.20-180306/ClassMyCommon.cs (revision 103)
@@ -0,0 +1,172 @@
1+/***********************************************************//*!
2+ * @brief 共通部品
3+ * @author S.Hori
4+ * @date 2018-02-10
5+ * @details
6+ **************************************************************/
7+using System;
8+using System.Collections.Generic;
9+using System.Linq;
10+using System.Text;
11+using System.Threading.Tasks;
12+using System.Windows;
13+using System.Windows.Forms;
14+
15+namespace TenKeyCapture
16+{
17+ /***********************************************************//*!
18+ * @brief 共通部品クラス
19+ * @details よく使う処理とかオブジェクトを定義
20+ **************************************************************/
21+ class ClassMyCommon
22+ {
23+ //! プログラムのタイトル
24+ public const string TITLE = "TenKeyCapture";
25+
26+ //! プログラムのバージョン
27+ public const string VERSION = "00.20-180306";
28+
29+ //! プログラム開始時の表示メッセージ
30+ public const string OPENING_MSG
31+ = "Programmed by S.Hori\r\n"
32+ + "\r\n"
33+ + "下記のWEBサイトから最新版を入手できます。\r\n"
34+ + "https://osdn.net/users/hor931101jp/pf/02 \r\n"
35+ + "下記のSVNリポジトリからソースコードをチェックアウトできます。\r\n"
36+ + "svn://svn.pf.osdn.net/h/ho/hor931101jp/02/tags \r\n";
37+
38+ //! メインフォームのインスタンス
39+ public static Form frmMain;
40+
41+ //!設定用インスタンス宣言と生成
42+ public static ClassConfig Config = new ClassConfig();
43+
44+ //! ログの管理インスタンス
45+ public static ClassLog Log;
46+
47+ //! CSVの管理インスタンス
48+ public static ClassCSV CSV = new ClassCSV();
49+
50+ //! 現在時刻格納変数
51+ public static DateTime NowTime = DateTime.Now;
52+
53+ /***********************************************************//*!
54+ * @brief 待機処理
55+ * @date 2018-02-10
56+ * @param[in] WaitTime 待ち時間[ms]
57+ * @details Application.DoEventsとThread.Sleepをしながら待機
58+ **************************************************************/
59+ static public void WaitTickCount(Int32 WaitTime)
60+ {
61+ Int64 StartTickCount = Environment.TickCount;
62+ Int64 NowTickCount;
63+ do
64+ {
65+ Application.DoEvents();
66+ System.Threading.Thread.Sleep(1);
67+ NowTickCount = Environment.TickCount;
68+ }
69+ while ((NowTickCount - StartTickCount) < WaitTime);
70+ }
71+
72+ [System.Runtime.InteropServices.DllImport("user32.dll")]
73+ static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
74+ [System.Runtime.InteropServices.DllImport("user32.dll")]
75+ static extern bool DrawMenuBar(IntPtr hWnd);
76+ [System.Runtime.InteropServices.DllImport("user32.dll")]
77+ static extern bool RemoveMenu(IntPtr hMenu, uint uPosition, uint uFlags);
78+
79+ /***********************************************************//*!
80+ * @brief フォームの右上ボタンと左上メニューのカスタマイズ
81+ * @date 2018-02-10
82+ * @param[in] f 対象とするフォーム
83+ * @details フォーム右上ボタンのうち[x]ボタンを無効化する。
84+ * 左上メニューの[閉じる]を消去
85+ **************************************************************/
86+ public static void FormControlBoxCustomize(Form f)
87+ {
88+ //const uint SC_SIZE = 0xF000; //システムメニューの「サイズ変更」
89+ //const uint SC_MOVE = 0xF010; //システムメニューの「移動」
90+ //const uint SC_MINIMIZE = 0xF020; //システムメニューの「最小化」
91+ //const uint SC_MAXIMIZE = 0xF030; //システムメニューの「最大化」
92+ const uint SC_CLOSE = 0xF060; //システムメニューの「閉じる」
93+ //const uint SC_RESTORE = 0xF120; //システムメニューの「元のサイズに戻す」
94+ const uint MF_BYCOMMAND = 0x0; //メニュー項目指定
95+ const uint MF_BYPOSITION = 0x400; //ポジション指定
96+ //const uint MF_ENABLED = 0x0; //有効化
97+ //const uint MF_GRAYED = 0x1; //無効化
98+ //const uint MF_DISABLED = 0x2; //半無効化(見かけ上有効)
99+ bool DUMMY;
100+
101+ //「区切り線」の削除
102+ DUMMY = RemoveMenu(GetSystemMenu(f.Handle, false), 5, MF_BYPOSITION);
103+ //「閉じる」の削除 + xボタンの無効化
104+ DUMMY = RemoveMenu(GetSystemMenu(f.Handle, false), SC_CLOSE, MF_BYCOMMAND);
105+ //描画(変更を反映)
106+ DUMMY = DrawMenuBar(f.Handle);
107+ }
108+
109+ /***********************************************************//*!
110+ * @brief 自身の exe ファイルの存在するパスを返す
111+ * @date 2018-02-10
112+ * @details パスは string で最後に '\' 付き
113+ **************************************************************/
114+ public static string AppPath()
115+ {
116+ return System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\";
117+ }
118+
119+ /***********************************************************//*!
120+ * @brief 文字列を渡して先頭から指定した長さだけの文字列を切り出して返す
121+ * @date 2018-02-10
122+ * @param[in] str 文字列
123+ * @param[in] len 長さ
124+ * @return 切り出した文字列
125+ * @details BASICに昔からある Left$ 関数
126+ **************************************************************/
127+ public static string Left(string str, int len)
128+ {
129+ if (len < 0)
130+ {
131+ throw new ArgumentException("引数'len'は0以上でなければなりません。");
132+ }
133+ if (str == null)
134+ {
135+ return "";
136+ }
137+ if (str.Length <= len)
138+ {
139+ return str;
140+ }
141+ return str.Substring(0, len);
142+ }
143+
144+ /***********************************************************//*!
145+ * @brief 文字列の末尾から指定した長さの文字列を取得する
146+ * @date 2018-02-10
147+ * @param[in] str 文字列
148+ * @param[in] len 長さ
149+ * @return 切り出した文字列
150+ * @details BASICに昔からある Right$ 関数
151+ **************************************************************/
152+ public static string Right(string str, int len)
153+ {
154+ if (len < 0)
155+ {
156+ throw new ArgumentException("引数'len'は0以上でなければなりません。");
157+ }
158+ if (str == null)
159+ {
160+ return "";
161+ }
162+ if (str.Length <= len)
163+ {
164+ return str;
165+ }
166+ return str.Substring(str.Length - len, len);
167+ }
168+
169+ //! キーコードを格納するキュー
170+ public static Queue<uint> wkQueue = new Queue<uint>();
171+ }
172+}
--- tags/TenKeyCapture_00.20-180306/ClassLog.cs (nonexistent)
+++ tags/TenKeyCapture_00.20-180306/ClassLog.cs (revision 103)
@@ -0,0 +1,252 @@
1+/***********************************************************//*!
2+ * @brief ログ処理
3+ * @author S.Hori
4+ * @date
5+ * 2018-02-10 初版<br>
6+ * @details
7+ **************************************************************/
8+using System;
9+using System.Collections.Generic;
10+using System.Linq;
11+using System.Text;
12+using System.Threading.Tasks;
13+using System.Windows.Forms;
14+using System.IO;
15+using static TenKeyCapture.ClassMyCommon;
16+
17+namespace TenKeyCapture
18+{
19+
20+ /***********************************************************//*!
21+ * @brief ログクラス
22+ * @details ログを管理する
23+ **************************************************************/
24+ class ClassLog
25+ {
26+ //! ログを保存するフルパス付ファイル名
27+ private string LogFileName;
28+
29+ //! ファイル保存用のログ文字列を確保する
30+ private string _ShadowBuf;
31+
32+ //! ログ表示用テキストボックス
33+ private TextBox _LogTextBox;
34+
35+ /***********************************************************//*!
36+ * @brief コンストラクタ
37+ * @date 2018-02-10
38+ * @param[in] LogTextBox ログ表示用のテキストボックス
39+ * @details
40+ **************************************************************/
41+ public ClassLog(TextBox LogTextBox)
42+ {
43+ _LogTextBox = LogTextBox;
44+ _LogTextBox.Text = "";
45+ _ShadowBuf = "";
46+ LogFileName = ClassMyCommon.AppPath() + ClassMyCommon.TITLE
47+ + "Log" + System.DateTime.Now.ToString("yyMMdd") + ".txt";
48+ }
49+
50+ /***********************************************************//*!
51+ * @brief 他のスレッドからコールする為のデリゲート
52+ **************************************************************/
53+ delegate void Add_Callback(string stradd);
54+
55+ /***********************************************************//*!
56+ * @brief ログに文字列を追加する
57+ * @date 2018-02-10
58+ * @param[in] stradd ログへ追加する文字列
59+ * @details ログの表示は更新スクロールされない
60+ **************************************************************/
61+ public void Add(string stradd)
62+ {
63+ if (stradd == "")
64+ {
65+ //! 文字列がカラなら即終了
66+ return;
67+ }
68+
69+ if (_LogTextBox.InvokeRequired)
70+ {
71+ //! 別スレッドから呼び出された場合デリゲートからコールバックさせる
72+ _LogTextBox.Invoke(new Add_Callback(Add), stradd);
73+ return;
74+ }
75+
76+ //! 表示されている古いログは削除する
77+ DeleteOld();
78+
79+ // タイムスタンプ文字列を生成
80+ string TimeStamp = System.DateTime.Now.ToString("MM/dd HH:mm:ss : ");
81+ // ログ追加文字列の先頭にタイムスタンプを追加
82+ stradd = TimeStamp + stradd;
83+
84+ // ログ追加文字列の最後尾に "\r\n" があった場合は、いったん削除する
85+ if (stradd.Substring(stradd.Length - "\r\n".Length, "\r\n".Length) == "\r\n")
86+ {
87+ stradd = stradd.Substring(0, stradd.Length - "\r\n".Length);
88+ }
89+
90+ // ログ追加文字列の中に "\r\n" があった場合は、"\r\n+タイムスタンプ" に置換する
91+ stradd = stradd.Replace("\r\n", "\r\n" + TimeStamp);
92+
93+ // ログ追加文字列の最後尾に "\r\n" を追加
94+ stradd += "\r\n";
95+
96+ // 加工したログ追加文字列を保存用文字列とテキストボックスへ追加
97+ _LogTextBox.Text += stradd;
98+ _ShadowBuf += stradd;
99+
100+ }
101+
102+ /***********************************************************//*!
103+ * @brief 他のスレッドからコールする為のデリゲート
104+ **************************************************************/
105+ delegate void Put_Callback(string stradd);
106+
107+ /***********************************************************//*!
108+ * @brief ログに文字列を追加しログ表示を最下行へ強制スクロールする
109+ * @date 2018-02-10
110+ * @param[in] stradd ログへ追加する文字列
111+ * @details
112+ **************************************************************/
113+ public void Put(string stradd)
114+ {
115+ if (_LogTextBox.InvokeRequired)
116+ {
117+ //! 別スレッドから呼び出された場合デリゲートからコールバックさせる
118+ _LogTextBox.Invoke(new Put_Callback(Put), stradd);
119+ return;
120+ }
121+
122+ // ログ追加
123+ Add(stradd);
124+
125+ // ログ表示を最下行へスクロールする。
126+ _LogTextBox.SelectionStart = _LogTextBox.Text.Length;
127+ _LogTextBox.ScrollToCaret();
128+
129+ }
130+
131+ /***********************************************************//*!
132+ * @brief ログにデバッグ用文字列を追加
133+ * @date 2018-02-10
134+ * @param[in] stradd ログへ追加する文字列
135+ * @details
136+ **************************************************************/
137+ public void DebugPut(string stradd)
138+ {
139+#if false
140+ Put(stradd);
141+#endif
142+ }
143+
144+ /***********************************************************//*!
145+ * @brief ログをファイルに保存
146+ * @date 2018-02-10
147+ * @details
148+ **************************************************************/
149+ public void Save()
150+ {
151+ using (StreamWriter sw = new StreamWriter(
152+ LogFileName,
153+ true,
154+ Encoding.GetEncoding("shift-jis")))
155+ {
156+ // ファイルへの書き込み
157+ sw.Write(_ShadowBuf);
158+ }
159+ }
160+
161+ /***********************************************************//*!
162+ * @brief ログ表示部から古いログを削除
163+ * @date 2018-02-10
164+ * @details 削除されるのは表示部のみ。保存用文字列からは削除しない。
165+ **************************************************************/
166+ private void DeleteOld()
167+ {
168+ //! ログ表示量が MaxLength-1024 より大きくなったら破棄する
169+ if (_LogTextBox.Text.Length > (_LogTextBox.MaxLength - 1024))
170+ {
171+ _LogTextBox.Text = _LogTextBox.Text.Substring(_LogTextBox.MaxLength / 2);
172+ }
173+ }
174+
175+ /***********************************************************//*!
176+ * @brief ログ表示部からログをすべて削除
177+ * @date 2018-02-10
178+ * @details クリアされるのはログ表示のみ。ログ保存用文字列からは削除しない。
179+ **************************************************************/
180+ public void Clear()
181+ {
182+ _LogTextBox.Text = "";
183+ }
184+ }
185+
186+ /***********************************************************//*!
187+ * @brief CSVクラス
188+ * @date 2018-02-10
189+ * @details CSVを管理する
190+ **************************************************************/
191+ class ClassCSV
192+ {
193+ //! CSVファイル保存用の文字列を確保する
194+ private string _ShadowBuf;
195+
196+ /***********************************************************//*!
197+ * @brief CSVに保存する文字列を一時的に文字列に保存する。
198+ * @date 2018-02-10
199+ * @param[in] Tcommand テンキーに設定された文字列
200+ * @details
201+ **************************************************************/
202+ public void Add(string stradd)
203+ {
204+ string straddCSV;
205+
206+ if (stradd.IndexOf("[capture]") >= 0)
207+ {
208+ //! テンキーがキャプチャ機能キーだった場合は改行してタイムスタンプを追加して[capture]文字列削除して保存
209+ straddCSV = "\r\n" + NowTime.ToString("HH:mm:ss,") + stradd.Replace("[capture]", "");
210+ }
211+ else
212+ {
213+ //! テンキーがキャプチャ機能キーでなかった場合はそのまま保存
214+ straddCSV = stradd;
215+ }
216+ _ShadowBuf += straddCSV;
217+ //Log.Put("CSVadd() " + straddCSV);
218+ }
219+
220+ /***********************************************************//*!
221+ * @brief CSVに保存
222+ * @date 2018-02-10
223+ **************************************************************/
224+ public void Save()
225+ {
226+ if (_ShadowBuf.Length == 0)
227+ {
228+ return;
229+ }
230+
231+ try
232+ {
233+ // 追記モードで書き込み
234+ using (StreamWriter sw = new StreamWriter(
235+ AppPath() + NowTime.ToString("yyMMdd") + "\\" + NowTime.ToString("yyMMdd") + ".csv",
236+ true,
237+ Encoding.GetEncoding("shift_jis")
238+ )
239+ )
240+ {
241+ sw.Write(_ShadowBuf);
242+ }
243+ _ShadowBuf = "";
244+ Log.Put("CSVSave()");
245+ }
246+ catch (Exception e)
247+ {
248+ Log.Put("CSVSave():Exception" + e.Message);
249+ }
250+ }
251+ }
252+}
--- tags/TenKeyCapture_00.20-180306/FormMain.cs (nonexistent)
+++ tags/TenKeyCapture_00.20-180306/FormMain.cs (revision 103)
@@ -0,0 +1,557 @@
1+/***********************************************************//*!
2+ * @brief メインウインドウ処理
3+ * @author S.Hori
4+ * @date 2018-02-10
5+ * @details
6+ **************************************************************/
7+using System;
8+using System.Collections.Generic;
9+using System.ComponentModel;
10+using System.Data;
11+using System.Drawing;
12+using System.Linq;
13+using System.Text;
14+using System.Threading.Tasks;
15+using System.Windows.Forms;
16+using System.Runtime.InteropServices;
17+using static TenKeyCapture.ClassMyCommon;
18+using static TenKeyCapture.ClassConfig;
19+
20+namespace TenKeyCapture
21+{
22+ /***********************************************************//*!
23+ * @brief メインウインドウのフォーム
24+ * @author S.Hori
25+ * @date 2018-02-10
26+ * @details
27+ **************************************************************/
28+ public partial class FormMain : Form
29+ {
30+ [DllImport("user32.dll")]
31+ static extern IntPtr FindWindowEx(IntPtr hWnd, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
32+
33+ // EnumWindowsから呼び出されるコールバック関数WNDENUMPROCのデリゲート
34+ public delegate bool EnumWindowsDelegate(IntPtr hWnd, IntPtr lparam);
35+ [DllImport("user32.dll")]
36+ [return: MarshalAs(UnmanagedType.Bool)]
37+ public extern static bool EnumWindows(EnumWindowsDelegate lpEnumFunc, IntPtr lparam); //可視判定
38+
39+ [DllImport("user32")]
40+ private static extern bool IsWindowVisible(IntPtr hWnd);
41+
42+ [DllImport("user32", CharSet = CharSet.Auto)]
43+ private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
44+
45+ [DllImport("user32", CharSet = CharSet.Auto)]
46+ private static extern int GetWindow(IntPtr hWnd, UInt32 wCmd);
47+ //public const UInt32 GW_OWNER = 4;
48+
49+ [StructLayout(LayoutKind.Sequential)]
50+ private struct RECT
51+ {
52+ public int left;
53+ public int top;
54+ public int right;
55+ public int bottom;
56+ }
57+ [DllImport("user32.dll")]
58+ private static extern int GetWindowRect(IntPtr hwnd, ref RECT lpRect);
59+
60+ [DllImport("User32.dll")]
61+ private extern static bool PrintWindow(IntPtr hwnd, IntPtr hDC, uint nFlags);
62+
63+ //! キーボードフック処理インスタンス
64+ private KeyboardHooker KeyboardHooker1;
65+ //! テンキーが押された時の対応するコマンドを格納する変数
66+ private static string Tcommand;
67+
68+ //! キャプチャタスクスレッド
69+ public Task CaptureThread;
70+
71+ /***********************************************************//*!
72+ * @brief コンストラクタ
73+ * @author S.Hori
74+ * @date 2018-02-10
75+ * @details
76+ **************************************************************/
77+ public FormMain()
78+ {
79+ InitializeComponent();
80+ }
81+
82+ /***********************************************************//*!
83+ * @brief 終了時の処理
84+ * @author S.Hori
85+ * @date 2018-02-10
86+ * @param[in] sender 未使用。イベントを発生させたオブジェクト
87+ * @param[in] e 未使用。イベントのオプション
88+ * @details
89+ **************************************************************/
90+ private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
91+ {
92+ //! ウインドウポップアップ
93+ Visible = true;
94+ WindowState = FormWindowState.Normal;
95+ TopMost = true;
96+
97+ Log.Put("終了");
98+ //! ログを保存する
99+ Log.Save();
100+ }
101+
102+ /***********************************************************//*!
103+ * @brief フォームロード時の処理
104+ * @author S.Hori
105+ * @date 2018-02-10
106+ * @param[in] sender 未使用。イベントを発生させたオブジェクト
107+ * @param[in] e 未使用。イベントのオプション
108+ * @details
109+ **************************************************************/
110+ private void FormMain_Load(object sender, EventArgs e)
111+ {
112+ //多重起動チェック
113+ //Process.GetProcessesByName メソッド
114+ //指定したプロセス名を共有するリモートコンピュータ上の
115+ //すべてのプロセスリソースに関連付けます。
116+ string pn = System.Diagnostics.Process.GetCurrentProcess().ProcessName; //Process.ProcessName プロパティ(プロセスの名前を取得します)
117+ if (System.Diagnostics.Process.GetProcessesByName(pn).GetUpperBound(0) > 0)
118+ {
119+ //! 多重起動しているならばエラーメッセージ表示して終了。
120+ MessageBox.Show("すでに起動しています。", TITLE + " エラーメッセージ",
121+ MessageBoxButtons.OK,
122+ MessageBoxIcon.Error);
123+ Environment.Exit(0);
124+ }
125+
126+ frmMain = this;
127+ FormControlBoxCustomize(frmMain);
128+ frmMain.Text = TITLE + " " + VERSION;
129+ Log = new ClassLog(this.textBox1);
130+
131+ notifyIcon1.Text = TITLE + " " + VERSION;
132+ notifyIcon1.Visible = true;
133+
134+ button1.PerformClick();
135+ Log.Put("タスクトレイにアイコンを登録しました。");
136+
137+ //! iniファイルから設定を読み出す
138+ Config.Load();
139+
140+ Popup();
141+
142+ NowTime = DateTime.Now;
143+
144+ //! データフォルダ作成
145+ System.IO.Directory.CreateDirectory(AppPath() + NowTime.ToString("yyMMdd") + "\\");
146+
147+ //! ナムロックONにする
148+ SetNumLock(true);
149+
150+ //! キーボードフック処理インスタンス
151+ KeyboardHooker1 = new KeyboardHooker();
152+
153+ //! キャプチャタスク起動
154+ Task t = CaptureTask();
155+ Log.Put("キャプチャタスク起動しました。");
156+ Log.Save();
157+
158+ //button4.Click += new EventHandler(quitToolStripMenuItem_Click);
159+
160+ //! 起動時は最前面にもってくる
161+ Show();
162+ TopMost = true;
163+ WaitTickCount(100);
164+ TopMost = false;
165+ Log.Put("起動完了しました。");
166+ }
167+
168+ /***********************************************************//*!
169+ * @brief Aboutボタンを押された時の処理
170+ * @date 2018-02-10
171+ * @param[in] sender 未使用。イベントを発生させたオブジェクト
172+ * @param[in] e 未使用。イベントのオプション
173+ * @details オープニングメッセージをログに表示する
174+ **************************************************************/
175+ private void button1_Click(object sender, EventArgs e)
176+ {
177+ Log.Add("----------------------------------------------------------------\r\n");
178+ Log.Put(OPENING_MSG);
179+ Log.Put("----------------------------------------------------------------\r\n");
180+ }
181+
182+ /***********************************************************//*!
183+ * @brief Clear Log ボタンを押された時の処理
184+ * @date 2018-02-10
185+ * @param[in] sender 未使用。イベントを発生させたオブジェクト
186+ * @param[in] e 未使用。イベントのオプション
187+ * @details ログの表示をクリアする
188+ **************************************************************/
189+ private void button2_Click(object sender, EventArgs e)
190+ {
191+ Log.Clear();
192+ }
193+
194+ /***********************************************************//*!
195+ * @brief Data Folder ボタンを押された時の処理
196+ * @date 2018-02-10
197+ * @param[in] sender 未使用。イベントを発生させたオブジェクト
198+ * @param[in] e 未使用。イベントのオプション
199+ * @details
200+ **************************************************************/
201+ private void button3_Click(object sender, EventArgs e)
202+ {
203+ //! データフォルダを開く
204+ System.Diagnostics.Process.Start(AppPath() + NowTime.ToString("yyMMdd"));
205+ }
206+
207+ /***********************************************************//*!
208+ * @brief Quit ボタンを押された時の処理
209+ * @date 2018-02-10
210+ * @param[in] sender 未使用。イベントを発生させたオブジェクト
211+ * @param[in] e 未使用。イベントのオプション
212+ * @details プログラム終了
213+ **************************************************************/
214+ private void button4_Click(object sender, EventArgs e)
215+ {
216+ Close();
217+ }
218+
219+ /***********************************************************//*!
220+ * @brief メインウインドウの最小化時にウインドウを非表示にする
221+ * @date 2018-02-10
222+ * @param[in] sender 未使用。イベントを発生させたオブジェクト
223+ * @param[in] e 未使用。イベントのオプション
224+ * @details
225+ **************************************************************/
226+ private void FormMain_Resize(object sender, EventArgs e)
227+ {
228+ if (WindowState == FormWindowState.Minimized)
229+ {
230+ Visible = false;
231+ //トレイアイコンの表示テキストも初期化する
232+ //notifyIcon1.Text = TITLE + " " + VERSION;
233+ }
234+ }
235+
236+ /***********************************************************//*!
237+ * @brief メインウインドウをポップアップする
238+ * @date 2018-02-10
239+ * @details
240+ **************************************************************/
241+ private void Popup()
242+ {
243+ Visible = true;
244+ WindowState = FormWindowState.Normal;
245+ //! 短時間かならずトップに表示
246+ TopMost = true;
247+ WaitTickCount(100);
248+ TopMost = false;
249+ //トレイアイコンの状態を初期化する
250+ // notifyIcon1.Text = TITLE + " " + VERSION;
251+ //! 最新ログを表示
252+ Log.Put("");
253+ Log.Save();
254+ }
255+
256+ /***********************************************************//*!
257+ * @brief タスクトレイアイコンをダブルクリックされたらメインウインドウをポップアップする
258+ * @date 2018-02-10
259+ * @param[in] sender 未使用。イベントを発生させたオブジェクト
260+ * @param[in] e 未使用。イベントのオプション
261+ * @details 短時間かならずメインウインドウをトップに表示。
262+ **************************************************************/
263+ private void notifyIcon1_DoubleClick(object sender, EventArgs e)
264+ {
265+ Popup();
266+ }
267+
268+ /***********************************************************//*!
269+ * @brief タスクトレイアイコンメニュの TenKeyCaputer Open をクリックされたときの処理
270+ * @date 2018-02-10
271+ * @param[in] sender 未使用。イベントを発生させたオブジェクト
272+ * @param[in] e 未使用。イベントのオプション
273+ * @details 短時間かならずメインウインドウをトップに表示。
274+ **************************************************************/
275+ private void tenKeyCaptureOpenToolStripMenuItem_Click(object sender, EventArgs e)
276+ {
277+ Popup();
278+ }
279+
280+ /***********************************************************//*!
281+ * @brief タスクトレイアイコンメニュの TenKeyCaputer Open をクリックされたときの処理
282+ * @date 2018-02-10
283+ * @param[in] sender 未使用。イベントを発生させたオブジェクト
284+ * @param[in] e 未使用。イベントのオプション
285+ * @details
286+ **************************************************************/
287+ private void dataFolderToolStripMenuItem_Click(object sender, EventArgs e)
288+ {
289+ //! データフォルダを開く
290+ System.Diagnostics.Process.Start(AppPath() + NowTime.ToString("yyMMdd"));
291+ }
292+
293+ /***********************************************************//*!
294+ * @brief タスクトレイアイコンのメニューからQuitを選択された時の処理
295+ * @date 2018-02-10
296+ * @param[in] sender 未使用。イベントを発生させたオブジェクト
297+ * @param[in] e 未使用。イベントのオプション
298+ * @details 短時間かならずメインウインドウをトップに表示。
299+ **************************************************************/
300+ private void quitToolStripMenuItem_Click(object sender, EventArgs e)
301+ {
302+ Popup();
303+ Close();
304+ }
305+
306+ [DllImport("user32.dll")]
307+ static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);
308+ public const byte VK_NUMLOCK = 0x90;
309+ //public const uint KEYEVENTF_EXTENDEDKEY = 1;
310+ public const int KEYEVENTF_KEYUP = 0x2;
311+ /***********************************************************//*!
312+ * @brief ナムロック状態を変更する
313+ * @date 2018-02-10
314+ * @param[in] bOnOffFlag true=ナムロックON false=ナムロックオフ
315+ **************************************************************/
316+ private void SetNumLock(Boolean bOnOffFlag)
317+ {
318+ if (Control.IsKeyLocked(Keys.NumLock) != bOnOffFlag)
319+ {
320+ keybd_event(VK_NUMLOCK, 0x45, 0, 0);
321+ keybd_event(VK_NUMLOCK, 0x45, KEYEVENTF_KEYUP, 0);
322+ Log.Put("NumLockを" + bOnOffFlag.ToString() + "にしました。");
323+ }
324+ }
325+
326+ /***********************************************************//*!
327+ * @brief キャプチャタスク
328+ * @date 2018-02-10
329+ * @details 無限ループ処理
330+ **************************************************************/
331+ public async Task CaptureTask()
332+ {
333+ int TaskLoopCount = 0;
334+ while (true)
335+ {
336+ while (wkQueue.Count > 0)
337+ {
338+ uint KeyCode = wkQueue.Dequeue();
339+ NowTime = DateTime.Now;
340+ try
341+ {
342+ Log.Put("KeyCode = " + KeyCode);
343+ switch (KeyCode)
344+ {
345+ case 96:
346+ Tcommand = T0;
347+ break;
348+ case 97:
349+ Tcommand = T1;
350+ break;
351+ case 98:
352+ Tcommand = T2;
353+ break;
354+ case 99:
355+ Tcommand = T3;
356+ break;
357+ case 100:
358+ Tcommand = T4;
359+ break;
360+ case 101:
361+ Tcommand = T5;
362+ break;
363+ case 102:
364+ Tcommand = T6;
365+ break;
366+ case 103:
367+ Tcommand = T7;
368+ break;
369+ case 104:
370+ Tcommand = T8;
371+ break;
372+ case 105:
373+ Tcommand = T9;
374+ break;
375+ case 106:
376+ Tcommand = Tastah;
377+ break;
378+ case 107:
379+ Tcommand = Tplus;
380+ break;
381+ case 108:
382+ //なし
383+ break;
384+ case 109:
385+ Tcommand = Tminus;
386+ break;
387+ case 110:
388+ Tcommand = Tdot;
389+ break;
390+ case 111:
391+ Tcommand = Tslash;
392+ break;
393+ default:
394+ break;
395+ }
396+ if (Tcommand.IndexOf("[capture]") >= 0)
397+ {
398+ CaptureWindows();
399+ }
400+ Log.Put(Tcommand);
401+ CSV.Add(Tcommand);
402+ Console.Beep();
403+ await Task.Delay(1);
404+ TaskLoopCount = 0;
405+ }
406+ catch (Exception e)
407+ {
408+ Log.Put("CaptureTask():Exception" + e.Message);
409+ }
410+ }
411+
412+ await Task.Delay(100);
413+ SetNumLock(true);
414+ TaskLoopCount++;
415+ if (TaskLoopCount > 50)
416+ {
417+ //Log.Put("loop");
418+ TaskLoopCount = 0;
419+ Log.Save();
420+ CSV.Save();
421+ }
422+
423+ }
424+ }
425+
426+ /***********************************************************//*!
427+ * @brief ウインドウのキャプチャ処理
428+ * @date 2018-02-10
429+ **************************************************************/
430+ private void CaptureWindows()
431+ {
432+ //! 保存用のデータフォルダが存在なければ作成
433+ System.IO.Directory.CreateDirectory(AppPath() + NowTime.ToString("yyMMdd") + "\\");
434+ //! ウィンドウを列挙する
435+ EnumWindows(new EnumWindowsDelegate(EnumWindowCallBack), IntPtr.Zero);
436+ }
437+
438+ //public delegate bool EnumWindowsDelegate(IntPtr hWnd, IntPtr lparam);
439+
440+ //[DllImport("user32.dll")]
441+ //[return: MarshalAs(UnmanagedType.Bool)]
442+ //public extern static bool EnumWindows(EnumWindowsDelegate lpEnumFunc, IntPtr lparam);
443+
444+ //[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
445+ //private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
446+
447+ [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
448+ private static extern int GetWindowTextLength(IntPtr hWnd);
449+
450+ [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
451+ private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
452+
453+ //[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
454+ //private static extern Boolean IsWindowVisible(IntPtr hWnd);
455+
456+ private static Boolean EnumWindowCallBack(IntPtr hWnd, IntPtr lparam)
457+ {
458+ //visibleでないなら即リターン
459+ if (!IsWindowVisible(hWnd))
460+ {
461+ return true;
462+ }
463+
464+ //ウィンドウのタイトルの長さが0以下なら即リターン
465+ int textLen = GetWindowTextLength(hWnd);
466+ if (textLen <= 0)
467+ {
468+ return true;
469+ }
470+
471+ //ウィンドウのタイトルを取得する
472+ StringBuilder tsb = new StringBuilder(textLen + 1);
473+ GetWindowText(hWnd, tsb, tsb.Capacity);
474+ if (tsb.ToString().Length <= 0)
475+ {
476+ return true;
477+ }
478+
479+ //ウィンドウのタイトルの中にキャプチャしないウインドウタイトルキーワードが含まれているか確認する
480+ foreach (string str in ClassConfig.IgnoreWindowTitles)
481+ {
482+ if (tsb.ToString().IndexOf(str) >= 0)
483+ {
484+ Log.Put("WindowTitle が " + str + " と一致したのでキャプチャ処理スキップします");
485+ return true;
486+ }
487+ }
488+
489+ //ウィンドウのクラス名を取得する
490+ StringBuilder csb = new StringBuilder(256);
491+ GetClassName(hWnd, csb, csb.Capacity);
492+ if (csb.ToString().Length <= 0)
493+ {
494+ return true;
495+ }
496+
497+ try
498+ {
499+ RECT gWB = new RECT(); ;
500+ if (!hWnd.Equals(System.IntPtr.Zero))
501+ {
502+ GetWindowRect(hWnd, ref gWB);
503+ if ((gWB.right - gWB.left) < 100 || (gWB.bottom - gWB.top) < 100)
504+ {
505+ return true;
506+ }
507+#if false
508+ if (gWB.right < -100 || gWB.bottom < -100)
509+ {
510+ return true;
511+ }
512+#endif
513+ //Log.Put("----------");
514+ //Log.Put("タイトル,ハンドル:" + tsb.ToString() + "_" + (((UInt64)hWnd).ToString("x")));
515+ //Log.Put("left,right,top,bottom:" + gWB.left.ToString() + "," + gWB.right.ToString() + "," + gWB.top.ToString() + "," + gWB.bottom.ToString());
516+
517+ using (Bitmap img = new Bitmap(gWB.right - gWB.left, gWB.bottom - gWB.top))
518+ using (Graphics memg = Graphics.FromImage(img))
519+ {
520+ IntPtr dc = memg.GetHdc();
521+
522+ PrintWindow(hWnd, dc, 0);
523+ memg.ReleaseHdc(dc);
524+
525+ if (tsb.ToString().IndexOf("mpc-hc") >= 0)
526+ {
527+ // media player classic home chinema のウインドウはJPGで保存
528+ img.Save(AppPath() + NowTime.ToString("yyMMdd") + "\\"
529+ + NowTime.ToString("yyMMdd_HHmmssfff") + "_"
530+ + Tcommand.Replace("[capture]", "").Split(',')[0] + "_"
531+ + tsb.ToString() + "_"
532+ + ((UInt64)hWnd).ToString("X8")
533+ + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
534+ }
535+ else
536+ {
537+ // 上記以外のウインドウはPNGで保存
538+ img.Save(AppPath() + NowTime.ToString("yyMMdd") + "\\"
539+ + NowTime.ToString("yyMMdd_HHmmssfff") + "_"
540+ + Tcommand.Replace("[capture]", "").Split(',')[0] + "_"
541+ + tsb.ToString() + "_"
542+ + ((UInt64)hWnd).ToString("X8")
543+ + ".png", System.Drawing.Imaging.ImageFormat.Png);
544+ }
545+ }
546+ }
547+ }
548+ catch (Exception e)
549+ {
550+ Log.Put("EnuWindowCallBack():Exception " + e.Message);
551+ Log.Put("EnuWindowCallBack():tsb " + tsb.ToString());
552+ }
553+ return true;
554+ }
555+ }
556+}
557+
--- tags/TenKeyCapture_00.20-180306/FormMain.Designer.cs (nonexistent)
+++ tags/TenKeyCapture_00.20-180306/FormMain.Designer.cs (revision 103)
@@ -0,0 +1,180 @@
1+namespace TenKeyCapture
2+{
3+ partial class FormMain
4+ {
5+ /// <summary>
6+ /// 必要なデザイナー変数です。
7+ /// </summary>
8+ private System.ComponentModel.IContainer components = null;
9+
10+ /// <summary>
11+ /// 使用中のリソースをすべてクリーンアップします。
12+ /// </summary>
13+ /// <param name="disposing">マネージ リソースを破棄する場合は true を指定し、その他の場合は false を指定します。</param>
14+ protected override void Dispose(bool disposing)
15+ {
16+ if (disposing && (components != null))
17+ {
18+ components.Dispose();
19+ }
20+ base.Dispose(disposing);
21+ }
22+
23+ #region Windows フォーム デザイナーで生成されたコード
24+
25+ /// <summary>
26+ /// デザイナー サポートに必要なメソッドです。このメソッドの内容を
27+ /// コード エディターで変更しないでください。
28+ /// </summary>
29+ private void InitializeComponent()
30+ {
31+ this.components = new System.ComponentModel.Container();
32+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormMain));
33+ this.textBox1 = new System.Windows.Forms.TextBox();
34+ this.button1 = new System.Windows.Forms.Button();
35+ this.button2 = new System.Windows.Forms.Button();
36+ this.button3 = new System.Windows.Forms.Button();
37+ this.button4 = new System.Windows.Forms.Button();
38+ this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components);
39+ this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
40+ this.tenKeyCaptureOpenToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
41+ this.dataFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
42+ this.quitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
43+ this.contextMenuStrip1.SuspendLayout();
44+ this.SuspendLayout();
45+ //
46+ // textBox1
47+ //
48+ this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
49+ | System.Windows.Forms.AnchorStyles.Left)
50+ | System.Windows.Forms.AnchorStyles.Right)));
51+ this.textBox1.Location = new System.Drawing.Point(12, 12);
52+ this.textBox1.Multiline = true;
53+ this.textBox1.Name = "textBox1";
54+ this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Both;
55+ this.textBox1.Size = new System.Drawing.Size(510, 190);
56+ this.textBox1.TabIndex = 0;
57+ this.textBox1.WordWrap = false;
58+ //
59+ // button1
60+ //
61+ this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
62+ this.button1.Location = new System.Drawing.Point(12, 219);
63+ this.button1.Name = "button1";
64+ this.button1.Size = new System.Drawing.Size(110, 30);
65+ this.button1.TabIndex = 1;
66+ this.button1.Text = "About";
67+ this.button1.UseVisualStyleBackColor = true;
68+ this.button1.Click += new System.EventHandler(this.button1_Click);
69+ //
70+ // button2
71+ //
72+ this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
73+ this.button2.Location = new System.Drawing.Point(128, 219);
74+ this.button2.Name = "button2";
75+ this.button2.Size = new System.Drawing.Size(110, 30);
76+ this.button2.TabIndex = 2;
77+ this.button2.Text = "Clear Log";
78+ this.button2.UseVisualStyleBackColor = true;
79+ this.button2.Click += new System.EventHandler(this.button2_Click);
80+ //
81+ // button3
82+ //
83+ this.button3.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
84+ | System.Windows.Forms.AnchorStyles.Right)));
85+ this.button3.Location = new System.Drawing.Point(244, 219);
86+ this.button3.Name = "button3";
87+ this.button3.Size = new System.Drawing.Size(162, 30);
88+ this.button3.TabIndex = 3;
89+ this.button3.Text = "Data Folder";
90+ this.button3.UseVisualStyleBackColor = true;
91+ this.button3.Click += new System.EventHandler(this.button3_Click);
92+ //
93+ // button4
94+ //
95+ this.button4.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
96+ this.button4.Location = new System.Drawing.Point(412, 219);
97+ this.button4.Name = "button4";
98+ this.button4.Size = new System.Drawing.Size(110, 30);
99+ this.button4.TabIndex = 4;
100+ this.button4.Text = "Quit";
101+ this.button4.UseVisualStyleBackColor = true;
102+ this.button4.Click += new System.EventHandler(this.button4_Click);
103+ //
104+ // notifyIcon1
105+ //
106+ this.notifyIcon1.ContextMenuStrip = this.contextMenuStrip1;
107+ this.notifyIcon1.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon1.Icon")));
108+ this.notifyIcon1.Text = "notifyIcon1";
109+ this.notifyIcon1.Visible = true;
110+ this.notifyIcon1.DoubleClick += new System.EventHandler(this.notifyIcon1_DoubleClick);
111+ //
112+ // contextMenuStrip1
113+ //
114+ this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
115+ this.tenKeyCaptureOpenToolStripMenuItem,
116+ this.dataFolderToolStripMenuItem,
117+ this.quitToolStripMenuItem});
118+ this.contextMenuStrip1.Name = "contextMenuStrip1";
119+ this.contextMenuStrip1.Size = new System.Drawing.Size(185, 70);
120+ //
121+ // tenKeyCaptureOpenToolStripMenuItem
122+ //
123+ this.tenKeyCaptureOpenToolStripMenuItem.Name = "tenKeyCaptureOpenToolStripMenuItem";
124+ this.tenKeyCaptureOpenToolStripMenuItem.Size = new System.Drawing.Size(184, 22);
125+ this.tenKeyCaptureOpenToolStripMenuItem.Text = "TenKeyCapture Open";
126+ this.tenKeyCaptureOpenToolStripMenuItem.Click += new System.EventHandler(this.tenKeyCaptureOpenToolStripMenuItem_Click);
127+ //
128+ // dataFolderToolStripMenuItem
129+ //
130+ this.dataFolderToolStripMenuItem.Name = "dataFolderToolStripMenuItem";
131+ this.dataFolderToolStripMenuItem.Size = new System.Drawing.Size(184, 22);
132+ this.dataFolderToolStripMenuItem.Text = "Data Folder";
133+ this.dataFolderToolStripMenuItem.Click += new System.EventHandler(this.dataFolderToolStripMenuItem_Click);
134+ //
135+ // quitToolStripMenuItem
136+ //
137+ this.quitToolStripMenuItem.Name = "quitToolStripMenuItem";
138+ this.quitToolStripMenuItem.Size = new System.Drawing.Size(184, 22);
139+ this.quitToolStripMenuItem.Text = "Quit";
140+ this.quitToolStripMenuItem.Click += new System.EventHandler(this.quitToolStripMenuItem_Click);
141+ //
142+ // FormMain
143+ //
144+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
145+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
146+ this.ClientSize = new System.Drawing.Size(534, 261);
147+ this.Controls.Add(this.button4);
148+ this.Controls.Add(this.button3);
149+ this.Controls.Add(this.button2);
150+ this.Controls.Add(this.button1);
151+ this.Controls.Add(this.textBox1);
152+ this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
153+ this.MinimumSize = new System.Drawing.Size(550, 300);
154+ this.Name = "FormMain";
155+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
156+ this.Text = "TenKeyCapture";
157+ this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FormMain_FormClosing);
158+ this.Load += new System.EventHandler(this.FormMain_Load);
159+ this.Resize += new System.EventHandler(this.FormMain_Resize);
160+ this.contextMenuStrip1.ResumeLayout(false);
161+ this.ResumeLayout(false);
162+ this.PerformLayout();
163+
164+ }
165+
166+ #endregion
167+
168+ private System.Windows.Forms.TextBox textBox1;
169+ private System.Windows.Forms.Button button1;
170+ private System.Windows.Forms.Button button2;
171+ private System.Windows.Forms.Button button3;
172+ private System.Windows.Forms.Button button4;
173+ private System.Windows.Forms.NotifyIcon notifyIcon1;
174+ private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
175+ private System.Windows.Forms.ToolStripMenuItem tenKeyCaptureOpenToolStripMenuItem;
176+ private System.Windows.Forms.ToolStripMenuItem dataFolderToolStripMenuItem;
177+ private System.Windows.Forms.ToolStripMenuItem quitToolStripMenuItem;
178+ }
179+}
180+
--- tags/TenKeyCapture_00.20-180306/KeyboardHooker.cs (nonexistent)
+++ tags/TenKeyCapture_00.20-180306/KeyboardHooker.cs (revision 103)
@@ -0,0 +1,110 @@
1+/***********************************************************//*!
2+ * @brief キーボードフック処理
3+ * @author S.Hori
4+ * @date
5+ * 2018-02-10 初版<br>
6+ * @details
7+ **************************************************************/using System;
8+using System.Collections.Generic;
9+using System.Linq;
10+using System.Text;
11+using System.Threading.Tasks;
12+using System.Windows.Forms;
13+using System.Runtime.InteropServices;
14+using static TenKeyCapture.ClassMyCommon;
15+
16+namespace TenKeyCapture
17+{
18+ /***********************************************************//*!
19+ * @brief キーボードフック処理クラス
20+ **************************************************************/
21+ class KeyboardHooker
22+ {
23+ private const uint WM_KEYDOWN = 0x100;
24+ private const uint WM_KEYUP = 0x101;
25+ private const int WH_KEYBOARD_LL = 13;
26+ private static IntPtr hHook;
27+
28+ private Callback hookproc;
29+
30+ public KeyboardHooker()
31+ {
32+ hookproc = KeybordHookProc;
33+ hHook = SetWindowsHookEx(WH_KEYBOARD_LL, hookproc, GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName), 0);
34+ if (hHook == null)
35+ {
36+ Log.Put("SetWindowsHookEx Failed");
37+ }
38+ }
39+
40+ public delegate IntPtr Callback(int nCode, IntPtr msg, IntPtr s);
41+
42+ [DllImport("user32.dll")]
43+ public static extern IntPtr SetWindowsHookEx(int idHook, Callback lpfn, IntPtr hMod, uint dwThreadId);
44+
45+ [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
46+ public static extern IntPtr GetModuleHandle(string lpModuleName);
47+
48+ [DllImport("user32.dll")]
49+ public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr msg, IntPtr s);
50+
51+ [DllImport("user32.dll")]
52+ [return: MarshalAs(UnmanagedType.Bool)]
53+ public static extern bool UnhookWindowsHookEx(IntPtr hhk);
54+
55+ [StructLayout(LayoutKind.Sequential)]
56+ private struct KeyboardLLHookStruct
57+ {
58+ public uint vkCode;
59+ public uint scanCode;
60+ public uint flags;
61+ public uint time;
62+ public IntPtr dwExtraInfo;
63+ }
64+
65+ private static IntPtr KeybordHookProc(int nCode, IntPtr msg, IntPtr s)
66+ {
67+ if (nCode < 0)
68+ {
69+ return CallNextHookEx(hHook, nCode, msg, s);
70+ }
71+
72+ KeyboardLLHookStruct hookStruct = new KeyboardLLHookStruct();
73+
74+ hookStruct = (KeyboardLLHookStruct)Marshal.PtrToStructure(s, typeof(KeyboardLLHookStruct));
75+
76+ uint vkCode = hookStruct.vkCode;
77+
78+ if (msg == new IntPtr(WM_KEYDOWN))
79+ {
80+ vkCode = hookStruct.vkCode;
81+ if (vkCode >= 96 && 111 >= vkCode)
82+ {
83+ wkQueue.Enqueue(vkCode);
84+ return new IntPtr(1);
85+ }
86+ }
87+
88+ if (msg == new IntPtr(WM_KEYUP))
89+ {
90+ vkCode = hookStruct.vkCode;
91+
92+ if (vkCode >= 96 && 111 >= vkCode)
93+ {
94+ return new IntPtr(1);
95+ }
96+ }
97+
98+ return CallNextHookEx(hHook, nCode, msg, s);
99+ }
100+
101+ public void Dispose()
102+ {
103+ Boolean ret = UnhookWindowsHookEx(hHook);
104+ if (ret.Equals(false))
105+ {
106+ }
107+ }
108+
109+ }
110+}
--- tags/TenKeyCapture_00.20-180306/ClassConfig.cs (nonexistent)
+++ tags/TenKeyCapture_00.20-180306/ClassConfig.cs (revision 103)
@@ -0,0 +1,294 @@
1+/***********************************************************//*!
2+ * @brief 設定管理
3+ * @author S.Hori
4+ * @date
5+ * 2018-02-10 初版<br>
6+ * @details
7+ **************************************************************/
8+using System;
9+using System.IO;
10+using System.Collections.Generic;
11+using System.Linq;
12+using System.Text;
13+using System.Threading.Tasks;
14+using static TenKeyCapture.ClassMyCommon;
15+
16+namespace TenKeyCapture
17+{
18+ /***********************************************************//*!
19+ * @brief 設定管理クラス
20+ * @details
21+ **************************************************************/
22+ class ClassConfig
23+ {
24+ //! 設定データ構造のバージョン
25+ public const string APPINI_VERSION = "01.00";
26+
27+ //! 設定データ格納ファイル名(フルパス付き)
28+ private string APPini = AppPath() + TITLE + ".ini";
29+
30+ //! デバッグフラグ
31+ public Int16 DebugFlag = 0;
32+
33+ //! キーが押された時、CSV内に記録される文字列
34+ public static string T0 = "ゼロキー ";
35+ //! キーが押された時、CSV内に記録される文字列
36+ public static string T1 = "[capture]1キー,,,,,";
37+ //! キーが押された時、CSV内に記録される文字列
38+ public static string T2 = "[capture]2キー,,,,,";
39+ //! キーが押された時、CSV内に記録される文字列
40+ public static string T3 = "[capture]3キー,,,,,";
41+ //! キーが押された時、CSV内に記録される文字列
42+ public static string T4 = "[capture]4キー,,,,,";
43+ //! キーが押された時、CSV内に記録される文字列
44+ public static string T5 = "[capture]5キー,,,,,";
45+ //! キーが押された時、CSV内に記録される文字列
46+ public static string T6 = "[capture]6キー,,,,,";
47+ //! キーが押された時、CSV内に記録される文字列
48+ public static string T7 = "[capture]7キー,,,,,";
49+ //! キーが押された時、CSV内に記録される文字列
50+ public static string T8 = "[capture]8キー,,,,,";
51+ //! キーが押された時、CSV内に記録される文字列
52+ public static string T9 = "[capture]9キー,,,,,";
53+ //! キーが押された時、CSV内に記録される文字列
54+ public static string Tdot = "ドットキー ";
55+ //! キーが押された時、CSV内に記録される文字列
56+ public static string Tslash = "スラッシュキー ";
57+ //! キーが押された時、CSV内に記録される文字列
58+ public static string Tastah = "アスタリスクキー ";
59+ //! キーが押された時、CSV内に記録される文字列
60+ public static string Tminus = "マイナスキー ";
61+ //! キーが押された時、CSV内に記録される文字列
62+ public static string Tplus = "プラスキー ";
63+
64+ //! ウインドウタイトルに下記の文字列が含まれていた場合キャプチャ対象外となる
65+ public static string[] IgnoreWindowTitles = { "Program Manager", "フォト", "シェル", "設定" };
66+
67+ /***********************************************************//*!
68+ * @brief xmlファイルから設定データ読み出し>
69+ * @date 2018-02-10
70+ * @details
71+ **************************************************************/
72+ public void Load()
73+ {
74+ string TempIgnoreWindowTitles;
75+ try
76+ {
77+ //! INIファイルがあるか判定する。なければ Save()をコールして初期値でINIファイルを生成する。
78+ if (!File.Exists(APPini))
79+ {
80+ Save();
81+ }
82+
83+ // INIファイル格納文字列
84+ string xmlsource = "";
85+
86+ // INIファイルを読みだす。
87+ using (StreamReader reader = new StreamReader(APPini, Encoding.GetEncoding("shift_jis")))
88+ {
89+ while (!reader.EndOfStream)
90+ {
91+ xmlsource += reader.ReadLine() + "\r\n";
92+ }
93+ }
94+
95+ //Log.Put("App.ini LOAD" + "\r\n" + xmlsource + "\r\n");
96+
97+ // INIファイルの中身を解釈する
98+ System.Xml.XmlTextReader xmlReader = new System.Xml.XmlTextReader(new StringReader(xmlsource));
99+ xmlReader.Read();
100+ while (!xmlReader.EOF)
101+ {
102+ if (xmlReader.IsStartElement("T0"))
103+ {
104+ T0 = xmlReader.ReadElementString("T0");
105+ }
106+ else if (xmlReader.IsStartElement("T1"))
107+ {
108+ T1 = xmlReader.ReadElementString("T1");
109+ }
110+ else if (xmlReader.IsStartElement("T2"))
111+ {
112+ T2 = xmlReader.ReadElementString("T2");
113+ }
114+ else if (xmlReader.IsStartElement("T3"))
115+ {
116+ T3 = xmlReader.ReadElementString("T3");
117+ }
118+ else if (xmlReader.IsStartElement("T4"))
119+ {
120+ T4 = xmlReader.ReadElementString("T4");
121+ }
122+ else if (xmlReader.IsStartElement("T5"))
123+ {
124+ T5 = xmlReader.ReadElementString("T5");
125+ }
126+ else if (xmlReader.IsStartElement("T6"))
127+ {
128+ T6 = xmlReader.ReadElementString("T6");
129+ }
130+ else if (xmlReader.IsStartElement("T7"))
131+ {
132+ T7 = xmlReader.ReadElementString("T7");
133+ }
134+ else if (xmlReader.IsStartElement("T8"))
135+ {
136+ T8 = xmlReader.ReadElementString("T8");
137+ }
138+ else if (xmlReader.IsStartElement("T9"))
139+ {
140+ T9 = xmlReader.ReadElementString("T9");
141+ }
142+ else if (xmlReader.IsStartElement("Tslash"))
143+ {
144+ Tslash = xmlReader.ReadElementString("Tslash");
145+ }
146+ else if (xmlReader.IsStartElement("Tastah"))
147+ {
148+ Tastah = xmlReader.ReadElementString("Tastah");
149+ }
150+ else if (xmlReader.IsStartElement("Tminus"))
151+ {
152+ Tminus = xmlReader.ReadElementString("Tminus");
153+ }
154+ else if (xmlReader.IsStartElement("Tplus"))
155+ {
156+ Tplus = xmlReader.ReadElementString("Tplus");
157+ }
158+ else if (xmlReader.IsStartElement("Tdot"))
159+ {
160+ Tdot = xmlReader.ReadElementString("Tdot");
161+ }
162+ else if (xmlReader.IsStartElement("IgnoreWindowTitles"))
163+ {
164+ TempIgnoreWindowTitles = xmlReader.ReadElementString("IgnoreWindowTitles");
165+ IgnoreWindowTitles = TempIgnoreWindowTitles.Split(',');
166+ }
167+ else
168+ {
169+ xmlReader.Read();
170+ }
171+ }
172+
173+ // 読み出した結果を表示
174+ Log.Put(" ");
175+ Log.Put("T0 = \"" + T0 + "\"");
176+ Log.Put("T1 = \"" + T1 + "\"");
177+ Log.Put("T2 = \"" + T2 + "\"");
178+ Log.Put("T3 = \"" + T3 + "\"");
179+ Log.Put("T4 = \"" + T4 + "\"");
180+ Log.Put("T5 = \"" + T5 + "\"");
181+ Log.Put("T6 = \"" + T6 + "\"");
182+ Log.Put("T7 = \"" + T7 + "\"");
183+ Log.Put("T8 = \"" + T8 + "\"");
184+ Log.Put("T9 = \"" + T9 + "\"");
185+ Log.Put("Tslash = \"" + Tslash + "\"");
186+ Log.Put("Tastah = \"" + Tastah + "\"");
187+ Log.Put("Tminus = \"" + Tminus + "\"");
188+ Log.Put("Tplus = \"" + Tplus + "\"");
189+ Log.Put("Tdot = \"" + Tdot + "\"");
190+ // IgnoreWindowTitles配列内のデータをすべてカンマ区切りで連結する
191+ Log.Put("IgnoreWindowTitle = \"" + string.Join(",", IgnoreWindowTitles) + "\"");
192+ }
193+ catch (Exception ex)
194+ {
195+ Log.Put("Error:Config.Load()");
196+ Log.Put("ex.Message\r\n" + ex.Message);
197+ Log.Put("ex.StacTrace\r\n" + ex.StackTrace);
198+ }
199+
200+ }
201+
202+ /***********************************************************//*!
203+ * @brief xmlファイルへ設定データ書き込み
204+ * @date 2018-02-10
205+ * @details
206+ **************************************************************/
207+ public void Save()
208+ {
209+ StringWriter APPini_xml = new StringWriter();
210+ System.Xml.XmlTextWriter xmlWriter = new System.Xml.XmlTextWriter(APPini_xml);
211+
212+ //StringWriterを使用してXMLをパッキングしてファイルへ書き出す
213+ //ただしStringWriterはEncoding設定がutf-16固定となっており、
214+ //StringWriterでXMLを出力するとXML宣言のencodingが強制的にutf-16になってしまいます。
215+
216+ xmlWriter.WriteStartDocument();
217+ xmlWriter.WriteWhitespace("\r\n");
218+
219+ xmlWriter.WriteComment("このファイルを編集する時は必ず " + TITLE + " を終了させてください。");
220+ xmlWriter.WriteWhitespace("\r\n");
221+
222+ xmlWriter.WriteStartElement("APPini");
223+ xmlWriter.WriteWhitespace("\r\n");
224+
225+ xmlWriter.WriteElementString("APPini_VERSION", APPINI_VERSION);
226+ xmlWriter.WriteWhitespace("\r\n");
227+
228+ xmlWriter.WriteElementString("T0", T0);
229+ xmlWriter.WriteWhitespace("\r\n");
230+
231+ xmlWriter.WriteElementString("T1", T1);
232+ xmlWriter.WriteWhitespace("\r\n");
233+
234+ xmlWriter.WriteElementString("T2", T2);
235+ xmlWriter.WriteWhitespace("\r\n");
236+
237+ xmlWriter.WriteElementString("T3", T3);
238+ xmlWriter.WriteWhitespace("\r\n");
239+
240+ xmlWriter.WriteElementString("T4", T4);
241+ xmlWriter.WriteWhitespace("\r\n");
242+
243+ xmlWriter.WriteElementString("T5", T5);
244+ xmlWriter.WriteWhitespace("\r\n");
245+
246+ xmlWriter.WriteElementString("T6", T6);
247+ xmlWriter.WriteWhitespace("\r\n");
248+
249+ xmlWriter.WriteElementString("T7", T7);
250+ xmlWriter.WriteWhitespace("\r\n");
251+
252+ xmlWriter.WriteElementString("T8", T8);
253+ xmlWriter.WriteWhitespace("\r\n");
254+
255+ xmlWriter.WriteElementString("T9", T9);
256+ xmlWriter.WriteWhitespace("\r\n");
257+
258+ xmlWriter.WriteElementString("Tslash", Tslash);
259+ xmlWriter.WriteWhitespace("\r\n");
260+
261+ xmlWriter.WriteElementString("Tastah", Tastah);
262+ xmlWriter.WriteWhitespace("\r\n");
263+
264+ xmlWriter.WriteElementString("Tminus", Tminus);
265+ xmlWriter.WriteWhitespace("\r\n");
266+
267+ xmlWriter.WriteElementString("Tplus", Tplus);
268+ xmlWriter.WriteWhitespace("\r\n");
269+
270+ xmlWriter.WriteElementString("Tdot", Tdot);
271+ xmlWriter.WriteWhitespace("\r\n");
272+
273+ string str = string.Join(",", IgnoreWindowTitles);
274+ xmlWriter.WriteElementString("IgnoreWindowTitles", str);
275+ xmlWriter.WriteWhitespace("\r\n");
276+
277+ xmlWriter.WriteEndElement();
278+
279+ xmlWriter.WriteWhitespace("\r\n");
280+ xmlWriter.WriteComment("end of document");
281+
282+ xmlWriter.WriteEndDocument();
283+
284+ //Log.Put("設定を保存しました。" + vbCrLf);
285+
286+ //上記の通りなのでファイルに書き出して保存する前に Shift-JIS に変換します
287+ string SaveString = APPini_xml.ToString().Replace("utf-16", "shift_jis");
288+ using (StreamWriter Writer = new StreamWriter(APPini, false, Encoding.GetEncoding("shift_jis")))
289+ {
290+ Writer.Write(SaveString);
291+ }
292+ }
293+ }
294+}
--- tags/TenKeyCapture_00.20-180306/Program.cs (nonexistent)
+++ tags/TenKeyCapture_00.20-180306/Program.cs (revision 103)
@@ -0,0 +1,22 @@
1+using System;
2+using System.Collections.Generic;
3+using System.Linq;
4+using System.Threading.Tasks;
5+using System.Windows.Forms;
6+
7+namespace TenKeyCapture
8+{
9+ static class Program
10+ {
11+ /// <summary>
12+ /// アプリケーションのメイン エントリ ポイントです。
13+ /// </summary>
14+ [STAThread]
15+ static void Main()
16+ {
17+ Application.EnableVisualStyles();
18+ Application.SetCompatibleTextRenderingDefault(false);
19+ Application.Run(new FormMain());
20+ }
21+ }
22+}
--- tags/TenKeyCapture_00.20-180306/Properties/AssemblyInfo.cs (nonexistent)
+++ tags/TenKeyCapture_00.20-180306/Properties/AssemblyInfo.cs (revision 103)
@@ -0,0 +1,36 @@
1+using System.Reflection;
2+using System.Runtime.CompilerServices;
3+using System.Runtime.InteropServices;
4+
5+// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。
6+// アセンブリに関連付けられている情報を変更するには、
7+// これらの属性値を変更してください。
8+[assembly: AssemblyTitle("TenKeyCapture")]
9+[assembly: AssemblyDescription("")]
10+[assembly: AssemblyConfiguration("")]
11+[assembly: AssemblyCompany("")]
12+[assembly: AssemblyProduct("TenKeyCapture")]
13+[assembly: AssemblyCopyright("Copyright © 2018")]
14+[assembly: AssemblyTrademark("")]
15+[assembly: AssemblyCulture("")]
16+
17+// ComVisible を false に設定すると、このアセンブリ内の型は COM コンポーネントから
18+// 参照できなくなります。COM からこのアセンブリ内の型にアクセスする必要がある場合は、
19+// その型の ComVisible 属性を true に設定してください。
20+[assembly: ComVisible(false)]
21+
22+// このプロジェクトが COM に公開される場合、次の GUID が typelib の ID になります
23+[assembly: Guid("e9742bad-8414-44a2-80c2-b047ca268dcf")]
24+
25+// アセンブリのバージョン情報は次の 4 つの値で構成されています:
26+//
27+// メジャー バージョン
28+// マイナー バージョン
29+// ビルド番号
30+// Revision
31+//
32+// すべての値を指定するか、次を使用してビルド番号とリビジョン番号を既定に設定できます
33+// 既定値にすることができます:
34+// [assembly: AssemblyVersion("1.0.*")]
35+[assembly: AssemblyVersion("1.0.0.0")]
36+[assembly: AssemblyFileVersion("1.0.0.0")]
--- tags/TenKeyCapture_00.20-180306/Properties/Resources.Designer.cs (nonexistent)
+++ tags/TenKeyCapture_00.20-180306/Properties/Resources.Designer.cs (revision 103)
@@ -0,0 +1,63 @@
1+//------------------------------------------------------------------------------
2+// <auto-generated>
3+// このコードはツールによって生成されました。
4+// ランタイム バージョン:4.0.30319.42000
5+//
6+// このファイルへの変更は、以下の状況下で不正な動作の原因になったり、
7+// コードが再生成されるときに損失したりします。
8+// </auto-generated>
9+//------------------------------------------------------------------------------
10+
11+namespace TenKeyCapture.Properties {
12+ using System;
13+
14+
15+ /// <summary>
16+ /// ローカライズされた文字列などを検索するための、厳密に型指定されたリソース クラスです。
17+ /// </summary>
18+ // このクラスは StronglyTypedResourceBuilder クラスが ResGen
19+ // または Visual Studio のようなツールを使用して自動生成されました。
20+ // メンバーを追加または削除するには、.ResX ファイルを編集して、/str オプションと共に
21+ // ResGen を実行し直すか、または VS プロジェクトをビルドし直します。
22+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
23+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25+ internal class Resources {
26+
27+ private static global::System.Resources.ResourceManager resourceMan;
28+
29+ private static global::System.Globalization.CultureInfo resourceCulture;
30+
31+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32+ internal Resources() {
33+ }
34+
35+ /// <summary>
36+ /// このクラスで使用されているキャッシュされた ResourceManager インスタンスを返します。
37+ /// </summary>
38+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39+ internal static global::System.Resources.ResourceManager ResourceManager {
40+ get {
41+ if (object.ReferenceEquals(resourceMan, null)) {
42+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TenKeyCapture.Properties.Resources", typeof(Resources).Assembly);
43+ resourceMan = temp;
44+ }
45+ return resourceMan;
46+ }
47+ }
48+
49+ /// <summary>
50+ /// 厳密に型指定されたこのリソース クラスを使用して、すべての検索リソースに対し、
51+ /// 現在のスレッドの CurrentUICulture プロパティをオーバーライドします。
52+ /// </summary>
53+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54+ internal static global::System.Globalization.CultureInfo Culture {
55+ get {
56+ return resourceCulture;
57+ }
58+ set {
59+ resourceCulture = value;
60+ }
61+ }
62+ }
63+}
--- tags/TenKeyCapture_00.20-180306/Properties/Settings.Designer.cs (nonexistent)
+++ tags/TenKeyCapture_00.20-180306/Properties/Settings.Designer.cs (revision 103)
@@ -0,0 +1,26 @@
1+//------------------------------------------------------------------------------
2+// <auto-generated>
3+// このコードはツールによって生成されました。
4+// ランタイム バージョン:4.0.30319.42000
5+//
6+// このファイルへの変更は、以下の状況下で不正な動作の原因になったり、
7+// コードが再生成されるときに損失したりします。
8+// </auto-generated>
9+//------------------------------------------------------------------------------
10+
11+namespace TenKeyCapture.Properties {
12+
13+
14+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.3.0.0")]
16+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17+
18+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19+
20+ public static Settings Default {
21+ get {
22+ return defaultInstance;
23+ }
24+ }
25+ }
26+}