• 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

Revision213 (tree)
Time2023-04-04 23:05:52
Authorhor931101jp

Log Message

(empty log message)

Change Summary

Incremental Difference

--- trunk/TenKeyCaptureCS2/TenKeyCaptureCS/FormMain.cs (nonexistent)
+++ trunk/TenKeyCaptureCS2/TenKeyCaptureCS/FormMain.cs (revision 213)
@@ -0,0 +1,956 @@
1+/***********************************************************//*!
2+ * @brief メインウインドウ処理
3+ **************************************************************/
4+
5+using System;
6+using System.IO;
7+using System.Collections.Generic;
8+using System.ComponentModel;
9+using System.Data;
10+using System.Drawing;
11+using System.Linq;
12+using System.Text;
13+using System.Threading.Tasks;
14+using System.Windows.Forms;
15+using System.Runtime.InteropServices;
16+using static TenKeyCapture.ClassMyCommon;
17+using static TenKeyCapture.ClassConfig;
18+using System.Collections.Concurrent;
19+using static System.Console;
20+
21+namespace TenKeyCapture
22+{
23+ /// <summary>
24+ /// メインウインドウのフォーム
25+ /// </summary>
26+ public partial class FormMain : Form
27+ {
28+ private static string PreCSVString = "";
29+
30+ [DllImport("user32.dll")]
31+ private 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+
36+ [DllImport("user32.dll")]
37+ [return: MarshalAs(UnmanagedType.Bool)]
38+ public extern static bool EnumWindows(EnumWindowsDelegate lpEnumFunc, IntPtr lparam); //可視判定
39+
40+ [DllImport("user32")]
41+ private static extern bool IsWindowVisible(IntPtr hWnd);
42+
43+ [DllImport("user32", CharSet = CharSet.Auto)]
44+ private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
45+
46+ [DllImport("user32", CharSet = CharSet.Auto)]
47+ private static extern int GetWindow(IntPtr hWnd, UInt32 wCmd);
48+
49+ //public const UInt32 GW_OWNER = 4;
50+
51+ [StructLayout(LayoutKind.Sequential)]
52+ private struct RECT
53+ {
54+ public int left;
55+ public int top;
56+ public int right;
57+ public int bottom;
58+ }
59+
60+ [DllImport("user32.dll")]
61+ private static extern int GetWindowRect(IntPtr hwnd, ref RECT lpRect);
62+
63+ [DllImport("User32.dll")]
64+ private extern static bool PrintWindow(IntPtr hwnd, IntPtr hDC, uint nFlags);
65+
66+ /// <summary>キーボードフック処理インスタンス</summary>
67+ private KeyboardHooker KeyboardHooker1;
68+
69+ /// <summary>テンキーが押された時の対応するコマンドを格納するインスタンス</summary>
70+ private static ClassTenKeyConfig CurrentTenkeyConfig;
71+
72+ /// <summary>キャプチャタスクスレッド</summary>
73+ public Task CaptureThread;
74+
75+ /// <summary>
76+ /// コンストラクタ
77+ /// </summary>
78+ public FormMain()
79+ {
80+ InitializeComponent();
81+ }
82+
83+ /// <summary>
84+ /// 終了時の処理
85+ /// </summary>
86+ /// <param name="sender">未使用。イベントを発生させたオブジェクト</param>
87+ /// <param name="e">未使用。イベントのオプション</param>
88+ private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
89+ {
90+ //! ウインドウポップアップ
91+ Visible = true;
92+ WindowState = FormWindowState.Normal;
93+ TopMost = true;
94+
95+ Log.Put("終了");
96+ //! ログを保存する
97+ Log.Save();
98+ CSV.Save();
99+ }
100+
101+ /// <summary>
102+ /// フォームロード時の処理
103+ /// </summary>
104+ /// <param name="sender">未使用。イベントを発生させたオブジェクト</param>
105+ /// <param name="e">未使用。イベントのオプション</param>
106+ private void FormMain_Load(object sender, EventArgs e)
107+ {
108+ //多重起動チェック
109+ //Process.GetProcessesByName メソッド
110+ //指定したプロセス名を共有するリモートコンピュータ上の
111+ //すべてのプロセスリソースに関連付けます。
112+ string pn = System.Diagnostics.Process.GetCurrentProcess().ProcessName; //Process.ProcessName プロパティ(プロセスの名前を取得します)
113+ if (System.Diagnostics.Process.GetProcessesByName(pn).GetUpperBound(0) > 0)
114+ {
115+ //! 多重起動しているならばエラーメッセージ表示して終了。
116+ MessageBox.Show("すでに起動しています。", TITLE + " エラーメッセージ",
117+ MessageBoxButtons.OK,
118+ MessageBoxIcon.Error);
119+ Environment.Exit(0);
120+ }
121+
122+ frmMain = this;
123+ FormControlBoxCustomize(frmMain);
124+ frmMain.Text = TITLE + " " + VERSION;
125+ Log = new ClassLog(this.textBox1);
126+
127+ notifyIcon1.Text = TITLE + " " + VERSION;
128+ notifyIcon1.Visible = true;
129+
130+ //! iniファイルから設定を読み出す
131+ Config.Load();
132+
133+ Log.Put("タスクトレイにアイコンを登録しました。");
134+
135+ Popup();
136+
137+ NowTime = DateTime.Now;
138+
139+ //! データフォルダ作成
140+ System.IO.Directory.CreateDirectory(AppFolder() + "\\" + NowTime.ToString("yyMMdd") + "\\");
141+
142+ //! ナムロックONにする
143+ SetNumLock(true);
144+
145+ //! キーボードフック処理インスタンス
146+ KeyboardHooker1 = new KeyboardHooker();
147+
148+ //! キャプチャタスク起動
149+ Task t = CaptureTask();
150+ Log.Put("キャプチャタスク生成しました。");
151+ //! サウンドタスク起動
152+ Task t2 = SoundTask();
153+ Log.Put("サウンドタスク生成しました。");
154+
155+ //! 起動時はウインドウを短時間最前面にもってくる
156+ Show();
157+ TopMost = true;
158+ WaitTickCount(100);
159+ TopMost = false;
160+ Log.Put("起動完了しました。");
161+
162+ button1.PerformClick();
163+
164+ Log.Save();
165+
166+ }
167+
168+ /// <summary>
169+ /// Aboutボタンを押された時の処理
170+ /// オープニングメッセージをログに表示する
171+ /// 設定を表示する
172+ /// サウンドテストを行う
173+ /// </summary>
174+ /// <param name="sender">未使用。イベントを発生させたオブジェクト</param>
175+ /// <param name="e">未使用。イベントのオプション</param>
176+ private async void button1_Click(object sender, EventArgs e)
177+ {
178+ Log.Add("------------------------------------------------------\r\n");
179+ Log.Add(TITLE + " " + VERSION);
180+ Log.Add(OPENING_MSG);
181+ Log.Put("------------------------------------------------------\r\n");
182+
183+ Config.Show();
184+
185+ Log.Put("シャッター音のサウンドテストを行います。");
186+ await Task.Delay(200);
187+ bool addSuccess = SoundQue.TryAdd(true, System.Threading.Timeout.Infinite);
188+ await Task.Delay(500);
189+ Log.Put("ビープ音のサウンドテストを行います。");
190+ await Task.Delay(200);
191+ addSuccess = SoundQue.TryAdd(false, System.Threading.Timeout.Infinite);
192+ Log.Save();
193+ }
194+
195+ /// <summary>
196+ /// Clear Log ボタンを押された時の処理 ログの表示をクリアする
197+ /// </summary>
198+ /// <param name="sender">sender 未使用。イベントを発生させたオブジェクト</param>
199+ /// <param name="e">未使用。イベントのオプション</param>
200+ private void button2_Click(object sender, EventArgs e)
201+ {
202+ Log.Clear();
203+ Log.Save();
204+ }
205+
206+ /// <summary>
207+ /// Data Folder ボタンを押された時の処理
208+ /// </summary>
209+ /// <param name="sender">未使用。イベントを発生させたオブジェクト</param>
210+ /// <param name="e">未使用。イベントのオプション</param>
211+ private void button3_Click(object sender, EventArgs e)
212+ {
213+ //! データフォルダ作成(ユーザーが消してしまった場合に備えて)
214+ System.IO.Directory.CreateDirectory(AppFolder() + "\\" + NowTime.ToString("yyMMdd") + "\\");
215+
216+ //! データフォルダを開く
217+ System.Diagnostics.Process.Start(AppFolder() + "\\" + NowTime.ToString("yyMMdd"));
218+
219+ Log.Save();
220+ }
221+
222+ /// <summary>
223+ /// Quit ボタンを押された時の処理 プログラム終了
224+ /// </summary>
225+ /// <param name="sender">未使用。イベントを発生させたオブジェクト</param>
226+ /// <param name="e">未使用。イベントのオプション</param>
227+ private void button4_Click(object sender, EventArgs e)
228+ {
229+ Close();
230+ }
231+
232+ /// <summary>
233+ /// メインウインドウの最小化時にウインドウを非表示にする
234+ /// </summary>
235+ /// <param name="sender">未使用。イベントを発生させたオブジェクト</param>
236+ /// <param name="e">未使用。イベントのオプション</param>
237+ private void FormMain_Resize(object sender, EventArgs e)
238+ {
239+ if (WindowState == FormWindowState.Minimized)
240+ {
241+ Visible = false;
242+ }
243+ }
244+
245+ /// <summary>
246+ /// メインウインドウをポップアップする
247+ /// </summary>
248+ private void Popup()
249+ {
250+ Visible = true;
251+ WindowState = FormWindowState.Normal;
252+ //! 短時間かならずトップに表示
253+ TopMost = true;
254+ WaitTickCount(100);
255+ TopMost = false;
256+ //! 最新ログを表示
257+ Log.Put("");
258+ Log.Save();
259+ }
260+
261+ /// <summary>
262+ /// タスクトレイアイコンをダブルクリックされたらメインウインドウをポップアップする
263+ /// </summary>
264+ /// <param name="sender">未使用。イベントを発生させたオブジェクト</param>
265+ /// <param name="e">未使用。イベントのオプション</param>
266+ private void notifyIcon1_DoubleClick(object sender, EventArgs e)
267+ {
268+ Popup();
269+ }
270+
271+ /// <summary>
272+ /// タスクトレイアイコンメニュの TenKeyCaputer Open をクリックされたときの処理
273+ /// </summary>
274+ /// <param name="sender">未使用。イベントを発生させたオブジェクト</param>
275+ /// <param name="e">未使用。イベントのオプション</param>
276+ private void tenKeyCaptureOpenToolStripMenuItem_Click(object sender, EventArgs e)
277+ {
278+ Popup();
279+ }
280+
281+ /// <summary>
282+ /// タスクトレイアイコンメニュの TenKeyCaputer Open をクリックされたときの処理
283+ /// </summary>
284+ /// <param name="sender">未使用。イベントを発生させたオブジェクト</param>
285+ /// <param name="e">未使用。イベントのオプション</param>
286+ private void dataFolderToolStripMenuItem_Click(object sender, EventArgs e)
287+ {
288+ //! データフォルダ作成(ユーザーが消してしまった場合に備えて)
289+ System.IO.Directory.CreateDirectory(AppFolder() + "\\" + NowTime.ToString("yyMMdd") + "\\");
290+
291+ //! データフォルダを開く
292+ System.Diagnostics.Process.Start(AppFolder() + "\\" + NowTime.ToString("yyMMdd"));
293+ }
294+
295+ /// <summary>
296+ /// タスクトレイアイコンのメニューからQuitを選択された時の処理
297+ /// メインウインドウをトップに表示。
298+ /// </summary>
299+ /// <param name="sender">未使用。イベントを発生させたオブジェクト</param>
300+ /// <param name="e">未使用。イベントのオプション</param>
301+ private void quitToolStripMenuItem_Click(object sender, EventArgs e)
302+ {
303+ Popup();
304+ Close();
305+ }
306+
307+ [DllImport("user32.dll")]
308+ private static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);
309+
310+ public const byte VK_NUMLOCK = 0x90;
311+
312+ //public const uint KEYEVENTF_EXTENDEDKEY = 1;
313+ public const int KEYEVENTF_KEYUP = 0x2;
314+
315+ /// <summary>
316+ /// NumLock状態を変更する
317+ /// </summary>
318+ /// <param name="bOnOffFlag">true=ナムロックON false=ナムロックオフ</param>
319+ private void SetNumLock(Boolean bOnOffFlag)
320+ {
321+ if (Control.IsKeyLocked(Keys.NumLock) != bOnOffFlag)
322+ {
323+ keybd_event(VK_NUMLOCK, 0x45, 0, 0);
324+ keybd_event(VK_NUMLOCK, 0x45, KEYEVENTF_KEYUP, 0);
325+ if (bOnOffFlag)
326+ {
327+ Log.Put("NumLock を ON にしました。");
328+ }
329+ else
330+ {
331+ Log.Put("NumLock を OFF にしました。");
332+ }
333+ }
334+ }
335+
336+ /// <summary>
337+ /// キーに応じてWAVファイルを再生するタスク 無限ループ処理
338+ /// </summary>
339+ /// <returns></returns>
340+ private async Task SoundTask()
341+ {
342+ try
343+ {
344+ System.Media.SoundPlayer player_shutter = new System.Media.SoundPlayer(AppFolder() + "\\" + "shutter.wav");
345+ System.Media.SoundPlayer player_beep = new System.Media.SoundPlayer(AppFolder() + "\\" + "beep.wav");
346+ Log.Put("サウンドタスク開始しました。");
347+ for (; ; )
348+ {
349+ await Task.Delay(1);
350+ try
351+ {
352+ if (SoundQue.Count > 0)
353+ {
354+ player_shutter.Stop();
355+ player_beep.Stop();
356+ Boolean outdata;
357+ bool takeSuccess = SoundQue.TryTake(out outdata, System.Threading.Timeout.Infinite);
358+ if (outdata == true)
359+ {
360+ player_shutter.Play();
361+ }
362+ else
363+ {
364+ player_beep.Play();
365+ }
366+ await Task.Delay(250);//最低でもこれだけは鳴らす時間を確保する
367+ }
368+ }
369+ catch (Exception e)
370+ {
371+ Log.Put("SoundTask():Exception" + e.Message);
372+ }
373+ }
374+ }
375+ catch (Exception e)
376+ {
377+ Log.Put("SoundTask():Exception" + e.Message);
378+ }
379+ }
380+
381+ /// <summary>
382+ /// キャプチャタスク 無限ループ処理
383+ /// </summary>
384+ /// <returns></returns>
385+ private async Task CaptureTask()
386+ {
387+ Int64 LastTickCount = Environment.TickCount;
388+ Log.Put("キャプチャタスク開始しました。");
389+
390+ for (; ; )
391+ {
392+ await Task.Delay(1); //非ブロッキング API 呼び出し
393+
394+ if (KeyQue.Count > 0)
395+ {
396+ LastTickCount = Environment.TickCount;
397+ uint KeyCode;
398+ // キューからキーデータを取り出す
399+ bool takeSuccess = KeyQue.TryTake(out KeyCode, System.Threading.Timeout.Infinite);
400+
401+ try
402+ {
403+ //Log.Put("KeyCode = " + KeyCode);
404+ CurrentTenkeyConfig = null;
405+
406+ switch (KeyCode)
407+ {
408+ case 96:
409+ CurrentTenkeyConfig =
410+ (from p in TenKeyConfig
411+ where p.KeyCode == "T0"
412+ select p).Single();
413+ break;
414+
415+ case 97:
416+ CurrentTenkeyConfig =
417+ (from p in TenKeyConfig
418+ where p.KeyCode == "T1"
419+ select p).Single();
420+ break;
421+
422+ case 98:
423+ CurrentTenkeyConfig =
424+ (from p in TenKeyConfig
425+ where p.KeyCode == "T2"
426+ select p).Single();
427+ break;
428+
429+ case 99:
430+ CurrentTenkeyConfig =
431+ (from p in TenKeyConfig
432+ where p.KeyCode == "T3"
433+ select p).Single();
434+ break;
435+
436+ case 100:
437+ CurrentTenkeyConfig =
438+ (from p in TenKeyConfig
439+ where p.KeyCode == "T4"
440+ select p).Single();
441+ break;
442+
443+ case 101:
444+ CurrentTenkeyConfig =
445+ (from p in TenKeyConfig
446+ where p.KeyCode == "T5"
447+ select p).Single();
448+ break;
449+
450+ case 102:
451+ CurrentTenkeyConfig =
452+ (from p in TenKeyConfig
453+ where p.KeyCode == "T6"
454+ select p).Single();
455+ break;
456+
457+ case 103:
458+ CurrentTenkeyConfig =
459+ (from p in TenKeyConfig
460+ where p.KeyCode == "T7"
461+ select p).Single();
462+ break;
463+
464+ case 104:
465+ CurrentTenkeyConfig =
466+ (from p in TenKeyConfig
467+ where p.KeyCode == "T8"
468+ select p).Single();
469+ break;
470+
471+ case 105:
472+ CurrentTenkeyConfig =
473+ (from p in TenKeyConfig
474+ where p.KeyCode == "T9"
475+ select p).Single();
476+ break;
477+
478+ case 106:
479+ CurrentTenkeyConfig =
480+ (from p in TenKeyConfig
481+ where p.KeyCode == "Tastah"
482+ select p).Single();
483+ break;
484+
485+ case 107:
486+ CurrentTenkeyConfig =
487+ (from p in TenKeyConfig
488+ where p.KeyCode == "Tplus"
489+ select p).Single();
490+ break;
491+
492+ case 108:
493+ //なし
494+ break;
495+
496+ case 109:
497+ CurrentTenkeyConfig =
498+ (from p in TenKeyConfig
499+ where p.KeyCode == "Tminus"
500+ select p).Single();
501+ break;
502+
503+ case 110:
504+ CurrentTenkeyConfig =
505+ (from p in TenKeyConfig
506+ where p.KeyCode == "Tdot"
507+ select p).Single();
508+ break;
509+
510+ case 111:
511+ CurrentTenkeyConfig =
512+ (from p in TenKeyConfig
513+ where p.KeyCode == "Tslash"
514+ select p).Single();
515+ break;
516+
517+ default:
518+ break;
519+ }
520+
521+ if (CurrentTenkeyConfig != null)
522+ {
523+ if (CurrentTenkeyConfig.RollBack == true)
524+ {
525+ CSV.RollBack();
526+ CaptureRollBack();
527+ Log.Put("最後の保存データを一つ削除しました。");
528+ }
529+ else
530+ {
531+ Log.Put(CurrentTenkeyConfig.CSVString.Replace("\r\n", ""));
532+ if (CurrentTenkeyConfig.CaptureFlag == true)
533+ {
534+ NowTime = DateTime.Now;
535+ CaptureWindows();
536+ CSV.Add("\r\n");
537+ }
538+ //Log.Put(CurrentTenkeyConfig.KeyCode);
539+
540+ CSV.Add(CurrentTenkeyConfig.CSVString);
541+ PreCSVString = CurrentTenkeyConfig.CSVString;
542+ }
543+ bool addSuccess = SoundQue.TryAdd(CurrentTenkeyConfig.CaptureFlag, System.Threading.Timeout.Infinite);
544+ }
545+ }
546+ catch (Exception e)
547+ {
548+ Log.Put("CaptureTask():Exception" + e.Message);
549+ }
550+ }
551+ if (Environment.TickCount - LastTickCount < 5000)
552+ {
553+ ;
554+ }
555+ else
556+ {
557+ try
558+ {
559+ SetNumLock(true);
560+ //Log.Put("loop");
561+ //TaskLoopCount = 0;
562+ Log.Save();
563+ CSV.Save();
564+ }
565+ catch (Exception e)
566+ {
567+ Log.Put("CaptureTask():Exception2" + e.Message);
568+ }
569+ NowTime = DateTime.Now;
570+ }
571+ }
572+ }
573+
574+ /// <summary>
575+ /// 二つのファイルの最終書き込み日時を取得して比較するメソッド
576+ /// </summary>
577+ private int CompareLastWriteTime(string fileX, string fileY)
578+ {
579+ return DateTime.Compare(File.GetLastWriteTime(fileX), File.GetLastWriteTime(fileY));
580+ }
581+
582+ /// <summary>
583+ /// キャプチャしたPNGファイルの中で最も新しいグループを一つ削除する
584+ /// </summary>
585+ private void CaptureRollBack()
586+ {
587+ //pngファイルをすべて取得する
588+ var di = new DirectoryInfo(AppFolder() + "\\" + NowTime.ToString("yyMMdd") + "\\");
589+ var files = di.GetFiles("*.png", SearchOption.AllDirectories);
590+ //pngファイルが一つもなければ終了
591+ if (files.Length <= 0)
592+ {
593+ return;
594+ }
595+ var filenames = files.Select(x => x.FullName).ToArray();
596+
597+ //ファイルの更新日時でソート
598+ Array.Sort(filenames, CompareLastWriteTime);
599+
600+ //フルパスからファイル名の部分だけをとりだす
601+ var lastfilename = Path.GetFileName(filenames.Last());
602+
603+ if (lastfilename == "")
604+ {
605+ return;
606+ }
607+
608+ //プリフィクス yyMMdd_HHmmssfff 16文字をとりだす
609+ var prefix = Left(lastfilename, 16);
610+
611+ files = di.GetFiles(prefix + "*.png", SearchOption.AllDirectories);
612+ filenames = files.Select(x => x.FullName).ToArray();
613+ foreach (var x in filenames)
614+ {
615+ File.Delete(x);
616+ }
617+ }
618+
619+ /// <summary>
620+ /// UWPアプリのウインドウがEnumWindowsでつかまらないので代用としてFindWindowExを使用する
621+ /// </summary>
622+ /// <param name="lpEnumFunc"></param>
623+ /// <param name="lParam"></param>
624+ private void EnumWindowsWithUWP(EnumWindowsDelegate lpEnumFunc, IntPtr lParam)
625+ {
626+ var hwList = new List<IntPtr>();
627+ IntPtr childWindow = IntPtr.Zero;
628+ int i = 0;
629+
630+ while (i < 1000)
631+ {
632+ i++;
633+ childWindow = FindWindowEx(IntPtr.Zero, childWindow, null, null);
634+ if (childWindow == null)
635+ {
636+ return;
637+ }
638+
639+ if (hwList.Contains(childWindow))
640+ {
641+ continue;
642+ }
643+ else
644+ {
645+ hwList.Add(childWindow);
646+ }
647+
648+ if (!lpEnumFunc(childWindow, lParam))
649+ {
650+ return;
651+ }
652+ }
653+ }
654+
655+ /// <summary>
656+ /// ウインドウのキャプチャし、最後にスクリーンショットをキャプチャする
657+ /// </summary>
658+ private void CaptureWindows()
659+ {
660+ //! 保存用のデータフォルダが存在しなければ作成
661+ System.IO.Directory.CreateDirectory(AppFolder() + "\\" + NowTime.ToString("yyMMdd") + "\\");
662+ //! ウィンドウを列挙し、コールバック関数内で各ウインドウのキャプチャを行う
663+ try
664+ {
665+ //EnumWindows(new EnumWindowsDelegate(EnumWindowCallBack), IntPtr.Zero);
666+ EnumWindowsWithUWP(new EnumWindowsDelegate(EnumWindowCallBack), IntPtr.Zero);
667+ }
668+ catch (Exception e)
669+ {
670+ }
671+
672+ //デスクトップをキャプチャする
673+ // Bitmapの作成
674+ Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
675+ //Graphicsの作成
676+ Graphics g = Graphics.FromImage(bmp);
677+ //画面全体をコピーする
678+ g.CopyFromScreen(new Point(0, 0), new Point(0, 0), bmp.Size);
679+ //解放
680+ g.Dispose();
681+
682+ var pngfilename = NowTime.ToString("yyMMdd_HHmmssfff") + "_"
683+ + CurrentTenkeyConfig.CSVString.Replace("\r\n", "").Replace(",", "") + "_"
684+ + "screen_00000000_.png";
685+
686+ //ファイル名やフォルダ名として不適切な文字を除去してPNGファイル名とする。
687+ var invalidChars = System.IO.Path.GetInvalidFileNameChars();
688+ pngfilename = string.Concat(pngfilename.ToString().Where(c => !invalidChars.Contains(c)));
689+ bmp.Save(AppFolder() + "\\" + NowTime.ToString("yyMMdd") + "\\" + pngfilename, System.Drawing.Imaging.ImageFormat.Png);
690+ }
691+
692+ //public delegate bool EnumWindowsDelegate(IntPtr hWnd, IntPtr lparam);
693+
694+ //[DllImport("user32.dll")]
695+ //[return: MarshalAs(UnmanagedType.Bool)]
696+ //public extern static bool EnumWindows(EnumWindowsDelegate lpEnumFunc, IntPtr lparam);
697+
698+ //[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
699+ //private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
700+
701+ [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
702+ private static extern int GetWindowTextLength(IntPtr hWnd);
703+
704+ [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
705+ private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
706+
707+ //[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
708+ //private static extern Boolean IsWindowVisible(IntPtr hWnd);
709+
710+ [System.Runtime.InteropServices.DllImport("User32.dll")]
711+ private static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
712+
713+ // GetDpiForMonitorが返したDPIの種類
714+ private enum MonitorDpiType
715+ { Effective, Angular, Raw, Default = Effective }
716+
717+ // MonitorFromWindowが返したディスプレイの種類
718+ public enum MonitorDefaultTo { Null, Primary, Nearest }
719+
720+ // ウィンドウハンドルから、そのウィンドウが乗っているディスプレイハンドルを取得
721+ [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
722+ private static extern IntPtr MonitorFromWindow(IntPtr hwnd, MonitorDefaultTo dwFlags);
723+
724+ // ディスプレイハンドルからDPIを取得
725+ [DllImport("SHCore.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
726+ private static extern void GetDpiForMonitor(IntPtr hmonitor, MonitorDpiType dpiType, ref uint dpiX, ref uint dpiY);
727+
728+ private static Boolean EnumWindowCallBack(IntPtr hWnd, IntPtr lparam)
729+ {
730+ //visibleでないなら即リターン
731+ if (!IsWindowVisible(hWnd))
732+ {
733+ return true;
734+ }
735+
736+ //ウィンドウのタイトルの長さが0以下なら即リターン
737+ int textLen = GetWindowTextLength(hWnd);
738+ if (textLen <= 0)
739+ {
740+ return true;
741+ }
742+
743+ //ウィンドウのタイトルを取得する
744+ StringBuilder tsb = new StringBuilder(textLen + 1);
745+ GetWindowText(hWnd, tsb, tsb.Capacity);
746+ if (tsb.ToString().Length <= 0)
747+ {
748+ return true;
749+ }
750+ //Log.Put("tsb:" + tsb.ToString());
751+
752+ //ウィンドウのタイトルの中にキャプチャしないウインドウタイトルキーワードが含まれているか確認する
753+ foreach (string str in ClassConfig.IgnoreWindowTitles)
754+ {
755+ if (tsb.ToString().IndexOf(str) >= 0)
756+ {
757+ //Log.Put("WindowTitle が " + str + " と一致したのでキャプチャ処理スキップします");
758+ return true;
759+ }
760+ }
761+
762+ //ウィンドウのクラス名を取得する
763+ StringBuilder csb = new StringBuilder(256);
764+ GetClassName(hWnd, csb, csb.Capacity);
765+ if (csb.ToString().Length <= 0)
766+ {
767+ return true;
768+ }
769+ //Log.Put("csb:" + csb.ToString());
770+
771+ try
772+ {
773+ RECT gWB = new RECT(); ;
774+ if (hWnd.Equals(System.IntPtr.Zero))
775+ {
776+ return true;
777+ }
778+ else
779+ {
780+#if true
781+ GetWindowRect(hWnd, ref gWB);
782+ if ((gWB.right - gWB.left) < 100 || (gWB.bottom - gWB.top) < 100)
783+ {
784+ return true;
785+ }
786+#if false
787+ if (gWB.right < -100 || gWB.bottom < -100)
788+ {
789+ return true;
790+ }
791+#endif
792+ //Log.Put("----------");
793+ //Log.Put("タイトル,ハンドル:" + tsb.ToString() + "_" + (((UInt64)hWnd).ToString("x")));
794+ //Log.Put("left,right,top,bottom:" + gWB.left.ToString() + "," + gWB.right.ToString() + "," + gWB.top.ToString() + "," + gWB.bottom.ToString());
795+
796+ // ウィンドウが乗っているディスプレイのハンドルを取得する
797+ var hmonitor = MonitorFromWindow(hWnd, MonitorDefaultTo.Nearest);
798+
799+ // ディスプレイのDPIを取得する
800+ uint dpiX = 96;
801+ uint dpiY = 96;
802+ GetDpiForMonitor(hmonitor, MonitorDpiType.Default, ref dpiX, ref dpiY);
803+
804+ float scaleX = dpiX / 96;
805+ float scaleY = dpiY / 96;
806+ var width = (int)(scaleX * (float)(gWB.right - gWB.left));
807+ var height = (int)(scaleY * (float)(gWB.bottom - gWB.top));
808+
809+ using (Bitmap img = new Bitmap(width, height))
810+ using (Graphics memg = Graphics.FromImage(img))
811+ {
812+ IntPtr dc = memg.GetHdc();
813+
814+ PrintWindow(hWnd, dc, 0);
815+ memg.ReleaseHdc(dc);
816+ //SetAlpha(img, 255);
817+
818+#if false
819+ img.Save(AppFolder() + "\\" + NowTime.ToString("yyMMdd") + "\\"
820+ + NowTime.ToString("yyMMdd_HHmmssfff") + "_"
821+ + Tcommand.Replace("[capture]", "").Split(',')[0] + "_"
822+ + tsb.ToString() + "_"
823+ + ((UInt64)hWnd).ToString("X8")
824+ + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
825+#endif
826+#if false
827+ img.Save(AppFolder() + "\\" + NowTime.ToString("yyMMdd") + "\\"
828+ + NowTime.ToString("yyMMdd_HHmmssfff") + "_"
829+ + Tcommand.Replace("[capture]", "").Split(',')[0] + "_"
830+ + tsb.ToString() + "_"
831+ + ((UInt64)hWnd).ToString("X8")
832+ + ".gif", System.Drawing.Imaging.ImageFormat.Gif);
833+#endif
834+#if false
835+ //Format32bppRgb 透明色ありのPNGフォーマット
836+ img.Save(AppFolder() + "\\" + NowTime.ToString("yyMMdd") + "\\"
837+ + NowTime.ToString("yyMMdd_HHmmssfff") + "_"
838+ + Tcommand.Replace("[capture]", "").Split(',')[0] + "_"
839+ + tsb.ToString() + "_"
840+ + ((UInt64)hWnd).ToString("X8")
841+ + ".png", System.Drawing.Imaging.ImageFormat.Png);
842+#endif
843+ //Format24bppRgb 透明色なしのPNGフォーマット
844+ Rectangle cloneRect = new Rectangle(0, 0, img.Width, img.Height);
845+ Bitmap cloneimg = img.Clone(cloneRect, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
846+
847+ if (BmpHasColor(cloneimg) == false)
848+ {
849+ //Log.Put("ウインドウ " + tsb.ToString() + " のキャプチャをスキップします。");
850+ return true;
851+ }
852+ var pngfilename = NowTime.ToString("yyMMdd_HHmmssfff") + "_"
853+ + CurrentTenkeyConfig.CSVString.Replace("\r\n", "").Replace(",", "") + "_"
854+ + tsb.ToString() + "_"
855+ + ((UInt64)hWnd).ToString("X8")
856+ + "_.png";
857+
858+ //ファイル名やフォルダ名として不適切な文字を除去してPNGファイル名とする。
859+ var invalidChars = System.IO.Path.GetInvalidFileNameChars();
860+ pngfilename = string.Concat(pngfilename.ToString().Where(c => !invalidChars.Contains(c)));
861+
862+ cloneimg.Save(AppFolder() + "\\" + NowTime.ToString("yyMMdd") + "\\" + pngfilename, System.Drawing.Imaging.ImageFormat.Png);
863+ }
864+#endif
865+#if false
866+ GetWindowRect(hWnd, ref gWB);
867+ if ((gWB.right - gWB.left) < 100 || (gWB.bottom - gWB.top) < 100)
868+ {
869+ return true;
870+ }
871+
872+ RECT rec = new RECT();
873+ var size = GetClientRect(hWnd, out rec);
874+
875+ //Log.Put("----------");
876+ Log.Put("タイトル,ハンドル:" + tsb.ToString() + "_" + (((UInt64)hWnd).ToString("x")));
877+ //Log.Put("left,right,top,bottom:" + gWB.left.ToString() + "," + gWB.right.ToString() + "," + gWB.top.ToString() + "," + gWB.bottom.ToString());
878+
879+ //using (Bitmap img = new Bitmap(gWB.right - gWB.left, gWB.bottom - gWB.top))
880+ using (Bitmap img = new Bitmap(rec.right - rec.left, rec.bottom))
881+ using (Graphics memg = Graphics.FromImage(img))
882+ {
883+ IntPtr dc = memg.GetHdc();
884+
885+ PrintWindow(hWnd, dc, 0);
886+ //PrintWindow(hWnd, dc, 1);
887+ memg.ReleaseHdc(dc);
888+ //SetAlpha(img, 255);
889+ //Format24bppRgb 透明色なしのPNGフォーマット
890+ Rectangle cloneRect = new Rectangle(0, 0, img.Width, img.Height);
891+ Bitmap cloneimg = img.Clone(cloneRect, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
892+
893+ if (BmpHasColor(cloneimg) == false)
894+ {
895+ Log.Put("カラー判定: false ウインドウ " + tsb.ToString() + " のキャプチャをスキップします。");
896+ //return true;
897+ }
898+ var pngfilename = NowTime.ToString("yyMMdd_HHmmssfff") + "_"
899+ + CurrentTenkeyConfig.CSVString.Replace("\r\n", "").Replace(",", "") + "_"
900+ + tsb.ToString() + "_"
901+ + ((UInt64)hWnd).ToString("X8")
902+ + "_.png";
903+
904+ //ファイル名やフォルダ名として不適切な文字を除去してPNGファイル名とする。
905+ var invalidChars = System.IO.Path.GetInvalidFileNameChars();
906+ pngfilename = string.Concat(pngfilename.ToString().Where(c => !invalidChars.Contains(c)));
907+
908+ //cloneimg.Save(AppFolder() + "\\" + NowTime.ToString("yyMMdd") + "\\" + pngfilename, System.Drawing.Imaging.ImageFormat.Png);
909+ img.Save(AppFolder() + "\\" + NowTime.ToString("yyMMdd") + "\\" + pngfilename, System.Drawing.Imaging.ImageFormat.Png);
910+
911+ Log.Put("保存: " + pngfilename);
912+ }
913+#endif
914+ }
915+ }
916+ catch (Exception e)
917+ {
918+ Log.Put("EnuWindowCallBack():Exception " + e.Message);
919+ Log.Put("EnuWindowCallBack():tsb " + tsb.ToString());
920+ }
921+ return true;
922+ }
923+
924+#if false
925+ /***********************************************************//*!
926+ * @brief αチャンネルを指定する
927+ * @param[in] bmp αチャンネルを指定するビットマップデータ
928+ * @param[in] alpha αチャンネル値 0:完全透過~255:完全不透過
929+ **************************************************************/
930+ public static void SetAlpha(Bitmap bmp, byte alpha)
931+ {
932+ if (bmp == null) throw new ArgumentNullException("bmp");
933+
934+ var data = bmp.LockBits(
935+ new Rectangle(0, 0, bmp.Width, bmp.Height),
936+ System.Drawing.Imaging.ImageLockMode.ReadWrite,
937+ System.Drawing.Imaging.PixelFormat.Format32bppArgb);
938+
939+ var line = data.Scan0;
940+ var eof = line + data.Height * data.Stride;
941+ while (line != eof)
942+ {
943+ var pixelAlpha = line + 3;
944+ var eol = pixelAlpha + data.Width * 4;
945+ while (pixelAlpha != eol)
946+ {
947+ Marshal.WriteByte(pixelAlpha, alpha);
948+ pixelAlpha += 4;
949+ }
950+ line += data.Stride;
951+ }
952+ bmp.UnlockBits(data);
953+ }
954+#endif
955+ }
956+}
\ No newline at end of file
--- trunk/TenKeyCaptureCS2/TenKeyCaptureCS/ClassMyCommon.cs (nonexistent)
+++ trunk/TenKeyCaptureCS2/TenKeyCaptureCS/ClassMyCommon.cs (revision 213)
@@ -0,0 +1,235 @@
1+/***********************************************************//*!
2+ * @brief 共通部品
3+ **************************************************************/
4+
5+using System;
6+using System.Collections.Generic;
7+using System.Linq;
8+using System.Text;
9+using System.Threading.Tasks;
10+using System.Windows;
11+using System.Windows.Forms;
12+using System.Collections.Concurrent;
13+using static System.Console;
14+
15+namespace TenKeyCapture
16+{
17+ /// <summary>
18+ /// 共通部品クラス よく使う処理とかオブジェクトを定義
19+ /// </summary>
20+ internal class ClassMyCommon
21+ {
22+ //! プログラムのタイトル
23+ public const string TITLE = "TenKeyCapture";
24+
25+ //! プログラムのバージョン
26+ public const string VERSION = "01.03-200226";
27+
28+ //! プログラム開始時の表示メッセージ
29+ public const string OPENING_MSG
30+ = "Programmed by S.Hori\r\n"
31+ + "\r\n"
32+ + "下記のWEBサイトから最新版を入手できます。\r\n"
33+ + "https://osdn.net/users/hor931101jp/pf/02 \r\n"
34+ + "下記のSVNリポジトリからソースコードをチェックアウトできます。\r\n"
35+ + "svn://svn.pf.osdn.net/h/ho/hor931101jp/02/tags \r\n";
36+
37+ //! メインフォームのインスタンス
38+ public static Form frmMain;
39+
40+ //!設定用インスタンス宣言と生成
41+ public static ClassConfig Config = new ClassConfig();
42+
43+ //! ログの管理インスタンス
44+ public static ClassLog Log;
45+
46+ //! CSVの管理インスタンス
47+ public static ClassCSV CSV = new ClassCSV();
48+
49+ //! キーボードの設定管理インスタンス
50+ public static ClassTenKeyConfig[] TenKeyConfig = {
51+ new ClassTenKeyConfig("T0"),
52+ new ClassTenKeyConfig("T1"),
53+ new ClassTenKeyConfig("T2"),
54+ new ClassTenKeyConfig("T3"),
55+ new ClassTenKeyConfig("T4"),
56+ new ClassTenKeyConfig("T5"),
57+ new ClassTenKeyConfig("T6"),
58+ new ClassTenKeyConfig("T7"),
59+ new ClassTenKeyConfig("T8"),
60+ new ClassTenKeyConfig("T9"),
61+ new ClassTenKeyConfig("Tslash"),
62+ new ClassTenKeyConfig("Tastah"),
63+ new ClassTenKeyConfig("Tminus"),
64+ new ClassTenKeyConfig("Tplus"),
65+ new ClassTenKeyConfig("Tdot"),
66+ };
67+
68+ //! 現在時刻格納変数
69+ public static DateTime NowTime = DateTime.Now;
70+
71+ //! サウンドリクエストのキュー(trueならキャプチャ音 falseならBEEP音)
72+ public static BlockingCollection<Boolean> SoundQue = new BlockingCollection<Boolean>();
73+
74+ //! キーコードを格納するキュー
75+ public static BlockingCollection<uint> KeyQue = new BlockingCollection<uint>();
76+
77+ /// <summary>
78+ /// Application.DoEventsとThread.Sleepをしながら待機
79+ /// </summary>
80+ /// <param name="WaitTime">待ち時間[ms]</param>
81+ static public void WaitTickCount(Int32 WaitTime)
82+ {
83+ Int64 StartTickCount = Environment.TickCount;
84+ Int64 NowTickCount;
85+ do
86+ {
87+ Application.DoEvents();
88+ System.Threading.Thread.Sleep(1);
89+ NowTickCount = Environment.TickCount;
90+ }
91+ while ((NowTickCount - StartTickCount) < WaitTime);
92+ }
93+
94+ [System.Runtime.InteropServices.DllImport("user32.dll")]
95+ private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
96+
97+ [System.Runtime.InteropServices.DllImport("user32.dll")]
98+ private static extern bool DrawMenuBar(IntPtr hWnd);
99+
100+ [System.Runtime.InteropServices.DllImport("user32.dll")]
101+ private static extern bool RemoveMenu(IntPtr hMenu, uint uPosition, uint uFlags);
102+
103+ /// <summary>
104+ /// フォームの右上ボタンと左上メニューのカスタマイズ
105+ /// フォーム右上ボタンのうち[x]ボタンを無効化する。左上メニューの[閉じる]を消去
106+ /// </summary>
107+ /// <param name="f">対象とするフォーム</param>
108+ public static void FormControlBoxCustomize(Form f)
109+ {
110+ //const uint SC_SIZE = 0xF000; //システムメニューの「サイズ変更」
111+ //const uint SC_MOVE = 0xF010; //システムメニューの「移動」
112+ //const uint SC_MINIMIZE = 0xF020; //システムメニューの「最小化」
113+ //const uint SC_MAXIMIZE = 0xF030; //システムメニューの「最大化」
114+ const uint SC_CLOSE = 0xF060; //システムメニューの「閉じる」
115+ //const uint SC_RESTORE = 0xF120; //システムメニューの「元のサイズに戻す」
116+ const uint MF_BYCOMMAND = 0x0; //メニュー項目指定
117+ const uint MF_BYPOSITION = 0x400; //ポジション指定
118+ //const uint MF_ENABLED = 0x0; //有効化
119+ //const uint MF_GRAYED = 0x1; //無効化
120+ //const uint MF_DISABLED = 0x2; //半無効化(見かけ上有効)
121+ bool DUMMY;
122+
123+ //「区切り線」の削除
124+ DUMMY = RemoveMenu(GetSystemMenu(f.Handle, false), 5, MF_BYPOSITION);
125+ //「閉じる」の削除 + xボタンの無効化
126+ DUMMY = RemoveMenu(GetSystemMenu(f.Handle, false), SC_CLOSE, MF_BYCOMMAND);
127+ //描画(変更を反映)
128+ DUMMY = DrawMenuBar(f.Handle);
129+ }
130+
131+ /// <summary>
132+ /// 自身の exe ファイルの存在するフォルダを返す
133+ /// </summary>
134+ /// <returns>自身の exe ファイルの存在するフォルダパス 最後に '\' なし</returns>
135+ public static string AppFolder()
136+ {
137+ return System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
138+ }
139+
140+ /// <summary>
141+ /// 文字列を渡して先頭から指定した長さだけの文字列を切り出して返す
142+ /// BASICに昔からある Left$ 関数
143+ /// </summary>
144+ /// <param name="str">文字列</param>
145+ /// <param name="len">長さ</param>
146+ /// <returns>切り出した文字列</returns>
147+ public static string Left(string str, int len)
148+ {
149+ if (len < 0)
150+ {
151+ throw new ArgumentException("引数'len'は0以上でなければなりません。");
152+ }
153+ if (str == null)
154+ {
155+ return "";
156+ }
157+ if (str.Length <= len)
158+ {
159+ return str;
160+ }
161+ return str.Substring(0, len);
162+ }
163+
164+ /// <summary>
165+ /// 文字列の末尾から指定した長さの文字列を取得する
166+ /// BASICに昔からある Right$ 関数
167+ /// </summary>
168+ /// <param name="str">文字列</param>
169+ /// <param name="len">長さ</param>
170+ /// <returns>切り出した文字列</returns>
171+ public static string Right(string str, int len)
172+ {
173+ if (len < 0)
174+ {
175+ throw new ArgumentException("引数'len'は0以上でなければなりません。");
176+ }
177+ if (str == null)
178+ {
179+ return "";
180+ }
181+ if (str.Length <= len)
182+ {
183+ return str;
184+ }
185+ return str.Substring(str.Length - len, len);
186+ }
187+
188+ /// <summary>
189+ /// Bitmapが真っ黒でないか判定する
190+ /// </summary>
191+ /// <param name="bmp">bitmapデータ</param>
192+ /// <returns>true ちゃんとした色がある。 false 真っ黒</returns>
193+ public static Boolean BmpHasColor(System.Drawing.Bitmap bmp)
194+ {
195+ var retval = false;
196+
197+ //ビットマップデータをアンマネージ配列にコピーしてから処理する
198+ System.Drawing.Imaging.BitmapData data = bmp.LockBits(
199+ new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height),
200+ System.Drawing.Imaging.ImageLockMode.ReadWrite,
201+ System.Drawing.Imaging.PixelFormat.Format32bppArgb);
202+ byte[] buf = new byte[bmp.Width * bmp.Height * 4];
203+ System.Runtime.InteropServices.Marshal.Copy(data.Scan0, buf, 0, buf.Length);
204+
205+ //取得したBMPが真っ黒かどうか確認する。ただしすべてのピクセルを確認すると時間かかるので、skiplenだけスキップして100箇所のみ確認する。
206+ var skiplen = ((UInt32)(buf.Length / 100)) & 0xfffffffc - 4; //skiplenは4の倍数でなければならない
207+ if (skiplen < 0) skiplen = 0;
208+
209+ for (UInt32 i = 0; i < buf.Length;)
210+ {
211+ //黒であれば R=G=B=0 Alpha=Don't Care
212+ if (buf[i++] != 0)
213+ {
214+ retval = true;
215+ break;
216+ }
217+ if (buf[i++] != 0)
218+ {
219+ retval = true;
220+ break;
221+ }
222+ if (buf[i++] != 0)
223+ {
224+ retval = true;
225+ break;
226+ }
227+ i++;
228+ i += skiplen;
229+ }
230+ bmp.UnlockBits(data);
231+
232+ return retval;
233+ }
234+ }
235+}
\ No newline at end of file
--- trunk/TenKeyCaptureCS2/TenKeyCaptureCS/app.manifest (nonexistent)
+++ trunk/TenKeyCaptureCS2/TenKeyCaptureCS/app.manifest (revision 213)
@@ -0,0 +1,72 @@
1+<?xml version="1.0" encoding="utf-8"?>
2+<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
3+ <assemblyIdentity version="1.0.0.0" name="MyApplication.app" />
4+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
5+ <security>
6+ <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
7+ <!-- UAC マニフェスト オプション
8+ Windows のユーザー アカウント制御のレベルを変更するには、
9+ requestedExecutionLevel ノードを以下のいずれかで置換します。
10+
11+ <requestedExecutionLevel level="asInvoker" uiAccess="false" />
12+ <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
13+ <requestedExecutionLevel level="highestAvailable" uiAccess="false" />
14+
15+ requestedExecutionLevel 要素を指定すると、ファイルおよびレジストリの仮想化が無効にされます。
16+ アプリケーションが下位互換性を保つためにこの仮想化を要求する場合、この要素を
17+ 削除します。
18+ -->
19+ <requestedExecutionLevel level="asInvoker" uiAccess="false" />
20+ </requestedPrivileges>
21+ </security>
22+ </trustInfo>
23+
24+ <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
25+ <application>
26+ <!-- このアプリケーションがテストされ、動作するよう設計された Windows バージョンの
27+ 一覧。適切な要素をコメント解除すると、最も互換性のある環境を Windows が
28+ 自動的に選択します。-->
29+
30+ <!-- Windows Vista -->
31+ <!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
32+
33+ <!-- Windows 7 -->
34+ <!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
35+
36+ <!-- Windows 8 -->
37+ <!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
38+
39+ <!-- Windows 8.1 -->
40+ <!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
41+
42+ <!-- Windows 10 -->
43+ <!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->
44+ </application>
45+ </compatibility>
46+
47+ <!-- アプリケーションが DPI 対応であり、それ以上の DPI で Windows によって自動的にスケーリングされないことを
48+ 示します。Windows Presentation Foundation (WPF) アプリケーションは自動的に DPI に対応し、オプトインする必要は
49+ ありません。さらに、この設定にオプトインする .NET Framework 4.6 を対象とする Windows Forms アプリケーションは、
50+ app.config ファイルで 'EnableWindowsFormsHighDpiAutoResizing' 設定を 'true' に設定する必要があります。-->
51+
52+ <application xmlns="urn:schemas-microsoft-com:asm.v3">
53+ <windowsSettings>
54+ <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">per monitor</dpiAware>
55+ </windowsSettings>
56+ </application>
57+
58+ <!-- Windows のコモン コントロールとダイアログのテーマを有効にします (Windows XP 以降) -->
59+ <!--
60+ <dependency>
61+ <dependentAssembly>
62+ <assemblyIdentity
63+ type="win32"
64+ name="Microsoft.Windows.Common-Controls"
65+ version="6.0.0.0"
66+ processorArchitecture="*"
67+ publicKeyToken="6595b64144ccf1df"
68+ language="*" />
69+ </dependentAssembly>
70+ </dependency>
71+ -->
72+</assembly>
\ No newline at end of file
--- trunk/TenKeyCaptureCS2/TenKeyCaptureCS/ClassCSV.cs (nonexistent)
+++ trunk/TenKeyCaptureCS2/TenKeyCaptureCS/ClassCSV.cs (revision 213)
@@ -0,0 +1,127 @@
1+using System;
2+using System.IO;
3+using System.Collections.Generic;
4+using System.Linq;
5+using System.Text;
6+using System.Threading.Tasks;
7+using static TenKeyCapture.ClassMyCommon;
8+
9+namespace TenKeyCapture
10+{
11+ /// <summary>
12+ /// CSVクラス CSVを管理する
13+ /// </summary>
14+ internal class ClassCSV
15+ {
16+ ///<summary>CSVファイル保存用の文字列を確保する</summary>
17+ private string _ShadowBuf = "";
18+
19+ /// <summary>
20+ /// CSVに保存する文字列を一時的に文字列に保存する。
21+ /// </summary>
22+ /// <param name="stradd">テンキーに設定された文字列</param>
23+ public void Add(string stradd)
24+ {
25+ //! 改行 [CR][LF] 0D 0A があったときはタイムスタンプを追加
26+ string straddCSV = stradd.Replace("\r\n", NowTime.ToString("\r\nHH:mm:ss,"));
27+
28+ _ShadowBuf += straddCSV;
29+ //Log.Put("CSVadd() " + straddCSV);
30+ }
31+
32+ /// <summary>
33+ /// CSV最後の一行削除
34+ /// </summary>
35+ public void RollBack()
36+ {
37+ string str = "";
38+ try
39+ {
40+ //! 読み込み
41+ using (var sr = new StreamReader(
42+ AppFolder() + "\\" + NowTime.ToString("yyMMdd") + "\\" + NowTime.ToString("yyMMdd") + ".csv"
43+ , Encoding.GetEncoding("shift_jis")
44+ )
45+ )
46+ {
47+ str = sr.ReadToEnd();
48+ }
49+ }
50+ catch (Exception ex)
51+ {
52+ //Log.Put(ex.Message);
53+ }
54+
55+ str += _ShadowBuf;
56+ if (str.Length <= 0)
57+ {
58+ return;
59+ }
60+
61+ string[] sep = { "\r\n" };//Separater
62+ string[] arr = str.Split(sep, StringSplitOptions.None);
63+
64+ str = arr[0];
65+ for (int i = 1; i < (arr.Length - 1); i++)
66+ {
67+ str += "\r\n" + arr[i];
68+ }
69+
70+ //! 上書きモードで書き込み
71+ using (StreamWriter sw = new StreamWriter(
72+ AppFolder() + "\\" + NowTime.ToString("yyMMdd") + "\\" + NowTime.ToString("yyMMdd") + ".csv",
73+ false,
74+ Encoding.GetEncoding("shift_jis")
75+ )
76+ )
77+ {
78+ sw.Write(str);
79+ }
80+ _ShadowBuf = "";
81+ }
82+
83+ /// <summary>CSVファイル保存失敗したときの時刻</summary>
84+ private static Int64 ErrorTickCount = 0;
85+
86+ /// <summary>
87+ /// CSVに保存
88+ /// </summary>
89+ public void Save()
90+ {
91+ if (_ShadowBuf.Length == 0)
92+ {
93+ return;
94+ }
95+ //Log.Put("CSV.Save()");
96+
97+ //CSVファイル保存失敗したときは10秒間は保存しない。
98+ if ((Environment.TickCount - ErrorTickCount) < 10000)
99+ {
100+ return;
101+ }
102+
103+ try
104+ {
105+ //! データフォルダ作成(ユーザーが消してしまった場合に備えて)
106+ Directory.CreateDirectory(AppFolder() + "\\" + NowTime.ToString("yyMMdd") + "\\");
107+
108+ //! 追記モードで書き込み
109+ using (StreamWriter sw = new StreamWriter(
110+ AppFolder() + "\\" + NowTime.ToString("yyMMdd") + "\\" + NowTime.ToString("yyMMdd") + ".csv",
111+ true,
112+ Encoding.GetEncoding("shift_jis")
113+ )
114+ )
115+ {
116+ sw.Write(_ShadowBuf);
117+ }
118+ _ShadowBuf = "";
119+ }
120+ catch (Exception e)
121+ {
122+ Log.Put("CSVファイルの保存に失敗しました。" + e.Message);
123+ ErrorTickCount = Environment.TickCount;
124+ }
125+ }
126+ }
127+}
\ No newline at end of file
--- trunk/TenKeyCaptureCS2/TenKeyCaptureCS/ClassConfig.cs (nonexistent)
+++ trunk/TenKeyCaptureCS2/TenKeyCaptureCS/ClassConfig.cs (revision 213)
@@ -0,0 +1,299 @@
1+/***********************************************************//*!
2+ * @brief 設定管理
3+ **************************************************************/
4+
5+using System;
6+using System.IO;
7+using System.Collections.Generic;
8+using System.Linq;
9+using System.Text;
10+using System.Threading.Tasks;
11+using static TenKeyCapture.ClassMyCommon;
12+using System.Xml.Linq;
13+
14+namespace TenKeyCapture
15+{
16+ /// <summary>
17+ /// キーボード設定管理クラス
18+ /// </summary>
19+ internal class ClassTenKeyConfig
20+ {
21+ /// <summary>キーが押された時にCSVに記入する文字列</summary>
22+ public string CSVString;
23+
24+ /// <summary>キーが押された時にキャプチャするかどうかのフラグ</summary>
25+ public Boolean CaptureFlag;
26+
27+ /// <summary>キーの識別文字列</summary>
28+ public string KeyCode;
29+
30+ /// <summary>キーが押された時に直前のキー入力をキャンセルするかどうかのフラグ</summary>
31+ public Boolean RollBack;
32+
33+ /// <summary>
34+ /// コンストラクタ キーボード設定管理クラス
35+ /// </summary>
36+ /// <param name="SetKeyCode">キー識別用コード</param>
37+ public ClassTenKeyConfig(string SetKeyCode)
38+ {
39+ KeyCode = SetKeyCode;
40+ CSVString = "\r\n";
41+ CaptureFlag = true;
42+ RollBack = false;
43+ }
44+ }
45+
46+ /// <summary>
47+ /// 設定管理クラス
48+ /// </summary>
49+ internal class ClassConfig
50+ {
51+ /// <summary>設定データ格納ファイル名(フルパス付き)</summary>
52+ private string APPini = AppFolder() + "\\" + TITLE + ".ini";
53+
54+ /// <summary>デバッグフラグ</summary>
55+ public Int16 DebugFlag = 0;
56+
57+ /// <summary>ウインドウタイトルに下記の文字列が含まれていた場合キャプチャ対象外となる</summary>
58+ public static string[] IgnoreWindowTitles = { "" };
59+
60+ /// <summary>
61+ /// 設定xmlファイルから設定データ読み出し
62+ /// </summary>
63+ public void Load()
64+ {
65+ try
66+ {
67+ //! INIファイルがあるか判定する。なければ初期値でINIファイルを生成する。
68+ if (!File.Exists(APPini))
69+ {
70+ SaveIni();
71+ }
72+
73+ // INIファイルを読みだす。
74+ var xmlsource = XDocument.Load(APPini);
75+
76+ //Log.Put("App.ini LOAD" + "\r\n" + xmlsource + "\r\n");
77+
78+ var skip = false;
79+
80+ // INIファイルの中身を解釈する
81+ foreach (ClassTenKeyConfig c in TenKeyConfig)
82+ {
83+ var Element1 = (from p in xmlsource.Elements("APPini").Elements("TenKeyConfig")
84+ where p.Element("KeyCode").Value == c.KeyCode
85+ select p).Single();
86+ if (Element1 != null)
87+ {
88+ string xmlvalue;
89+ try
90+ {
91+ xmlvalue = Element1.Element("CSVString").Value;
92+ c.CSVString = xmlvalue;
93+ }
94+ catch (Exception e)
95+ {
96+ Log.Put(c.KeyCode + ".CSVString の読込をスキップしました。");
97+ skip = true;
98+ }
99+
100+ try
101+ {
102+ xmlvalue = Element1.Element("CaptureFlag").Value;
103+ c.CaptureFlag = Convert.ToBoolean(xmlvalue);
104+ }
105+ catch (Exception e)
106+ {
107+ Log.Put(c.KeyCode + ".CaptureFlag の読込をスキップしました。");
108+ skip = true;
109+ }
110+
111+ try
112+ {
113+ xmlvalue = Element1.Element("RollBack").Value;
114+ c.RollBack = Convert.ToBoolean(xmlvalue);
115+ }
116+ catch (Exception e)
117+ {
118+ Log.Put(c.KeyCode + ".RollBack の読込をスキップしました。");
119+ skip = true;
120+ }
121+ }
122+ }
123+
124+ var Element2 = (from p in xmlsource.Elements("APPini").Elements("IgnoreWindowTitles")
125+ select p).Single();
126+ IgnoreWindowTitles = Element2.Value.Split(',');
127+
128+ //読み込みがスキップした場合は現状の設定でConfig.iniを生成する。
129+ if (skip)
130+ {
131+ Config.Save();
132+ }
133+ }
134+ catch (Exception ex)
135+ {
136+ Log.Put("Error:Config.Load()");
137+ Log.Put("ex.Message\r\n" + ex.Message);
138+ Log.Put("ex.StacTrace\r\n" + ex.StackTrace);
139+ }
140+ }
141+
142+ /// <summary>
143+ /// 設定データ表示
144+ /// </summary>
145+ public void Show()
146+ {
147+ // 読み出した結果を表示
148+ Log.Put("設定は以下の通りです。");
149+ foreach (ClassTenKeyConfig c in TenKeyConfig)
150+ {
151+ Log.Put(c.KeyCode);
152+ Log.Put("RollBack = " + c.RollBack);
153+ Log.Put("CaptureFlag = " + c.CaptureFlag);
154+ Log.Put("CSVString = " + c.CSVString);
155+ c.CSVString = c.CSVString.Replace("\\n", "\r\n");
156+ }
157+
158+ // IgnoreWindowTitles配列内のデータをすべてカンマ区切りで連結する
159+ Log.Put("IgnoreWindowTitle = \"" + string.Join(",", IgnoreWindowTitles) + "\"");
160+ }
161+
162+ /// <summary>
163+ /// xmlファイルへ設定データのを書き込み
164+ /// </summary>
165+ public void Save()
166+ {
167+ var XDoc = new XDocument(
168+ new XDeclaration("1.0", "utf-8", "true")
169+ , new XComment("[重要]このファイルを編集する前に必ず TenKeyCapture を終了させてください。")
170+ );
171+
172+ var APPini_element = new XElement("APPini");
173+ APPini_element.Add(new XElement("APPini_VERSION", "01.10"));
174+
175+ foreach (var x in TenKeyConfig)
176+ {
177+ // W3C勧告によるとXMLファイル内での改行コードは \n であるべきらしいので変換する。
178+ var xCSVString = x.CSVString.Replace("\r\n", @"\n");
179+
180+ APPini_element.Add(
181+ new XElement("TenKeyConfig",
182+ new XElement("KeyCode", x.KeyCode),
183+ new XElement("CSVString", xCSVString),
184+ new XElement("RollBack", x.RollBack),
185+ new XElement("CaptureFlag", x.CaptureFlag)
186+ )
187+ );
188+ }
189+ APPini_element.Add(new XElement("IgnoreWindowTitles", string.Join(",", IgnoreWindowTitles)));
190+ XDoc.Add(APPini_element);
191+ XDoc.Save(APPini);
192+ }
193+
194+ /// <summary>
195+ /// xmlファイルへ設定データの初期値を書き込み
196+ /// </summary>
197+ public void SaveIni()
198+ {
199+ var XDoc = new XDocument(new XDeclaration("1.0", "utf-8", "true"),
200+ new XComment("[重要]このファイルを編集する前に必ず TenKeyCapture を終了させてください。"),
201+ new XElement("APPini",
202+ new XElement("APPini_VERSION", "01.10"),
203+ new XElement("TenKeyConfig",
204+ new XElement("KeyCode", "T0"),
205+ new XElement("CSVString", "静止物,"),
206+ new XElement("RollBack", false),
207+ new XElement("CaptureFlag", false)
208+ ),
209+ new XElement("TenKeyConfig",
210+ new XElement("KeyCode", "T1"),
211+ new XElement("CSVString", "左後,,,"),
212+ new XElement("RollBack", false),
213+ new XElement("CaptureFlag", true)
214+ ),
215+ new XElement("TenKeyConfig",
216+ new XElement("KeyCode", "T2"),
217+ new XElement("CSVString", "真後,,,"),
218+ new XElement("RollBack", false),
219+ new XElement("CaptureFlag", true)
220+ ),
221+ new XElement("TenKeyConfig",
222+ new XElement("KeyCode", "T3"),
223+ new XElement("CSVString", "右後,,,"),
224+ new XElement("RollBack", false),
225+ new XElement("CaptureFlag", true)
226+ ),
227+ new XElement("TenKeyConfig",
228+ new XElement("KeyCode", "T4"),
229+ new XElement("CSVString", "真左,,,"),
230+ new XElement("RollBack", false),
231+ new XElement("CaptureFlag", true)
232+ ),
233+ new XElement("TenKeyConfig",
234+ new XElement("KeyCode", "T5"),
235+ new XElement("CSVString", ""),
236+ new XElement("RollBack", true),
237+ new XElement("CaptureFlag", false)
238+ ),
239+ new XElement("TenKeyConfig",
240+ new XElement("KeyCode", "T6"),
241+ new XElement("CSVString", "真右,,,"),
242+ new XElement("RollBack", false),
243+ new XElement("CaptureFlag", true)
244+ ),
245+ new XElement("TenKeyConfig",
246+ new XElement("KeyCode", "T7"),
247+ new XElement("CSVString", "左前,,,"),
248+ new XElement("RollBack", false),
249+ new XElement("CaptureFlag", true)
250+ ),
251+ new XElement("TenKeyConfig",
252+ new XElement("KeyCode", "T8"),
253+ new XElement("CSVString", "正面,,,"),
254+ new XElement("RollBack", false),
255+ new XElement("CaptureFlag", true)
256+ ),
257+ new XElement("TenKeyConfig",
258+ new XElement("KeyCode", "T9"),
259+ new XElement("CSVString", "右前,,,"),
260+ new XElement("RollBack", false),
261+ new XElement("CaptureFlag", true)
262+ ),
263+ new XElement("TenKeyConfig",
264+ new XElement("KeyCode", "Tslash"),
265+ new XElement("CSVString", "人・自転車,"),
266+ new XElement("RollBack", false),
267+ new XElement("CaptureFlag", false)
268+ ),
269+ new XElement("TenKeyConfig",
270+ new XElement("KeyCode", "Tastah"),
271+ new XElement("CSVString", "バイク,"),
272+ new XElement("RollBack", false),
273+ new XElement("CaptureFlag", false)
274+ ),
275+ new XElement("TenKeyConfig",
276+ new XElement("KeyCode", "Tminus"),
277+ new XElement("CSVString", "車,"),
278+ new XElement("RollBack", false),
279+ new XElement("CaptureFlag", false)
280+ ),
281+ new XElement("TenKeyConfig",
282+ new XElement("KeyCode", "Tplus"),
283+ new XElement("CSVString", "大型車,"),
284+ new XElement("RollBack", false),
285+ new XElement("CaptureFlag", false)
286+ ),
287+ new XElement("TenKeyConfig",
288+ new XElement("KeyCode", "Tdot"),
289+ new XElement("CSVString", "不明,"),
290+ new XElement("RollBack", false),
291+ new XElement("CaptureFlag", false)
292+ ),
293+ new XElement("IgnoreWindowTitles", "Program Manager,フォト,シェル,設定,テレビ")
294+ )
295+ );
296+ XDoc.Save(APPini);
297+ }
298+ }
299+}
\ No newline at end of file
--- trunk/TenKeyCaptureCS2/TenKeyCaptureCS/ClassLog.cs (nonexistent)
+++ trunk/TenKeyCaptureCS2/TenKeyCaptureCS/ClassLog.cs (revision 213)
@@ -0,0 +1,173 @@
1+/***********************************************************//*!
2+ * @brief ログ処理
3+ **************************************************************/
4+
5+using System;
6+using System.Collections.Generic;
7+using System.Linq;
8+using System.Text;
9+using System.Threading.Tasks;
10+using System.Windows.Forms;
11+using System.IO;
12+using static TenKeyCapture.ClassMyCommon;
13+
14+namespace TenKeyCapture
15+{
16+ /// <summary>
17+ /// ログクラス ログを管理する
18+ /// </summary>
19+ internal class ClassLog
20+ {
21+ /// <summary> ログを保存するフルパス付ファイル名</summary>
22+ private string LogFileName;
23+
24+ /// <summary> ファイル保存用のログ文字列を確保する</summary>
25+ private string _ShadowBuf;
26+
27+ /// <summary> ログ表示用テキストボックス</summary>
28+ private TextBox _LogTextBox;
29+
30+ /// <summary>
31+ /// コンストラクタ
32+ /// </summary>
33+ /// <param name="LogTextBox">ログ表示用のテキストボックス</param>
34+ public ClassLog(TextBox LogTextBox)
35+ {
36+ _LogTextBox = LogTextBox;
37+ _LogTextBox.Text = "";
38+ _ShadowBuf = "";
39+ LogFileName = ClassMyCommon.AppFolder() + "\\" + ClassMyCommon.TITLE
40+ + "Log" + System.DateTime.Now.ToString("yyMMdd") + ".txt";
41+ }
42+
43+ /// <summary>
44+ /// 他のスレッドからコールする為のデリゲート
45+ /// </summary>
46+ /// <param name="stradd">ログへ追加する文字列</param>
47+ private delegate void Add_Callback(string stradd);
48+
49+ /// <summary>
50+ /// ログに文字列を追加する ログの表示は更新スクロールされない
51+ /// </summary>
52+ /// <param name="stradd">ログへ追加する文字列</param>
53+ public void Add(string stradd)
54+ {
55+ if (stradd == "")
56+ {
57+ //! 文字列がカラなら即終了
58+ return;
59+ }
60+
61+ if (_LogTextBox.InvokeRequired)
62+ {
63+ //! 別スレッドから呼び出された場合デリゲートからコールバックさせる
64+ _LogTextBox.Invoke(new Add_Callback(Add), stradd);
65+ return;
66+ }
67+
68+ //! 表示されている古いログは削除する
69+ DeleteOld();
70+
71+ // タイムスタンプ文字列を生成
72+ string TimeStamp = System.DateTime.Now.ToString("MM/dd HH:mm:ss : ");
73+ // ログ追加文字列の先頭にタイムスタンプを追加
74+ stradd = TimeStamp + stradd;
75+
76+ // ログ追加文字列の最後尾に "\r\n" があった場合は、いったん削除する
77+ if (stradd.Substring(stradd.Length - "\r\n".Length, "\r\n".Length) == "\r\n")
78+ {
79+ stradd = stradd.Substring(0, stradd.Length - "\r\n".Length);
80+ }
81+
82+ // ログ追加文字列の中に "\r\n" があった場合は、"\r\n+タイムスタンプ" に置換する
83+ stradd = stradd.Replace("\r\n", "\r\n" + TimeStamp);
84+
85+ // ログ追加文字列の最後尾に "\r\n" を追加
86+ stradd += "\r\n";
87+
88+ // 加工したログ追加文字列を保存用文字列とテキストボックスへ追加
89+ _LogTextBox.Text += stradd;
90+ _ShadowBuf += stradd;
91+ }
92+
93+ /// <summary>
94+ /// 他のスレッドからコールする為のデリゲート
95+ /// </summary>
96+ /// <param name="stradd">ログへ追加する文字列</param>
97+ private delegate void Put_Callback(string stradd);
98+
99+ /// <summary>
100+ /// ログに文字列を追加しログ表示を最下行へ強制スクロールする
101+ /// </summary>
102+ /// <param name="stradd">ログへ追加する文字列</param>
103+ public void Put(string stradd)
104+ {
105+ if (_LogTextBox.InvokeRequired)
106+ {
107+ //! 別スレッドから呼び出された場合デリゲートからコールバックさせる
108+ _LogTextBox.Invoke(new Put_Callback(Put), stradd);
109+ return;
110+ }
111+
112+ // ログ追加
113+ Add(stradd);
114+
115+ // ログ表示を最下行へスクロールする。
116+ _LogTextBox.SelectionStart = _LogTextBox.Text.Length;
117+ _LogTextBox.ScrollToCaret();
118+ }
119+
120+ /// <summary>
121+ /// ログにデバッグ用文字列を追加
122+ /// </summary>
123+ /// <param name="stradd">ログへ追加する文字列</param>
124+ public void DebugPut(string stradd)
125+ {
126+#if false
127+ Put(stradd);
128+#endif
129+ }
130+
131+ /// <summary>
132+ /// ログをファイルに保存
133+ /// </summary>
134+ public void Save()
135+ {
136+ if (_ShadowBuf.Length <= 0)
137+ {
138+ return;
139+ }
140+ using (StreamWriter sw = new StreamWriter(
141+ LogFileName,
142+ true,
143+ Encoding.GetEncoding("UTF-8")))
144+ {
145+ // ファイルへの書き込み
146+ sw.Write(_ShadowBuf);
147+ _ShadowBuf = "";
148+ }
149+ }
150+
151+ /// <summary>
152+ /// ログ表示部から古いログを削除
153+ /// 削除されるのは表示部のみ。保存用文字列からは削除しない。
154+ /// </summary>
155+ private void DeleteOld()
156+ {
157+ //! ログ表示量が MaxLength-1024 より大きくなったら破棄する
158+ if (_LogTextBox.Text.Length > (_LogTextBox.MaxLength - 1024))
159+ {
160+ _LogTextBox.Text = _LogTextBox.Text.Substring(_LogTextBox.MaxLength / 2);
161+ }
162+ }
163+
164+ /// <summary>
165+ /// ログ表示部からログをすべて削除
166+ /// 削除されるのはログ表示のみ。ログ保存用文字列からは削除しない。
167+ /// </summary>
168+ public void Clear()
169+ {
170+ _LogTextBox.Text = "";
171+ }
172+ }
173+}
\ No newline at end of file
--- trunk/TenKeyCaptureCS2/TenKeyCaptureCS/FormMain.Designer.cs (nonexistent)
+++ trunk/TenKeyCaptureCS2/TenKeyCaptureCS/FormMain.Designer.cs (revision 213)
@@ -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+
--- trunk/TenKeyCaptureCS2/TenKeyCaptureCS/KeyboardHooker.cs (nonexistent)
+++ trunk/TenKeyCaptureCS2/TenKeyCaptureCS/KeyboardHooker.cs (revision 213)
@@ -0,0 +1,121 @@
1+/***********************************************************//*!
2+ * @brief キーボードフック処理
3+
4+ **************************************************************/using System;
5+using System.Collections.Generic;
6+using System.Linq;
7+using System.Text;
8+using System.Threading.Tasks;
9+using System.Windows.Forms;
10+using System.Runtime.InteropServices;
11+using static TenKeyCapture.ClassMyCommon;
12+
13+namespace TenKeyCapture
14+{
15+ /// <summary>
16+ /// キーボードフック処理クラス
17+ /// </summary>
18+ internal class KeyboardHooker
19+ {
20+ private const uint WM_KEYDOWN = 0x100;
21+ private const uint WM_KEYUP = 0x101;
22+ private const int WH_KEYBOARD_LL = 13;
23+ private static IntPtr hHook;
24+
25+ private Callback hookproc;
26+
27+ /// <summary>
28+ /// コンストラクタ
29+ /// </summary>
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+ /// <summary>
66+ /// キーボードフック処理
67+ /// </summary>
68+ /// <param name="nCode">キーコード</param>
69+ /// <param name="msg">イベントメッセージ</param>
70+ /// <param name="s"></param>
71+ /// <returns></returns>
72+ private static IntPtr KeybordHookProc(int nCode, IntPtr msg, IntPtr s)
73+ {
74+ if (nCode < 0)
75+ {
76+ return CallNextHookEx(hHook, nCode, msg, s);
77+ }
78+
79+ KeyboardLLHookStruct hookStruct = new KeyboardLLHookStruct();
80+
81+ hookStruct = (KeyboardLLHookStruct)Marshal.PtrToStructure(s, typeof(KeyboardLLHookStruct));
82+
83+ uint vkCode = hookStruct.vkCode;
84+
85+ if (msg == new IntPtr(WM_KEYDOWN))
86+ {
87+ vkCode = hookStruct.vkCode;
88+ if (vkCode >= 96 && 111 >= vkCode)
89+ {
90+ // キューへキーデータを投入する(ロック不要)
91+ bool addSuccess = KeyQue.TryAdd(vkCode, System.Threading.Timeout.Infinite);
92+
93+ return new IntPtr(1);
94+ }
95+ }
96+
97+ if (msg == new IntPtr(WM_KEYUP))
98+ {
99+ vkCode = hookStruct.vkCode;
100+
101+ if (vkCode >= 96 && 111 >= vkCode)
102+ {
103+ return new IntPtr(1);
104+ }
105+ }
106+
107+ return CallNextHookEx(hHook, nCode, msg, s);
108+ }
109+
110+ /// <summary>
111+ ///
112+ /// </summary>
113+ public void Dispose()
114+ {
115+ Boolean ret = UnhookWindowsHookEx(hHook);
116+ if (ret.Equals(false))
117+ {
118+ }
119+ }
120+ }
121+}
\ No newline at end of file
--- trunk/TenKeyCaptureCS2/TenKeyCaptureCS/Program.cs (nonexistent)
+++ trunk/TenKeyCaptureCS2/TenKeyCaptureCS/Program.cs (revision 213)
@@ -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+}
--- trunk/TenKeyCaptureCS2/TenKeyCaptureCS/Properties/AssemblyInfo.cs (nonexistent)
+++ trunk/TenKeyCaptureCS2/TenKeyCaptureCS/Properties/AssemblyInfo.cs (revision 213)
@@ -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")]
--- trunk/TenKeyCaptureCS2/TenKeyCaptureCS/Properties/Resources.Designer.cs (nonexistent)
+++ trunk/TenKeyCaptureCS2/TenKeyCaptureCS/Properties/Resources.Designer.cs (revision 213)
@@ -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+}
--- trunk/TenKeyCaptureCS2/TenKeyCaptureCS/Properties/Settings.Designer.cs (nonexistent)
+++ trunk/TenKeyCaptureCS2/TenKeyCaptureCS/Properties/Settings.Designer.cs (revision 213)
@@ -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+}