6月 13

ウィンドウのタイトルを点滅(FlashWindow)させる

ウィンドウのタイトルを点滅させたい場合は
Win32APIの FlashWindowEx APIをコールします。

サンプルコードの前半は同APIを利用するための準備で
ボタンを押すと点滅させています。

点滅後はタイトルが強調表示されたままになります。

何かの処理が完了したことを知らせる場合などに利用します。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;   // DllImportのために必要

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll")]
        static extern Int32 FlashWindowEx(ref FLASHWINFO pwfi);

        [StructLayout(LayoutKind.Sequential)]
        public struct FLASHWINFO
        {
            public UInt32 cbSize;    // FLASHWINFO構造体のサイズ
            public IntPtr hwnd;      // 点滅対象のウィンドウ・ハンドル
            public UInt32 dwFlags;   // 以下の「FLASHW_XXX」のいずれか
            public UInt32 uCount;    // 点滅する回数
            public UInt32 dwTimeout; // 点滅する間隔(ミリ秒単位)
        }

        
        public const UInt32 FLASHW_STOP = 0;        // 点滅を止める
        public const UInt32 FLASHW_CAPTION = 1;     // タイトルバーを点滅させる
        public const UInt32 FLASHW_TRAY = 2;        // タスクバー・ボタンを点滅させる
        public const UInt32 FLASHW_ALL = 3;         // タスクバー・ボタンとタイトルバーを点滅させる
        public const UInt32 FLASHW_TIMER = 4;       // FLASHW_STOPが指定されるまでずっと点滅させる
        public const UInt32 FLASHW_TIMERNOFG = 12;  // ウィンドウが最前面に来るまでずっと点滅させる

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            FLASHWINFO fInfo = new FLASHWINFO();
            fInfo.cbSize = Convert.ToUInt32(Marshal.SizeOf(fInfo));
            fInfo.hwnd = this.Handle;
            fInfo.dwFlags = FLASHW_ALL;
            fInfo.uCount = 5; // 点滅回数
            fInfo.dwTimeout = 0;

            FlashWindowEx(ref fInfo);
        }
    }
}
6月 13

メールスロット Mailslot(受信)

詳細は省略します。
メールスロット経由でデータを受信するサンプルです。

タイマーを使って
一定周期でメールスロットに溜まったデータを取得しています。
応用すればデバッグトレースなどに役立つと思います。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
using System.IO;

namespace MailSlotSample
{
    public partial class FormMain : Form
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            static extern SafeFileHandle CreateMailslot(
            string lpName,
            uint nMaxMessageSize,
            uint lReadTimeout,
            IntPtr lpSecurityAttributes);

        [DllImport("kernel32.dll")]
            static extern bool GetMailslotInfo(
            SafeFileHandle hMailslot,
            ref uint lpMaxMessageSize,
            ref uint lpNextSize,
            ref uint lpMessageCount,
            ref uint lpReadTimeout);

        [DllImport("kernel32.dll", SetLastError = true)]
            static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess,
            uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
            uint dwFlagsAndAttributes, IntPtr hTemplateFile);

        public const uint FILE_ATTRIBUTE_NORMAL = 0x80;
        public const short INVALID_HANDLE_VALUE = -1;
        public const uint GENERIC_READ = 0x80000000;
        public const uint GENERIC_WRITE = 0x40000000;
        public const uint CREATE_NEW = 1;
        public const uint CREATE_ALWAYS = 2;
        public const uint OPEN_EXISTING = 3;
        public const uint FILE_SHARE_READ = 0x00000001;

        private enum MailSlotStatus : uint
        {
            MAILSLOT_NO_MESSAGE = 0xffffffff,
        }

        const string MAILSLOT_NAME = "\\\\.\\mailslot\\hogehoge";

        //
        // メールスロットハンドル
        //
        SafeFileHandle _handleMailslot = null;

        //
        // メールスロットから情報取得するためのStream
        //
        FileStream _fs = null;

        public FormMain()
        {
            InitializeComponent();

            // メールスロットハンドル生成
            _handleMailslot = CreateMailslot(MAILSLOT_NAME, 0, 0, (IntPtr)0);

            // メールスロットから情報取得するためのStream
            _fs = new FileStream(_handleMailslot, FileAccess.Read);

            // タイマー始動
            timer.Enabled = true;
        }

        ~FormMain()
        {
            _fs.Close();
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            //
            // タイマーを使って一定間隔でメールスロットからRead
            //
            string text = ReadMailSlot(MAILSLOT_NAME, 4096);

            // ここで取得したtextを表示。TextBoxやListBoxに追加するとかお好きにどうぞ
            MessageBox.Show(text);
        }

        private string ReadMailSlot(string slot, uint bufSize)
        {
            string ret = string.Empty;
            try
            {
                if (_handleMailslot.IsInvalid)
                    return ret;

                uint maxMessageSize = 1;
                uint nextSize = 0;
                uint messageCount = 0;
                uint readTimeout = 0;

                GetMailslotInfo(_handleMailslot, ref maxMessageSize, ref nextSize, ref messageCount, ref readTimeout);

                if (messageCount > 0 && nextSize != (uint)MailSlotStatus.MAILSLOT_NO_MESSAGE)
                {
                    byte[] buf = new byte[bufSize];
                    int len = _fs.Read(buf, 0, buf.Length);

                    // 適時、文字コードは送信元に合わせてください
                    ret = Encoding.Unicode.GetString(buf, 0, len);
                }
            }
            catch (Exception ex)
            {
                // 何かエラーだって!
                MessageBox.Show(ex.Message);
            }

            return ret;
        }
    }
}
6月 12

iniファイルの値を設定する

Win32APIのWritePrivateProfileString関数を使う例です。
Formに配置されたButtonを押すと書き込みます。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;   // これが必要

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        // Win32APIを使う宣言
        [DllImport("KERNEL32.DLL")]
        public static extern uint WritePrivateProfileString(
          string lpAppName,
          string lpKeyName,
          string lpString,
          string lpFileName);

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // iniファイル名を決める(実行ファイルが置かれたフォルダと同じ場所)
            string iniFileName = AppDomain.CurrentDomain.BaseDirectory + "hogehoge.ini";

            uint ret = WritePrivateProfileString(
                            "SECTION",      // セクション名
                            "KEY",          // キー名
                            "hogehoge",     // 書き込む値
                            iniFileName);   // iniファイル名

            if(ret == 0)
                MessageBox.Show("失敗");
            else
                MessageBox.Show("成功");
        }
    }
}

6月 12

iniファイルの値を取得する

iniファイルはテキストファイルなので
直接iniファイルを開いて自力で解析する方法もありますが
Win32APIの GetPrivateProfileString関数 をC#から呼び出す例です。

GetPrivateProfileString関数はKERNEL32.DLLの中にその実態があるので
DLLをインポートする宣言を行っています。

このコードを動かす場合は
実行ファイルが置かれているフォルダにhogehoge.iniファイルを作成し

[SECTION]
KEY=hogehoge

のような2行を記述して保存しておいてください。
Formに配置されたButtonを押すと内容が表示されます。

iniファイルは簡単な構成で
[]でセクション名を囲み、次のセクション名まで
キー名=値
が続きます。改行区切りです。

例:
[section_1]
data=hogehoge
length=128

[section_2]
data=hogehoge
length=128

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;   // これが必要

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        // Win32APIの GetPrivateProfileString を使う宣言
        [DllImport("KERNEL32.DLL")]
        public static extern uint
          GetPrivateProfileString(string lpAppName,
          string lpKeyName, string lpDefault,
          StringBuilder lpReturnedString, uint nSize,
          string lpFileName);

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // iniファイル名を決める(実行ファイルが置かれたフォルダと同じ場所)
            string iniFileName = AppDomain.CurrentDomain.BaseDirectory + "hogehoge.ini";

            // iniファイルから文字列を取得
            StringBuilder sb = new StringBuilder(1024);
            GetPrivateProfileString(
                "SECTION",      // セクション名
                "KEY",          // キー名    
                "ありません",   // 値が取得できなかった場合に返される初期値
                sb,             // 格納先
                Convert.ToUInt32(sb.Capacity), // 格納先のキャパ
                iniFileName);   // iniファイル名

            MessageBox.Show(sb.ToString());
        }
    }
}