HIDORI on The Web

マネージコードしか書きたくない

Archive for the ‘ダウンロード’ Category

Pseudo Live SDK version 0.6.1.1 をリリースしました

without comments

Pseudo Live SDK version 0.6.1.1 をリリースしました。

Pseudo Live SDK は、WPF や Windows.Forms, コンソールアプリケーションをサポートする Live SDK クローンです。

Live SDK の “Managed API” のサポート対象は Windows 8 の Metro スタイルアプリケーションと Windows Phone アプリケーションであり、Windows 7 やそれ以前の環境で動作する一般的なデスクトップアプリケーション(WPF や Windows.Forms, コンソールアプリケーション)はサポート対象外です。

Pseudo Live SDK は、 Windows 7 などで動作するそれら「対象外」のアプリケーションに対して、Live SDK の “Managed API” 相当の API を提供します。Pseudo Live SDK を使用すれば、オリジナルの Live SDK と同じように、アプリケーションから SkyDrive に保存されたファイルや Hotmail のアドレス帳、カレンダーなどの情報にアクセスすることが出来ます。

主な変更点

今回のリリースにおける、主な変更点は以下のとおりです。

  • T4 によるコード生成を導入
  • 単体テストを増強
  • "BeginGet" および "EndGet" の使用方法を紹介する、 "MeConsoleApplication2" サンプルを追加
  • LiveConnectClientAsyncResult.WaitHandle のリークを修正。@dilbert_124 さんに感謝
  • LiveConnectItem.LiveConnectItem のバグを修正
  • LiveOperationProgress.ProgressPercentage のバグを修正
  • クラス名やメンバ名など、いくつかのスペルミスを修正 ;-p

ダウンロード

Pseudo Live SDK は、以下よりダウンロードすることが出来ます。

インストール

あなたのプロジェクトで Pseudo Live SDK を利用するためには、以下を手順を実行します。

  • PseudoLiveSDK-0.6.1.1-bin.zip をダウンロード
  • 上記ファイルを解凍して、Mjollnir.Live.dll を取り出す
  • Mjollnir.Live.dll を、あなたのプロジェクトの「参照設定」に追加する

NuGet が利用可能なら、Pseudo Live SDK のインストールはもっとずっと簡単です。

NuGet Package Console で以下のコマンドを実行すると、プロジェクトに Pseudo Live SDK が追加されます。

Install-Package PseudoLiveSDK

あるいは、NuGet Package Manager が導入済みなら、”NuGet official package source” から “Pseudo Live SDK” を検索して、インストールを行なってください。

動作環境

Pseudo Live SDK は、以下の環境で動作することを願って作成されています。

  • Windows XP SP3 以上, Windows 7, Windows 8 Consumer Preview
  • .NET Framework 3.5 SP1, .NET Framrwork 4.0 (Client Profile は対象外)
  • WPF, Windows.Forms, コンソールアプリケーション

技術情報

以下より、Live SDK 関連の技術情報を参照することが出来ます。

Written by Hiroaki SHIBUKI

5月 20th, 2012 at 5:28 pm

Pseudo Live SDK version 0.6.0.1 をリリースしました

without comments

Pseudo Live SDK version 0.6.0.1 をリリースしました。

Pseudo Live SDK は、WPF, Windows.Forms および Console Application をサポートする Live SDK クローンです。

オリジナルの Live SDK は WPF, Windows.Forms および Console Application のサポートを含んでいませんが、Pseudo Live SDK は WPF, Windows.Forms および Console Application をすべてサポートします。

Pseudo Live SDK はオリジナルの Live SDK と同じく、アプリケーションへの Windows Live ID によるシングルサインオン (SSO) の統合や、SkyDrive, Hotmail, Windows Live Messanger 内のデータにアクセスを行うための API を提供します。

主な変更点

今回のリリースにおける、主な変更点は以下のとおりです。

  • SyncronizationContext を導入、イベントハンドラ内での "Invoke" や "BeginInvoke" が不要に
  • "BeginGet" や "EndGet" など、APM (非同期プログラミングモデル) 型のメソッドを追加
  • 単体テストを増強
  • サンプルを更新。新たに "SkyDriveWindowsFormsApplication1" サンプルを追加。

以下のスクリーンショットは、Pseudo Live SDK に含まれている "SkyDriveWindowsFormsApplication1"  サンプルのものです。

2012-05-16-01

ダウンロード

Pseudo Live SDK は、以下よりダウンロードすることが出来ます。

  • Pseudo Live SDK project home
  • SkyDrive
    • ソースファイル(クラスライブラリ+単体テスト+サンプル)
    • バイナリ(クラスライブラリのアセンブリ+サンプルの実行ファイル)

概要

Pseudo Live SDK には、以下のクラスが含まれています。

  • SignInDialog は、Windows Live ID によるサインイン ダイアログを表示します。
  • LiveConnectSession は、セッション情報をカプセルします。
  • LiveConnectClient は、SkyDrive や otmail, Windows Live Messenger 内のデータにアクセスします。
  • EventArgs 派生クラス、etc …

動作環境

Pseudo Live SDK は、以下の環境で作動することを願って作成されています。

  • Windows XP SP3 以上, Windows 7, Windows 8 Consumer Preview
  • .NET Framework 3.5 SP1, .NET Framrwork 4.0 (Client Profile は対象外)
  • WPF, Windows.Forms, Console Application

技術情報

以下より、Live SDK 関連の技術情報を参照することが出来ます。

Written by Hiroaki SHIBUKI

5月 17th, 2012 at 12:23 am

Pseudo Live SDK version 0.5.0.3 をリリースしました

without comments

Pseudo Live SDK version 0.5.0.3 をリリースしました。

Pseudo Live SDK は、Windows.Forms, WPF, および Console Application をサポートする Live SDK クローンです。

オリジナルの Live SDK は Windows.Forms, WPF, および Console Application のサポートを含んでいませんが、Pseudo Live SDK は Windows.Forms, WPF, および Console Application をサポートします。

Pseudo Live SDK はオリジナルの Live SDK と同じく、アプリケーションへの Windows Live ID によるシングルサインオン (SSO) を統合や、SkyDrive, Hotmail, Windows Live Messanger 内のデータにアクセスを行うための API を提供します。

ダウンロード

Pseudo Live SDK は、以下よりダウンロードすることが出来ます。

Pseudo Live SDK project home
http://PseudoLiveSDK.codeplex.com/

概要

Pseudo Live SDK には、以下のクラスが含まれています。

  • LiveAuthDialog は、Windows Live ID によるサインインのためのダイアログを表示します。
  • LiveConnectSession は、Windows Live ID セッションをカプセルします。
  • LiveConnectClient は、SkyDrive や otmail, Windows Live Messenger 内のデータにアクセスします。
  • EventArgs 派生クラス、etc …

動作環境

Pseudo Live SDK は、以下の環境で作動することを願って作成されています。

  • Windows XP SP3 以上, Windows 7, Windows 8 Consumer Preview
  • .NET Framework 3.5 SP1, .NET Framrwork 4.0 (Client Profile は対象外)

技術情報

以下より、技術情報を参照することが出来ます。

Written by Hiroaki SHIBUKI

5月 12th, 2012 at 3:11 am

Pseudo Live SDK 制作開始

with one comment

SkyDrive for Windows が公開されたことで、刺激を受けました。

Live SDK を使えば、ユーザプログラムから SkyDrive を操作することが出来る」というのは、以前から知識としては知っていたため、早速 Live SDK をダウンロードしてみました。

んがしかし、Live SDK の中を見てびっくり。「Windows Forms のサポートが含まれていない」という衝撃の事実が発覚。

それにしても、まだ正式リリースされてもいない Windows 8 Metro Style アプリケーション向けのライブラリが含まれてるってゆーのに、歴史ある Windows Forms サポートが含まれてのはなんとも…

企業戦略だとしても、ちょっと厳しすぎな気が ;-p

なんてことを言っても今更どーにもなりそーもないので、気を取り直して

  • Windows コンソールアプリケーション
  • Windows Forms アプリケーション

そしてたぶん WPF アプリケーションでも利用可能な Live SDK 「もどき」を作ることにしました。

ライブラリ実装のお手本は、本家 Live SDK の Windows Phone 向けライブラリです。

LiveAuthClient クラスによる認証部分は、そのまま移植してもいいことなさそうなので、完全オリジナルとしました。

LiveConnectSession, LiveConnectClient クラスによる REST API へのアクセスについては、できる限りオリジナルと同じような動作を目指すこととします。

で、とりあえずなんとか

  • LiveAuthDialog クラスによるサインイン
  • LiveConnectClient.GetAsync() メソッドによるコンテンツ取得
  • LiveConnectClient.DownloadAsync() メソッドによるコンテンツ取得

まで出来たので、ソリューションを SkyDrive で公開します。

サインイン

サインインには、LiveAuthDialog クラスを使用します。

以下は、LiveAuthDialog クラスによるサインインのサンプルコードです。

var session = default(LiveConnectSession);

using (var dialog = new LiveAuthDialog())
{
    dialog.ClientId = "<Your Client ID>";
    dialog.Scopes = new[] { "wl.signin" };
    dialog.RedirectUri = new Uri("http://oauth.live.com/desktop");
    dialog.Locale = "ja";

    if (dialog.ShowDialog() != DialogResult.OK)
    {
        if (dialog.Error != null)
        {
            Console.WriteLine(dialog.Error.Message);
        }
        else
        {
            Console.WriteLine("操作がキャンセルされました。");
        }

        return;
    }

    session = dialog.Session;
}

LiveAuthDialog クラスは、Windows Forms ダイアログの典型的な実装です。

インスタンス生成した後にパラメータ設定を行い、ShowDialog() メソッドでサインインダイアログの表示を行います。

2012-05-06-01

サインインを正常に完了すると、Session プロパティに有効な LiveConnectSession クラスのインスタンスが返ります。

サインインを完了する前にサインインダイアログを閉じたり、認証エラーが発生した場合などに、ShowDialog() は DialogResult.Cancel を返します。

認証エラーが発生した場合、Error プロパティにはエラーの詳細を示す例外オブジェクトが返ります。

LiveConnectClient クラスのインスタンス生成

SkyDrive に保存されたファイルなど、Windows Live のコンテンツ操作には LiveConnectClient クラスを使用します。

LiveConnectClient クラスは、Live Connect REST API の汎用ラッパです。LiveConnectClient クラスが公開する GetAsync(), DownloadAsync() などのメソッドを利用して、Windows Live のコンテンツ操作を行います。

以下は、LiveConnectSession クラスのインスタンスを使用して LiveConnectClient クラスのインスタンスを作成するサンプルコードです。

var connect = new LiveConnectClient(session);

LiveConnectClient.GetAsync() によるアカウント情報の取得

LiveConnectClient.GetAsync() メソッドは、SkyDrive に保存されたファイルのメタ情報の取得など、JSON 形式の応答を返す API  呼び出しに適しています 。

GetAsync() メソッドは非同期 API であるため、GetCompleted イベントを使用して、GetAsync() メソッドの実行完了を待ち合わせます。

以下は、LiveConnectClient.GetAsync() メソッドによるアカウント情報取得のサンプルコードです。

var result = default(IDictionary);

using (var signal = new ManualResetEventSlim(false))
{
    connect.GetCompleted += (s, e) => { result = e.Result; signal.Set(); };
    connect.GetAsync("me");

    signal.Wait();
}

foreach (var key in result.Keys)
{
    Console.WriteLine(string.Format("{0}={1}", key, result[key]));
}

LiveConnectClient.DownloadAsync() によるアカウント情報の取得

LiveConnectClient.DownloadAsync() メソッドは、SkyDrive に保存されたファイル本体など、Live Connect REST API からの応答をバイトストリームで受け取りるのに適しています。

DownloadAsync() メソッドは非同期 API であるため、DownloadCompleted イベントを使用して、DownloadAsync() メソッドの実行完了を待ち合わせます。

また、DownloadProgressChanged イベントを使用して、バイトストリームのダウンロードの進捗を知ることも可能です。

以下は、LiveConnectClient.DownloadAsync() メソッドによるアカウント情婦取得のサンプルコードです。

var result = default(Stream);

using (var signal = new ManualResetEventSlim(false))
{
    connect.DownloadCompleted += (s, e) => { result = e.Result; signal.Set(); };
    connect.DownloadProgressChanged += (s, e) => Console.WriteLine("{0}/{1} - {2}%", e.BytesRecieved, e.TotalBytesToRecieve, e.ProgressPercentage);
    connect.DownloadAsync("me");

    signal.Wait();
}

using (var stream = new MemoryStream())
{
    result.CopyTo(stream);
    Console.WriteLine(stream.ToArray().Length);
}

result.Close();

Written by Hiroaki SHIBUKI

5月 6th, 2012 at 4:02 am

ZoomKeeper 1.2.8159.44: 最大化ウィンドウ&マルチモニタ愛好者のための常駐モノ

without comments

ダウンロード: ZoomKeeper-1_2_8159_44.zip – Windows Live SkyDrive

現実逃避シリーズ第X段w

随分前にリリースして以降うっちゃらかしだった ZoomKeeper をメンテしました。

なお、今回の版から ZoomKeeper の実行には .NET Framework 3.5 ランタイムが必要になります。

 

はじめに

ZoomKeeper は、最大化ウィンドウとマルチモニタ環境を愛用する人を支援するための、以下の3つの機能を提供します。

  • 最大化ウィンドウのサイズ調整
    全画面モードで動作するゲームの実行後などに発生する、実画面のサイズと最大化ウィンドウの表示サイズの食い違いを補正します。
  • 最大化ウィンドウの移動
    マルチモニタ環境で、最大化ウィンドウを別モニタに移動する手間を軽減します。
  • 最大化ウィンドウを最背面へ
    簡単なマウス操作で、最大化ウィンドウを最背面へ移動します。マルチモニタ環境で、タスクバーまでマウスカーソルを移動する手間を軽減します。

 

ダウンロード

以下のリンクから、zip ファイルをダウンロードしてください。

ZoomKeeper の実行には .NET Framework 3.5 ランタイムが必要です。

システムに .NET Framework 3.5 ランタイムがインストールされていない場合、ZoomKeeper のインストーラを実行する前に .NET Framework 3.5 ランタイムをインストールしてください。

.NET Framework 3.5 ランタイムは、以下のリンクからダウンロードすることができます。

 

インストール

ダウンロードした zip ファイルを展開して、setup.exe を起動します。

ややこしいオプション指定とかは必要ないので、流れに沿ってインストールしてください。

 

起動

インストールが完了すると、スタートメニューに ZoomKeeper のアイコンが登録されます。

スタートメニューの ZoomKeeper アイコンをクリックして、ZoomKeeper を起動してください。

正常に起動すると、タスクバーの通知領域に ZoomKeeper のアイコンが表示されます。

 

 

終了

タスクバー通知領域に表示されている ZoomKeeper のアイコンを右クリックすると、コンテキストメニューが表示されます。

コンテキストメニューの「終了」を選択すると、ZoomKeeper は終了します。

 

使用方法

ZoomKeeper の主な機能の使用方法は以下のとおりです。

  • 最大化ウィンドウのサイズ調整
    デフォルト設定では、実画面サイズと最大化ウィンドウの表示サイズの「ずれ」を自動的に検出して「最大化ウィンドウのサイズ調整」を行います。
    オプション設定を行うことで、ホットキー押下で「最大化ウィンドウのサイズ調整」を行うことも可能です。
  • 最大化ウィンドウの移動
    最大化ウィンドウのキャプションバーを左クリックし、そのまま別のモニタまでドラッグすると、最大化ウィンドウの移動を行います。
    デフォルト設定では、Ctrl キーを押しながらであれば、キャプションバー以外の部分をドラッグしても最大化ウィンドウの移動を行います。
  • 最大化ウィンドウを最背面へ
    最大化ウィンドウのキャプションバー部分で、左マウスボタンを長押し(デフォルト設定では1秒間)して離すと、最大化ウィンドウを最背面へ送ります。

 

オプション設定

タスクバー通知領域に表示されている ZoomKeeper のアイコンをダブルクリックすると、ZoomKeeper のオプション設定画面が表示されます。

「全般」ページでは、以下の設定を行うことができます。

  • Windows へのログオン時に ZoomKeeper を実行する
    チェックを有効にすると、Windows へのログオン時に ZoomKeeper を実行します。

「サイズ調整」ページでは、以下の設定を行うことができます。

  • システム設定を監視して、最大化ウィンドウのサイズ調整を自動的に行う
    チェックを有効にすると、システム設定を監視して、最大化ウィンドウのサイズ調整を自動的に行います。
  • ホットキー
    チェックを有効にすると、指定されたホットキーを押下すると、最大化ウィンドウのサイズ調整を自動的に行います。

「移動」ページでは、以下の設定を行うことができます。

  • 最大化ウィンドウの移動を行う
    チェックを有効にすると、最大化ウィンドウの移動を行いま

Written by Hiroaki SHIBUKI

6月 7th, 2008 at 4:18 pm

Posted in ダウンロード

VS Reversi 1.0 Beta2: AI 対戦用リバーシ盤

without comments

ネタ元: VS Reversi 1.0 Beta1: AI 対戦用リバーシ盤

絶賛現実逃避中 (>o<) につき、Beta2 のリリースです。

ゲーム盤のバグ修正とゲームエンジンの改良を行いました。

※遊び方は「ネタ元」を参照してください。

 

ダウンロード

以下のリンクから、zip ファイルをダウンロードしてください。

なお、実行には .NET Framework 3.5 が必要です。

 

インストール

ダウンロードした zip ファイルを展開して、setup.exe を起動します。

ややこしいオプションとかはないので、流れに沿ってインストールを行ってください。

 

変更履歴

前版からの変更点は以下のとおりです。

 

ゲーム盤
==
1.0.8147.15:
2008-05-26    Hiroaki SHIBUKI<Hiroaki.SHIBUKI@hotmail.com>
・停止状態での「ステップ実行」の動作を改良。
・非正方形のゲーム盤も正しいく表示できるように修正。
・[選手選択]: 「選手」の表示を違う場合があるバグを修正。

1.0.8147.14:
2008-05-26    Hiroaki SHIBUKI<Hiroaki.SHIBUKI@hotmail.com>
・[選手選択]: [ファイル名] の表示内容が間違っていたのを修正。
・アプリケーション終了時に「選手」設定を保存、起動時に前回の「選手」設定を復帰する機能を追加。
・[選手選択]: [ファイル名] の表示更新の手順を修正。
・[選手選択]: [選手一覧] を ListView から DataGridView に変更。

1.0.8147.13:
2008-05-26    Hiroaki SHIBUKI<Hiroaki.SHIBUKI@hotmail.com>
・jp.hidori/Games.Reversi 1.0.8147.17 に対応。
・最新の打ち手の背景を白色に変更。

 

ゲームエンジン
==
1.0.8147.18:
2008-05-26    Hiroaki SHIBUKI<Hiroaki.SHIBUKI@hotmail.com>
・パスの判定をゲームエンジン側で行うように変更。

1.0.8147.17:
2008-05-26    Hiroaki SHIBUKI<Hiroaki.SHIBUKI@hotmail.com>
・PsedoBoard.Width プロパティ, IGame.Height プロパティを追加。
・PsedoBoard.Size プロパティを廃止。
・IGame.Width プロパティ, IGame.Height プロパティを追加。
・IGame.Size プロパティを廃止。
・Board.Width プロパティ, IGame.Height プロパティを追加。
・Board.Size プロパティを廃止。

1.0.8147.16:
2008-05-26    Hiroaki SHIBUKI<Hiroaki.SHIBUKI@hotmail.com>
・IPlayer.Initialize() に IBoard board 引数を追加。
・IPlayer.Terminate() に IBaord board 引数を追加。

 

利用条件等

商業・非商業を問わず、利用を制限しません。

再配布等も自由に行っていただいて結構です。

ただし、本作品を使用したことによって生じるいかなる損害に関しても、作者はその責務を負わないことをご承知ください。

Written by Hiroaki SHIBUKI

5月 26th, 2008 at 4:20 pm

Posted in ダウンロード

VS Reversi 1.0 Beta1: AI 対戦用リバーシ盤

without comments

一部で流行の兆しを見せている、AI 対戦用のリバーシ 盤を作りました。

ゲーム画面はこんな感じ。

 

 

ダウンロード

以下のリンクから、zip ファイルをダウンロードしてください。

なお、実行には .NET Framework 3.5 が必要です。

 

インストール

ダウンロードした zip ファイルを展開して、VSReversiSetup.exe を起動します。

特に難しいオプションとかはないので、流れに沿ってインストールを行ってください。

 

遊び方・その1

アプリケーションフォルダ配下の Players フォルダに、以下のサンプルの AI プレイヤーが配置されています。

  • SimplePlayer.dll – ゲーム盤を左上からスキャンして、最初に見つけた「置けるところ」に置く
  • RandomPlayer.dll – ランダムに選んだ「置けるところ」に置く

まずはこれらをゲーム盤に読み込んで、文字通りの乱打戦 (^^; を観戦してください。

 

遊び方・その2

「こんなちゃちな AI なんか、俺様の AI でコテンパンだぜ!」というお友達は、AI  プレイヤーを自作して楽しみましょう。

AI プレイヤーは、IPlayer インターフェースを実装するクラスとして作成します。

VS Reversi 1.0 Beta1 の段階では、IPlayer インターフェースは

public interface IPlayer
{
    void Initialize(Piece piece);

    void Terminate();

    Position? GetNextPosition(IBoard board);
}

と定義されています。

各メソッドの詳細は以下の通りです。

  • IPlayer.Initialize() メソッド
    ゲーム開始時に呼び出されます。
  • IPlayer.Terminate() メソッド
    ゲーム終了時に呼び出されます。
  • IPlayer.GetNextPosition() メソッド
    AI プレイヤーの次の指し手を取得するために呼び出されます。
    board で渡された盤面の情報を精査して、次の指し手(の位置)を返します。
    指し手が見つからない場合は null を返します。

サンプルの AI プレイヤーである SimplePlayer も、IPlayer インターフェースを実装しています。

SimplePlayer クラスは

public class SimplePlayer : IPlayer
{
    Piece Piece { get; set; }

    #region IPlayer メンバ

    public void Initialize(Piece piece)
    {
        this.Piece = piece;
    }

    public void Terminate()
    {
        // 何もしない
    }

    public Position? GetNextPosition(IBoard board)
    {
        var cell = board.Cells.FirstOrDefault(x => board.Cells.CanPut(x.Position, this.Piece));
        return (cell == null) ? default(Position?) : cell.Position;
    }

    #endregion
}

となっています。

ゲーム盤のデバッグ用に、「どんな場面でもうち筋の予想がつく AI」が欲しかったため、最初に見つけた「置けるところ」にとにかく石を置いてしまう、というアルゴリズムになっています。

なお、アプリケーションフォルダ配下の Samples フォルダには、サンプル AI のソースコードが配置されているので、参考にしてみてください。

 

利用条件等

商業・非商業を問わず、利用を制限しません。

再配布等も自由に行っていただいて結構です。

ただし、本作品を使用したことによって生じるいかなる損害に関しても、作者はその責務を負わないことをご承知ください。

Written by Hiroaki SHIBUKI

5月 25th, 2008 at 11:32 pm

Posted in ダウンロード

VS Reversi 1.0.8144.7 – AI 対戦リバーシ盤

without comments

リバーシの AI を作るのが流行っているようなので、AI プレイヤーを対戦させるためのリバーシ盤を作ってみました。

AI プレイヤーは .NET クラスライブラリ形式の .DLL にしてもらって、ゲーム盤アプリに読み込ませて実行する。。。予定w

とりあえずはゲームのエンジン部分の動作確認ができたので、お試し公開します。

ゲームエンジンは UI と分離してあって、ゲームエンジンのテスト用に GUI, CUI のゲーム盤アプリが入っています。

http://cid-f11bb9fd8e1bc5f9.skydrive.live.com/embedrowdetail.aspx/Downloads/Reversi-20080523.zip

Written by Hiroaki SHIBUKI

5月 23rd, 2008 at 4:50 pm

Posted in ダウンロード

LowLevelMouseHook コンポーネント

without comments

「低レベルマウスフック」を簡単に扱うためのコンポーネントです。

現実逃避ネタにしてはよくできたものの、真面目に取説書いている暇もないので、とりあえずブログエントリとしてうぷしときます。

Form に LowLevelMouseHook コンポーネントを配置して、Form.Load 辺りで

  • LowLevelMouseHook.Start()

すると、システムグローバルなマウス操作を

  • LowLevelMouseHook.MouseDown イベント
  • LowLevelMouseHook.MouseUp イベント
  • LowLevelMouseHook.MouseMove イベント
  • LowLevelMouseHook.MouseWheel イベント

として通知します。

なお、アプリケーションが終了までに

  • LowLevelMouseHook.Stop()

で必ずフック解除してください。

ソースのアーカイブはここ

using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;

using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace jp.hidori.Windows.Forms
{
    public class LowLevelMouseHook : Component
    {
        #region 8d\92z

        /// <summary>
        /// 83N838983X82cc90V8bK83C839383X83^839383X82f08f898afa89bb82b582dc82b781B
        /// </summary>
        public LowLevelMouseHook()
        {
            InitializeComponent();

            this.Initialize();
        }

        /// <summary>
        /// 83N838983X82cc90V8bK83C839383X83^839383X82f08f898afa89bb82b582dc82b781B
        /// </summary>
        /// <param name="container">83R839383e83i82f095\82b7IContainer81B</param>
        public LowLevelMouseHook(IContainer container)
        {
            container.Add(this);

            InitializeComponent();

            this.Initialize();
        }

        #endregion

        #region 83R839383|81[83l839383g83f83U83C83i82c590b690ac82b382ea82bd83R81[83h

        /// <summary>
        /// 95K97v82c883f83U83C83i95cf909482c582b781B
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// 8eg97p928682cc838a83\81[83X82f082b782d782c483N838a81[839383A83b83v82b582dc82b781B
        /// </summary>
        /// <param name="disposing">83}83l81[83W838a83\81[83X82aa94j8afc82b382ea82e98fea8d87true81A94j8afc82b382ea82c882a28fea8d8782cdfalse 82c582b781B</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        /// <summary>
        /// 83f83U83C83i83T83|81[83g82c995K97v82c8838183\83b83h82c582b781B82b182cc838183\83b83h82cc93e097e82f0
        /// 83R81[83h83G83f83B83^82c595cf8dX82b582c882a282c582ad82be82b382a281B
        /// </summary>
        private void InitializeComponent()
        {
            components = new System.ComponentModel.Container();
        }

        #endregion

        #region P/INVOKE

        private enum WM_ : int
        {
            WM_MOUSEMOVE = 0x0200,
            WM_LBUTTONDOWN = 0x0201,
            WM_LBUTTONUP = 0x0202,
            WM_RBUTTONDOWN = 0x0204,
            WM_RBUTTONUP = 0x0205,
            WM_MBUTTONDOWN = 0x0207,
            WM_MBUTTONUP = 0x0208,
            WM_MOUSEWHEEL = 0x020A,
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct MSLLHOOKSTRUCT
        {
            public Point pt;
            public int mouseData;
            public int flags;
            public int time;
            public IntPtr dwExtraInfo;
        }

        [DllImport("Kernel32", SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string moduleName);

        private delegate IntPtr HookProc(int code, IntPtr wParam, IntPtr lParam);

        private static readonly int WH_MOUSE_LL = 14;

        private static readonly int HC_ACTION = 0;

        [DllImport("User32", SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int id, HookProc lpfn, IntPtr hmod, int threadId);

        [DllImport("User32", SetLastError = true)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("User32", SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        #endregion

        #region 83t83B81[838b83h

        private IntPtr hhk = IntPtr.Zero;

        private HookProc lowLevelMouseHookProc;

        #endregion

        #region 83v838d83p83e83B

        private bool _Enabled = false;

        /// <summary>
        /// 83t83b83N82aa90dd92e882b382ea82c482a282e982a982c782a482a982f08ee693be82dc82bd82cd90dd92e882b582dc82b781B
        /// </summary>
        [DefaultValue(false)]
        public bool Enabled
        {
            get { return _Enabled; }
            set
            {
                if (_Enabled != value)
                {
                    if (value)
                    {
                        this.AddHook();
                    }
                    else
                    {
                        this.RemoveHook();
                    }

                    _Enabled = value;
                }
            }
        }

        #endregion

        #region 83C83x839383g

        /// <summary>
        /// 83}83E83X83{83^839382aa83N838a83b83N82b382ea82e982c694ad90b682b582dc82b781B
        /// </summary>
        public event MouseEventHandler MouseDown;

        protected virtual void OnMouseDown(MouseEventArgs e)
        {
            if (this.MouseDown != null)
            {
                this.MouseDown(this, e);
            }
        }

        /// <summary>
        /// 83}83E83X83{83^839382aa97a382b382ea82e982c694ad90b682b582dc82b781B
        /// </summary>
        public event MouseEventHandler MouseUp;

        protected virtual void OnMouseUp(MouseEventArgs e)
        {
            if (this.MouseUp != null)
            {
                this.MouseUp(this, e);
            }
        }

        /// <summary>
        /// 83}83E83X83|83C839383^82aa88da93ae82b782e982c694ad90b682b582dc82b781B
        /// </summary>
        public event MouseEventHandler MouseMove;

        protected virtual void OnMouseMove(MouseEventArgs e)
        {
            if (this.MouseMove != null)
            {
                this.MouseMove(this, e);
            }
        }

        /// <summary>
        /// 83}83E83X83z83C81[838b82aa93ae82ad82c694ad90b682b582dc82b781B
        /// </summary>
        public event MouseEventHandler MouseWheel;

        protected virtual void OnMouseWheel(MouseEventArgs e)
        {
            if (this.MouseWheel != null)
            {
                this.MouseWheel(this, e);
            }
        }

        #endregion

        #region 91808dec

        /// <summary>
        /// 83t83b83N82f090dd92e882b582dc82b781B
        /// </summary>
        public void Start()
        {
            this.Enabled = true;
        }

        /// <summary>
        /// 83t83b83N82f089f08f9c82b582dc82b781B
        /// </summary>
        public void Stop()
        {
            this.Enabled = false;
        }

        #endregion

        #region 8ec09195

        private void Initialize()
        {
            this.lowLevelMouseHookProc = this.LowLevelMouseHookProc;
        }

        private void AddHook()
        {
            if (this.hhk != IntPtr.Zero) return;

            this.hhk = SetWindowsHookEx(WH_MOUSE_LL, this.lowLevelMouseHookProc, GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);
        }

        private void RemoveHook()
        {
            if (this.hhk == IntPtr.Zero) return;

            IntPtr hhk = this.hhk;
            this.hhk = IntPtr.Zero;

            UnhookWindowsHookEx(hhk);
        }

        private IntPtr LowLevelMouseHookProc(int code, IntPtr wParam, IntPtr lParam)
        {
            if (code == HC_ACTION)
            {
                MSLLHOOKSTRUCT msll = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));

                switch (wParam.ToInt32())
                {
                case (int)WM_.WM_MOUSEMOVE:
                    this.OnMouseMove(new MouseEventArgs(MouseButtons.None, 0, msll.pt.X, msll.pt.Y, 0));
                    break;

                case (int)WM_.WM_LBUTTONDOWN:
                    this.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, msll.pt.X, msll.pt.Y, 0));
                    break;

                case (int)WM_.WM_LBUTTONUP:
                    this.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, msll.pt.X, msll.pt.Y, 0));
                    break;

                case (int)WM_.WM_RBUTTONDOWN:
                    this.OnMouseDown(new MouseEventArgs(MouseButtons.Right, 1, msll.pt.X, msll.pt.Y, 0));
                    break;

                case (int)WM_.WM_RBUTTONUP:
                    this.OnMouseUp(new MouseEventArgs(MouseButtons.Right, 1, msll.pt.X, msll.pt.Y, 0));
                    break;

                case (int)WM_.WM_MBUTTONDOWN:
                    this.OnMouseDown(new MouseEventArgs(MouseButtons.Middle, 1, msll.pt.X, msll.pt.Y, 0));
                    break;

                case (int)WM_.WM_MBUTTONUP:
                    this.OnMouseUp(new MouseEventArgs(MouseButtons.Middle, 1, msll.pt.X, msll.pt.Y, 0));
                    break;

                case (int)WM_.WM_MOUSEWHEEL:
                    this.OnMouseDown(new MouseEventArgs(MouseButtons.None, 0, msll.pt.X, msll.pt.Y, (int)(short)HighValue((uint)msll.mouseData)));
                    break;
                }
            }

            return LowLevelMouseHook.CallNextHookEx(this.hhk, code, wParam, lParam);
        }

        private static ushort HighValue(uint value)
        {
            return (ushort)((value >> 16) & 0x0ffff);
        }

        #endregion
    }
}

formatted by vspaste

Written by Hiroaki SHIBUKI

11月 16th, 2007 at 4:55 pm

Posted in ダウンロード

改訂: ZoomKeeper – 最大化ウィンドウのサイズを自動調整

without comments

「スクリーンサイズの変更を検知して、最大化ウィンドウィンドウのサイズを自動調整するツール」、ZoomKeeper を改訂しました。

以前のバージョンでは、システム設定の検知後、すぐに最大化ウィンドウの表示サイズの調整を行なっていましたが、新しいバージョンではシステム設定の変更を検知した後、最低でも 0.5 秒間待ってから最大化ウィンドウの表示サイズの調整を開始します。

なんとなーくサイズ調整の動作がスムースになったような気がします。(気のせい?)

Link to ZoomKeeper

Written by Hiroaki SHIBUKI

4月 1st, 2007 at 1:37 pm

Posted in ダウンロード