FC2ブログ

まったり開発日誌

embossの工具箱(J2EE Java2 Linux Zaurus C++)

  1. T-01A でリモートデスクトップ モバイル(06/23)
  2. [コラム]DoxyCommentでC++でもコメントを自動生成(05/17)
  3. Zaurus SL-C3100改 pdaXromでサーバ化計画!(12/28)
  4. 019:モードレスダイアログを作る (11/20)
  5. コーディング規約でヘボン式を使用するならこの関数(11/18)
前のページ 次のページ

T-01A でリモートデスクトップ モバイル

T-01A の[プログラム]を見ても、リモートデスクトップが見つかりません。もしかしてインストールされていないのか?

見つからないので仕方なくインストールすることにしました。
リモートデスクトップ が使えたら、何かと便利かも?

【入手&インストール】
http://andrewblock.net/?tag=wm6rdpcab
から WM6RDP.cab ファイルを入手しT-01Aにインストール。

『このプログラムの発行者は不明です。・・・』云々と表示されるので、自己責任で「はい」または「いいえ」を選択する。
インストール先は \Storage Card にしました。

【起動】
[スタート]-[プログラム]-[WM6 Remote Desktop]を起動
あとは普通に
Computer:(接続先)、User name:、Password:
を入力。

※DOCOMO T-01Aの場合、キーボードが無いのでリモートデスクトップには向かないかも・・・

 

<2009年7月1日追記>ソフトウェアキーボードを使えば操作することが可能です。

RemoteDesktop01 RemoteDesktop02

テーマ:Windows Mobile - ジャンル:コンピュータ

  1. 2009/06/23(火) 02:51:29|
  2. T-01A
  3. | トラックバック:0
  4. | コメント:10

[コラム]DoxyCommentでC++でもコメントを自動生成

DoxyCommentでC++でもコメントを自動生成

JavaにはJavadocというコメントから自動的にドキュメントを生成する標準的な機能がありますが、Visual C++には標準ツールはありません。
お勧めなのはdoxygenというドキュメント生成ツールです。ソースファイルのコメントから文書を抜き出し、HTMLをはじめとするさまざまなフォーマットのドキュメントを生成することができます。

DoxygenはQtスタイル及びJavaDocスタイルのコメン トを認識してくれます。
私はお仕事ではJavaプログラマーなのでJavaDocスタイルのコメントに慣れていますのでJavaDoc形式のコメントは助かります。

さて、今回インストールするDoxyCommentですが、そのdoxygen形式のコメントを自動生成してくれるツールです。Visual Studioにアドイン(add-in)して使用します。

別にDoxygenでドキュメント作らないよーという場合でも、ソースにコメントは入れると思います。コメント作成の作業をちょっと楽にしてくれるお勧め便利ツールです。

インストール

プロジェクトのサイト
http://sourceforge.net/projects/doxycomment/
よりインストーラをダウンロードしてインストールしてみました。

Visual Studio2005 用と2008用があります。ご自分の環境にあったファイルをダウンロードしてください。
※現在2008用はベータバージョンのようです。

Visual Studio2005の場合
ダウンロードした、doxycomment_0_4_3_setup.msi をインストールします。

Visual Studioを起動すると画像のようなツールバーがでます。

Add Code Commentをクリックすると、コメントが生成されます。

カスタムコメントプロバイダで自分好みのコメントを生成する

さて、DoxygenのデフォルトではQt形式のタグになっており、JavaDoc形式のコメントになりません。[ツール]-[オプション]のDoxyCommentで設定すればコメントブロックだけはJavaDoc形式にできますが、\authorや\versionなどのコマンドの接頭辞は\(バックスラッシュ(¥マーク))のままです。ここはやはり@で記述してほしいところです。

DoxyCommentにはコメントプロバイダというDLLを作成することで、コメントの生成を自分好みにカスタマイズすることができます。
これを使ってJavaDoc風のコメントにしてみましょう。

[ファイル]-[新しいプロジェクト]-[Visual C#]
より、クラスライブラリを選択します。
プロジェクト名:JavaDocComment
OKを押します。

参照設定に

EnvDTE(.NETライブラリ)
Microsoft.VisualStudio.VCCodeModel(.NETライブラリ)
DoxyComment(デフォルトではC:\Program Files\SourceForge.net\DoxyComment add-in for Visual Studio 2005\DoxyComment.dllにあります。)

を追加します。
DoxyComment.ICommentProviderインターフェースを実装する新しいパブリッククラスを作成してください。
ICommentProviderインターフェースのすべての方法を実装してください。
DoxyCommentのインストールフォルダにTest Providerフォルダがあります。これを参考にすると良いでしょう。
C:\Program Files\SourceForge.net\DoxyComment add-in for Visual Studio 2005\Test Provider


using System;
using System.Collections
;
using DoxyComment
;
using EnvDTE
;
using System.ComponentModel
;
using Microsoft.VisualStudio.VCCodeModel
;

namespace JavaDocComment
{
   [CommentProviderFriendlyName("JavaDocComment"
)]
   public class JavaDocComment : DoxyComment.ICommentProvider
   
{
       [CommentProviderProperty
]
       private string firstLineTag = "/**"
;
       [CommentProviderProperty
]
       private string normalLineTag = " * "
;
       [CommentProviderProperty
]
       private string lastLineTag = " */"
;
       [CommentProviderProperty
]
       private string commandPrefix = "@"
;

       public JavaDocComment
()
       
{
       
}

       [Category("コメントブロック概観"),
       Description("コメントブロックの先頭行の接頭辞."
)]
       public string FirstLineTag
       
{
           get
           
{
               return firstLineTag
;
           
}
           set
           
{
               firstLineTag = value
;
           
}
       
}

       [Category("コメントブロック概観"),
       Description("コメントブロックの行の接頭辞."
)]
       public string NormalLineTag
       
{
           get
           
{
               return normalLineTag
;
           
}
           set
           
{
               normalLineTag = value
;
           
}
       
}

       [Category("コメントブロック概観"),
       Description("コメントブロックの最終行の接頭辞."
)]
       public string LastLineTag
       
{
           get
           
{
               return lastLineTag
;
           
}
           set
           
{
               lastLineTag = value
;
           
}
       
}
       [Category("コマンド接頭辞"),
       Description("コマンドの接頭辞です。\\や@を指定します."
)]
       public string CommandPrefix
       
{
           get
           
{
               return commandPrefix
;
           
}
           set
           
{
               commandPrefix = value
;
           
}
       
}

       #region ICommentProvider implementation

       private ArrayList CreateCommentHeader(VCCodeElement codeElem
)
       
{
           ArrayList rv = new ArrayList
();

           if (FirstLineTag.Length > 0
)
           
{
               rv.Add(FirstLineTag
);
           
}

           rv.Add(NormalLineTag + CommandPrefix +"brief   ここに" + codeElem.Name + " の要約を記載."
);
           rv.Add(NormalLineTag
);
           return rv
;
       
}

       private void AppendCommentFooter(VCCodeElement codeElem, ArrayList buffer
)
       
{
           buffer.Add(NormalLineTag + "ここに " + codeElem.Name + " の詳細を記載."
);
           buffer.Add(NormalLineTag
);
           buffer.Add(NormalLineTag + CommandPrefix +"remarks ここに" + codeElem.Name + " の備考を記載."
);
           buffer.Add(NormalLineTag
);
           buffer.Add(NormalLineTag + CommandPrefix +"see     "
);

           
// Does the comment provider require a last line tag?
           if (LastLineTag.Length > 0
)
           
{
               buffer.Add(LastLineTag
);
           
}
       
}

       public string[] CreateFileComment(Document doc
)
       
{
           ArrayList rv = new ArrayList
();
           DateTime now = DateTime.Now
;

           
// Begin tag?
           if (FirstLineTag.Length > 0
)
           
{
               rv.Add(FirstLineTag
);
           
}

           rv.Add(NormalLineTag + CommandPrefix +"file    " + doc.Name
);
           rv.Add(NormalLineTag + CommandPrefix +"brief   "
);
           rv.Add(NormalLineTag
);
           rv.Add(NormalLineTag + CommandPrefix +"author  "
);
           rv.Add(NormalLineTag + CommandPrefix +"date    " + now.ToString("yyyy/MM/dd"
));
           rv.Add(NormalLineTag + CommandPrefix +"version "
);

           
// End tag?
           if (LastLineTag.Length > 0
)
           
{
               rv.Add(LastLineTag
);
           
}

           return (string[])rv.ToArray(typeof(string
));
       
}

       public string[] CreateTypeDefComment(VCCodeTypedef codeElem
)
       
{
           ArrayList rv
;

           rv = CreateCommentHeader((VCCodeElement)codeElem
);
           AppendCommentFooter((VCCodeElement)codeElem, rv
);

           return (string[])rv.ToArray(typeof(string
));
       
}

       public string[] CreateUnionComment(VCCodeUnion codeElem
)
       
{
           ArrayList rv
;

           rv = CreateCommentHeader((VCCodeElement)codeElem
);
           AppendCommentFooter((VCCodeElement)codeElem, rv
);

           return (string[])rv.ToArray(typeof(string
));
       
}

       public string[] CreateMacroComment(VCCodeMacro codeElem
)
       
{
           ArrayList rv
;

           rv = CreateCommentHeader((VCCodeElement)codeElem
);
           if ((codeElem.Parameters.Count > 0
))
           
{
               foreach (VCCodeParameter curParam in codeElem.Parameters
)
               
{
                   rv.Add(NormalLineTag + CommandPrefix +"param   " + curParam.Name
                       + " パラメータ  " + curParam.Name + " の説明を記載."
);
                   rv.Add(NormalLineTag
);
               
}
           
}
           AppendCommentFooter((VCCodeElement)codeElem, rv
);

           return (string[])rv.ToArray(typeof(string
));
       
}

       public string[] CreateStructComment(VCCodeStruct codeElem
)
       
{
           ArrayList rv
;

           rv = CreateCommentHeader((VCCodeElement)codeElem
);
           AppendCommentFooter((VCCodeElement)codeElem, rv
);

           return (string[])rv.ToArray(typeof(string
));
       
}

       public string[] CreateNamespaceComment(VCCodeNamespace codeElem
)
       
{
           ArrayList rv
;

           rv = CreateCommentHeader((VCCodeElement)codeElem
);
           AppendCommentFooter((VCCodeElement)codeElem, rv
);

           return (string[])rv.ToArray(typeof(string
));
       
}

       public string[] CreateFunctionComment(VCCodeFunction codeElem
)
       
{
           ArrayList rv
;

           rv = CreateCommentHeader((VCCodeElement)codeElem
);

           
// Create /param sections for each parameters in the function
           if (codeElem.Parameters.Count > 0
)
           
{
               foreach (VCCodeParameter curParam in codeElem.Parameters
)
               
{

                   rv.Add(NormalLineTag + CommandPrefix +"param   " + curParam.Name
                       + " パラメータ " + curParam.Name + " の説明を記載."
);
                   rv.Add(NormalLineTag
);
               
}
           
}

           
// Create /returns section
           if ((codeElem.TypeString.Length > 0)
&
               (codeElem.TypeString.ToLower() != "void"
))
           
{

               rv.Add(NormalLineTag + CommandPrefix +
"returns "
                   + "ここに戻り値の説明を記載."
);
               rv.Add(NormalLineTag
);
           
}

           
// Create /throws section
           rv.Add(NormalLineTag + CommandPrefix +"throws <exception class>"
);
           rv.Add(NormalLineTag + "    この例外を投げるための基準の説明を記載."
);
           rv.Add(NormalLineTag
);

           AppendCommentFooter((VCCodeElement)codeElem, rv
);

           return (string[])rv.ToArray(typeof(string
));
       
}

       public string[] CreateEnumValueComment(VCCodeVariable codeElem
)
       
{
           ArrayList rv = new ArrayList
();

           if (FirstLineTag.Length > 0
)
           
{
               rv.Add(FirstLineTag
);
           
}

           rv.Add(NormalLineTag + CommandPrefix +"brief   ここに " + codeElem.Name + " の要約を記載."
);

           
// End tag required?
           if (LastLineTag.Length > 0
)
           
{
               rv.Add(LastLineTag
);
           
}

           return (string[])rv.ToArray(typeof(string
));
       
}

       public string[] CreateEnumComment(VCCodeEnum codeElem
)
       
{
           ArrayList rv
;

           rv = CreateCommentHeader((VCCodeElement)codeElem
);
           AppendCommentFooter((VCCodeElement)codeElem, rv
);

           return (string[])rv.ToArray(typeof(string
));
       
}

       public string[] CreateVariableComment(VCCodeVariable codeElem
)
       
{
           ArrayList rv
;

           rv = CreateCommentHeader((VCCodeElement)codeElem
);
           AppendCommentFooter((VCCodeElement)codeElem, rv
);

           return (string[])rv.ToArray(typeof(string
));
       
}

       public string[] CreateClassComment(VCCodeClass codeElem
)
       
{
           ArrayList rv
;

           
// Header
           rv = CreateCommentHeader((VCCodeElement)codeElem
);

           
// Template parameters?
           if ((codeElem.IsTemplate
))
           
{
               foreach (VCCodeParameter curTemplateParam in codeElem.Templatizations
)
               
{
                   string typeStr
;
                   if ((curTemplateParam.Name.Length != 0
))
                   
{
                       typeStr = curTemplateParam.Name
;
                   
}
                   
else
                   
{
                       int typeIdx
;

                       typeIdx = curTemplateParam.TypeString.LastIndexOf(" "
);
                       typeStr = curTemplateParam.TypeString.Substring(typeIdx + 1
);
                   
}

                   rv.Add(NormalLineTag + CommandPrefix +"param   " + typeStr
);
                   rv.Add(NormalLineTag + "パラメータ " + typeStr + " の説明を記載."
);
                   rv.Add(NormalLineTag
);
               
}
           
}

           AppendCommentFooter((VCCodeElement)codeElem, rv
);

           return (string[])rv.ToArray(typeof(string
));
       
}
using System
;
using System.Collections
;
using DoxyComment
;
using EnvDTE
;
using System.ComponentModel
;
using Microsoft.VisualStudio.VCCodeModel
;

namespace JavaDocComment
{
   [CommentProviderFriendlyName("JavaDocComment"
)]
   public class JavaDocComment : DoxyComment.ICommentProvider
   
{
       [CommentProviderProperty
]
       private string firstLineTag = "/**"
;
       [CommentProviderProperty
]
       private string normalLineTag = " * "
;
       [CommentProviderProperty
]
       private string lastLineTag = " */"
;
       [CommentProviderProperty
]
       private string commandPrefix = "@"
;
       [CommentProviderProperty
]
       private string author =""
;

       public JavaDocComment
()
       
{
       
}

       [Category("コメントブロック概観"),
       Description("コメントブロックの先頭行の接頭辞です."
)]
       public string FirstLineTag
       
{
           get
           
{
               return firstLineTag
;
           
}
           set
           
{
               firstLineTag = value
;
           
}
       
}

       [Category("コメントブロック概観"),
      Description("コメントブロックの行の接頭辞です."
)]
       public string NormalLineTag
       
{
           get
           
{
               return normalLineTag
;
           
}
           set
           
{
               normalLineTag = value
;
           
}
       
}

       [Category("コメントブロック概観"),
      Description("コメントブロックの最終行の接頭辞です."
)]
       public string LastLineTag
       
{
           get
           
{
               return lastLineTag
;
           
}
           set
           
{
               lastLineTag = value
;
           
}
       
}
       [Category("コマンド接頭辞"),
       Description("コマンドの接頭辞です。\\や@を指定します."
)]
       public string CommandPrefix
       
{
           get
           
{
               return commandPrefix
;
           
}
           set
           
{
               commandPrefix = value
;
           
}
       
}
       [Category("制作者"),
       Description("制作者を指定します."
)]
       public string Author
       
{
           get
           
{
               return author
;
           
}
           set
           
{
               author = value
;
           
}
       
}
       #region ICommentProvider implementation

       private ArrayList CreateCommentHeader(VCCodeElement codeElem
)
       
{
           ArrayList rv = new ArrayList
();

           if (FirstLineTag.Length > 0
)
           
{
               rv.Add(FirstLineTag
);
           
}

           rv.Add(NormalLineTag + "ここに" + codeElem.Name + "の要約を記載."
);
           rv.Add(NormalLineTag + "ここに" + codeElem.Name + "の詳細を記載."
);
           return rv
;
       
}

       private void AppendCommentFooter(VCCodeElement codeElem, ArrayList buffer
)
       
{
           buffer.Add(NormalLineTag + CommandPrefix +"remarks ここに" + codeElem.Name + "の備考を記載."
);

           
// Does the comment provider require a last line tag?
           if (LastLineTag.Length > 0
)
           
{
               buffer.Add(LastLineTag
);
           
}
       
}

       public string[] CreateFileComment(Document doc
)
       
{
           ArrayList rv = new ArrayList
();
           DateTime now = DateTime.Now
;

           
// Begin tag?
           if (FirstLineTag.Length > 0
)
           
{
               rv.Add(FirstLineTag
);
           
}

           rv.Add(NormalLineTag + "ここに" + doc.Name + "の概要を記載."
);
           rv.Add(NormalLineTag + CommandPrefix + "file    " + doc.Name
);
           rv.Add(NormalLineTag + CommandPrefix + "author  " + Author
);
           rv.Add(NormalLineTag + CommandPrefix + "date    " + now.ToString("yyyy/MM/dd"
));
           rv.Add(NormalLineTag + CommandPrefix + "version "
);

           
// End tag?
           if (LastLineTag.Length > 0
)
           
{
               rv.Add(LastLineTag
);
           
}

           return (string[])rv.ToArray(typeof(string
));
       
}

       public string[] CreateTypeDefComment(VCCodeTypedef codeElem
)
       
{
           ArrayList rv
;

           rv = CreateCommentHeader((VCCodeElement)codeElem
);
           AppendCommentFooter((VCCodeElement)codeElem, rv
);

           return (string[])rv.ToArray(typeof(string
));
       
}

       public string[] CreateUnionComment(VCCodeUnion codeElem
)
       
{
           ArrayList rv
;

           rv = CreateCommentHeader((VCCodeElement)codeElem
);
           AppendCommentFooter((VCCodeElement)codeElem, rv
);

           return (string[])rv.ToArray(typeof(string
));
       
}

       public string[] CreateMacroComment(VCCodeMacro codeElem
)
       
{
           ArrayList rv
;

           rv = CreateCommentHeader((VCCodeElement)codeElem
);
           if ((codeElem.Parameters.Count > 0
))
           
{
               foreach (VCCodeParameter curParam in codeElem.Parameters
)
               
{
                   rv.Add(NormalLineTag + CommandPrefix +"param   " + curParam.Name
                       + " パラメータ" + curParam.Name + "の説明を記載."
);
               
}
           
}
           AppendCommentFooter((VCCodeElement)codeElem, rv
);

           return (string[])rv.ToArray(typeof(string
));
       
}

       public string[] CreateStructComment(VCCodeStruct codeElem
)
       
{
           ArrayList rv
;

           rv = CreateCommentHeader((VCCodeElement)codeElem
);
           AppendCommentFooter((VCCodeElement)codeElem, rv
);

           return (string[])rv.ToArray(typeof(string
));
       
}

       public string[] CreateNamespaceComment(VCCodeNamespace codeElem
)
       
{
           ArrayList rv
;

           rv = CreateCommentHeader((VCCodeElement)codeElem
);
           AppendCommentFooter((VCCodeElement)codeElem, rv
);

           return (string[])rv.ToArray(typeof(string
));
       
}

       public string[] CreateFunctionComment(VCCodeFunction codeElem
)
       
{
           ArrayList rv
;

           rv = CreateCommentHeader((VCCodeElement)codeElem
);

           
// Create /param sections for each parameters in the function
           if (codeElem.Parameters.Count > 0
)
           
{
               foreach (VCCodeParameter curParam in codeElem.Parameters
)
               
{

                   rv.Add(NormalLineTag + CommandPrefix +"param   " + curParam.Name
                       + " パラメータ" + curParam.Name + "の説明を記載."
);
               
}
           
}
           rv.Add(NormalLineTag + CommandPrefix + "see     "
);
           
// Create /returns section
           if ((codeElem.TypeString.Length > 0)
&
               (codeElem.TypeString.ToLower() != "void"
))
           
{

               rv.Add(NormalLineTag + CommandPrefix +
"return  "
                   + "ここに戻り値の説明を記載."
);
           
}

           
// Create /throws section
           rv.Add(NormalLineTag + CommandPrefix +"throws <exception class> この例外を投げるための基準の説明を記載."
);

           AppendCommentFooter((VCCodeElement)codeElem, rv
);

           return (string[])rv.ToArray(typeof(string
));
       
}

       public string[] CreateEnumValueComment(VCCodeVariable codeElem
)
       
{
           ArrayList rv = new ArrayList
();

           if (FirstLineTag.Length > 0
)
           
{
               rv.Add(FirstLineTag
);
           
}

           rv.Add(NormalLineTag + CommandPrefix +"brief   ここに " + codeElem.Name + " の要約を記載."
);

           
// End tag required?
           if (LastLineTag.Length > 0
)
           
{
               rv.Add(LastLineTag
);
           
}

           return (string[])rv.ToArray(typeof(string
));
       
}

       public string[] CreateEnumComment(VCCodeEnum codeElem
)
       
{
           ArrayList rv
;

           rv = CreateCommentHeader((VCCodeElement)codeElem
);
           AppendCommentFooter((VCCodeElement)codeElem, rv
);

           return (string[])rv.ToArray(typeof(string
));
       
}

       public string[] CreateVariableComment(VCCodeVariable codeElem
)
       
{
           ArrayList rv
;

           rv = CreateCommentHeader((VCCodeElement)codeElem
);
           AppendCommentFooter((VCCodeElement)codeElem, rv
);

           return (string[])rv.ToArray(typeof(string
));
       
}

       public string[] CreateClassComment(VCCodeClass codeElem
)
       
{
           ArrayList rv
;

           
// Header
           rv = CreateCommentHeader((VCCodeElement)codeElem
);

           
// Template parameters?
           if ((codeElem.IsTemplate
))
           
{
               foreach (VCCodeParameter curTemplateParam in codeElem.Templatizations
)
               
{
                   string typeStr
;
                   if ((curTemplateParam.Name.Length != 0
))
                   
{
                       typeStr = curTemplateParam.Name
;
                   
}
                   
else
                   
{
                       int typeIdx
;

                       typeIdx = curTemplateParam.TypeString.LastIndexOf(" "
);
                       typeStr = curTemplateParam.TypeString.Substring(typeIdx + 1
);
                   
}

                   rv.Add(NormalLineTag + CommandPrefix +"param   " + typeStr + " パラメータ" + typeStr + "の説明を記載."
);
               
}
           
}

           AppendCommentFooter((VCCodeElement)codeElem, rv
);

           return (string[])rv.ToArray(typeof(string
));
       
}

       
#endregion
   
}
}

       
#endregion
   
}
}

[ビルド]-[JavaDocCommentのビルド]を選択してDLLを作成します。

JavaDocComment.dll
が生成されるので、これをあなたがDoxyCommentをインストールしたフォルダに「Custom Providers」という名のサブフォルダを作ってそこへコピーしてください。
デフォルトのインストール先であれば

C:\Program Files\SourceForge.net\DoxyComment add-in for Visual Studio 2005\Custom Providers

です。

Visual Studio 2005を再度起動すればカスタムコメントプロバイダがロードされます。

JavaDocCommentプロバイダを使用するように設定します。

[ツール]-[オプション]よりオプションウィンドウを開き、ツリー内のDoxyComment-Generalを選択します。
Active comment provider:JavaDocComment を設定します。

次にDoxyComment-Providerを選択します。


Comment provider:JavaDocComment を選択し、コマンド接頭辞やコメントブロック概観を好みのスタイルに設定してください。

さらにカスタマイズすれば、自分好みのコメントを自動生成できて、便利に使えるでしょう

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2009/05/17(日) 22:53:51|
  2. WindowsMobileではじめるWin32APIプログラミング入門
  3. | トラックバック:0
  4. | コメント:0

Zaurus SL-C3100改 pdaXromでサーバ化計画!

Zaurusサーバ化計画!!

■Zaurus生産停止!
シャープのザウルスは、OSにLinuxを搭載していることが売り物でした。多くの代替OSが存在するPDAでもあります。
腕に覚えがあれば、まさしくPDAといった標準のOSを捨て、Linuxディストリビューションをインストールして楽しむことが出来ます。
代替OSではX Window Systemが動くので、さながら極小Linuxノートブックといったところです。 
しかし、そのザウルスも今後は入手が難しくなりそうです。製造中止のニュースが入ってきました。

PDAの草分け「ザウルス」生産停止、高機能携帯に押され

http://www.yomiuri.co.jp/atmoney/news/20081213-OYT1T00466.htm


たしかに、今は低価格で高機能なモバイル機器が手に入りますからね。

zaurusの役目は終わったというところでしょうか。


私も最近は「Windows Mobile」機器を使い始め、zaurusはすっかりほこりをかぶっていました。

しかし、代替OSを入れることで、ファンレスの静音サーバになるのではないか!?と思い、押入れから引っ張り出してきたわけです。

せっかくですのでWebサーバとして活用してみましょう。


■どの代替OSを入れるか

Zaurusの代替OSにはいくつもの種類があります。


pdaXrom

http://www.pdaxrom.org/

Zaurusの代替OSとして、おそらくもっとも有名で人気が高いです。

安定版のバージョンは1.1.0beta3です。現在最も新しいのはテスト版の1.1.0r198です。


X/Qt

http://xqt.sourceforge.jp/index.ja.html

Qt上で動くX Window Systemです。日本人が開発しているので日本語環境が充実しているのが特徴です。代替OSではないので、今回は見送りです。


PocketWorkstation

http://www.pocketworkstation.org/

Zaurusで動くDebianです。


OpenZaurus

ふたつのGUIがあります。Qtopiaから派生したOpie、X11ベースのGPEです。どちらにするかはインストール時に選択します。


OpenBSD/zaurus

http://www.openbsd.org/zaurus.html

OpenBSDがzaurus上で動きます。BSD派な人にはオススメかも。私はLinuxしか使えないのでパス。


Gentoo Linux Zaurus

http://gentoo-zaurus.sourceforge.jp/

標準OS環境と併用するタイプのようです。


今回は、サーバとして使うので、標準OSと併用するタイプはパスしました。日本語の情報量が比較的多い、pdaXromを採用することにします。


■参考にしたURL

http://bird-memo.seesaa.net/category/805599-1.html
http://benefits.cocolog-nifty.com/pdaxrom/2006/05/pdaxrom_110_bet_3898.html
http://www.pdaxrom.org/
http://hirosuke.tea-nifty.com/pda/2006/04/__69a9.html
http://www.miraclelinux.com/technet/document/linux/training/1_3_2.html#training1_3_2_4
http://www.makichan.jp/home/index.php?swap%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3%A4%CE%BA%EE%C0%AE
http://www.ivoryworks.com/blog/2008/11/pdaxromvnc.php
http://www.mobile-bozu.com/weblog/archives/2006/11/pdaxromfirefox.html

http://comomo.shacknet.nu/pdaxrom/beta1_utf8

http://bird-memo.seesaa.net/article/22219587.html

http://d.hatena.ne.jp/kimicooldad/20060414

 

■feedへのリンク
http://distro.ibiblio.org/pub/linux/distributions/pdaxrom/download/1.1.0beta3/Zaurus-Cxx00/feed/

http://www.tyrannozaurus.com/feed/beta3/feed/



 

■NANDバックアップ

まずは、現在のHDの内容と、NANDのバックアップを取得しておく。
(これを忘れると、元のZAURUSに戻せないです!)

ここhttp://d.hatena.ne.jp/kimicooldad/20060414を参考にNANDバックアップ。




■1.1.0beta3のインストール

 

http://distro.ibiblio.org/pub/linux/distributions/pdaxrom/download/1.1.0beta3/Zaurus-Cxx00/
より

kathrin-1.1.0beta3-akita.zip

をダウンロード。
展開すると、
initrd.bin
tools.tar
updater.sh
ができる。
これをSDカードにコピーする。


zaurusをリセットする。
電源を接続しOKキーを押したまま電源ON。

メンテナンスメニューが起動するので

「4.アップデート」を選択。

「2.SD」を選択。

アップデートの警告が表示されたら「はい(Y)」を選択。


pdaXrom installerが起動する。
「3.NAND Flas Utils」を選ぶ

「1.Resize root partition」で121を入力してOKする。

Repartition finished.と表示されたらOKする。
再起動がかかるのでOKを押したままにしておく。

再びメンテナンスメニューになるので、

「4.アップデート」を選択。

「2.SD」を選択。

アップデートの警告が表示されたら「はい(Y)」を選択。


 

pdaXrom installerが起動する。

「4:run console shell」を選択。


HDに256Mのスワップパーティションを作成し、

残りをpdaXromアプリ用と
DATA保存用に確保します。

 

# fdisk /dev/hda

 

既存のパーティションを全部削除するためdコマンドを何回か実行。

pコマンドで全部のパーティションが削除できたか確認。


スワップパーティションの作成

 

Command (m for help): n [ENTER]
Command action
e extended
p primary partition (1-4)
p [ENTER]
Partition number (1-4): 1 [ENTER]
First cylinder (1-608, default 1): [ENTER]
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-608, default 608): +256M [ENTER]

 



アプリインストール用パーティションの作成

 

Command (m for help): n [ENTER]
Command action
e extended
p primary partition (1-4)
p [ENTER]
Partition number (1-4): 2 [ENTER]
First cylinder (33-608, default 33):  [ENTER]
Using default value 3
Last cylinder or +size or +sizeM or +sizeK (33-608, default 608): +512M [ENTER]

 



データ用パーティションの作成

 

Command (m for help): n [ENTER]
Command action
e extended
p primary partition (1-4)
p [ENTER]
Partition number (1-4): 3 [ENTER]
First cylinder (96-608, default 96):  [ENTER]
Using default value 5
Last cylinder or +size or +sizeM or +sizeK (96-608, default 608):  [ENTER]
Using default value 608

 



SWAPパーティションの設定

今回は、せっかくハードディスクに作成するのですから、色々なサイトで説明されている「スワップファイル」ではなく、ちゃんと専用のスワップパーティションを設けたいと思います。

 

Command (m for help): t [ENTER]
Partition number (1-4): 1
Hex code(type L to list codes): 82 [ENTER] 

 


確認のために表示する。

 

Command (m for help): p

Disk /dev/hda: 5000MB, 5000970240 bytes
255 heads, 63 sectors/track, 608 cylinders
Units = cylinders of 16065 *512 = 8225280 bytes

Device Boot Start End  Blocks  Id System
/dev/hda1       1  32  257008+ 82 Linux swap
/dev/hda2      33  96  506047+ 83 Linux
/dev/hda3      96 608 5120672+ 83 Linux

 


編集結果を書き込む。

 

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

# mke2fs -j /dev/hda2
# mke2fs -j /dev/hda3
# exit

 


pdaXrom installerに戻る。

「6.Reboot」で再起動する。
再起動がかかるのでOKを押したままにしておく。同様の手順で

pdaXrom installerを起動する。

「1.Install new ROM」を選択する。

進捗バーが100%になるまで待つ。


「6.Reboot」を選択。


再起動するとpdaXromが起動を始める。


■セットアップ


rootでログイン。

ログインしたら「startx」を実行する。

キャリブレーションを行う。


pdaXromが起動する。


スワップパーティションの設定

 

# /sbin/mkswap /dev/hda1    ← スワップの作成
# /sbin/swapon /dev/hda1    ← スワップの有効化
# /sbin/swapon -s           ← スワップの確認

 



不要なアプリの削除

System Tools⇒Packege managerを起動。

Installdタブで削除したいアプリにチェック。お好みに応じて削除してください。当方では以下のファイルを削除。

abiword
dillo-xft
sylpheed-gtk2
xdemineur
xchat
xmms
xmms-dump
xmms-mad
xmms-tremor
xpdf


歯車マークをクリックしてアンインストール。

再起動。
# reboot


ネットワークに接続
LANカードにはLPC-CF-CLTを使用。挿すだけで認識してくれる、すばらしい。

System Tools⇒Lan & WIFIをクリック。

TCP/IP&DNSタブを開く。
IP address,Subnet mask,Gateway,DNSを環境に合わせて設定。


壁紙の設定

別に、サーバとして使うのだから、Xはめったに立ち上げないと思うし、どうでもいいのですが、なんとなくデスクトップも設定してみる。

http://www.zaurusthemes.biz/index.html
から壁紙を取得、設定する。


ユーザの追加(hogeというユーザを追加する場合)

# adduser hoge
Enter new password:<設定したいパスワード>[ENTER]
Re-enter new passowrd:<設定したいパスワード>[ENTER]


以降は母艦よりターミナル接続する。ターミナルソフトはTeraTermを使用。SSHにて接続する。


先ほど作成したユーザでログイン後、su でrootになって作業する。

# su


/etc/fstabの編集


# vi /etc/fstab

# vi /etc/fstab


fstabファイルの最後に次の行を追加して保存する。

/dev/hda1       swap            swap    defaults        0  0


再起動する。



swaponでスワップを有効化する。freeでスワップの状態を確認する。


# swapon -a
# free

              total         used         free       shared      buffers
  Mem:        62292        25036        37256            0           56
 Swap:       257000            0       257000
Total:       319292        25036       294256


起動時に毎回スワップパーティションが有効になるように、 

inittabに、スワップファイルの設定を追加。

# vi /etc/inittab


l6:6:wait:/etc/rc.d/rc 6 の次の行に、以下の行を追加

so:5:wait:/sbin/swapon -a

 

フォント設定

フォントをハードディスク上に配置します。

まず、使いたいフォントを母艦でダウンロードし、SDカードにコピーしておきます。


フォント用ディレクトリを作成します

mkdir -p /mnt/ide2/usr/X11R6/lib/X11/fonts/TTF

mkdir -p /mnt/ide2/usr/X11R6/lib/X11/fonts/TTF
SDカードから、作成したフォント用ディレクトリにフォントをコピーします。

cp /mnt/card/<Font名>.TTF /mnt/ide2/usr/X11R6/lib/X11/fonts/TTF/


「/usr/X11R6/lib/X11/fonts/TTF」以下へシンボリックリンクを張ります。

# cd /usr/X11R6/lib/X11/fonts/TTF
# ln -s /mnt/ide2/usr/X11R6/lib/X11/fonts/TTF/<Font名1>.ttf ./<Font名1>.ttf
# ln -s /mnt/ide2/usr/X11R6/lib/X11/fonts/TTF/<Font名2>.ttf ./<Font名2>.ttf


例)
# ln -s /mnt/ide2/usr/X11R6/lib/X11/fonts/TTF/sazanami-gothic.ttf ./sazanami-gothic.ttf
# ln -s /mnt/ide2/usr/X11R6/lib/X11/fonts/TTF/sazanami-mincho.ttf ./sazanami-mincho.ttf


# fc-cache -fv


# vi /home/root/.xinitrc

最初のほうに
xset fp+ /usr/X11R6/lib/X11/fonts/japanese
xset fp rehash 

を追加します。


# vi /usr/X11R6/lib/X11/fonts/TTF/fonts.cache-1

で、フォントの名前を調べます。


例)Sazanami Gothic の場合

 

# vi /home/root/.gtkrc-2.0

 


フォント名を変更する


# vi /usr/share/themes/Artwiz/openbox-3/themerc


下から三行のフォント名を変更する。


window.active.label.text.font: Bitstream Sazanami Gothic:pixelsize=14
menu.title.text.font: Bitstream Sazanami Gothic:pixelsize=14
menu.items.font: Bitstream Sazanami Gothic:pixelsize=14


Feedの設定

 

System Tools⇒Packege managerを起動。
Settingsタブをクリック

登録されているFEEDをすべて削除。

次のfeedを登録する。
1 http://distro.ibiblio.org/pub/linux/distributions/pdaxrom/download/1.1.0beta3/Zaurus-Cxx00/feed/
2 http://www.tyrannozaurus.com/feed/beta3/feed/
3 http://pdaxrom.sourceforge.jp/feed/



コンソールから

# ipkg update

# ipkg upgrade


Availableタブでインストールしたいパッケージにチェックを入れて
歯車をクリックするとインストールされる。
右上のInstall on プルダウンでインストール先を指定する。


apache2
apache2-php-module

samba-cliant
samba-common
samba-server



 

色々なサイトでの説明では、

http://www.pdaxrom.org/unstable/

を追加すると書いてあるのだが、すでにこのfeedは存在しない。


また、samba-codepage-932 も見当たらないです。

むかしはhttp://mail.pdaxrom.org/1.1.0beta1/Zaurus-7x0-860/feed/にあったのだが、すでにリンク切れ。

色々探したところ、

http://www.tyrannozaurus.com/feed/adf/index.html

 

にありました。上記をfeedに追加して

 

コンソールから

# ipkg update

# ipkg upgrade


Packege managerを起動して

samba-codepage-932

もインストールしましょう。


■サスペンド不具合対応


サスペンド復帰が上手くいかない。これを調整するために、できるだけ早い段階で、必ず、以下を実施すること。

viエディタで
「/etc/apm/resume.sh」 を作成し、以下のように編集。

vi /etc/apm/resume.sh

------------------ここから----------
#!/bin/sh
/sbin/hwclock -s
------------------ここまで----------


実行可能に設定します。


# chmod 755 /etc/apm/resume.sh



■ハードウェアクロック不具合対応

 

crondが起動しているかチェックする。

# /etc/rc.d/init.d/crond status


起動していなければ、起動する。


# /etc/rc.d/init.d/crond start

以下のコマンドでディレクトリを作る。

# mkdir /etc/cron.5minutely


viエディタで

「adj_clock.sh」 を作成し、以下のように編集。


# vi /etc/cron.5minutely/adj_clock.sh

------------------ここから----------
#!/bin/sh
/usr/bin/sethwclock
------------------ここまで----------


実行出来るようにアクセス権を設定する。

# chmod +x /etc/cron.5minutely/adj_clock.sh



■firefoxを使う

ブラウザがあればメンテナンス用に何かと重宝するかもしれないので、一応入れておこう。
Systrm Tools→Package manager起動

Firefoxにチェックして歯車マーククリック

インストール完了後再起動

# reboot



■Apache2設定

さて、ようやくサーバーらしい設定を行います。まずはwebサーバから。


Webサーバの設定ファイルは「httpd.conf」です。以下の場所にあります。

/etc/apache/httpd.conf


まずは設定フィルをバックアップしておきましょうか。

# cp /etc/apache/httpd.conf /etc/apache/httpd.conf.original



ドキュメントルートを変更します。デフォルトでは、内部メモリに設定されているので、ハードディスク上のディレクトリをドキュメントルートに設定します。
まずは、ハードディスク上にHTMLファイルの保存場所を作成します。

# mkdir -p /mnt/ide3/var/www/html


 

■以下のとおりhttpd.confを編集します。
・サーバ名の設定

サーバ名は、実際のサーバにつけた名前ではなく、ネットワーク上から参照されるときの名前です。

ServerName <ネット上でのサーバ名>:80


・セキュリティ強化設定

ServerTokens ProductOnly
ServerSignature Off

#IndexOptions FancyIndexing VersionSort


・ユーザディレクトリは使いません。コメントアウトしましょう。
#UserDir public_html


・さらに、不要な記述をがんがんコメントアウトしていきましょう。
#Alias /icons/ "/usr/local/apache/icons/"
#
#<Directory "/usr/local/apache/icons">
#    Options Indexes MultiViews
#    AllowOverride None
#    Order allow,deny
#    Allow from all
#</Directory>

#AliasMatch ^/manual(?:/(?:de|en|es|fr|ja|ko|ru))?(/.*)?$ "/usr/local/apache/manual$1"
#
#<Directory "/usr/local/apache/manual">
#    Options Indexes
#    AllowOverride None
#    Order allow,deny
#    Allow from all
#
#    <Files *.html>
#        SetHandler type-map
#    </Files>
#
#    SetEnvIf Request_URI ^/manual/(de|en|es|fr|ja|ko|ru)/ prefer-language=$1
#    RedirectMatch 301 ^/manual(?:/(de|en|es|fr|ja|ko|ru)){2,}(/.*)?$ /manual/$1$2
#</Directory>


#ScriptAlias /cgi-bin/ "/usr/local/apache/cgi-bin/"
#
#<IfModule mod_cgid.c>
#</IfModule>
#
#<Directory "/usr/local/apache/cgi-bin">
#    AllowOverride None
#    Options None
#    Order allow,deny
#    Allow from all
#</Directory>


#IndexOptions FancyIndexing VersionSort

#AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip

#AddIconByType (TXT,/icons/text.gif) text/*
#AddIconByType (IMG,/icons/image2.gif) image/*
#AddIconByType (SND,/icons/sound2.gif) audio/*
#AddIconByType (VID,/icons/movie.gif) video/*

#AddIcon /icons/binary.gif .bin .exe
#AddIcon /icons/binhex.gif .hqx
#AddIcon /icons/tar.gif .tar
#AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv
#AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip
#AddIcon /icons/a.gif .ps .ai .eps
#AddIcon /icons/layout.gif .html .shtml .htm .pdf
#AddIcon /icons/text.gif .txt
#AddIcon /icons/c.gif .c
#AddIcon /icons/p.gif .pl .py
#AddIcon /icons/f.gif .for
#AddIcon /icons/dvi.gif .dvi
#AddIcon /icons/uuencoded.gif .uu
#AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl
#AddIcon /icons/tex.gif .tex
#AddIcon /icons/bomb.gif core

#AddIcon /icons/back.gif ..
#AddIcon /icons/hand.right.gif README
#AddIcon /icons/folder.gif ^^DIRECTORY^^
#AddIcon /icons/blank.gif ^^BLANKICON^^

#DefaultIcon /icons/unknown.gif

#ReadmeName README.html
#HeaderName HEADER.html

#IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t


・エラードキュメントぐらいは自分でよういしましょうか。有効化します。
ErrorDocument 404 /missing.html


・ドキュメントルートを、先ほど作ったディレクトリへと書き換える。
・セキュリティ上、ファイル表示は使わないのでIndexesの前に「-」をつけましょう。


<Directory "/mnt/ide3/var/www/html">

    Options -Indexes FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all

</Directory>

 


ファイルを編集したら、記述にミスがないかチェックしましょう。

# /etc/rc.d/init.d/apachectl configtest



「Syntax OK」と表示されれば問題ありません。


apacheを再起動しましょう。

# /etc/rc.d/init.d/apachectl restart



FireFoxでhttp://<ZaurusのIPアドレス>/

を表示してみましょう。ページが表示できたら成功。

 

■pdaXromでVNC

メンテナンス用にVNCを入れます。ちまちまとzaurusで作業するのはとっても面倒。VNCを入れておけばメンテナンスも楽々ですよ。


SystemTool⇒PackegeMangerを開く。
SettingsタブでFeedを追加

Name: 4
Url : http://www.focv.com/feed/

を追加する。

コンソールで
ipkg update

OpenSSHを先にインストールする必要がある。
今回はすでにOpenSShをインストール済みだったので問題なし。
x11vncをインストール。


インストール後、コマンドラインから x11vnc を起動。

単に

#/usr/bin/x11vnc

で起動すると、クライアントから接続後クライアントを切断すると、x11vncが終了してしまう。

#/usr/bin/x11vnc -forever 

とすることで、クライアントを切断してもx11vncを終了しないように出来る。
パソコンでvncクライアントを起動。Serverに<zaurusのIPアドレス>:5900 を指定する。

 

 

■日本語入力環境を整えたり、アプリを追加たりしてみる。あれ、だんだんサーバーじゃなくなってきたなぁ。

bzip2bz2ファイルの展開と圧縮
glibc-localeGNUプロジェクトにおけるCの標準ライブラリの locale data
glibc-locale-ja-jp-utf-8ja_JP.UTF-8 用の locale data
gtkterm2日本語表示可能なターミナル
inetutils-clients 
lv 
ntp時計合わせ用
timezones 
unzipzipファイルの展開と圧縮
vimeditor
xutf8 
gconf

 


orbit2

 

 gconf と orbit2 は/(ルート)にインストールします。あとはご自由に。



uimとanthyはPakageManagerからのインストールが上手くいかない。なんでだろー。

仕方ないので、ファイルをダウンロードしてからインストールする。


ファイルをダウンロードするフォルダを作る。

# mkdir -p /mnt/card/feed

# cd /mnt/card/feed

# mkdir -p /mnt/card/feed

# cd /mnt/card/feed 

 

ファイルをダウンロードする。

# wget http://pdaxrom.sourceforge.jp/feed/uim_0.4.5_armv5tel.ipk

# wget http://pdaxrom.sourceforge.jp/feed/anthy_7500_armv5tel.ipk 

 

これらパッケージもなるべく/(ルート)にインストール。

 

ipkgでファイルからインストール。 

# ipkg install anthy_7500_armv5tel.ipk 
# ipkg install uim_0.4.5_armv5tel.ipk



 

uim 0.4.5 
anthy 7500  

をインストールした。上記以外の組み合わせも色々試したがうまくいかなかった。 

 

/etc/profile の最後に次の3行を追加

 

export LANG=ja_JP.UTF-8
export LC_ALL=ja_JP.UTF-8
export TZ=JST-09

 

~/.xinitrc の編集

 

"test -f /etc/profile && . /etc/profile"の次に以下の4行を追加

 

export GTK_IM_MODULE=uim
export XMODIFIERS=@im=uim

exec uim-xim &
exec uim-toolbar-gtk-systray &

 

 

    SL-C1000|SL-C3000|SL-C3100|SL-C3200)
 test -f /etc/X11/kb/akita.xmodmap && xmodmap /etc/X11/kb/akita.xmodmap の次に1行追加


test -f /etc/X11/kb/akita.xmodmap_jp && xmodmap /etc/X11/kb/akita.xmodmap_jp


 

akita.xmodmap_jpを作成する。以下のように編集する。


# vi /etc/X11/kb/akita.xmodmap_jp

------------------ここから----------

keycode 78 = Kanji

 

keycode 71 = comma slash less less
keycode 28 = t T braceleft braceleft
keycode 33 = y Y braceright braceright
keycode 29 = u U bracketleft bracketleft
keycode 17 = i I bracketright bracketright

 

------------------ここまで----------

 

 

■タイムゾーンの設定

# ln -sf /usr/share/zoneinfo/Japan /etc/localtime


 

■sambaの設定

sambaの設定は「smb.conf」ファイルで行う。

# vi /etc/samba/smb.conf


[global]に以下の9行を追加する。

 

Log file = /dev/null 

coding system = utf8

client code page =932
force create mode = 0755
strict sync = yes
sync always = yes

security = share

null passwords = yes

interfaces = usbd0

 

Webサーバのドキュメントルートへアクセスできるようにする。次の4行を追加

 

[html]
 comment = access to html
 path = /mnt/ide3/var/www/html
 guest ok = yes 

 writable = yes



 

sambaを再起動して、設定を確認してみる

# /etc/rc.d/init.d/samba stop 
# /etc/rc.d/init.d/samba start

 

他のPCから接続してみて、内容が表示されることを確認。

 

最後に

reboot

で再起動しておく。

  1. 2008/12/28(日) 03:41:48|
  2. Linux Zaurus
  3. | トラックバック:0
  4. | コメント:0

019:モードレスダイアログを作る

モードレスダイアログを作る 

ダイアログボックスの場合も、考え方は今まで作ってきたウィンドウのプログラムと同じです。

今まではウインドウに発生した色々な処理をウィンドウプロシージャに記述し処理していました。 ダイアログボックスの場合も同じです。ダイアログプロシージャを作成し、ダイアログに発生したいろいろな処理をダイアログプロシージャで受け取り、適切に処理します。

ではサンプルを見てみましょう。
 
 

// SampleDialog002.cpp
//
// モードレスダイアログを作る

#include <windows.h
>
#include
"resource.h"

#define ID_BUTTON1 (0)             
// ボタンのID

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM
);
BOOL CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM
);

ATOM InitApp(HINSTANCE
);
HWND InitInstance(HINSTANCE, int
);
HWND hDlg;          
// モードレスダイアログボックスのハンドル
HINSTANCE hInst;    
// アプリケーションインスタンスハンドル
TCHAR szClassName[] = _T("SampleDialog002"
);
                   
// ウィンドウクラス。UNICODEとしての文字列定数
TCHAR szStr[4];     
// ダイアログとのデータ受け渡し用。4文字確保(うち1つはNULLポインタ用)

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine,int nShowCmd
)
{
   MSG msg
;
   BOOL bRet
;
   HWND hWnd
;

   hInst = hInstance;
// アプリケーションインスタンスハンドルをグローバル変数へ格納

   if (!InitApp(hInstance
))
       return FALSE
;
   if (!(hWnd = InitInstance(hInstance,nShowCmd
)))
       return FALSE
;
   while((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{
       if (bRet == -1
){
           break
;
       } else
{
           
//ダイアログからのメッセージを処理する。
           if(!IsDialogMessage(hDlg,&msg
)){
               
// ダイアログで処理されなかったメッセージは
               
// ウィンドウプロシージャで処理する。
               TranslateMessage(&msg);
// 仮想キーメッセージを文字メッセージに変換
               DispatchMessage(&msg);  
// メッセージをウィンドウプロシージャに送る
           
}
       
}
   
}
   return (int)msg.wParam
;
}

// ウィンドウクラスの登録

ATOM InitApp(HINSTANCE hInst
)
{
   WNDCLASS wc
;
   wc.style        = CS_HREDRAW|CS_VREDRAW
;
   wc.lpfnWndProc  = WndProc;  
// プロシージャ名
   wc.cbClsExtra   = 0
;
   wc.cbWndExtra   = 0
;
   wc.hInstance    = hInst
;
   wc.hIcon        = NULL;     
// 未サポート
   wc.hCursor      = NULL;     
// 未サポート
   wc.hbrBackground= (HBRUSH) COLOR_WINDOW
;
   wc.lpszMenuName = NULL;     
// 未サポート
   wc.lpszClassName=(LPCTSTR) szClassName
;

   return (RegisterClass(&wc
));
}

// ウィンドウの生成
HWND InitInstance(HINSTANCE hInst, int nShowCmd
)
{
   HWND hWnd
;

   hWnd = CreateWindow(szClassName,_T("モードレス"),
       WS_CLIPCHILDREN,    
// ウィンドウの種類
       CW_USEDEFAULT,      
// x座標
       CW_USEDEFAULT,      
// y座標
       CW_USEDEFAULT,      
// 幅
       CW_USEDEFAULT,      
// 高さ
       NULL,               
// 親ウィンドウのハンドル。親を作るのでNULL
       NULL,               
// メニューハンドルまたは子ウィンドウID
       hInst,              
// インスタンスハンドル
       NULL
);
   if (!hWnd
)
       return FALSE
;
   ShowWindow(hWnd, nShowCmd
);
   UpdateWindow(hWnd
);
   return hWnd
;
}

// ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp
)
{
   PAINTSTRUCT ps
;
   HDC hdc
;
   size_t size;        
// 文字列のサイズを格納する
   HWND hButton
;
   HWND hDlg
;

   switch (msg
){
       case WM_CREATE:
// 初期化処理開始

           
// モードレスダイアログを開くボタン
           hButton = CreateWindow
(
               _T("BUTTON"),                           
// ウィンドウクラス名
               _T("DIALOG"),                           
// キャプション
               WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,  
// スタイル指定
               50, 50,                                 
// 座標
               60, 40,                                 
// サイズ
               hWnd,                                   
// 親ウィンドウのハンドル
               HMENU(ID_BUTTON1),                      
// メニューハンドル
               hInst,                                  
// インスタンスハンドル
               NULL                                    
// その他の作成データ
               
);

           break
;

       case WM_PAINT
:

           hdc = BeginPaint(hWnd,&ps);     
// 描画処理を開始

           StringCchLength(szStr,STRSAFE_MAX_CCH,&size);
// 安全な文字列長取得

           ExtTextOut
(
               hdc,    
// デバイスコンテキストのハンドル
               0,      
// 開始位置(基準点)の x 座標
               20,     
// 開始位置(基準点)の y 座標
               NULL,   
// 長方形領域の使い方のオプション
               NULL,   
// 長方形領域の入った構造体へのポインタ
               szStr,  
// 文字列
               size,   
// 文字数
               NULL    
// 文字間隔の入った配列
           
);
           EndPaint(hWnd,&ps
);

           break
;

       case WM_COMMAND
:
           switch (LOWORD(wp
)){
               case ID_BUTTON1
:
                   
// モードレスダイアログウィンドウを開く
                   hDlg = CreateDialog
(
                       hInst,      
// アプリケーションのインスタンスのハンドル
                       MAKEINTRESOURCE(IDD_DIALOG1),
                                   
// ダイアログボックステンプレートを指定
                       hWnd,       
// 親ウィンドウのハンドル
                       DlgProc     
// ダイアログボックスプロシージャへのポインタ
                   
);
                   ShowWindow(hDlg,SW_SHOW
);
           
}
           break
;
       case WM_DESTROY
:
           PostQuitMessage(0
);
           break
;
       default
:
           return (DefWindowProc(hWnd, msg, wp, lp
));
   
}
   return 0
;
}

// ダイアログプロシージャ
BOOL CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp
)
{
   static HWND hParent;    
// 親ウィンドウのハンドル
   int copyCount
;

   switch(msg
){
       case WM_INITDIALOG:
// ダイアログの初期化処理
           hParent = GetParent(hDlg);
// 親ウィンドウハンドル

           return TRUE
;

       case WM_COMMAND:    
// ダイアログのボタンが押されたときの処理
           switch (LOWORD(wp
)){
               case IDOK
:

                   
// エディットコントロールの値を取得
                   copyCount = GetDlgItemText(hDlg,IDC_EDIT1,szStr,4
);

                   
// デバッグプリント
                   NKDbgPrintfW(_T("szStr :バイト数: %d 文字数:%d コピーした文字数:%d"
)
                       ,sizeof(szStr),lstrlen(szStr),copyCount
);

                   InvalidateRect(hParent,NULL,TRUE);  
// 親ウィドウに再描画を指示
                   return TRUE
;

               case IDCANCEL
:
                   DestroyWindow(hDlg);    
// ダイアログを破棄
                   return TRUE
;

           
}
           return FALSE
;
   
}
   return FALSE
;



}


動作イメージは次のようになります。
起動するとメインウィンドウが表示されます。
ボタンをクリックするとダイアログが表示されます。
OKを押すと、入力した内容がメインウィンドウに反映されます。
キャンセルでダイアログを閉じます。
 
今回は、メインウィンドウを作成後、ダイアログウィンドウを作成します。
メインウィンドウにはウィンドウプロシージャ、ダイアログにはダイアログプロシージャをそれぞれ用意しています。
メインウィンドウの作成は今までと全く同じですので問題ないでしょう。
ウィンドウプロシージャを見てください。
ウィンドウを作成するときの初期化処理として、WM_CREATEメッセージがきたら、ウィンドウにボタンを表示しています。
よく見てください。ボタンの生成にCreateWindowを使っています。メインウィンドウと同じですよね。実はボタンやエディットコントロール、ラジオボタンといったよく使われるコントロールは皆、特殊なウィンドウなのです。ウィンドウですからCreateWindowで作成します。
 
HWND CreateWindow(
  LPCTSTR lpClassName,  // 登録されているクラス名
  LPCTSTR lpWindowName, // ウィンドウ名
  DWORD dwStyle,        // ウィンドウスタイル
  int x,                // ウィンドウの横方向の位置
  int y,                // ウィンドウの縦方向の位置
  int nWidth,           // ウィンドウの幅
  int nHeight,          // ウィンドウの高さ
  HWND hWndParent,      // 親ウィンドウまたはオーナーウィンドウのハンドル
  HMENU hMenu,          // メニューハンドルまたは子ウィンドウ ID
  HINSTANCE hInstance,  // アプリケーションインスタンスのハンドル
  LPVOID lpParam        // ウィンドウ作成データ
);
 

いままではCreateWindow関数の第1引数lpClassNameにはウィンドウクラス名を定義していました。ここに定義済みのウィンドウクラス名を指定することが出来ます。
今回の例ではウィンドウクラス名に_T("BUTTON")を指定して、ボタンのコントロールを生成しています。
第3引数dwStyleに、BS_PUSHBUTTONを指定していますので、いわゆるコマンドボタンになります。この第3引数にBS_CHECKBOXを指定するとチェックボックス、BS_GROUPBOXを指定するとグループボックスになります。チェックボックスもグループボックスも「ボタン」の一種ってのがちょっと不思議に感じられるかも知れません。
dwStyleに指定できるスタイルはウィンドウクラスによって異なってきます。詳しくはMSDNを参照してください。
また第8引数hWndParentに親ウィンドウのハンドルを指定します。メインウィンドウのハンドルを指定しましたので、作成するボタンは、メインウィンドウの子ウィンドウになります。
第9引数hMenuのメニューハンドルには、このボタンを識別するコードを設定します。あとでこのボタンからのメッセージであることを識別するのに使います。
今回は識別用に
#define ID_BUTTON1 (0)             // ボタンのID
を作りました。
 
ボタンが押されたときの処理は、ウィンドウプロシージャにWM_COMMANDメッセージが届いたときの処理に記述します。LOWORD(wp)がID_BUTTON1であれば、ボタンが押されたということです。
このときにモードレスダイアログを開くようにします。
モードレスダイアログはCreateDialogマクロで作成し、DestroyWindow関数でダイアログを破棄します。
 
CreateDialogマクロ
ダイアログボックステンプレートリソースから、モードレスダイアログボックスを作成します。
HWND CreateDialog(
  HINSTANCE hInstance,  // モジュールのハンドル
  LPCTSTR lpTemplate,   // ダイアログボックステンプレートの名前
  HWND hWndParent,      // オーナーウィンドウのハンドル
  DLGPROC lpDialogFunc  // ダイアログボックスプロシージャ
);
hInstance にはアプリケーションハンドルを指定します。
lpTemplate にはダイアログボックステンプレートを指定します。指定にはMAKEINTRESOURCEマクロを使用します。
hWndParent には親ウィンドウのハンドルを指定します。
lpDialogFunc にはダイアログボックスプロシージャを指定します。
 
DestroyWindow関数
指定されたウィンドウを破棄します。
BOOL DestroyWindow(
  HWND hWnd   // 破棄するウィンドウのハンドル
);
 
DlgProc関数がモードレスダイアログボックスのプロシージャです。
プロシージャ内で最初に呼ばれるのはWM_INITDIALOGメッセージです。ダイアログが初期化されるときにWM_INITDIALOGメッセージが送られてきます。このメッセージが来たら、ダイアログボックスで必要な初期化処理を記述しておけばよいわけです。
ここでは、親ウィンドウの再描画処理のために親ウィンドウのハンドルが必要となりますので取得しておきます。
親ウィンドウハンドルの取得にはGetParent関数を使います。
 
GetParent関数
親ウィンドウハンドルを返します。
HWND GetParent(
  HWND hWnd   // 子ウィンドウのハンドル
);
 
ダイアログのボタンが押されると、WM_COMMANDメッセージが送られてきます。どのボタンが押されたのか判定するにはWPARAMの下位バイトを見ればよかったですよね。

OKボタン(IDOK)が押されたらエディットコントロールに入力された値を取得して、グローバル変数に格納します。
エディットコントロールから文字列を取得するにはGetDlgItemText関数を使います。

 
GetDlgItemText関数
ダイアログボックス内の指定されたコントロールに関連付けられているタイトルまたはテキストを取得します。
UINT GetDlgItemText(
  HWND hDlg,       // ダイアログボックスのハンドル
  int nIDDlgItem,  // コントロールの識別子
  LPTSTR lpString, // テキストを受け取るバッファへのポインタ
  int nMaxCount    // 文字列の最大サイズ
);
hDlg にダイアログボックスのハンドルを指定します。
nIDDlgItem には取得したいコントロールの識別子を指定します。
lpString には文字列格納用の領域を指定します。ここでは親ウィンドウに文字列を渡したいのでグローバル変数を指定しています。
nMaxCount  には文字列の長さをTCHAR単位で指定します。 
格納したら親ウィンドウに再描画を指示します。すると親ウィンドウはグローバル変数に格納された文字列を、自分のウィンドウ内に描画します。 再描画にはInvalidateRect関数を使います。

 

InvalidateRect関数
指定されたウィンドウの更新リージョン(再描画しなければならない部分)に 1 個の長方形を追加します。 
BOOL InvalidateRect(
  HWND hWnd,           // ウィンドウのハンドル
  CONST RECT *lpRect,  // 長方形の座標
  BOOL bErase          // 消去するかどうかの状態
);
 
InvalidateRect関数を使って無効領域(更新領域)を発生させます。
無効領域とは、画面が他のウィンドウなどで隠れてしまうことです。通常は、無効領域が発生するとWM_PAINTが発生して、再描画する仕組みになっています。
しかし、プログラムの中で状態を変化させ、それを画面に反映したい場合もあると思います。
そのような場合に、InvalidateRect関数を実行して無効領域を発生させるわけです。
意図的に無効領域を発生させると、WM_PAINTが発生します。
つまり結果的に、親ウィドウに再描画を指示することが出来るというわけです。
 
ダイアログプロシージャの中に、NKDbgPrintfW関数という見慣れないものがありますね。これはデバッグ出力ストリーム(出力ウィンドウ)に文字列を出力できる関数です。デバッグには重宝します。

NKDbgPrintfW関数
デバッグ出力ストリームに文字列を出力します。
void WINAPIV NKDbgPrintfW(
  LPCWSTR lpszFmt,
);
引数lpszFmtにはprintfスタイルの書式を指定します。デバッグには結構便利な関数です。 
 
関数がたくさん出てきましたね。 
今日はここまでです。
 

 

テーマ:Windows Mobile - ジャンル:コンピュータ

  1. 2008/11/20(木) 23:28:42|
  2. WindowsMobileではじめるWin32APIプログラミング入門
  3. | トラックバック:0
  4. | コメント:0

コーディング規約でヘボン式を使用するならこの関数

コーディング規約などで、日本語からアルファベットへの変換は「ヘボン式」を使うことと規定されていることがある。

そんなときは、Excelマクロで一気に変換すると楽だ。使い方はこんな感じ。

=hebooon(PHONETIC(A1))

 

[コーディング規約でヘボン式を使用するならこの関数]の続きを読む
  1. 2008/11/18(火) 22:51:46|
  2. 便利なツール類
  3. | トラックバック:0
  4. | コメント:0
前のページ 次のページ

RSSフィード

カレンダー

07 | 2019/08 | 09
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

カテゴリー

最近の記事

最近のコメント

最近のトラックバック

月別アーカイブ

ブロとも申請フォーム

この人とブロともになる

ブログ内検索

リンク

このブログをリンクに追加する

メールフォーム

名前:
メール:
件名:
本文: