<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;D0UARHc5fSp7ImA9WxBREEk.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735</id><updated>2009-12-29T09:07:25.925+09:00</updated><title>とりあえずプログラミング</title><subtitle type="html">プログラムをとりあえず作ってみるためのＴＩＰＳとか。言語、プラットホームはなんでもあり。&lt;br /&gt;
とりあえずなので、多少勘違いこいてるかもしれませんが、そのへんはご容赦願います。</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://quickprogram.blogspot.com/" /><link rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>34</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/quickprogram" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry gd:etag="W/&quot;D0MMRHsyeSp7ImA9WxNTFEQ.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-7556843517081288557</id><published>2009-08-17T14:48:00.006+09:00</published><updated>2009-08-17T16:51:25.591+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-17T16:51:25.591+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Form" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Windows" /><title>[.NET] Windowsフォームでのダイアログの作成と終了処理について</title><content type="html">&lt;p&gt;
Windowsフォームでダイアログを作成するには、普通にFormを作成してFormBorderStyleやMaximizeBoxやMinimizeBoxのプロパティを変更して、ダイアログの概観を持つフォームを作成します。またモーダルダイアログとして表示するには、ShowDialog();を呼び出します。
&lt;/p&gt;
&lt;p&gt;
ＯＫやキャンセルなどのいわゆるダイアログボタンは、普通にボタンを配置してDialogResultプロパティを設定し、それに合うような文字列をTextプロパティに設定します。DialogResultが設定されたボタンを押すと自動的にFormを閉じようとするので、Clickイベントハンドラでは、Close()を呼び出す記述してはいけません。
&lt;/p&gt;
&lt;p&gt;
DialogResultが設定されたボタンとウィンドウクローズボタン（右上の×ボタン）を含めて、これらのボタンを押されたときに終了させないようにするには、FormClosingイベントハンドラを登録して、FormClosingEventArgsのCloseにfalseを設定します。この処理は、ShowDialog();で表示するFormに限らず、一般的なFormについても同様です。
&lt;/p&gt;
&lt;p&gt;
プログラムからShowDialog();で表示したFormを閉じるには、Visibleプロパティをfalseにします。そうすると、ダイアログが非表示になり、ShowDialog();が復帰します。このときの戻り値は、FormのDialogResultプロパティに設定されているものになります。そのため、Visibleを設定するときにDialogResultを設定しておいたほうがよいでしょう。
&lt;/p&gt;
&lt;div style="text-align:center"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article Link */
google_ad_slot = "5036282279";
google_ad_width = 468;
google_ad_height = 15;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-7556843517081288557?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/23gEY4twAstmRN1-2qPtRytQb38/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/23gEY4twAstmRN1-2qPtRytQb38/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/23gEY4twAstmRN1-2qPtRytQb38/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/23gEY4twAstmRN1-2qPtRytQb38/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/9srxSKRR2x8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/7556843517081288557/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=7556843517081288557" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/7556843517081288557?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/7556843517081288557?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/9srxSKRR2x8/net-windows.html" title="[.NET] Windowsフォームでのダイアログの作成と終了処理について" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2009/08/net-windows.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEcCR3s6eyp7ImA9WxJUEUw.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-6015501747568421040</id><published>2009-07-09T12:56:00.005+09:00</published><updated>2009-07-09T13:01:06.513+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-09T13:01:06.513+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="namespace" /><category scheme="http://www.blogger.com/atom/ns#" term="エラー" /><category scheme="http://www.blogger.com/atom/ns#" term="VC++" /><title>[VC++] ミニメモ</title><content type="html">&lt;p&gt;
自分で作ったnamespaceやclassの「名前空間が見つかりません」のエラーが出たときは、一番最後のエラーメッセージを見よ。
&lt;/p&gt;
&lt;p&gt;
どこかでnamespaceを閉じ忘れているかも…。
&lt;/p&gt;
&lt;div style="text-align:center"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article Link */
google_ad_slot = "5036282279";
google_ad_width = 468;
google_ad_height = 15;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-6015501747568421040?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/1x6LnDb08bDhPJ-jYVGRTeK6T2w/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/1x6LnDb08bDhPJ-jYVGRTeK6T2w/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/1x6LnDb08bDhPJ-jYVGRTeK6T2w/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/1x6LnDb08bDhPJ-jYVGRTeK6T2w/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/ed4vnvKNPLU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/6015501747568421040/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=6015501747568421040" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/6015501747568421040?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/6015501747568421040?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/ed4vnvKNPLU/vc.html" title="[VC++] ミニメモ" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2009/07/vc.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0MFSXsyeSp7ImA9WxJVGEg.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-7558509167094324377</id><published>2009-07-06T14:13:00.005+09:00</published><updated>2009-07-06T14:50:18.591+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-06T14:50:18.591+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Express" /><category scheme="http://www.blogger.com/atom/ns#" term="VC++" /><title>[VC++2008] VC++ 2008 Expressでアセンブリに署名をする</title><content type="html">&lt;p&gt;
VC++ 2008 Expressでアセンブリを遅延署名をしてから、署名する方法です。署名をするためのキーについては、ドキュメントの「公開キーと秘密キーのキー ペアを作成する  」や「厳密名ツール (Sn.exe) 」についてを参照してください。
&lt;/p&gt;
&lt;h4&gt;遅延署名をする&lt;/h4&gt;
&lt;p&gt;
assemblyInfo.cppに遅延署名をするアトリビュートを追加します。ここでは、「AssemblyKeyFileAttribute」の指定はしません。
&lt;code&gt;&lt;pre style="border:2px solid #0000ff; padding:0.2em; overflow:auto"&gt;[assembly:AssemblyDelaySignAttribute(true)];
&lt;/pre&gt;&lt;/code&gt;
&lt;/p&gt;
&lt;h4&gt;リンカオプションでパブリックキーを設定する&lt;/h4&gt;
&lt;p&gt;
要するに「/KEYFILE:」のオプションを設定するのですが、プロジェクトのプロパティで「リンカ」の中の「詳細」の一覧の中に「キーファイル」という項目があるので、そこに公開キーファイルを指定します。ファイルのありかによっては、マクロを使ってパスを設定する必要があるかもしれません。
&lt;/p&gt;
&lt;h4&gt;ちゃんと署名をする&lt;/h4&gt;
&lt;p&gt;
遅延署名のままだとデバッグすらできません。デバッグなら一時的に署名のチェックを外すこともできますが、リンクが終わった後に署名します。&lt;br /&gt;
カスタムビルドステップで、コマンド(sn.exe)を使って署名をします。基本的には以下のようにコマンドビルドステップのコマンドラインを設定すればよいでしょう。
&lt;/p&gt;
&lt;code&gt;&lt;pre style="border:2px solid #0000ff; padding:0.2em; overflow:auto"&gt;"$(WindowsSdkDir)bin\sn" -R "$(TargetPath)" &amp;lt;キーペアファイル&amp;gt;&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;
なお、キーペアファイルの指定でフルパスになるようでしたら、二重引用符「"」でくくる必要があります。
&lt;/p&gt;
&lt;div style="text-align:center"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article Link */
google_ad_slot = "5036282279";
google_ad_width = 468;
google_ad_height = 15;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-7558509167094324377?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/FgxTZE7qg-CbCX-Z4Gfkr7CrBq8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FgxTZE7qg-CbCX-Z4Gfkr7CrBq8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/FgxTZE7qg-CbCX-Z4Gfkr7CrBq8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FgxTZE7qg-CbCX-Z4Gfkr7CrBq8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/R7SrXXwBUy8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/7558509167094324377/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=7558509167094324377" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/7558509167094324377?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/7558509167094324377?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/R7SrXXwBUy8/vc2008-vc-2008-express.html" title="[VC++2008] VC++ 2008 Expressでアセンブリに署名をする" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2009/07/vc2008-vc-2008-express.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0EHRXk9eip7ImA9WxJVEk0.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-4653368007642751283</id><published>2009-06-28T22:18:00.009+09:00</published><updated>2009-06-29T00:07:14.762+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-29T00:07:14.762+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Form" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Express" /><category scheme="http://www.blogger.com/atom/ns#" term="ApplicationSettings" /><category scheme="http://www.blogger.com/atom/ns#" term="VC++" /><title>[VC++2008] VC++ 2008 ExpressではApplicationSettingsは使えないらしい</title><content type="html">&lt;p&gt;
VC++ 2008 ExpressnのIDEのフォームデザイナを使ってフォームを作成するとき、コンポーネントのプロパティにあるデータというカテゴリに「(ApplicationSettings)」という項目がある。ApplicationSettingsの詳細についてはドキュメントに譲るが、これを使うとフォームの位置などの情報を簡単に保存して、起動したときに前回の状態と同じように表示させることができる仕組みである。
&lt;/p&gt;
&lt;p&gt;
まず、おもむろにこの「(ApplicationSettings)」にある「(Property Binding)」という項目をクリックすると、設定画面が表示できるボタンが現れる。このボタンを押すと、アプリケーション設定というダイアログが表示されるのだが、この中にはバインド可能なプロパティの一覧が表示されている。&lt;br /&gt;
そのプロパティのコンボボックスをドロップダウンさせると、アプリケーション設定を定義することができる。ここで「新規を」クリックするとアプリケーション設定が作成できるのだが、項目を埋めて「ＯＫ」ボタンを押すと「設定ファイルがプロジェクトに見つかりません。設定ファイルを追加して、再試行してください。」と表示されて追加することが出来ない。
&lt;/p&gt;
&lt;p&gt;
ここで見つからないといわれているファイルは、「app.settings」である。このファイルもxmlで記述されていて、マイクロソフトでスキーマが定義されている。このファイルの空の状態は、おそらく以下の通り。
&lt;/p&gt;
&lt;code&gt;&lt;pre style="border:2px solid #000000;overflow:auto;height:5em;padding:0.1em"&gt;&amp;lt;?xml version='1.0' encoding='utf-8'?&amp;gt;
&amp;lt;SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="" GeneratedClassName="app"&amp;gt;
&amp;lt;/SettingsFile&amp;gt;
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;
このapp.settingsファイルをプロジェクトに追加すれば、(Property Binding)にアプリケーション設定を定義することができる。また、このapp.settingsファイルを開くとアプリケーション設定用のビューが開き、そこで項目の追加や変更もできる。
&lt;/p&gt;
&lt;p&gt;
ただし、この状態でビルドをすると「stdafx.h」に「app.h」がありませんというコンパイルエラーが発生する。どうやら、app.settingsから値をやりとりするためのクラスをapp.hに定義してあるものとしてビルドしているように思える。&lt;br /&gt;
実際にはアプリケーション設定を定義したフォームのコードをみると「::app::Default」という参照をしている。結局のところ、このクラスを定義しないとアプリケーション設定は利用できないということになる。
&lt;/p&gt;
&lt;div style="text-align:center"&gt;
&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article */
google_ad_slot = "4760784415";
google_ad_width = 468;
google_ad_height = 60;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;
ここからは、試してないのでなんともいえないが、このapp.hを&lt;span style="font-weight:bold;"&gt;手で&lt;/span&gt;作成してみようとするのであれば、ドキュメントにある「アプリケーション設定アーキテクチャ 」というページをヒントにすれば、うまくいくと思われる。&lt;br /&gt;
おそらく、appというクラスを「ApplicationSettingsBase」から派生させて、その中には先ほどのアプリケーション設定のビューで定義した名前と型をプロパティを作成する。スコープがユーザーなら「UserScopedSetting()」アトリビュートで、アプリケーションなら「ApplicationScopedSetting()」アトリビュートとなる。デフォルト値は、「DefaultSettingValue()」のアトリビュートで設定すればよいだろう。&lt;br /&gt;
プロパティのget()とset()は、ApplicationSettingsBaseのインデクサの参照、代入となる。
&lt;/p&gt;
&lt;p&gt;
あとは、フォームを閉じるときにファイルに保存する（ApplicationSettingsBase::Save()を呼ぶ）ようにすれば、状態が保存されるはず。&lt;br /&gt;
app.hの作成のところは、試してないので動作保障はいたしません。もし、試してうまくいったという人がいらしたら、お知らせしていただければうれしいですw。
&lt;/p&gt;
&lt;div style="text-align:center"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article Link */
google_ad_slot = "5036282279";
google_ad_width = 468;
google_ad_height = 15;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-4653368007642751283?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/-DRyvEizS5yXzlISQ5T_5Yq8Cgk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-DRyvEizS5yXzlISQ5T_5Yq8Cgk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/-DRyvEizS5yXzlISQ5T_5Yq8Cgk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-DRyvEizS5yXzlISQ5T_5Yq8Cgk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/Ca1-KB3LKM8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/4653368007642751283/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=4653368007642751283" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/4653368007642751283?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/4653368007642751283?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/Ca1-KB3LKM8/vc2008-vc-2008-expressapplicationsettin.html" title="[VC++2008] VC++ 2008 ExpressではApplicationSettingsは使えないらしい" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2009/06/vc2008-vc-2008-expressapplicationsettin.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0YFSHY8eip7ImA9WxJVEUQ.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-5089935466380183756</id><published>2009-04-02T11:37:00.008+09:00</published><updated>2009-06-28T22:18:39.872+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-28T22:18:39.872+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="Eclipse" /><category scheme="http://www.blogger.com/atom/ns#" term="Debugger" /><category scheme="http://www.blogger.com/atom/ns#" term="PDT" /><title>【Windows】Eclipse3.4.2（Ganymede）＋PDTでZendDebuggerを使う</title><content type="html">&lt;p&gt;
WindowsでApache2.0でPHP5.2が動作して、Eclipse GanymedeにPDTが組み込まれているという環境で、ZendDebbuggerを組み込む方法についてです。Webサーバーとデバッグするマシンは同じである必要はありません。
&lt;/p&gt;
&lt;h4&gt;ApacheにZendDebuggerを組み込む&lt;/h4&gt;
&lt;dl&gt;
&lt;dt&gt;ZendDebuggerの入手&lt;/dt&gt;
&lt;dd style="margin-left:1.0em"&gt;
&lt;a href="http://downloads.zend.com/pdt/server-debugger/" target="_blank"&gt;http://downloads.zend.com/pdt/server-debugger/&lt;/a&gt;にいく。ZendDebugger-5.2.xx-cygwin_nt-i386.zipをダウンロードする（基本的には最新版でよいはず）。
&lt;/dd&gt;
&lt;dt&gt;インストール&lt;/dt&gt;
&lt;dd style="margin-left:1.0em"&gt;
Zipを展開すると?_?_x_compのようなフォルダがあるが、最初の２つの数がPHPのバージョンを意味しているので5_2_x_compか5_2_x_nts_compのいずれかのフォルダにあるDLLをどこかにコピーする（展開されたフォルダーごとどこかにおいてもよい）。&lt;br /&gt;
5_2_x_compと5_2_x_nts_compの違いは、スレッドセーフか非スレッドセーフであり、どちらを組み込むかは、PHPのビルドによって異なる。phpinfo();で出力された中に「Thread Safety」という項目が「enable」で「Debug Build」が「no」であれば、スレッドセーフであり、いずれかがそうでなければ非スレッドセーフということになる。PHPをバイナリでインストールした場合には、スレッドセーフになっているはず。
&lt;/dd&gt;
&lt;dt&gt;php.iniの設定&lt;/dt&gt;
&lt;dd style="margin-left:1.0em"&gt;
以下の設定をphp.iniに追加する。
&lt;pre style="border:1px #0000ff solid;padding:0.3em"&gt;zend_extension_ts=&amp;lt;コピーしたDLLのパス&amp;gt;ZendDebugger.dll
zend_debugger.allow_hosts=&amp;lt;アクセスを許可するIPアドレス&amp;gt;
zend_debugger.expose_remotely=always&lt;/pre&gt;
もし非スレッドセーフなDLLを組み込むときは、「zend_extension_ts」は「zend_extension」となる。&lt;br /&gt;
IPアドレスの設定は、複数ある場合カンマ「,」で区切る。
&lt;/dd&gt;
&lt;dt&gt;dummy.phpのコピー&lt;/dt&gt;
&lt;dd style="margin-left:1.0em"&gt;
展開されたフォルダにあるdummy.phpをApacheのドキュメントルートにコピーする。このファイルは、PDTのデバッグの設定で「TestDebugger」で接続テストをするときにアクセスする。本質的には必須ではない。
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;
設定完了後にApacheを開始または再起動し、エラーログをチェックする。
&lt;/p&gt;
&lt;h4&gt;Eclipseの設定&lt;/h4&gt;
&lt;dl&gt;
&lt;dt&gt;Webサーバーの設定&lt;/dt&gt;
&lt;dd style="margin-left:1.0em"&gt;
Eclipseの設定ダイアログ(Preferencesで表示される）の「PHP」の「PHP Servers」の項目を表示して、デバッグのターゲットとなるWebサーバーを指定する。&lt;br /&gt;
または、「PHP」か「PHP Debug」のパースペクティブを表示にあるデバッグのダイアログ（Debug Configurationで表示される）を表示して、「PHP Server」をいう項目を変更または追加する（デフォルトはlocalhostになっている）。
&lt;/dd&gt;
&lt;dt&gt;接続の確認&lt;/dt&gt;
&lt;dd style="margin-left:1.0em"&gt;
上記のデバッグのダイアログで「Test Debugger」というボタンを押すと接続確認ができる。ただし、dummy.phpをドキュメントルートにコピーしておかないとテストはできない。
&lt;/dd&gt;
&lt;dt&gt;デバッグファイルの設定&lt;/dt&gt;
&lt;dd style="margin-left:1.0em"&gt;
デバッグのダイアログで、対象となるファイルを指定する。ここでは、ローカルなファイルを指定するので、普通はプロジェクトのフォルダからの相対パスとなる。&lt;br /&gt;
ドキュメントルートからのパスの関係がプロジェクトのパスと一致していれば、URLの設定は「Auto Generate」でデバッグできることになる。すなわちこれは、Apacheのドキュメントルート上にPHPのプロジェクトを作成したという状態を意味している。
&lt;/dd&gt;
&lt;dt&gt;デバッグの確認&lt;/dt&gt;
&lt;dd style="margin-left:1.0em"&gt;
あとは、デバッグのダイアログで「Debug」ボタン（Runの設定の場合「Run」ボタン）を押すとApache上で実行される。&lt;br /&gt;
このとき、表示をEclipse上ではなく別のブラウザ上に表示することができる。設定するには、PHPのパースペクティブで、「Window」のメニューで「Web Browser」で変更するか、設定ダイアログの「General」の「Web Browser」で変更することができる。
&lt;/dd&gt;
&lt;/dl&gt;
&lt;div style="text-align:center"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article Link */
google_ad_slot = "5036282279";
google_ad_width = 468;
google_ad_height = 15;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-5089935466380183756?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/6ppL40ODKtr7BCdv_Am4ygMH_DI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6ppL40ODKtr7BCdv_Am4ygMH_DI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/6ppL40ODKtr7BCdv_Am4ygMH_DI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6ppL40ODKtr7BCdv_Am4ygMH_DI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/XUZoU8jTfts" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/5089935466380183756/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=5089935466380183756" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/5089935466380183756?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/5089935466380183756?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/XUZoU8jTfts/winowseclipse342ganymedepdtzenddebugger.html" title="【Windows】Eclipse3.4.2（Ganymede）＋PDTでZendDebuggerを使う" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2009/04/winowseclipse342ganymedepdtzenddebugger.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQMSX04fSp7ImA9WxRaFE0.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-6412828292405175362</id><published>2008-12-16T12:38:00.003+09:00</published><updated>2008-12-16T13:56:28.335+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-16T13:56:28.335+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Form" /><category scheme="http://www.blogger.com/atom/ns#" term="ランタイムエラー" /><category scheme="http://www.blogger.com/atom/ns#" term="namespace" /><category scheme="http://www.blogger.com/atom/ns#" term="Express" /><category scheme="http://www.blogger.com/atom/ns#" term="VC++" /><title>[VC++ 2008 Express] Formのnamespaceを変更するとランタイムエラーが出る</title><content type="html">&lt;p&gt;
VC++ 2008 Express Editionでフォームアプリケーションを作成すると、formのソースコードにnamespaceが定義される。このnamespaceはプロジェクト名になっているのであるが、変更したくなることもあるだろう。
&lt;/p&gt;
&lt;p&gt;
namespaceを変更してもビルドも成功するのであるが、実行時に「指定されたカルチャまたはニュートラル カルチャに対して適切なリソースが見つかりませんでした。…」のようなエラーが発生する。&lt;br /&gt;
このエラーの発生しているのは、formのなかでリソースを読み取るところ、実際のコードでは「System::ComponentModel::ComponentResourceManager^ resources = …」となっている場所になる。
&lt;/p&gt;
&lt;p&gt;
なぜエラーになるかというと、ComponentResourceManagerを作成するところで、typeidをベースに読み取るのであるが、typeidはnamespaceに依存する。すなわち、&amp;lt;namespace&amp;gt;.&amp;lt;クラス名&amp;gt;となっている。&lt;br /&gt;
しかしながら、コンパイルされたリソース（マネージリソース）は、ソースコードで変更されたnamespaceが反映されないため、ランタイム時にリソースを読み込むことができずエラーとなるという仕組みなようだ。
&lt;/p&gt;
&lt;p&gt;
そこで、マネージリソースのコンパイル設定を変えればうまくいくはずで、プロジェクトのプロパティでは、リソースファイル名の設定が「$(IntDir)\$(RootNamespace).$(InputName).resources」となっている。&lt;br /&gt;
すなわち、「$(RootNamespace)」の部分が変更したnamespaceになっていればよいということになる。
&lt;/p&gt;
&lt;p&gt;
ひとつの解決方法としては、RootNamespaceの値の参照をやめて、変更したnamespaceに変えてしまうというのがある。要するに「$(RootNamespace)」を書き換えるということである。
&lt;/p&gt;
&lt;p&gt;
どうせなら、RootNamespaceの値を変更したほうがよさそうだと思うのだが、IDE上で変更できそうな画面が見つからない。仕方がないので、プロジェクトの定義ファイル(.vcproj)をテキストエディタで変更する。変更箇所は簡単に見つかるはずで、RootNamespace="…"となっているところを書き換える。
&lt;/p&gt;
&lt;p&gt;
といっても、ある意味無理やり変更しているので、IDE上でなんだかの不都合が生じる可能性もあるので、あくまでも自己責任の範囲でやってみてください。
&lt;/p&gt;
&lt;div style="text-align:center"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article Link */
google_ad_slot = "5036282279";
google_ad_width = 468;
google_ad_height = 15;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-6412828292405175362?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/HnVqg5QHh7QAyiAYbrmtExUd6VY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HnVqg5QHh7QAyiAYbrmtExUd6VY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/HnVqg5QHh7QAyiAYbrmtExUd6VY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HnVqg5QHh7QAyiAYbrmtExUd6VY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/lWuBKCfiTWo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/6412828292405175362/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=6412828292405175362" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/6412828292405175362?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/6412828292405175362?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/lWuBKCfiTWo/vc-2008-express-formnamespace.html" title="[VC++ 2008 Express] Formのnamespaceを変更するとランタイムエラーが出る" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2008/12/vc-2008-express-formnamespace.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C04MRH4-eip7ImA9WxVQFk4.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-6627585956023525511</id><published>2008-11-28T11:52:00.010+09:00</published><updated>2009-02-03T12:33:05.052+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-03T12:33:05.052+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="リソース" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="フォーム" /><category scheme="http://www.blogger.com/atom/ns#" term="resX" /><category scheme="http://www.blogger.com/atom/ns#" term="Express" /><category scheme="http://www.blogger.com/atom/ns#" term="VC++" /><title>[VC++ 2008 Express] FormのresXにリソースを追加しても消されてしまう</title><content type="html">&lt;p&gt;
VC++のフォームアプリケーションで、フォームとは無関係なリソース（例えばイメージ）をそのフォームのresXに追加することはできるのですが、何かの拍子に消えてしまいます（おそらく、フォームデザイナがヘッダーファイルを生成ときのタイミングだと思います）。
&lt;/p&gt;
&lt;p&gt;
VC++のフォームプロジェクトにあるフォームは、ソリューションエクスプローラー内においては、ソースコードは「&amp;lt;フォーム名&amp;gt;.h」でその下の階層に「&amp;lt;フォーム名&amp;gt;.resX」という表示になっています。このresXを開くとリソースの一覧が表示されて、編集可能となっています。そこで、イメージなどのリソースを追加できるのですが、何故か消えてしまうのです。
&lt;/p&gt;
&lt;p&gt;
そこで、フォームとは別なところにリソースを定義して、プログラムで読み取ろうということですが、少なくとも「rcファイル」はmanagedなプロジェクトでは意味がありません。なぜ、Formアプリケーションのプロジェクトに存在している&lt;del datetime="2009-02-03T12:00:00+09:00"&gt;かはわかりません&lt;/del&gt;&lt;ins datetime="2009-02-03T12:00:00+09:00"&gt;のは、おそらくアプリケーションのアイコンの設定するためなのだ&lt;/ins&gt;が、.NETのドキュメントを読むとrcファイルのリソースは利用できませんと書いてあります。
&lt;/p&gt;
&lt;p&gt;
managedなモジュール（Assemblyといったほうが適切か…）にこの手のリソースを組み込む方法はいくつか存在するようですが、新たにresXファイルを追加してそこにリソースを定義するという方法をやってみました。
&lt;/p&gt;
&lt;h4&gt;空のresXファイルを作る&lt;/h4&gt;
&lt;p&gt;
プロジェクトに組み込むresXファイルを用意します。resXといっても所詮XMLファイルなので、ベタな方法として「メモ帳」で作ることにします。ただし、中身がresXの定義に則してないとIDE上で編集できないですし、ビルド時にエラーになるので、最低限の定義だけを書いておきます。
&lt;/p&gt;
&lt;p&gt;
必要な部分だけ、プロジェクト内にあるresXからコピペするのですが、まず、プロジェクトにある（エラーになっていない）resXファイルをXMLエディタで開きます（コンテキストメニューから「ファイルを開くアプリケーションの選択」というのを選ぶ）。そのresXファイルから、最初の「&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;/code&gt;」から、「&lt;code&gt;&amp;lt;/resheader&amp;gt;&lt;/code&gt;」の部分まで（たぶん、「&lt;code&gt;&amp;lt;resheader name="writer"&amp;gt;&lt;/code&gt;」の対になっているのが最後のなので、そこまでをコピー、ペーストします。そのあとの行に「&lt;code&gt;&amp;lt;/root&amp;gt;&lt;/code&gt;」でrootを閉じればＯＫです。&lt;br /&gt;
ファイルは、拡張子をresXにしてUTF-8で保存します。拡張子よりも前の部分（いわゆるbasename）はプログラムで読み込むときに指定するので、わかり易いものにしておいたほうがよいでしょう。
&lt;/p&gt;
&lt;h4&gt;プロジェクトに追加する&lt;/h4&gt;
&lt;p&gt;
作った空のresXファイルをプロジェクトのコンテキストメニューで「追加&amp;rarr;既存の項目」で追加すると、ソリューションエクスプローラー上でプロジェクトの下の「リソースファイル」というツリーの中に現れるはずです。そうしたら、そのresXファイルを開くと、resX用のリソース定義用のビュー（マネージリソースエディタ）が表示されます。&lt;br /&gt;
そこで、好きなリソースを追加してください。
&lt;/p&gt;
&lt;h4&gt;リソースの読み込み&lt;/h4&gt;
&lt;p&gt;
ManagedなC++のコードの中でリソースを読み込む方法ですが、まずResourceManagerでresXに定義されたリソースを読み込みます。resXファイル名のbasenameを「リソース名」ということにすると（「hoge.resX」なら「hoge」）。
&lt;/p&gt;
&lt;code&gt;&lt;pre style="background-color:#000000;color:#ffffff;padding:0.2em;overflow:auto"&gt;//アセンブリを取得する
System::Reflection::Assembly^ assembly = System::Reflection::Assembly::GetExecutingAssembly();
//リソースを読み込む
System::Resources::ResourceManager^ resources = 
 gcnew System::Resources::ResourceManager("&amp;lt;アセンブリ名&amp;gt;.&amp;lt;リソース名&amp;gt;", assembly);
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;
ここでの「アセンブリ名」といっているのは（この言い方が正しいかは不明）、普通はプロジェクト名になっているのでプロジェクト名にします。
&lt;/p&gt;
&lt;p&gt;
あとは、ResourceManagerなどのドキュメント、サンプルを見ると使い方がわかりますが、例として、イメージを読み込む場合は以下のような感じになります。
&lt;/p&gt;
&lt;code&gt;&lt;pre style="background-color:#000000;color:#ffffff;padding:0.2em;overflow:auto"&gt;//リソースからイメージを読み込む
System::Drawing::Bitmap^ image = (System::Drawing::Bitmap^)(resources-&gt;GetObject(L"&amp;lt;リソースオブジェクト名&amp;gt;"));
&lt;/pre&gt;&lt;/code&gt;
&lt;div style="text-align:center"&gt;
&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article */
google_ad_slot = "4760784415";
google_ad_width = 468;
google_ad_height = 60;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;
ここでの「リソースオブジェクト名」は、resXの定義で命名したものを指定します。マネージリソースエディタでイメージファイルを読み込むとファイル名のbasenameになりますが、エディタ上で変更できます。
&lt;/p&gt;
&lt;p&gt;
この場合、リソースファイルを手動で追加しましたが、いわゆる国際化（カルチャー毎の設定）も対応しているはずなので、ファイル名にカルチャー名を付加したresXファイルを用意しておけば、ResourceManagerで適切に処理されるはずです。
&lt;/p&gt;
&lt;div style="text-align:center"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article Link */
google_ad_slot = "5036282279";
google_ad_width = 468;
google_ad_height = 15;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-6627585956023525511?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/_DcbZlyUIEZg6x14OzoeRjllw3o/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_DcbZlyUIEZg6x14OzoeRjllw3o/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/_DcbZlyUIEZg6x14OzoeRjllw3o/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_DcbZlyUIEZg6x14OzoeRjllw3o/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/5POu_KOhAHE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/6627585956023525511/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=6627585956023525511" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/6627585956023525511?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/6627585956023525511?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/5POu_KOhAHE/vc-2008-express-formresx.html" title="[VC++ 2008 Express] FormのresXにリソースを追加しても消されてしまう" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2008/11/vc-2008-express-formresx.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0QDQHk-fip7ImA9WxVQFk4.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-8995653589673992868</id><published>2008-11-26T21:30:00.012+09:00</published><updated>2009-02-03T12:22:51.756+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-03T12:22:51.756+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="DataSource" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="DataGridView" /><category scheme="http://www.blogger.com/atom/ns#" term="BindingSource" /><category scheme="http://www.blogger.com/atom/ns#" term="VC++" /><title>[.NET]バインドされたDataGridViewに追加した項目を選択状態にする</title><content type="html">&lt;p&gt;
&lt;a href="http://quickprogram.blogspot.com/2008/11/netdatagridview.html"&gt;先ほどの記事&lt;/a&gt;でDataGridViewとBindingSourceおよびDataTableの関係について書いたが、それを調べるための目的は、DataGridViewにバインドされたDataTableにプログラムで行を追加したときにその項目を選択させるためだったので、その方法を書いてみることにする。
&lt;/p&gt;
&lt;p&gt;
実際にこのような動作をするプログラムを書かないと、状況がつかめないかもしれないが、DataGridViewは、バインドされたDataTableに新しく行を追加しても、選択位置は一番最初のままである。そのため、新しく追加された項目は、スクロールアウトされていると表示されない。しかも、DataGridViewは選択されている項目を表示させようとするため、さらに行が追加されると、選択されている行がスクロールアウトされていても選択行を表示させるためスクロールする。
&lt;/p&gt;
&lt;p&gt;
すなわち、新しい行を表示させるためにはDataGridViewの選択行を変更しなければならない。ここで前提としては、DataGridViewの選択モードは、FullRowSelectになっているものとする。CellSelectでもうまくいくと思われるが試してはいない。
&lt;/p&gt;
&lt;p&gt;
以下のコードはC++で書くことにするが、VC++2008 Express EditionでDataTableやDataSetをデータデザイナを使って定義する方法は、&lt;a href="http://quickprogram.blogspot.com/2008/10/vc-2008-express-datagridviewdatasource.html"&gt;こちらの記事&lt;/a&gt;を参照されたい。
&lt;/p&gt;
&lt;p&gt;
まず、データデザイナで定義をするとヘッダファイルにDataSetのサブクラスが作られて、その中にDataTableのサブクラスを定義するようなコードを生成するが、ここでは、"MyDataSet"や"MyDataTable"のように"My"＋クラス名というものを定義したとする。
&lt;/p&gt;
&lt;p&gt;
あと、DataTableの定義の前提として、主キーでAutoIncrementされる列(Column)を定義し、カラム名は"ID"とする。あと、定義されたDataSet（すなわち"MyDataSet"）は、Formのメンバー変数として、「MyDataSet^ myDataSet;」と定義され、コンストラクタのどこかで、「myDataSet = gcnew MyDataSet();」のようにインスタンスを生成しており、また、フォームデザイナでは、BindingSourceを"myBindingSource"と定義したとする。
&lt;/p&gt;
&lt;p&gt;とりあえず、コードは以下の通り&lt;/p&gt;
&lt;code&gt;&lt;pre style="background-color:#000000;color:#ffffff;overflow:auto;padding:0.2em"&gt;//新しい行を生成する
MyDataSet::MyDataTableRow^ newRow = myDataSet-&amp;gt;MyDataTable-&amp;gt;NewMyDataTableRow();

//ここでnewRowのメンバー（カラム）にデータを代入する
//newRow-&amp;gt;&amp;lt;カラム名&amp;gt; = …;
//カラム"ID"は追加時に設定されるので何もしなくてよい

//行をDataTableに追加する
myDataSet-&amp;gt;MyDataTable-&amp;gt;Rows-&amp;gt;Add(newRow);
myDataSet-&amp;gt;MyDataTable-&amp;gt;AcceptChanges();

//追加した行のBindingSourceの位置を取得する
int position = myBindingSource-&amp;gt;Find(L"ID", newRow-&amp;gt;ID);

//BindingSourceの現在の位置を変更する
myBindingSource-&amp;gt;Position = position;
&lt;/pre&gt;&lt;/code&gt;
&lt;div style="text-align:center"&gt;
&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article */
google_ad_slot = "4760784415";
google_ad_width = 468;
google_ad_height = 60;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;
&lt;/div&gt;
&lt;p&gt;
ここでの最大のポイントは、BindingSourceの現在の位置はDataGridViewの選択行に一致するのだが、項目がソートされているとDataTableの行（Row）のインデックスとは一致しない。そのため、新しく追加した項目がBindingSourceでどの位置にあるかを調べてから設定するということである。
&lt;/p&gt;
&lt;p&gt;
あと、このコードでの"newRow"はAdd();で"MyDataTable"に追加すると、"ID"にAutoIncrementされた値が代入される。そのため、この値を使って"myBindingSource"のFind();を呼び出せば、位置がわかるということになる。
&lt;/p&gt;
&lt;div style="text-align:center"&gt;
&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article Link */
google_ad_slot = "5036282279";
google_ad_width = 468;
google_ad_height = 15;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-8995653589673992868?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/WtqpZPXa_ado7_2KgIbxTXNEZfg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WtqpZPXa_ado7_2KgIbxTXNEZfg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/WtqpZPXa_ado7_2KgIbxTXNEZfg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WtqpZPXa_ado7_2KgIbxTXNEZfg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/3yXcjFTmBQM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/8995653589673992868/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=8995653589673992868" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/8995653589673992868?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/8995653589673992868?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/3yXcjFTmBQM/netdatagridview_26.html" title="[.NET]バインドされたDataGridViewに追加した項目を選択状態にする" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2008/11/netdatagridview_26.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE4BQHc4fip7ImA9WxRUFko.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-7024089262222582936</id><published>2008-11-26T12:41:00.006+09:00</published><updated>2008-11-26T14:22:31.936+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-11-26T14:22:31.936+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="VC#" /><category scheme="http://www.blogger.com/atom/ns#" term="DataGridView" /><category scheme="http://www.blogger.com/atom/ns#" term="CLI" /><category scheme="http://www.blogger.com/atom/ns#" term="BindingSource" /><category scheme="http://www.blogger.com/atom/ns#" term="VC++" /><title>[.NET]DataGridViewのデータについて</title><content type="html">&lt;p&gt;
&lt;a href="http://quickprogram.blogspot.com/2008/10/vc-2008-express-datagridviewdatasource.html"&gt;前記事&lt;/a&gt;でVC++ 2008 ExpressでDataGridViewにDataSetをバインドする方法について書いたが、その後DataGridViewを操作しようとしたところ、多少はまってしまった。ドキュメントを読んでわかったことだが、DataGridViewと表示･編集しようとしているデータとの関係について書いてみることにする。
&lt;/p&gt;
&lt;p&gt;
DataGridViewに表示されるデータがどこにあるのか、という意味で３つのパターンがある。
&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;普通のモード&lt;/dt&gt;
&lt;dd style="margin-left:1em"&gt;
普通という言い方が正しいかどうかはわからないが、単にDataGridViewのインスタンスを生成した場合の状態で、対象となるデータはDataGridViewの中に存在する。具体的には、DataGridView.RowsプロパティであるDataGridViewRowCollectionの中に行のデータが格納されている。
&lt;/dd&gt;
&lt;dt&gt;バインディングモード&lt;/dt&gt;
&lt;dd style="margin-left:1em"&gt;
これは、&lt;a href="http://quickprogram.blogspot.com/2008/10/vc-2008-express-datagridviewdatasource.html"&gt;前記事&lt;/a&gt;で書いた、DataSetなどに存在するデータをDataGridViewに表示・編集する方法で、具体的には、DataGridView.DataSourceプロパティにデータの実体があるオブジェクトを設定する。VC++やVC#のIDEでデータデザイナとフォームデザイナを使った場合には、これらの設定はIDEによってコード化されるので、特にコードを書く必要はない。
&lt;/dd&gt;
&lt;dt&gt;仮想モード&lt;/dt&gt;
&lt;dd style="margin-left:1em"&gt;
このモードについては、MSDNなどのドキュメントにいろいろ書かれているので、詳細はそちらへ譲るが、基本的にはDataGridViewが表示・編集のためにデータの参照･設定が必要になった場合、イベントが発生する。そのイベントの処理でデータを受け渡しなどをする。この場合、データの実体はプログラマー任せとなる。
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;
実際には、編集などではもっと複雑なデータのやりとりをするようだが、特殊なことをしない限り、あまり意識する必要はないもよう。この手のことは、DataGridViewのドキュメントの中に「共有モード」という記述があるので、それを参照されたい。
&lt;/p&gt;
&lt;p&gt;
ここのでポイントは、バインディングや仮想モードになっているときには、DataGridView.Rowsプロパティにデータが存在しないということである。要するにこのプロパティを使ってデータを操作しているドキュメント上のサンプルなどは、普通のモードで動いているDataGridViewでの話であって、バインディングなどの場合には通用しない。
&lt;/p&gt;
&lt;p&gt;
ところで、バインディングの場合、DataSourceは、基本的にはBindingSourceのインスタンスを設定する。このBindingSourceに実際のデータをBindingSource.DataSourceに設定する。このことは、ドキュメントに詳しく書かれているので詳細は割愛するが、BindingSource.DataSourceには、DataSetなどの複雑な構造のデータや、単純なオブジェクトのリスト(System.Collections.Generic.Listなど)を設定することができる。
&lt;/p&gt;
&lt;p&gt;
DataGridViewで編集などをする場合には、行やセルの選択をいう操作が必要になるのだが、BindingSource.DataSourceに設定されるデータは、列挙可能(IListが実装されている）なものでしかないので、選択された位置という情報は持っていない。すなわち、BindingSourceが選択や項目の並び替え（ソート）を担っているということになる。
&lt;/p&gt;
&lt;div style="text-align:center"&gt;
&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article */
google_ad_slot = "4760784415";
google_ad_width = 468;
google_ad_height = 60;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;
&lt;/div&gt;
&lt;p&gt;
プログラムで項目を選択したい場合、普通のモードのDataGridViewときには、Rowsプロパティから行に対するデータを取得して、セルや行（Row）に対して選択を設定する。ところが、バインディングモードの場合、DataGridView.Rowsプロパティを使うのではなく、DataSourceプロパティに設定されたBindingSourceを操作する。具体的にはPositionプロパティやMoveFirstメソッドなどで現在の位置を変更する。
&lt;/p&gt;
&lt;p&gt;
DataGridView.DataSourceにBindingSourceを設定している場合、プログラムでBindingSourceの現在の位置を変更すると、DataGridViewの表示上の選択位置が変更され、マウス操作などでDataGridViewの選択位置が変更されるとBindingSourceの現在の位置が変更される、という仕組みになっている。
&lt;/p&gt;
&lt;div style="text-align:center"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article Link */
google_ad_slot = "5036282279";
google_ad_width = 468;
google_ad_height = 15;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-7024089262222582936?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/0_4uyswGBUf6iY02as6LnWzcnlk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0_4uyswGBUf6iY02as6LnWzcnlk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/0_4uyswGBUf6iY02as6LnWzcnlk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0_4uyswGBUf6iY02as6LnWzcnlk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/-t31Zj7FOjM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/7024089262222582936/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=7024089262222582936" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/7024089262222582936?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/7024089262222582936?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/-t31Zj7FOjM/netdatagridview.html" title="[.NET]DataGridViewのデータについて" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2008/11/netdatagridview.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MNSH8zcSp7ImA9WxRXEkw.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-8788696966868657795</id><published>2008-10-12T22:38:00.005+09:00</published><updated>2008-10-17T12:51:39.189+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-17T12:51:39.189+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="DataSource" /><category scheme="http://www.blogger.com/atom/ns#" term="VC++" /><title>VC++ 2008 Express でDataGridViewとDataSourceを使ってみる</title><content type="html">&lt;p&gt;
C#でDataSourceを使ってDataGridViewに表示させるサンプルは、ドキュメントに書かれているようですが、C++については載ってなかったので、勘でコードを書いて見たのですが、それでもちゃんと動いているようなので、簡単なやり方を書いてみます。ただし、この方法が最適なものかはわかりません。とりあえずです…。
&lt;/p&gt;
&lt;p&gt;
まずは、テーブルの定義をどこかでやるのですが、VC++でサポートされているデータベースであれば、接続してテーブル定義を引っ張ることができるようですが、そうでない場合、データデザイナを使って定義したいところですが、VC++でサポートされていないということになってます。&lt;br /&gt;
とりあえず、VC# Express Editionであれば、データデザイナでテーブル定義ができるのそれで定義します。そうすると、xsdファイルが生成されるので、これをVC++のプロジェクトに追加します（プロジェクトのディレクトリにコピーして、既存追加したほうがよいかも）。
&lt;/p&gt;
&lt;p&gt;
そうすると、xsdファイルを開くとデータデザイナらしき画面が表示されます。ここでも編集が可能なようです。さらにxsc、xssとヘッダファイルが生成されます。xscとxssはソリューションエクスプローラー上では、エラーを示すアイコンが表示されているのですが、C++のビルドにはこれらは使わなくてもよさそうなので、そのまま放置しておきます。&lt;br /&gt;
生成されるヘッダーですが、中身をみる限りちゃんと定義されたテーブルどおりのDataSetやDataTableのコードになっていて、コンパイルもできます。ただ、このヘッダファイルをプリコンパイルヘッダ（stdafx.h）に追加するようですが、そのままだと何故か致命的なコンパイルエラーが出て失敗するのですが、それを外してコンパイルすればビルドが成功します（これらのクラスを使うソースコードに普通にインクルードする）。
&lt;/p&gt;
&lt;p&gt;
DataGridViewなどに表示されるためには、BindingSourceを生成して、テーブルデザイナで定義したDataSetを割り当てればよいです。この操作は、フォームのデザイナを使って、BindingSourceをツールボックスなどで作成して、DataSourceプロパティに定義したDataSetを設定すればよいです。DataSetがうまくコンパイルできていれば一覧に表れるはずです。
&lt;/p&gt;
&lt;p&gt;
ここまでうまくいけば、C#でBindingSourceを使ってデータを表示される手順と同じ要領で、Formのコンストラクタかどこかで、BindingSourceのDataSourceプロパティにDataSetのインスタンスを設定します。すなわち、生成されたヘッダに定義されているDataSetのサブクラスをgcnewしたものをフォームデザイナで生成したBindingSourceのインスタンスのDataSourceに代入するということです。ちなみにフォームのデザイナは、BindingSourceのDataSourceに定義したDataSetのタイプIDを代入していますが、これはそのままにしておいて、そのコードの後に実行されるどこかで、インスタンスをDataSourceに代入してしまってもよいみたいです。
&lt;/p&gt;
&lt;div style="text-align:center"&gt;
&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article */
google_ad_slot = "4760784415";
google_ad_width = 468;
google_ad_height = 60;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;
&lt;/div&gt;
&lt;p&gt;
その後コードについては、ドキュメントに書いてあるC#のコードをC++に書き直すつもりでコーディングしていけばうまくいくはずです。簡単な例とすれば、DataSetのサブクラスに定義したDataTableのサブクラスのインスタンスが取得できるプロパティがあるので、そのDataTableのRowsプロパティに、定義されたDataRowのサブクラスのインスタンス（生成はDataTableのNewRowに相当するメソッドが定義されているのでそれを呼び出す）をAddすると項目が追加されると、いった感じです。
&lt;/p&gt;
&lt;div style="text-align:center"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article Link */
google_ad_slot = "5036282279";
google_ad_width = 468;
google_ad_height = 15;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-8788696966868657795?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/we8WUmMVm3Hn5LwoqSKVQrxZq-U/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/we8WUmMVm3Hn5LwoqSKVQrxZq-U/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/we8WUmMVm3Hn5LwoqSKVQrxZq-U/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/we8WUmMVm3Hn5LwoqSKVQrxZq-U/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/slqB6ccgqfI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/8788696966868657795/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=8788696966868657795" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/8788696966868657795?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/8788696966868657795?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/slqB6ccgqfI/vc-2008-express-datagridviewdatasource.html" title="VC++ 2008 Express でDataGridViewとDataSourceを使ってみる" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2008/10/vc-2008-express-datagridviewdatasource.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMMR3oyfSp7ImA9WxdUGE4.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-6487583967324579197</id><published>2008-08-04T15:02:00.002+09:00</published><updated>2008-08-04T15:48:06.495+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-08-04T15:48:06.495+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Capture" /><category scheme="http://www.blogger.com/atom/ns#" term="Managed" /><category scheme="http://www.blogger.com/atom/ns#" term="DirectX" /><category scheme="http://www.blogger.com/atom/ns#" term="VC++" /><category scheme="http://www.blogger.com/atom/ns#" term="DirectSound" /><title>Managed DirectXでのサウンドキャプチャ（２）</title><content type="html">&lt;p&gt;
&lt;a href="http://quickprogram.blogspot.com/2008/07/managed-directx.html"&gt;前記事&lt;/a&gt;でVC++でManaged DirectSoundを使ってサウンドをキャプチャする方法について書いたのだが、アンマネージドでキャプチャされたデータを取得するところが曖昧だったので、ちゃんと書いてみる。&lt;p&gt;
&lt;/p&gt;
キャプチャバッファからデータを取得する場合、読み取り用のメソッド(CaptureBuffer::Read)でArrayかStreamのいずれかを得ることができるが、最終的にアンマネージドなコードで処理するために、キャプチャされたデータが格納されているバッファへのポインタ(const unsigned char*)を取得したいとする。
&lt;/p&gt;
&lt;p&gt;
マネージドなデータをアンマネージドなコードから参照する手段は、pin_ptr&amp;lt;&amp;gt;を使用するとして、その場合、array&amp;lt;&amp;gt;が必要になるわけだが、メソッドとして、ArrayかStreamのいずれかの選択肢がある中、どれを使ってpin_ptr&amp;lt;&amp;gt;を得るのがよいのかということを試行した結果、MemoryStreamを使って、CaptureBuffer::Readを呼び出す方法が無難であるという結論になった。
&lt;/p&gt;
&lt;p&gt;以下のコードは&lt;a href="http://quickprogram.blogspot.com/2008/07/managed-directx.html"&gt;前回&lt;/a&gt;の最後のコードの続きとなるが、最終的には、16bitデータ(const short*)へのポインタを得ている。
&lt;/p&gt;
&lt;code&gt;&lt;pre style="background-color:#000000;color:#ffffff;padding:0.3em;overflow:auto"&gt;int size;//キャプチャされたデータのサイズ[byte]
array&amp;lt;unsigned char&amp;gt;^ dataBuffer = gcnew array&amp;lt;unsigned char&amp;gt;(size);
MemoryStream^ dataStream = gcnew MemoryStream(dataBuffer);
captureBuffer-&gt;Read(lastReadPos, dataStream, size, LockFlag::None);
pin_ptr&amp;lt;unsigned char&amp;gt; ptr = &amp;amp;dataBuffer[0];
const short* sampleBuffer = (const short*) ptr;
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;
ここで注意することとしては、const short*にキャストしているので、実際のデータはsizeの半分(sizeof(short)分の１)になっていることと、キャプチャしているスレッドで時間がかかる処理をすると、データを取りこぼす可能性があるということである。&lt;br /&gt;
キャプチャの取りこぼしを避けるための無難な手段としては、取り込んだデータ(array&amp;lt;unsigned char&amp;gt;^)をキュー(Queue)に入れて、別のスレッドで取り込む方法が考えられる。ただし、CLIで用意されているキューは同期化はサポートされているものの、空の状態のブロッキングはしてくれないので、なんだかの同期オブジェクト(AutoResetEventなど)を利用したほうがよいかもしれない。
&lt;/p&gt;
&lt;div style="text-align:center"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article Link */
google_ad_slot = "5036282279";
google_ad_width = 468;
google_ad_height = 15;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-6487583967324579197?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ACCTnfyU5Z9RSCVLt6sPPoKxERU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ACCTnfyU5Z9RSCVLt6sPPoKxERU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ACCTnfyU5Z9RSCVLt6sPPoKxERU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ACCTnfyU5Z9RSCVLt6sPPoKxERU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/qfJVDMNooMo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/6487583967324579197/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=6487583967324579197" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/6487583967324579197?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/6487583967324579197?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/qfJVDMNooMo/managed-directx.html" title="Managed DirectXでのサウンドキャプチャ（２）" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2008/08/managed-directx.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk8NSHc_eCp7ImA9WxdVEU8.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-222097377168392531</id><published>2008-07-15T13:09:00.009+09:00</published><updated>2008-07-15T21:28:19.940+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-07-15T21:28:19.940+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Capture" /><category scheme="http://www.blogger.com/atom/ns#" term="Managed" /><category scheme="http://www.blogger.com/atom/ns#" term="DirectX" /><category scheme="http://www.blogger.com/atom/ns#" term="VC++" /><category scheme="http://www.blogger.com/atom/ns#" term="DirectSound" /><title>Managed DirectXでサウンドをキャプチャする</title><content type="html">&lt;p&gt;
とりあえず、VC++ 2008 Express Editionでサウンドをキャプチャするコードを書いてみることになったのだが、折角なのでManaged DirectX(MDX)のDirectSoundを使ってみることにした。&lt;br /&gt;
コードは、VC++ではあるが、&lt;acronym title="Common Language Runtime"&gt;CLR&lt;/acronym&gt;で動作するので、C#などの他言語でもほぼ同じコードになるはずである。&lt;br /&gt;
MDXのDirectSoundを利用するには、「Microsoft.DirectX.DirectSound」という、.NETの参照をプロジェクトに追加しなければならない。もしこれが「参照の追加」の一覧で見つからなければ、DX9以降のランタイムかSDKをインストールする。
&lt;/p&gt;
&lt;p&gt;MDXとはいえ、所詮DirectXをラップしたようなものであるがゆえに、基本的な概念はDirectSoundに由来する。もし、DirectSound関連のドキュメントを読んだことがなければ、一読することをおすすめする。&lt;br /&gt;というわけで、ManagedなDirectSoundを利用するに当たり、知っていたほうがよいと思われること（アンマネージドのDirectSoundとの違いも含む）は、以下のことであると思われる。&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;CaptureはIDirectSound8&lt;/dt&gt;
&lt;dd style="margin-left:1em"&gt;サウンドデバイス関連を司っていると考えてよい。&lt;/dd&gt;
&lt;dt&gt;CaptureBufferはIDirectSoundCaptureBuffer8に相当&lt;/dt&gt;
&lt;dd style="margin-left:1em"&gt;ただし、使い方はManaged風になっているため多少違う。&lt;/dd&gt;
&lt;dt&gt;非同期用のイベント(IDirectSoundNotify8)はNotify&lt;/dt&gt;
&lt;dd style="margin-left:1em"&gt;イベントの処理は、System.Threadingにあるものを使う。&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;まずは、Captureクラスだが、IDirectSound8とほとんど同じ様なものなので、特に説明はしない。単純にデフォルトキャプチャデバイス（コントロールパネルのサウンドで定義されている）を使って、キャプチャするには以下のようなコードをになる。&lt;/p&gt;
&lt;code&gt;&lt;pre style="background-color:#000000; color:#ffffff;padding:0.3em"&gt;Capture^ capture = gcnew Capture();
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;次にCaptureBufferクラスだが、これもやっていることは同じで、「CaptureBufferDescription」という構造体(DSCBUFFERDESCに相当）に必要な情報を入れて、インスタンスを作成すればよい。エフェクトを利用しない場合のバッファの作成は以下のようになる。&lt;/p&gt;&lt;code&gt;&lt;pre style="background-color:#000000; color:#ffffff;padding:0.3em;overflow:auto"&gt;CaptureBufferDescription desc;
desc.ControlEffects = false;
desc.WaveMapped = true;
//GetWaveFormat()はWaveFormat構造体を返す関数
desc.Format = GetWaveFormat(44100, 2, 16);
//BufferSecondsはバッファの秒数
desc.BufferBytes = desc.Format.AverageBytesPerSecond * BufferSeconds;

CaptureBuffer^ captureBuffer = gcnew CaptureBuffer(desc, capture);
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;ちなみに上記のGetWaveFormat()は、誰が書いても同じようなコードになると思われるが、いちおうこんな感じ。MDXの「WaveFormat」は、DXの「WAVEFORMATEX」と同じ。&lt;/p&gt;
&lt;code&gt;&lt;pre style="background-color:#000000; color:#ffffff;padding:0.3em;overflow:auto"&gt;WaveFormat GetWaveFormat(int rate, int channel, int rez)
{
 WaveFormat format;
 format.FormatTag = WaveFormatTag::Pcm;
 format.SamplesPerSecond = rate;
 format.Channels = channel;
 format.BitsPerSample = rez;
 format.BlockAlign = format.Channels * format.BitsPerSample / 8;
 format.AverageBytesPerSecond = format.SamplesPerSecond * format.BlockAlign;
 return format;
}
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;バッファの更新通知の設定については、DXの「IDirectSoundNotify8::SetNotificationPositions()」を使って設定する方法とイメージは同じだが、登録するためのイベントハンドルは、Managedなものを使う。基本的には、「AutoResetEvent」を使うようなのでここでもこれを使って登録する。&lt;/p&gt;
&lt;code&gt;&lt;pre style="background-color:#000000; color:#ffffff;padding:0.3em;overflow:auto"&gt;AutoResetEvent^ autoResetEvent = gcnew AutoResetEvent(false);
// BufferSecondsはバッファの秒数
// CapturePerSecondは１秒間に通知してほしい回数
int notifications = BufferSeconds * CapturePerSecond;
array&lt;BufferPositionNotify&gt;^ bufferPositionNotifies = gcnew array&lt;BufferPositionNotify&gt;(notifications);
for (int i=0; i&amp;lt;notifications; i++) {
 bufferPositionNotifies[i].EventNotifyHandle = autoResetEvent-&gt;Handle;
 bufferPositionNotifies[i].Offset = 
  format.AverageBytesPerSecond * (i+1) / CapturePerSecond - 1;
}
Notify^ notify = gcnew Notify(captureBuffer);
notify-&gt;SetNotificationPositions(bufferPositionNotifies);
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;
通知を登録したので、別スレッドでイベントを待って、キャプチャされたデータを取得する。以下の関数は、スレッド用の関数となる。&lt;br /&gt;
ちなみにDXの場合、「IDirectSoundCaptureBuffer8::Lock()」を使ってデータを得るのであるが、この関数は露骨にリングバッファから読み取る仕様になっている。MDXの場合は、単純にArrayまたはSystem::IO::Streamに読み込むことができる。以下の例は、shortが格納されているArrayに読み込むようにしている。
&lt;/p&gt;
&lt;code&gt;&lt;pre style="background-color:#000000; color:#ffffff;padding:0.3em;overflow:auto"&gt;void CaptureThreadProc()
{
 int bufferSize = captureBuffer-&gt;Caps.BufferBytes;
 int capturePos, lastReadPos;
 captureBuffer-&gt;GetCurrentPosition(capturePos, lastReadPos);
 do {
  autoResetEvent-&gt;WaitOne();
  int readPos;
  captureBuffer-&gt;GetCurrentPosition(capturePos, readPos);
  int size = readPos - lastReadPos;
  if (size == 0) continue;
  if (size &lt; 0) size += bufferSize;
  // shortで読む場合、読み込むサイズをsizeof(short)で割らないとエラーになる
  Array^ captureData = 
   captureBuffer-&gt;Read(lastReadPos, Type::GetType("System.Int16"), LockFlag::None, size / 2);
  //ここでcaptureDataにあるデータを処理する
  lastReadPos = readPos;
 } while(captureBuffer-&gt;Capturing);
}
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;ちなみにこの関数では、キャプチャが停止するとループを抜けてスレッドが終了するようにしている。そのため、キャプチャ開始前に(CaptureBuffer::Start()を呼ぶ前）にスレッドを作成して走らせておく必要がある。&lt;br /&gt;
この場合、Arrayにデータが入ってくるのであるが、実際のデータはGC内にあるため、ネイティブ(アンマネージド)で処理をする場合には、ArrayのGetEnumerator()でEnumeratorを得てからひとつずつ取り出すか、array&amp;lt;&amp;gt;にしてから、pin_ptr&amp;lt;&amp;gt;を使ってポインタを得て処理するという方法が考えられる。&lt;/p&gt;
&lt;p&gt;あと、キャプチャの開始、停止は、CaptureBuffer::Start()、CaptureBuffer::Stop()を呼び出せばよい。この場合にはスレッドで読み込み続けるのでStart(true)となる。&lt;/p&gt;
&lt;div style="text-align:center"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article Link */
google_ad_slot = "5036282279";
google_ad_width = 468;
google_ad_height = 15;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-222097377168392531?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/VZujZAQVOO5ipn_HyO-RHd7pzxM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/VZujZAQVOO5ipn_HyO-RHd7pzxM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/VZujZAQVOO5ipn_HyO-RHd7pzxM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/VZujZAQVOO5ipn_HyO-RHd7pzxM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/JWM2RkvNFCQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/222097377168392531/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=222097377168392531" title="1 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/222097377168392531?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/222097377168392531?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/JWM2RkvNFCQ/managed-directx.html" title="Managed DirectXでサウンドをキャプチャする" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2008/07/managed-directx.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YBRns7eyp7ImA9WxdWEE0.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-8458431833440600421</id><published>2008-04-27T18:39:00.008+09:00</published><updated>2008-07-02T23:32:37.503+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-07-02T23:32:37.503+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="アライメント" /><category scheme="http://www.blogger.com/atom/ns#" term="SSE" /><category scheme="http://www.blogger.com/atom/ns#" term="GCC" /><category scheme="http://www.blogger.com/atom/ns#" term="JNI" /><title>GCCを使ったJNIなどのDLLでSSE命令を使うときの問題点</title><content type="html">&lt;p&gt;JavaからJNIでDLLを呼び出せるので、JavaVMで処理に時間がかかりそうな処理をC/C++で開発してみようと思うのは普通だと思うし、どうせならMMXやSSEなどで高速に演算させたいと思うこともある。&lt;br /&gt;GCCには、MMX、SSEなどの命令を呼び出すためのAPI(__builtin_ia32_hogehoge())があるので、これらを使えば、わざわざアセンブラのお世話にならずとも実現することが可能である。ということで、JNIなDLLをSSE命令を使って開発するのであるが、これが一筋縄に行かないようなのである。&lt;/p&gt;
&lt;p&gt;SSEには、メモリー上のデーターをアクセスするための命令に128bitアライメントされているデーター用とそうでないもの用の２つがある(MOVAPSとMOVUPSなど）。要するに、128bitアライメントされているほうが高速にアクセスできるということであるが、もし、アライメントがされていないデーターにアクセスすれば、いわゆるソフトウェア割り込みが発生してアプリケーションエラーとなってしまう。&lt;br /&gt;
これらのアライメントを前提とする命令を使うには、コード上データーがアライメント上にあることが保証されているなければならないということになる。&lt;/p&gt;
&lt;p&gt;普通、C/C++でプログラムするときには、データーがメモリ上どう配置されるかということを気にすることなく、もし、なんだかの制約があるとすれば、コンパイラーが何とかしてくれる（それ用のオプションをつけて実行するとか）ことにしている。&lt;br /&gt;
ただし、デフォルトでない特殊なアライメントなどを利用したい場合には、GCCでは__attribute__((aligned(n)))のような属性をつけられる。これは例えば、&lt;code&gt;char data[256] __attribute__((aligned(16))) = {0};&lt;/code&gt;のように使うのだが、この例では、このchar配列を128bit(16byte)上に配置するようにしていている。&lt;/p&gt;
&lt;p&gt;ただし、このように書けるのはC/C++上での静的な変数に対してであり、動的に得る場合（mallocやnewで生成する領域）では、このような属性では制御できない。ただ、C/C++の場合、ポインターはメモリーアドレスそのものであると考えられるので、ポインターをずらして、合わせてしまうという事が可能である（本質的にはAPI側でなんとかしてほしいところだが）。&lt;/p&gt;
&lt;p&gt;このようにすれば、SSEでのアライメントの問題が解決するということにしたいのだが、実際にはそういう訳にはいかない。というのが、本題であったりする。&lt;br /&gt;ここで根が深いのは、基本的にはコンパイラーのオプションや属性の指定で解決されているべきものが、実際にはアライメントされていないということである。&lt;br/&gt;アセンブラ以外でアライメントなどを考慮しなくてはいけないのは、C/C++であるとしてでもおかしな話であると思うが、CPU固有の命令を使おうとしているので、なんだかの特殊な処理が必要であると考えても仕方がないかもしれない。確実に動くコードが書ければ、それはそれで問題ないといえるだろう。&lt;/p&gt;
&lt;p&gt;ところで、C/C++で変数といわれるものは２つあり、それはいわゆるstaticで宣言されるものと、関数やブロックのなかで宣言されるいわゆるauto変数といわれるものである。&lt;br /&gt;
staticな変数は、モジュールがロードされるときに確保され、その領域はモジュールがなくなるまで存在する。この変数は、その領域のアドレスをどこかに保持し、領域内の相対アドレスをコード内に持って、それを足してアドレスを確定してアクセスする。&lt;br /&gt;
ここでアライメントを保持するには、領域の先頭のアドレスをアライメントされるように配置して、相対アドレスもアライメントを保持するように割り当てるようにする。&lt;br /&gt;コンパイラーでオプションや属性で指定するアライメントは、相対アドレスにを指定するものであり、領域のアドレスはモジュールのロードにアライメントされて確保されるので、問題なく使える。&lt;/p&gt;
&lt;div style="text-align:center"&gt;
&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article */
google_ad_slot = "4760784415";
google_ad_width = 468;
google_ad_height = 60;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;auto変数は、スタックといわれる領域に確保される。これは、関数が呼び出されるときのスタックのアドレス（スタックポインター）を基に相対的に割り当てられる。&lt;br /&gt;
autoな変数のアライメントは、staticと同様に相対アドレスは、コンパイラーが割り当てて、スタックは、モジュールのロード後、最初の関数を呼び出すときにアライメントされるように割り当てられるようになっている。その後、呼び出される関数もアライメントするように配置することによって、アライメントを維持するようにしている。&lt;br /&gt;
そうすると、staticな変数と同様にauto変数も問題なく動くはずなのだが…。&lt;/p&gt;
&lt;p&gt;最初に述べたのだが、DLLでSSEを使うときの問題があるということなのだが、それは、DLLのスタックは、呼ばれる元のモジュールのスタックを引き継いで利用する。これは、C/C++で関数を呼び出すために必要な仕組みである。&lt;/p&gt;
&lt;p&gt;もし、C/C++コード上でアライメントが不明であれば、アライメントを前提としない命令を使えばよいのだが、コンパイラーはauto変数に割り当てられたSSE用の変数を、アライメントされているものとして、読み書きするような命令を出力するのである。&lt;br /&gt;
ということで、おわかりであると思うが、DLLを呼び出すモジュールがアライメントを維持しないようにスタックを使っている場合、DLLでアライメントを保持するようになっていても、うまく動かないということになるわけである。それは、JNIがJavaVMから呼び出されるときも起きていて、JNIのDLLでSSE命令を使おうとすると、ほとんどうまくいかない（うまくいくのは、SSE用の変数がすべてレジスタ上に配置されたときか、運良くスタックがアライメントされているときだけ）。&lt;/p&gt;
&lt;div style="text-align:center"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article Link */
google_ad_slot = "5036282279";
google_ad_width = 468;
google_ad_height = 15;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;どうやら、このことを問題だと思っている人が多く居るらしく、GCCでこれを回避するオプションを作ることが想定されているようだが、まだ実装されていないもよう。ましては、MinGWでの移植にも時間がかかるため、おそらくMinGWのGCC環境では、うまく動くコードをはくコンパイラーはしばらく先になるだろう。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-8458431833440600421?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/AR7KjYmQ9y0qK7yy5eCRgsdtDl4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AR7KjYmQ9y0qK7yy5eCRgsdtDl4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/AR7KjYmQ9y0qK7yy5eCRgsdtDl4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AR7KjYmQ9y0qK7yy5eCRgsdtDl4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/lbuQWfWXWoo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/8458431833440600421/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=8458431833440600421" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/8458431833440600421?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/8458431833440600421?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/lbuQWfWXWoo/gccjnidllsse.html" title="GCCを使ったJNIなどのDLLでSSE命令を使うときの問題点" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2008/04/gccjnidllsse.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cDSXY_fSp7ImA9WxdWEE0.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-7338629640520619876</id><published>2008-04-14T21:46:00.008+09:00</published><updated>2008-07-02T23:31:18.845+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-07-02T23:31:18.845+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="Javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="AJAX" /><title>PHPでAJAXをやってみる</title><content type="html">&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article Link */
google_ad_slot = "5036282279";
google_ad_width = 468;
google_ad_height = 15;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;
&lt;p&gt;PEARにHTML_AJAXというパッケージがあるが、それを使わずにいわゆるAJAXをやってみるということです。&lt;br /&gt;とりあえずということで、基本的なことだけかもしれませんが、いちおう動いているコードを書いてみます。PHPとかいっている割には、大半がJavascriptな内容かもしれません。&lt;/p&gt;&lt;p&gt;AJAXとはなにか？ということは、世の偉い人があちこちで解説されているので、ここでは説明しませんが、基本的には「非同期でサーバーから情報を取る」というのと、
「サーバーがXMLドキュメントを送る」、「XMLドキュメントをJavascriptで処理をしてブラウザに表示」という３つであると思って書きます。&lt;/p&gt;
&lt;h4&gt;非同期でサーバーから読み出す&lt;/h4&gt;&lt;p&gt;まずは、Javascriptの「XMLHttpRequest」のオブジェクトを作成して、それを使ってデーターを読み込むという手順になります。XMLHttpRequestを作成するコードは以下のような感じ（どこかのコードのパクリかもしれないが…）。&lt;/p&gt;
&lt;code&gt;&lt;pre style="background-color:#000000;color:#ffffff;overflow:auto;height:12em;padding:0.2em"&gt;function createHttpRequest(){
 if(window.ActiveXObject){
  try {
   return new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
   try {
    return new ActiveXObject("Microsoft.XMLHTTP");
   } catch (e2) {
                return null;
            }
         }
    } else if(window.XMLHttpRequest){
        return new XMLHttpRequest();
    } else {
  return null;
    }
}
&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;という関数を定義して、&lt;code&gt;var request = createHttpRequest();&lt;/code&gt;とすれば、XHTMLRequestのオブジェクトが得られる。&lt;/p&gt;&lt;p&gt;次にデータを取得するわけだが、クラス化されたJavascriptで処理をするために以下のような関数を作ってみた。&lt;/p&gt;
&lt;code&gt;&lt;pre style="background-color:#000000;color:#ffffff;overflow:auto;height:12em;padding:0.2em"&gt;function sendRequest(obj, callback, url) {
 var request = createHttpRequest();
 if (request == null) return false;
 request.onreadystatechange = function() {
  callback.call(obj, request);
 }
 request.open('GET', url, true);
 request.send(null);
 return true;
}
&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;データーの受信は、非同期で行われるため、コールバック関数を用意して、読み込みが完了したら、コールバック関数が呼び出されて、そこからデーターを読み取るという処理になる。&lt;br /&gt;この関数を使うためのクラスは、以下のようになる。&lt;/p&gt;
&lt;code&gt;&lt;pre style="background-color:#000000;color:#ffffff;overflow:auto;height:12em;padding:0.2em"&gt;function MyClass(){
 this.callback = function(request) {
  if (request.readyState == 4) {
   if (request.status == 200) {
    var xmlDoc = request.responseXML;
    //このxmlDocから情報を読み取る
   }
  }
 }
}
&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;ちなみに&lt;code&gt;request.readyState&lt;/code&gt;というのは、1から4までが設定されて呼び出されるのだが、4というのが完了したということになる。あと、&lt;code&gt;request.status&lt;/code&gt;を確認するも必須で、これはHTTPのリザルトコードになっている。すなわち、200で正常に通信したということであり、そのほかはなんだかのエラーということになる（エラー処理はここでは省略…）。このクラスと先ほどの関数を使ったコードは以下の通り。&lt;/p&gt;
&lt;code&gt;&lt;pre style="background-color:#000000;color:#ffffff;overflow:auto;padding:0.2em"&gt;var url;//データーを持ってくるためのURL
var obj = new MyClass();
sendRequest(obj, obj.callback, url);&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;この関数は、MyClassの中で定義してしまってもよいかと思います。そのときは、objはthisになります。&lt;/p&gt;
&lt;h4&gt;サーバー側の処理&lt;/h4&gt;
&lt;p&gt;サーバーから送るデーターはXMLになっていれば、Javascriptで値が取り出せるということになるわけだが、例えばa=1とt=testというデーターを送りたいのであれば、&lt;/p&gt;
&lt;code&gt;&lt;pre style="background-color:#000000;color:#ffffff;overflow:auto;padding:0.2em"&gt;&amp;lt;?xml version="1.0"?&amp;gt;
&amp;lt;result&amp;gt;
 &amp;lt;a&amp;gt;1&amp;lt;/a&amp;gt;
 &amp;lt;t&amp;gt;test&amp;lt;/t&amp;gt;
&amp;lt;/result&amp;gt;&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;というXMLを送ればよいということになる。ちなみにコード系がUTF-8以外ならば、versionのあとにcharsetを設定しなければならないだろう。&lt;br /&gt;要するに、このようなXMLを返すのであれば、なんでもいいのであるが、PHPでなんだかの処理をして返すということにした場合、PHPのソースのどこかで、HTTPヘッダを設定しなければならず、&lt;code&gt;header("Content-Type: text/xml");&lt;/code&gt;と書けばよいということになる（application/xmlというタイプもあるが、使い分けはよくわかってません…）。&lt;/p&gt;
&lt;p&gt;XMLドキュメントをPHPでどう生成するかということになるわけだが、ごりごりと自分で上記のようなXMLを出力するコードを書いて、送るのでもよい。そのへんは規模にもよるとは思うが、PHPに組み込まれている関数を使ったほうがよい場合もあると思う。&lt;br /&gt;
ここでは、本来の使い方ではないかもしれないが、「DOM XML 関数」というPHPの組み込み関数を使うことにする。具体的には「DOMDocument」というクラスのオブジェクトを生成して、そこにXMLのデーターをセットして、saveXML();というメソッドでXMLの文字列を得る。それをechoして、クライアントに送るという手順になる。&lt;br /&gt;先ほどのXMLと同じ内容を出力するコードは以下のようになる。&lt;/p&gt;
&lt;code&gt;&lt;pre style="background-color:#000000;color:#ffffff;overflow:auto;height:12em;padding:0.2em"&gt;header("Content-Type: text/xml");
$doc = new DOMDocument();
$resultElement = $doc-&gt;createElement('result');
$doc-&gt;appendChild(resultElement);
$aElement = $doc-&gt;createElement('a');
$aElement-&gt;appendChild($doc-&gt;createTextNode('1'));
$resultElement-&gt;appendChild($aElement);
$tElement = $doc-&gt;createElement('t');
$tElement-&gt;appendChild($doc-&gt;createTextNode('test'));
$resultElement-&gt;appendChild($tElement);
echo $doc-&gt;saveXML();
&lt;/pre&gt;&lt;/code&gt;
&lt;h4&gt;Javascriptでデーターを得る&lt;/h4&gt;
&lt;p&gt;まず、いきなりいい訳だが…、以下の手順はちゃんと動いているものの正しいかどうかはあまり自信がない。ネットでいろいろ調べてみたものの、いくつかのコードが見受けられた。&lt;br /&gt;とりあえずは、取得したXMLドキュメントに同じタグ（エレメント）が存在しない（上記の例では&lt;code&gt;&amp;lt;a&amp;gt;1&amp;lt;/a&amp;gt;&lt;/code&gt;という'a'タグがひとつしかない）というのを前提とする。&lt;/p&gt;
&lt;p&gt;以下のようなJavascriptの関数を用意してみた。&lt;/p&gt;
&lt;code&gt;&lt;pre style="background-color:#000000;color:#ffffff;overflow:auto;padding:0.2em"&gt;function getElement(parent, name) {
 return parent.getElementsByTagName(name).item(0);
}
function getNodeValue(element) {
 return element.childNodes.item(0).nodeValue;
}
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;この関数を使って、先ほどのXMLドキュメントのオブジェクト（xmlDocという変数）から"a"という値を得るコードは以下の通り。&lt;/p&gt;
&lt;code&gt;&lt;pre style="background-color:#000000;color:#ffffff;overflow:auto;padding:0.2em"&gt;var aElement = getElement(xmlDoc, 'a');
var a = getNodeValue(aElement);
&lt;/pre&gt;&lt;/code&gt;
&lt;div style="text-align:center"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article */
google_ad_slot = "4760784415";
google_ad_width = 468;
google_ad_height = 60;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/div&gt;
&lt;p&gt;あとは、これらの得られたデーターをブラウザ上に表示するわけだが、これはいわゆるDOMといわれている仕組みを使って表示するのだが、ここではさらに長くなりそうなので割愛させていただく。&lt;/p&gt;
&lt;p&gt;というわけで、とりあえずながらも、PHPを使ってAJAXをやってみた。あとは、いわゆる配列のようなデーターをJavascriptのXMLDocumentから取得できるようにする必要があると思う。これについては、いずれ書きたいと思う。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-7338629640520619876?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/9M-GgUwrXlXx4BOjITKcs6UhY2k/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9M-GgUwrXlXx4BOjITKcs6UhY2k/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/9M-GgUwrXlXx4BOjITKcs6UhY2k/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9M-GgUwrXlXx4BOjITKcs6UhY2k/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/mGM4P55eyp0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/7338629640520619876/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=7338629640520619876" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/7338629640520619876?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/7338629640520619876?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/mGM4P55eyp0/phpajax.html" title="PHPでAJAXをやってみる" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2008/04/phpajax.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUCSHkzfyp7ImA9WxZbEUU.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-831212311710806026</id><published>2008-04-14T15:45:00.004+09:00</published><updated>2008-04-15T00:34:29.787+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-15T00:34:29.787+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="はてな" /><title>はてな</title><content type="html">&lt;p&gt;はてなスターをつけてみたよ&lt;br /&gt;&amp;uarr;と書いてみるテストwww&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.hatena.ne.jp/"&gt;はてな&lt;/a&gt;から訪問される方が多いので、はてなに登録して、はてなスターをつけてみました。&lt;br /&gt;ちなみにＢｌｏｇｇｅｒもOpenIDに対応しているので、はてなのIDでコメントなどができるようです（実際にやってないので、どんなもんだかは不明）。&lt;/p&gt;&lt;p&gt;もっと、ちゃんとした記事を書いていかなくては、いけないなぁと感じております。&lt;br /&gt;おしえて君以外のコメント等は歓迎ですので、よろしくおねがいします。&lt;/p&gt;
&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article Link */
google_ad_slot = "5036282279";
google_ad_width = 468;
google_ad_height = 15;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-831212311710806026?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/oqc0jl2Hgz6_wPTGYY9EDRdI0cs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/oqc0jl2Hgz6_wPTGYY9EDRdI0cs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/oqc0jl2Hgz6_wPTGYY9EDRdI0cs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/oqc0jl2Hgz6_wPTGYY9EDRdI0cs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/LO7t_VsrXR8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/831212311710806026/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=831212311710806026" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/831212311710806026?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/831212311710806026?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/LO7t_VsrXR8/blog-post.html" title="はてな" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2008/04/blog-post.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkEGRHkyeCp7ImA9WxRUFks.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-2535963966913269706</id><published>2008-04-01T21:00:00.010+09:00</published><updated>2008-11-26T09:50:25.790+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-11-26T09:50:25.790+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="MinGW" /><category scheme="http://www.blogger.com/atom/ns#" term="Eclipse" /><category scheme="http://www.blogger.com/atom/ns#" term="JNI" /><title>EclipseとMinGWでJNIモジュールを開発する</title><content type="html">&lt;p&gt;ずいぶん前の記事で、JNIモジュールをEclipseでビルドやデバッグする方法を書いたのだが、久しぶりにJNIモジュールを作ってみようとしたら、同じようにはまってしまったw。今回は、はまったついでに、手順についてまとめることにする&lt;/p&gt;&lt;p&gt;前提としては、WindowsでEclipseを使って、JNIモジュールを作るということで、コンパイラはMinGWのG++を使う。ネイティブ側はC++で書くことにする（Cでもそれほど違いはないはずだが）。&lt;br /&gt;あとは、JDKドキュメントにあるJava Native Interface 仕様とMinGWのFAQぐらいは読んでいるという前提になる。EclipseはJavaとC/C++の開発環境(CDT)の両方がインストールされているものとする。&lt;/p&gt;&lt;h4&gt;プロジェクトの作成&lt;/h4&gt;&lt;p&gt;まずは、Javaのプロジェクトを作成する。Javaの方はJDKのドキュメントにあるとおり、nativeなメソッドを持つクラスを作成し、static{}の中でSysytem.LoadLibrary();を記述する。LoadLibraryの引数は、パッケージがある場合、"package_class"のように"."（ドット）を"_"（アンダースコア）に置き換えた文字列にする。&lt;br /&gt;例）myproject.testというパッケージでクラスがMyclassの場合、"myproject_test_Myclass"となる&lt;/p&gt;&lt;p&gt;C++のプロジェクトを作成するのだが、そのときにプロジェクトタイプは、"Shared Library"を指定する。蛇足かもしれないが、C++でJNIのAPIを呼び出すときには、JNIEnvのオブジェクトのメンバー関数を呼ぶ形になる。例えば、JNIのAPIがvoid hoge(JNIEnv* env, jstring str);という風にドキュメントに書いてあったら、C++では、env-&gt;hoge(str);という風に呼び出す。&lt;br /&gt;次にビルドの設定で、出力ファイルはLoadLibrary();で設定した文字列に拡張子".dll"が付くファイルが出力されるように指定する。makeコマンドの設定のところで、MinGWであれば、デフォルトを外して"mingw32-make -k"とする。&lt;br /&gt;ツールの設定(g++などの設定)のところを設定する、C++のコンパイルの設定で、プリプロセッサ(-D)のところに"_JNI_IMPLEMENTATION_"というdefineを追加する。あと、インクルードパス(-I)にJDKにあるincludeとinclude/win32の二つを設定する。もし、JDK_HOMEとかの環境変数が設定されていれば"${JDK_HOME}\include"と"${JDK_HOME}\include\win32"となる。この手の環境変数を設定したいならば、環境変数のところで設定できる。&lt;br /&gt;次にリンカの設定のところで、"-Wl,--kill-at"というオプションを設定するのであるが、適当なところがなさそうなので、コマンドラインのところで"g++"のあとにスペースを空けて設定する。リンクするライブラリ(-l)のところには、"jvm"を設定し、ライブラリの検索パスのところには、JDKにあるlibを設定する。JDK_HOMEを設定していれば"${JDK_HOME}\lib"となる。&lt;/p&gt;&lt;h4&gt;javahを実行する設定&lt;/h4&gt;&lt;p&gt;Javaのソースでnativeを含むクラスファイルをjavahコマンドに渡すと、JNIようのCのヘッダファイルを出力するのだが、javahをどうやって起動するのか？ということです。一度javahを実行すれば、ファイルが出来上がるので、DOS窓でコマンドを打ってもいいわけですが、きっと何度かコマンドを実行するハメになるので、どこかに書いておいて、簡単に実行できるようにしておきたい、と考えてみた。&lt;br /&gt;その方法はいくつかあるが、とりあえず思いついたのは&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Javaのプロジェクトにantを書いて、手で実行する&lt;/li&gt;&lt;li&gt;Cのビルド設定のステップビルドのところで、ビルド前のコマンドのところでjavahを書いて、ビルド時に実行する&lt;/li&gt;&lt;li&gt;ビルド前コマンドのころで、javahを起動するmakefileを書いて、ビルド時にmakeを実行する&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;といったところだが、どれか楽そうなのを選べばよいと思う。ちなみにantは、antを実行するjavaコマンドがJDKのものでないと、javahタスクは実行できないもよう。あと、ビルド前コマンドは、ビルドを実行するときに毎回起動されるので、場合によってはうざいかもしれない。少なくとも自動ビルド向きではない。&lt;br /&gt;makefileを書いて、DOS窓から手動実行するぐらいが無難なのかもしれない…。&lt;/p&gt;&lt;h4&gt;Javaの実行設定&lt;/h4&gt;&lt;p&gt;nativeを含むクラスを読み込むと、LoadLibrary();でDLLをロードする仕組みなので、EclipseでJavaの実行を設定して、実行(Run)すればよい。ここでの問題は、DLLをロードしようとしたときにjava.library.pathというシステムプロパティに登録してあるパスの中から、DLLを探し出して、ロードするという仕組みになっているので、それらのパスに含まれてないと、実行時に失敗するということである。これを解決する方法もいくつか考えられる。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;java.library.pathにあるパスにDLLをコピーする&lt;/li&gt;&lt;li&gt;実行時にjava.library.pathをDLLが存在するパスに設定する(起動時オプションのVMの設定で"-D java.library.path=…"と書く）&lt;/li&gt;&lt;li&gt;実行時にPATH変数(SolarisとかはLD_LIBRARY_PATH)にDLLが存在するパスを追加する&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;とりあえず、ここではデバッグをすることを目標とすることにして、実行時にビルドされたデバッグようのDLLのパスをPATH変数を追加するという方法をとることにする。&lt;br /&gt;具体的には、実行時の環境変数の設定で、"PATH"と変数を追加して、値を「${workspace_loc:&amp;lt;Cのプロジェクト名&amp;gt;/Debug}」とする。このとき、環境変数は追加するの方にしておいたほうがよい。&lt;/p&gt;&lt;p&gt;この段階で、Javaプロジェクトのほうが実行できなければ、デバッグもできないので、普通に実行できるようにしておく。&lt;/p&gt;&lt;h4&gt;JNIモジュールのデバッグ&lt;/h4&gt;&lt;p&gt;実行(Run)で動いていることが前提として、デバッグをするのだが、あとはC側のデバッグの設定をする。&lt;br /&gt;アタッチをするデバッグを定義して、アプリケーションのところには、Debugフォルダに出力されたDLLを設定する（普通は"Debug/&amp;lt;LoadLibrary();に設定した文字列&amp;gt;.DLL"）。これで、設定は完了。&lt;br /&gt;デバッグの手順は以下の通り。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;デバッグしたいCのソースにブレイクポイントを貼る&lt;/li&gt;&lt;li&gt;JavaのLoadLibrary()が実行された後でかつ、デバッグしたいCの関数が呼び出される前のどこかにブレイクポイントを貼る&lt;/li&gt;&lt;li&gt;Javaをデバッグ実行する&lt;/li&gt;&lt;li&gt;Javaのブレイクポイントで止まったら、Cをデバッグ実行する（アタッチをする）。アタッチコマンドは"javaw"であるが、Eclipseも"javaw"で動いているので、間違えないこと。タスクマネージャをみて、EclipseのPIDを確認しておいたほうがよいかも。&lt;/li&gt;&lt;li&gt;Cの実行が止まるので、Cのモジュール（gdb/mi）を選んで、再開させて実行中(Running)の状態にする&lt;/li&gt;&lt;li&gt;Javaのモジュールを選んで、ブレイクポイントで止まっているJavaを再開させる&lt;/li&gt;&lt;li&gt;Cのほうがブレイクポイントで止まる&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;と、いった具合でちょっと面倒だがこういった感じになる。&lt;br /&gt;JavaのブレイクポイントのところでLoadLibrary()のあと…といっているところは、LoadLibrary();のところにブレイクポイントを貼って、LoadLibrary()をステップ実行させるという方法が無難かもしれない（手順は増えてさらに面倒になるけども）。&lt;br /&gt;あと、アタッチのあとで、コンソールにエラーのような文字列が現れるが、そのまま、実行を再開させても問題ないもよう。場合によっては、問題が生じるかもしれないが。&lt;br /&gt;アタッチ直後にCのデバッグが停止したり、エラーを出力するのは、g++、gdbのバージョンなどで変わる可能性がある。&lt;/p&gt;
&lt;div style="text-align:center"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article Link */
google_ad_slot = "5036282279";
google_ad_width = 468;
google_ad_height = 15;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/div&gt;&lt;p&gt;ということで、なんとかEclipseとMinGWでJNIのモジュールが開発できるようになった。上記にも述べたが、MinGWのバージョン（g++やgdbなど）によって、状況は変わる可能性がある。ここではMinGWは5.1.3を使っている。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-2535963966913269706?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/hS51rYcbeV2mPpAz5sNS4fXq6k0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hS51rYcbeV2mPpAz5sNS4fXq6k0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/hS51rYcbeV2mPpAz5sNS4fXq6k0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hS51rYcbeV2mPpAz5sNS4fXq6k0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/ds22X0cogu4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/2535963966913269706/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=2535963966913269706" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/2535963966913269706?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/2535963966913269706?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/ds22X0cogu4/eclipsemingwjni.html" title="EclipseとMinGWでJNIモジュールを開発する" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2008/04/eclipsemingwjni.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUFRXY-eip7ImA9WxZUEU8.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-4405432752679004443</id><published>2008-03-28T11:31:00.006+09:00</published><updated>2008-04-02T16:43:34.852+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-02T16:43:34.852+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Swing" /><title>Java SwingでUndo/Redoを実装する</title><content type="html">&lt;p&gt;Swingのなかにあるjavax.swing.undoというパッケージを使ってUndo/Redoを実装するということなのだが、使い方については"&lt;a href="http://java.sun.com/docs/books/tutorial/"&gt;The Java Tutorial&lt;/a&gt;"に記載されてはいるものの実態がよくわからなかった。いつものごとく、やっつけでサンプルを作成して、どうなっているかを調べてみた。ちなみにサンプルソースは、どうにもならないほど煩雑になってしまったため、公開はしません。&lt;br /&gt;念のためですが、Undo/Redoというのは、なんだかの操作によって変更された履歴を保存して、一つ前の状態に戻すことがUndo、Undoで戻したものを元の戻すのがRedoということである。&lt;/p&gt;&lt;p&gt;The Java Tutorialでも書かれているが、一般的な実装方法は、以下のような感じになっている。&lt;/p&gt;&lt;dl&gt;&lt;dt&gt;UndoManagerを生成&lt;/dt&gt;&lt;dd style="margin-left:1em"&gt;これは単純に、UndoManagerをクラスの変数にして、&lt;code&gt;new UndoMnager();&lt;/code&gt;を代入すればよい。&lt;/dd&gt;&lt;dt&gt;UIの生成&lt;/dt&gt;&lt;dd style="margin-left:1em"&gt;これは、Undo/Redoをさせるためのメニューアイテムなどを作っておくということであるが、ドキュメントの例ではAbstractActionをサブクラス化して、メニュに追加しているが、普通にMenuItemを作ってもかまわない。&lt;br /&gt;メニューアイテムが選択されたときの動作（すなわち、ActionListenerのpublic void actionPerformed(ActionEvent e)の実装）は、Undoのときは、UndoManager.undo();でRedoのときは、UndoManager.redo();を呼び出せばよい。&lt;br /&gt;あとは、メニューアイテムは、UndoManager.canUndo();やUndoManager.canRedo();でUndo/Redoが可能かどうか判断して制御する。&lt;/dd&gt;&lt;dt&gt;Undo/Redo対象となるオブジェクトの監視&lt;/dt&gt;&lt;dd style="margin-left:1em"&gt;これは、Undo/Redoの状態に変化したときのイベントを拾ってくるためのものである。&lt;br /&gt;ここで、変更された履歴のデーターをUndoManagerに登録するのものであるが、同時にUIの制御のためにUndo/Redoが可能かどうかを調べて、UIに反映させる（enable/disableする）。&lt;br /&gt;UndoableEditEventというイベントを受けて取るためのUndoableEditListenerをどこかに実装する。具体的には、&lt;code&gt;&lt;pre style="background-color:black;color:white;padding:0.3em;overflow:auto"&gt;void undoableEditHappened(UndoableEditEvent e) {
    //このundoManagerは、クラスメンバー
    undoManager.addEdit(e.getEdit());
    //このあとUIの制御をする undoAction,redoActionもクラスメンバー
    undoAction.setEnabled(undoManager.canUndo());
    redoAction.setEnabled(undoManager.canRedo());
}&lt;/pre&gt;&lt;/code&gt;といった感じになる。&lt;/dd&gt;&lt;/dl&gt;&lt;p&gt;といったところが、ドキュメントから読み取れることなのだが、さらにDocumentというものがあるといっている。これらの内容は、どうやらjavax.swing.text.JTextComponentに特化した話のように見える。&lt;br /&gt;ドキュメント内のサンプルコードでは、Undo/Redoの対象となるオブジェクトに対して、&lt;code&gt;doc.addUndoableEditListener(new MyUndoableEditListener());&lt;/code&gt;という記述がされているが、"doc"にあたるものは、例えば、JTextAreaの場合、JTextArea.getDocument()から得られるjavax.swing.text.Documentとなっている。getDocument()は、JTextComponentで定義されている。&lt;/p&gt;&lt;p&gt;しかしながら、JTextComponent以外のUIコンポーネントでUndo/Redoをするにはどうすればいいのかというのが疑問となる。おそらく、javax.swing.text.Documentに実装されているUndo/Redo関連の処理を自前でやらないといけないのであろうと考えてみた。&lt;br /&gt;そうすると、javax.swing.undoのパッケージにあるクラスやインタフェースをどう使うのか？ということになる。&lt;/p&gt;&lt;p&gt;それをいろいろやってみた結果、「履歴を吐き出し、読み込む仕組み」「Undo/Redoの状態の変化を通知する仕組み」の２つが必要であるということにたどり着いた。&lt;br /&gt;何か変化があったときにモデルの状態（履歴）をUndoMangerに記憶させておき、Undo/Redoの操作により、UndoManagerから履歴を受け取って、状態を戻すというのが、基本的な動作となる。&lt;/p&gt;&lt;dl&gt;&lt;dt&gt;履歴を吐き出し、読み込む仕組み&lt;/dt&gt;&lt;dd style="margin-left:1em"&gt;ストレートにいってしまうと、StateEditableインターフェースを実装しているオブジェクトを用意することである。ここでいうオブジェクトは、いわゆるモデルと思ってよい。&lt;br /&gt;void storeState(Hashtable&amp;lt;Object,Object&amp;gt; state)は、そのオブジェクトの状態を送り出すときに呼び出される。パラメタのHashtableに適当なKeyとデータを追加する（putする）。&lt;br /&gt;void restoreState(Hashtable&amp;lt;?,?&amp;gt; state)は、Undo/Redoにより、状態を受け取るときに呼び出される。パラメタのHashtableは、storeStateで渡したものと同じものである（はず）。&lt;br /&gt;Hashtableになっているのは、おそらくオブジェクト内部に複数のデータが存在しているときに、Keyとデータをセットで管理するためであると考えられる。例えば、オブジェクトの中に文字列しかなければ、Keyは"Text"で値はその文字列のStringにすればよいということだろう。Keyはなんでもいいので、"Text"でなくても"String"でもいいでしょう。&lt;/dd&gt;&lt;dt&gt;Undo/Redoの状態の変化を通知する仕組み&lt;/dt&gt;&lt;dd style="margin-left:1em"&gt;これは、javax.swing.text.Documentに相当するものだが、基本的には、UndoableEditListenerを登録、削除とリスナーへの通知をするオブジェクトである。UndoableEditSupportというクラスを使うと、リスナーの管理などをしてくれるので、これを使ったほうが便利である。&lt;br /&gt;具体的には、モデルの状態を変更してリスナーに通知する方法は、ドキュメントにも記述されている通り、以下のようにすればよい。&lt;code&gt;&lt;pre style="background-color:black;color:white;padding:0.3em;overflow:auto"&gt;//dataはStateEditableを実装しているオブジェクト
StateEdit stateEdit = new StateEdit(data);
//ここでコンポーネントを操作するメソッドを呼ぶ
data.doAnything();
stateEdit.end();
//undoEditSupportは、イベントリスナーを保存している
undoEditSupport.postEdit(stateEdit);
&lt;/pre&gt;&lt;/code&gt;ちなみにこの操作により、前記のvoid storeState(Hashtable&amp;lt;Object,Object&amp;gt; state)が呼び出される。&lt;/dd&gt;&lt;/dl&gt;&lt;div style="text-align:center;background-color:white"&gt;&lt;a href="http://click.j-a-net.jp/188016/220030/" target="_blank"&gt;&lt;img src="http://image.j-a-net.jp/188016/220030/" width="234" height="60"  border="0"&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://click.j-a-net.jp/188016/220024/" target="_blank"&gt;白ロム専門だからケータイが安い！
&lt;img src="http://text.j-a-net.jp/188016/220024/" height="1" width="1" border="0"&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;というわけで、実際の実装では、UIコンポーネントと内部にあるデータ（すなわちモデル）を分離する。そのモデルにStateEditableインターフェースを実装する。UIコンポーネントにUndoableEditListenerを登録する方法を追加する。モデルが変更されたときにリスナーに通知する処理の追加をする（上記のStateEditを使ったコード）。ということになる。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-4405432752679004443?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/rv2QJFKABEI_F3ucl6WO97-zmFE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rv2QJFKABEI_F3ucl6WO97-zmFE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/rv2QJFKABEI_F3ucl6WO97-zmFE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rv2QJFKABEI_F3ucl6WO97-zmFE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/JDZuaQqn56w" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/4405432752679004443/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=4405432752679004443" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/4405432752679004443?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/4405432752679004443?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/JDZuaQqn56w/java-swingundoredo.html" title="Java SwingでUndo/Redoを実装する" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2008/03/java-swingundoredo.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck4GRn8yeSp7ImA9WxZVEk0.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-3012863465148732329</id><published>2008-03-23T00:08:00.003+09:00</published><updated>2008-03-23T00:48:47.191+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-23T00:48:47.191+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="正規表現" /><title>JavaのRegexのパターンマッチがうまくいかない？</title><content type="html">&lt;p&gt;明らかに小ネタな話であるが、PHPとかのつもりでJavaのRegexでパターンマッチさせると、マッチしないと勘違いするかもしれないという話。&lt;br /&gt;
Javaで単純にRegexに文字列がマッチしているか否かを知るには、以下のようなコードを使う。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;java.lang.String str = "…";&lt;br /&gt;str.matches(regex);&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;java.util.regex.Pattern.matches(regex, str);&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;java.util.regex.Pattern pattern = java.util.regex.Pattern.complie(regex);&lt;br /&gt;java.util.regex.Matcher matcher = pattern.matcher(str);&lt;br /&gt;matcher.matches();&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;いずれにしろ、java.util.regex.Patternがregexで記述されたパターンを処理している。&lt;br /&gt;&lt;/p&gt;&lt;p&gt;ところで、PHPでパターンマッチさせるときには、だいたい、PCRE(Perl互換正規表現)を使うわけだが、そこで単純なパターンマッチは、&lt;code&gt;pcre_match(pattern, str);&lt;/code&gt;となる。&lt;br /&gt;例えば、文字列の先頭が"prefx"という文字列で始まっているかどうかを知るには、PHPでは&lt;code&gt;pcre_match('/^prefix/', str) &amp;gt; 0&lt;/code&gt;と書く。&lt;/p&gt;&lt;p&gt;そこで、同じ感じでJavaで書くと、&lt;code&gt;java.util.regex.Pattern.matches("^prefix", str);&lt;/code&gt;と書きたくなる。しかし、こう書いてしまうとうまくマッチしてくれないのである。&lt;br /&gt;それは、Regexでは、パターンに完全にマッチしてないとだめなのである。&lt;/p&gt;&lt;p&gt;すなわち、Javaでは&lt;code&gt;java.util.regex.Pattern.matches("^prefix&lt;b&gt;.*&lt;/b&gt;", str);&lt;/code&gt;と書いてあげないとマッチしないということになる。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-3012863465148732329?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/wbDf5qDerBLF2MRFGjk6qm2qQXU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wbDf5qDerBLF2MRFGjk6qm2qQXU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/wbDf5qDerBLF2MRFGjk6qm2qQXU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wbDf5qDerBLF2MRFGjk6qm2qQXU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/wgwL3DBXcMk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/3012863465148732329/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=3012863465148732329" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/3012863465148732329?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/3012863465148732329?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/wgwL3DBXcMk/javaregex.html" title="JavaのRegexのパターンマッチがうまくいかない？" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2008/03/javaregex.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkcFSXY8fSp7ImA9WxZVEUg.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-2480590304237673658</id><published>2008-03-22T10:25:00.000+09:00</published><updated>2008-03-22T10:40:18.875+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-22T10:40:18.875+09:00</app:edited><title>投稿のテスト</title><content type="html">&lt;p&gt;MicrosoftのWindows Liveに&lt;a href="http://get.live.com/writer/overview" target="_blank"&gt;Writer&lt;/a&gt;という、ブログの編集ツールがあるのだが、それを使ってためしに投稿してみるテスト。     &lt;br /&gt;しかし、結局のところWYSIWYGなエディタを使わずに、テキストモードでHTMLタグを打ち込んでいる始末。&lt;/p&gt;  &lt;p&gt;ちゃんと、ブログを読み込んで、レイアウトなどを保存して、プレビューしてくれるので、&lt;a href="http://www.blogger.com/" target="_blank"&gt;Blogger&lt;/a&gt;のプレビューよりはよいかもしれない。     &lt;br /&gt;このツールの良し悪しは、しばらく使ってみてから、レビューしてみることにする。&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-2480590304237673658?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/QI2wr-X1XN0h4q89IRbolWUKPwo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/QI2wr-X1XN0h4q89IRbolWUKPwo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/QI2wr-X1XN0h4q89IRbolWUKPwo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/QI2wr-X1XN0h4q89IRbolWUKPwo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/v3vjhgTp6B8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/2480590304237673658/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=2480590304237673658" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/2480590304237673658?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/2480590304237673658?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/v3vjhgTp6B8/blog-post.html" title="投稿のテスト" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2008/03/blog-post.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUMGRnkzeip7ImA9WxdVEEQ.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-5101104522337049847</id><published>2008-02-28T11:39:00.005+09:00</published><updated>2008-07-15T12:43:47.782+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-07-15T12:43:47.782+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ボタン" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Swing" /><title>Swingで独自のボタンを作る</title><content type="html">&lt;p&gt;Swingでは、UI委譲でLook&amp;Feelが統一されているので、独自のViewを持つ部品を作るのもどうかと思うが、いちおうできるようなのでやってみた。
ボタンといっても、いわゆるプッシュボタン以外も、ラジオボタンとかチェックボックスもボタンなので、クリックなどの操作で状態が変わるUI部品の類は、ボタンということになる。そういう意味では、独自の外観を持つボタンを作りたくなることもあるかもしれない。&lt;/p&gt;&lt;p&gt;Swingには、ボタンの機能が実装されている便利なクラス「AbstractButton」があるので、これを使う。AbstractButtonクラスのドキュメントを読めば、だいたいの作り方はわかるかもしれないが、とりあえず、最低限すべきであろうと思われる処理について書くことにする。&lt;/p&gt;&lt;p&gt;UIの描画はもちろん自前でするわけだが、AbstractButtonクラスを使うとしても、マウスなどの入力処理も書かなくてはならない。プッシュボタンの場合、マウスが押されたときに概観が変わるので当然といえばそうなのだが…&lt;/p&gt;&lt;dl&gt;&lt;dt&gt;描画の処理&lt;/dt&gt;&lt;dd style="margin-left:1em"&gt;「protected void paintBorder(Graphics g);」を記述する。理由は定かではないが、printComponentなどを使わずにこのメソッドを書く。ボタンの状態によって描画する処理になる。&lt;/dd&gt;&lt;dt&gt;マウスイベントを拾う処理&lt;/dt&gt;&lt;dd style="margin-left:1em"&gt;MouseListenerインターフェースを実装して、コンストラクタでaddMouseListener(this);を呼び出す。&lt;/dd&gt;&lt;dt&gt;クリックされたときの処理&lt;/dt&gt;&lt;dd style="margin-left:1em"&gt;public void mouseClicked(MouseEvent e);に処理を書く。マウスボタンの切り分けは、MouseEventのgetButton();で「MouseEvent.BUTTONx」か、getModifiersEx();で「MouseEvent.BUTTONx_DOWN_MASK」で(xは1とか2)判断する。左クリックのときは、BUTTON1でいいのだが、右クリックの場合、マウスボタン数を意識する必要があるかもしれない。
UIの変更があるのであれば、内部的な状態の変更を保持して、repaint();を呼び出して再描画させる。ただし、場合によってはgetGraphics();でGraphicsを取得して、直接描画する必要もあるかもしれない。&lt;/dd&gt;&lt;dt&gt;ボタン押下の処理&lt;/dt&gt;&lt;dd style="margin-left:1em"&gt;もし、ボタンが押された状態でUIが変化するのであれば、public void mousePressed(MouseEvent e);とpublic void mouseReleased(MouseEvent e);を記述する。場合によっては、public void mouseEntered(MouseEvent e);とpublic void mouseExited(MouseEvent e);も記述する必要があるかもしれない。&lt;/dd&gt;&lt;dt&gt;キーイベントの処理&lt;/dt&gt;&lt;dd style="margin-left:1em"&gt;ここはでは実装してません（すみません）。たぶん、キー入力をしようとすると、フォーカスを意識しなくてはならないはずなので、処理はちょっと面倒かもしれない。いずれ、フォーカスのねたもわかり次第、どこかで記事を書くかもしれない。&lt;/dd&gt;&lt;/dl&gt;&lt;p&gt;あんまり、意味がないかもしれないが、ここまでのコードは以下のとおりになる。&lt;/p&gt;&lt;p&gt;&lt;code&gt;&lt;pre style="background-color:black;color:white;overflow:auto"&gt;public class MyButton extends AbstractButton implements MouseListener {
 public MyButton() {
  initialize();
 }
 private void initialize() {
  addMouseListener(this);
 }
 protected void paintBorder(Graphics g) {
  //状態に応じた描画をする
 }
 public void mouseClicked(MouseEvent e) {
  //マウスがクリックされたときの処理
 }
 public void mouseEntered(MouseEvent e) {
  //場合によっては何かをする
 }
 public void mouseExited(MouseEvent e) {
  //場合によっては何かをする
 }
 public void mousePressed(MouseEvent e) {
  //押されたときにUIが変化する場合
 }
 public void mouseReleased(MouseEvent e) {
  //押されたときにUIが変化する場合
 }
}
&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;
&lt;div style="text-align:cetner"&gt;
&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article Link */
google_ad_slot = "5036282279";
google_ad_width = 468;
google_ad_height = 15;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-5101104522337049847?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/1AA9Pl4FL9oeBFebKpSDJgcWA94/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/1AA9Pl4FL9oeBFebKpSDJgcWA94/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/1AA9Pl4FL9oeBFebKpSDJgcWA94/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/1AA9Pl4FL9oeBFebKpSDJgcWA94/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/iV83eEJlN1k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/5101104522337049847/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=5101104522337049847" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/5101104522337049847?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/5101104522337049847?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/iV83eEJlN1k/swing.html" title="Swingで独自のボタンを作る" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2008/02/swing.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUHQXY4fip7ImA9WxRbGE8.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-5563982720113219775</id><published>2008-02-14T12:29:00.008+09:00</published><updated>2008-12-09T19:57:10.836+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-09T19:57:10.836+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="JMenu" /><category scheme="http://www.blogger.com/atom/ns#" term="Swing" /><category scheme="http://www.blogger.com/atom/ns#" term="AWT" /><category scheme="http://www.blogger.com/atom/ns#" term="Panel" /><title>SwingとAWTの混在はだめなのか？</title><content type="html">&lt;p&gt;SwingがいちおうAWTと共存して利用できるようになっているが、だめなパターンがある。どうやら、SwingのJMenuの類（JManuBarとか）とAWTのPanelをいっしょに使うととPanelがJMenuを隠してしまう。&lt;/p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Vb3xMfMtshk/R7O5Og3jYZI/AAAAAAAAANs/vCMV0cLkdcE/s1600-h/Swing1.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_Vb3xMfMtshk/R7O5Og3jYZI/AAAAAAAAANs/vCMV0cLkdcE/s320/Swing1.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5166676856516338066" /&gt;&lt;/a&gt;&lt;p style="margin-top:0"&gt;とりあえず、EclipseのVisual Editorを使って、やっつけでサンプルを作ってみた。JFrameにJMenuとJTabbedPaneを置いて、そのうえにJPanelを置いたものである。
上の画像のウィンドウは、メニューはちゃんと表示されていて、これは特に問題ない。&lt;/p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Vb3xMfMtshk/R7O6nQ3jYaI/AAAAAAAAAN0/sjiVsjNrXyU/s1600-h/Swing2.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_Vb3xMfMtshk/R7O6nQ3jYaI/AAAAAAAAAN0/sjiVsjNrXyU/s320/Swing2.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5166678381229728162" /&gt;&lt;/a&gt;&lt;p style="margin-top:0"&gt;つぎの画像は、JPanelの上にPanelを置いたものである。見た目あまりわかりづらいかもしれないが、メニューのセパレーターの下からが隠れてしまっている。AWTのPanelがメニューの上にかぶさってしまって、隠れて見えなくなっている。JTabbedPaneの青いところの上にメニューがあるようなので、Panelだけがメニューを隠しているようだ。&lt;/p&gt;&lt;p style="clear:right"&gt;参考になるコードではないが、折角作ったので載せておくw。&lt;/p&gt;&lt;p&gt;&lt;pre style="background-color:black; color:white; padding 0.5em; height:20em; overflow:auto"&gt;&lt;code&gt;import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import java.awt.event.KeyEvent;

import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JSeparator;
import javax.swing.JTabbedPane;
import java.awt.GridBagLayout;
import javax.swing.JLabel;
import java.awt.GridBagConstraints;
import java.awt.Label;
import java.awt.Panel;

/**
 * Main.java
 *  Swing and AWT Component test
 * 
 * @author finky
 *
 */
public class Main extends JFrame {

 private static final long serialVersionUID = 1L;

 private JPanel jContentPane = null;

 private JMenuBar frameMenuBar = null;

 private JMenu fileMenu = null;

 private JMenuItem openMenuItem = null;

 private JTabbedPane jTabbedPane = null;

 private JPanel jPanel = null;

 private JLabel jLabel = null;

 private JMenuItem exitMenuItem = null;

 private JPanel jPanel1 = null;

 private Panel panel = null;

 private Label label = null;

 /**
  * This method initializes frameMenuBar 
  *  
  * @return javax.swing.JMenuBar 
  */
 private JMenuBar getFrameMenuBar() {
  if (frameMenuBar == null) {
   frameMenuBar = new JMenuBar();
   frameMenuBar.add(getFileMenu());
  }
  return frameMenuBar;
 }

 /**
  * This method initializes fileMenu 
  *  
  * @return javax.swing.JMenu 
  */
 private JMenu getFileMenu() {
  if (fileMenu == null) {
   fileMenu = new JMenu();
   fileMenu.setText("File");
   fileMenu.setMnemonic(KeyEvent.VK_F);
   fileMenu.add(getOpenMenuItem());
   fileMenu.add(new JSeparator());
   fileMenu.add(getExitMenuItem());
  }
  return fileMenu;
 }

 /**
  * This method initializes openMenuItem 
  *  
  * @return javax.swing.JMenuItem 
  */
 private JMenuItem getOpenMenuItem() {
  if (openMenuItem == null) {
   openMenuItem = new JMenuItem();
   openMenuItem.setText("Open");
   openMenuItem.setMnemonic(KeyEvent.VK_O);
  }
  return openMenuItem;
 }

 /**
  * This method initializes jTabbedPane 
  *  
  * @return javax.swing.JTabbedPane 
  */
 private JTabbedPane getJTabbedPane() {
  if (jTabbedPane == null) {
   jTabbedPane = new JTabbedPane();
   jTabbedPane.addTab("Panel1", null, getJPanel(), null);
   jTabbedPane.addTab("Panel2", null, getJPanel1(), null);
  }
  return jTabbedPane;
 }

 /**
  * This method initializes jPanel 
  *  
  * @return javax.swing.JPanel 
  */
 private JPanel getJPanel() {
  if (jPanel == null) {
   GridBagConstraints gridBagConstraints = new GridBagConstraints();
   gridBagConstraints.gridx = 0;
   gridBagConstraints.anchor = GridBagConstraints.NORTHWEST;
   gridBagConstraints.weighty = 1.0;
   gridBagConstraints.weightx = 1.0;
   gridBagConstraints.gridy = 0;
   jLabel = new JLabel();
   jLabel.setText("This is JPanel");
   jPanel = new JPanel();
   jPanel.setLayout(new GridBagLayout());
   jPanel.add(jLabel, gridBagConstraints);
  }
  return jPanel;
 }

 /**
  * This method initializes exitMenuItem 
  *  
  * @return javax.swing.JMenuItem 
  */
 private JMenuItem getExitMenuItem() {
  if (exitMenuItem == null) {
   exitMenuItem = new JMenuItem();
   exitMenuItem.setText("Exit");
   exitMenuItem.setMnemonic(KeyEvent.VK_X);
   exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent e) {
     System.out.println("actionPerformed()"); // TODO Auto-generated Event stub actionPerformed()
     dispose();
    }
   });
  }
  return exitMenuItem;
 }

 /**
  * This method initializes jPanel1 
  *  
  * @return javax.swing.JPanel 
  */
 private JPanel getJPanel1() {
  if (jPanel1 == null) {
   GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
   gridBagConstraints1.gridx = 0;
   gridBagConstraints1.fill = GridBagConstraints.BOTH;
   gridBagConstraints1.weightx = 1.0;
   gridBagConstraints1.weighty = 1.0;
   gridBagConstraints1.gridy = 0;
   jPanel1 = new JPanel();
   jPanel1.setLayout(new GridBagLayout());
   jPanel1.add(getPanel(), gridBagConstraints1);
  }
  return jPanel1;
 }

 /**
  * This method initializes panel 
  *  This panel hides Menus.
  * @return java.awt.Panel 
  */
 private Panel getPanel() {
  if (panel == null) {
   GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
   gridBagConstraints2.weightx = 1.0;
   gridBagConstraints2.anchor = GridBagConstraints.NORTHWEST;
   gridBagConstraints2.weighty = 1.0;
   label = new Label();
   label.setText("This is Panel on JPanel");
   panel = new Panel();
   panel.setLayout(new GridBagLayout());
   panel.add(label, gridBagConstraints2);
  }
  return panel;
 }

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  SwingUtilities.invokeLater(new Runnable() {
   public void run() {
    Main thisClass = new Main();
    thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    thisClass.setVisible(true);
   }
  });
 }

 /**
  * This is the default constructor
  */
 public Main() {
  super();
  initialize();
 }

 /**
  * This method initializes this
  * 
  * @return void
  */
 private void initialize() {
  this.setSize(300, 200);
  this.setJMenuBar(getFrameMenuBar());
  this.setContentPane(getJContentPane());
  this.setTitle("Swing Test");
 }

 /**
  * This method initializes jContentPane
  * 
  * @return javax.swing.JPanel
  */
 private JPanel getJContentPane() {
  if (jContentPane == null) {
   jContentPane = new JPanel();
   jContentPane.setLayout(new BorderLayout());
   jContentPane.add(getJTabbedPane(), BorderLayout.CENTER);
  }
  return jContentPane;
 }

}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;div style="text-align:center"&gt;
&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article Link */
google_ad_slot = "5036282279";
google_ad_width = 468;
google_ad_height = 15;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-5563982720113219775?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/0Z6t_vWgm1ZZZjIjNpm3zsp2lA4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0Z6t_vWgm1ZZZjIjNpm3zsp2lA4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/0Z6t_vWgm1ZZZjIjNpm3zsp2lA4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0Z6t_vWgm1ZZZjIjNpm3zsp2lA4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/V_7xwrk_4Q8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/5563982720113219775/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=5563982720113219775" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/5563982720113219775?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/5563982720113219775?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/V_7xwrk_4Q8/swingawt.html" title="SwingとAWTの混在はだめなのか？" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_Vb3xMfMtshk/R7O5Og3jYZI/AAAAAAAAANs/vCMV0cLkdcE/s72-c/Swing1.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2008/02/swingawt.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUICQHw9cSp7ImA9WxdVEEQ.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-6587235774644457623</id><published>2008-02-12T14:16:00.005+09:00</published><updated>2008-07-15T12:46:01.269+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-07-15T12:46:01.269+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="バンドル" /><category scheme="http://www.blogger.com/atom/ns#" term="Ant" /><category scheme="http://www.blogger.com/atom/ns#" term="リソース" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Eclipse" /><category scheme="http://www.blogger.com/atom/ns#" term="国際化" /><title>ResourceBundleを使って国際化する</title><content type="html">&lt;p&gt;UIに表示される文字列をソースコードに書き込む（いわゆるハードコーディング）をするのではなく、ソースコードとは別なところに定義しておいて、プログラム的に読み込む方法の話です。 Windowsならリソースを定義するわけなのだが、Javaではどうするのかということです。Javaの場合、Cocoaのそれと同じ感じで、ロケールごとに文字列を定義する方法をとります。&lt;/p&gt;  &lt;p&gt;まずは、プログラム側ですが、ResourceBundleを使って表示しようとしているロケールの定義を呼び出します。そこから、定義されている文字列を取得する。&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;pre style="padding-right: 0.5em; padding-left: 0.5em; padding-bottom: 0.5em; overflow: auto; color: white; padding-top: 0.5em; background-color: black"&gt;&lt;code&gt;ResourceBundle bundle = ResourceBundle.getBundle(&amp;lt;リソース名&amp;gt;);
bundle.getString(&amp;lt;キー文字列&amp;gt;);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;ここで、&amp;lt;リソース名&amp;gt;といっているのは、リソースを定義するファイル名だが、デフォルトは「&amp;lt;リソース名&amp;gt;.properties」というファイル名になり、言語ごとの定義は「&amp;lt;リソース名&amp;gt;_&amp;lt;ロケール名&amp;gt;.properties」となる。ちなみに日本語の場合、「&amp;lt;リソース名&amp;gt;_ja.properties」でよいだろう（「ja」でよいかどうか心配なら、JDKドキュメントの国際化とのころを参照されたし）。あと、パッケージの中に定義ファイルを置くときは、「&amp;lt;パッケージ名&amp;gt;.&amp;lt;リソース名&amp;gt;_&amp;lt;ロケール名&amp;gt;.properties」とすればよい。&lt;/p&gt;

&lt;p&gt;リソースの定義ファイルの中身は「&amp;lt;キー文字列&amp;gt;=&amp;lt;リソース文字列&amp;gt;」となる。例えばこんな感じ。&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre style="padding-right: 0.5em; padding-left: 0.5em; padding-bottom: 0.5em; overflow: auto; color: white; padding-top: 0.5em; background-color: black"&gt;&lt;code&gt;FileMenuItem=ファイル(F)
EditMenuItem=編集(E)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;ただし、このファイルを作成するに当たり、気をつけないといけないことは、コード系を「ISO-8859-1」（すなわち、ASCII）で保存しなければならない。日本語のリソースの場合どうすればいいかというと、Unicodeエスケープ（\udddd 表記）で保存する。エスケープされた文字列を手で打ち込んでもかまわないが、あまりにも面倒なので日本語として可視なファイルから変換したほうがよさそうだと思う。&lt;/p&gt;

&lt;p&gt;そこで、どうするかというと「native2ascii」というツールがJDKにあるのでこれを使って変換する。&lt;/p&gt;

&lt;p&gt;Windowsの場合だと、Windowsネイティブ（Shift_JIS）で書いておいて、ASCIIコードに変換するという手順になるだろう。例としてのコマンド実行は以下にような感じ&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre style="padding-right: 0.5em; padding-left: 0.5em; padding-bottom: 0.5em; overflow: auto; color: white; padding-top: 0.5em; background-color: black"&gt;&lt;code&gt;&amp;gt; native2ascii -encoding=ShiftJIS myBundle_ja.sjis myBundle_ja.properties&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;もちろん、この方法でコマンド実行すればよいのだが、いわゆるバッチファイルを使ったり、makeファイルを書いたほうが便利だと思う。ここでは、Eclipseを使っているとして、折角なのでAntで書いてみる。
  &lt;br /&gt;ちなみにターゲットとなるpropertyiesファイルと同じ名前で、どこかのフォルダに入れておいて、そのフォルダのパスを&amp;quot;src&amp;quot;に設定する。&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre style="padding-right: 0.5em; padding-left: 0.5em; padding-bottom: 0.5em; overflow: auto; color: white; padding-top: 0.5em; background-color: black"&gt;&lt;code&gt;&amp;lt;project name=&amp;quot;MyProject&amp;quot; default=&amp;quot;bundle&amp;quot;&amp;gt;
&amp;lt;target name=&amp;quot;bundle&amp;quot;&amp;gt;
&amp;lt;native2ascii src=&amp;quot;&amp;lt;入力パス&amp;gt;&amp;quot; dest=&amp;quot;&amp;lt;出力パス&amp;gt;&amp;quot; encoding=&amp;quot;Shift_JIS&amp;quot; includes=&amp;quot;**/*.properties&amp;quot; /&amp;gt;
&amp;lt;/target&amp;gt;
&amp;lt;/project&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;というような内容のファイルを「build.xml」という名前で保存して、実行する（パッケージエクスプローラーで「build.xml」のコンテキストメニューからRun（実行)をメニューから「Ant」を選択）。&lt;/p&gt;  
&lt;div style="text-align:center"&gt;
&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article Link */
google_ad_slot = "5036282279";
google_ad_width = 468;
google_ad_height = 15;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-6587235774644457623?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/g1CsWrf3Ec3WHSZIhaoMbTwfUaU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/g1CsWrf3Ec3WHSZIhaoMbTwfUaU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/g1CsWrf3Ec3WHSZIhaoMbTwfUaU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/g1CsWrf3Ec3WHSZIhaoMbTwfUaU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/QZz1tBNO2v4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/6587235774644457623/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=6587235774644457623" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/6587235774644457623?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/6587235774644457623?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/QZz1tBNO2v4/resourcebundle.html" title="ResourceBundleを使って国際化する" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2008/02/resourcebundle.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUHQHw9eCp7ImA9WxRbGE8.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-6918436900884243543</id><published>2007-10-03T11:52:00.001+09:00</published><updated>2008-12-09T19:57:11.260+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-09T19:57:11.260+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Eclipse" /><category scheme="http://www.blogger.com/atom/ns#" term="Bug" /><category scheme="http://www.blogger.com/atom/ns#" term="PDT" /><title>Eclipse PDTでPHPコマンド実行のUIがでない</title><content type="html">&lt;p&gt;PDTを1.0.0.v20070917というのに入れ替えたのですが、Run/DebugのビューでPHPコマンドの設定がエラーとなり表示されません。PHP Web ページの方は問題なく表示されています。
Eclipseのバグレポートを見たらそれらしいものがあったので、既に報告済みだと思われます。とりあえずはバグフィックス待ちということになるもよう。&lt;/p&gt;&lt;p&gt;Updateでバージョンアップしたのですが、念のためPDTのall-in-oneを手動でダウンロードして、インストールしてみましたがだめでした。プロジェクトの設定でみても、他のfeatureとの不都合などが見られないため、おそらくPDTのバグだと思います。
今のところ回避方法は見つけてはいません。おそらくバージョンアップに伴うレベルダウンと思われるので、古いfeatureに戻せばよいかと思ったんですが、何故か同じようにエラーになります。なぞです。&lt;/p&gt;&lt;p&gt;現状、PHPのコマンド実行でデバッグなどはしてないので、体制に影響はないのですが、PHPコマンドを実行したいときに、EclipseのRunから実行できないので、（Windowsなので）DOS窓から普通に「php xxx.php」のようにコマンドを叩いて実行しています。&lt;/p&gt;&lt;ul style="float:right;margin:0 0.5em 0 0;padding:0"&gt;&lt;li style="display:inline;margin-left:1em"&gt;&lt;a href="https://www.moshimo.com/bargain/coach/102403" target="_blank" onClick="javascript:urchinTracker('/drop/coach');"&gt;&lt;img src="http://1.bp.blogspot.com/_Vb3xMfMtshk/RxSGFrR4WtI/AAAAAAAAAH0/e9LpMdACsE8/s320/COACH80x30.jpg" alt="COACH今だけ価格" style="border:0 none" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li style="display:inline;margin-left:1em"&gt;&lt;a href="https://www.moshimo.com/bargain/drink/102403#coffee" target="_blank" onClick="javascript:urchinTracker('/drop/cancoffee');"&gt;&lt;img src="http://4.bp.blogspot.com/_Vb3xMfMtshk/RxSDRbR4WsI/AAAAAAAAAHs/OZpWrk3CirE/s320/coffee80x30.jpg" alt="缶コーヒーはまとめ買いがお得" style="border:0 none" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li style="display:inline;margin-left:1em"&gt;&lt;a href="https://www.moshimo.com/bargain/vivienne/102403" target="_blank" onClick="javascript:urchinTracker('/drop/vivianne');"&gt;&lt;img src="http://2.bp.blogspot.com/_Vb3xMfMtshk/RxSGu7R4WuI/AAAAAAAAAH8/oFAK3mzscuY/s320/vivian80x30.jpg" alt="Vivian Westwood期間限定プライス" style="border:0 none" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align:center;clear:right"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article Link */
google_ad_slot = "5036282279";
google_ad_width = 468;
google_ad_height = 15;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-6918436900884243543?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/FnmDc02EbLuNJzU3Xfqo3ntGpg0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FnmDc02EbLuNJzU3Xfqo3ntGpg0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/FnmDc02EbLuNJzU3Xfqo3ntGpg0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FnmDc02EbLuNJzU3Xfqo3ntGpg0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/sH3Mpzpzghg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/6918436900884243543/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=6918436900884243543" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/6918436900884243543?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/6918436900884243543?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/sH3Mpzpzghg/eclipse-pdtphpui.html" title="Eclipse PDTでPHPコマンド実行のUIがでない" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_Vb3xMfMtshk/RxSGFrR4WtI/AAAAAAAAAH0/e9LpMdACsE8/s72-c/COACH80x30.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2007/10/eclipse-pdtphpui.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUEDQ3o6fCp7ImA9WxdVEEQ.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-246931197022579808</id><published>2007-09-13T15:54:00.001+09:00</published><updated>2008-07-15T12:47:52.414+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-07-15T12:47:52.414+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="PEAR" /><category scheme="http://www.blogger.com/atom/ns#" term="HTML_Page2" /><title>PEAR::HTML_Page2を使う</title><content type="html">&lt;p&gt;PEARにHTML_Page2という、HTMLページを作成するためのパッケージがある。HTML_Page2については、PEARのサイトに&lt;a href="http://pear.php.net/manual/ja/package.html.html-page2.php" target="_blank"&gt;HTML_Page2のドキュメント（日本語）&lt;/a&gt;があって、このドキュメントを見れば特にこの先の話は必要ではないかもしれないが、初めてHTML_Page2を使う人向けに簡単な例を書こうと思う。&lt;/p&gt;&lt;div style="float:right;margin-left:0.5em"&gt;&lt;a href="http://s15.j-a-net.jp/gateway/click.cgi?a=188016&amp;d=54336&amp;u=" target="_blank"&gt;&lt;img src="http://s12.j-a-net.jp/gateway/s_image.cgi?a=188016&amp;d=54336&amp;u=" width="100" height="100"  border="0"&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;まず、HTML_Page2の基本的な使い方は以下の通り。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;オブジェクトの作成(newする)&lt;/li&gt;&lt;li&gt;ヘッダー関連を設定する&lt;/li&gt;&lt;li&gt;ボディコンテンツの追加&lt;/li&gt;&lt;li&gt;HTMLの出力&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;オブジェクトの作成&lt;/h3&gt;&lt;p&gt;newのパラメタ（すなわちコンストラクタのパラメタ）にいくつかの情報を設定することができる。&lt;br /&gt;まず、この文章を読んでいる人たちは、languageを"ja"にしたいと思うだろう。Windowsだったら、改行コードを"\r\n"にしたいと思うだろう。
という設定をしてインスタンスを生成するには、以下の通りにする。&lt;/p&gt;&lt;div style="background-color:#000000;color:#ffffff;padding:0.2em"&gt;&lt;pre&gt;require_once 'HTML/Page2.php';
$attributes = array(
 'language' =&gt; 'ja',
 'lineend' =&gt; 'win',
);
$page = new HTML_Page2($attributes);
&lt;/pre&gt;&lt;/div&gt;&lt;h3&gt;ヘッダー関連を設定する&lt;/h3&gt;&lt;p&gt;まずはHTML的にtitleタグが必須であるので、タイトルを設定する。あと、HTML_Page2でHTMLを生成すると、"Generator"をいうメタタグを設定するのであるが、これをなくしたいと思うとすると。以下の通りにすればよい。&lt;/p&gt;&lt;div style="background-color:#000000;color:#ffffff;padding:0.2em"&gt;&lt;pre&gt;$page-&gt;setTitle('ページのタイトル');
$page-&gt;setMetaData('Generator', NULL);&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;あとは、スクリプトやスタイルシートの設定などについては、&lt;a href="http://pear.php.net/manual/ja/package.html.html-page2.php" target="_blank"&gt;PEARのドキュメント&lt;/a&gt;に詳しく書いてある。&lt;/p&gt;&lt;h3&gt;ボディコンテンツの追加&lt;/h3&gt;&lt;p&gt;あとは、ブラウザに表示されるコンテンツを追加していけばよい。このとき、HTML_Page2::addBodyContent()というメソッドを使う。このメソッドの引数にHTMLのタグを含む文字列(String)を追加していけばよい。
また、このメソッドは、文字列だけでなく、オブジェクトも追加することができる。このときこのオブジェクトにtoHTML()もしくはtoString()というメソッドを実装しておくと、HTML_Page2がHTMLを生成するときに、それぞれのオブジェクトのこれらのメソッドを呼び出し、その結果を取り込み出力する。&lt;br /&gt;さらにHTML_Page2::addBodyContent()は、文字列やこのようなオブジェクトを含む配列(array)も渡すことができる。このときは、配列に含まれる順番に追加されていく。&lt;/p&gt;&lt;div style="text-align:center"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article Link */
google_ad_slot = "5036282279";
google_ad_width = 468;
google_ad_height = 15;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/div&gt;&lt;p&gt;ちなみにPEARに含まれるHTMLのパッケージ群は、toHTML()が実装されているので、オブジェクトのまま追加することができる。PEARのパッケージを使わなくても自前クラスでtoHTML()を実装して、HTML_Page2::addBodyContent()に渡すというやり方がHTML_Page2の多い使い方ではないかと思う。&lt;/p&gt;&lt;h3&gt;HTMLの出力&lt;/h3&gt;&lt;p&gt;ボディコンテンツを全て追加した後、HTMLとして出力する。&lt;/p&gt;&lt;div style="background-color:#000000;color:#ffffff;padding:0.2em"&gt;&lt;pre&gt;$page-&gt;display();
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;この例では標準出力に吐き出すが、文字列として結果を得るにはHTML_Page2::toHTML()を使う。また、HTML_Page2::toFile()というメソッドがあるが、これは引数にファイル名を与えるとそこに出力するというものである。&lt;/p&gt;&lt;h3&gt;HTML_Page2の派生&lt;/h3&gt;&lt;p&gt;上記のオブジェクトの生成で、"language"や"lineend"のパラメタを毎回コンストラクタに渡したりするよりは、クラスを派生したほうがよっぽどエレガントであると思われる。&lt;/p&gt;&lt;div style="background-color:#000000;color:#ffffff;padding:0.2em"&gt;&lt;pre&gt;require_once 'HTML/Page2.php';
class MyHTMLPage extends HTML_Page2 {
 function __construct($attributes = NULL) {
  if ($attributes != NULL) {
   if (!array_key_exists('language', $attributes)) {
    $attributes['language'] = 'ja';
   }
   if (!array_key_exists('lineend', $attributes)) {
    $attributes['lineend'] = 'win';
   }
  }
  else {
   $attributes = array('language' =&gt; 'ja', 'lineend' =&gt; 'win');
  }
  parent::__construct($attributes);
  $this-&gt;setMetaData('Generator', NULL);
 }
}
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;もちろん、これ以外のヘッダ関連の設定などを追加したほうが便利なことが多いだろう。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-246931197022579808?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/cR9WCQB0eoXo1WggXZcgZ4w4Fhs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cR9WCQB0eoXo1WggXZcgZ4w4Fhs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/cR9WCQB0eoXo1WggXZcgZ4w4Fhs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cR9WCQB0eoXo1WggXZcgZ4w4Fhs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/RqOpILb4DwY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/246931197022579808/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=246931197022579808" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/246931197022579808?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/246931197022579808?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/RqOpILb4DwY/pearhtmlpage2.html" title="PEAR::HTML_Page2を使う" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2007/09/pearhtmlpage2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUAGR3o7fyp7ImA9WxdVEEQ.&quot;"><id>tag:blogger.com,1999:blog-5271173396632814735.post-4061367885928298802</id><published>2007-09-12T23:22:00.001+09:00</published><updated>2008-07-15T12:48:46.407+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-07-15T12:48:46.407+09:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ブラウザ" /><category scheme="http://www.blogger.com/atom/ns#" term="Norton" /><category scheme="http://www.blogger.com/atom/ns#" term="NAV" /><category scheme="http://www.blogger.com/atom/ns#" term="Windows" /><title>Norton AntiVirusでブラウザが遅くなる</title><content type="html">&lt;p style="margin:0"&gt;今日はソフト開発系のネタではないのですが、最近困っていたことが解決したので、何かの役に立つかもしれないということで、ネタにしてみました。&lt;/p&gt;&lt;div style="float:right;margin-left:0.5em"&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=quickprogram-22&amp;o=9&amp;p=6&amp;l=st1&amp;mode=software-jp&amp;search=%E3%82%A6%E3%82%A4%E3%83%AB%E3%82%B9&amp;fc1=000000&amp;lt1=&amp;lc1=3366FF&amp;bg1=FFFFFF&amp;f=ifr" marginwidth="0" marginheight="0" width="120" height="150" border="0" frameborder="0" style="border:none;" scrolling="no"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;p style="margin:1em 0 0 0"&gt;ここ1週間ぐらい前から、ブラウザを使うとWindowsがものすごく遅くなるという現象になっていた。ブラウザは、Firefox、IE7、Operaのいずれも同様な現象が発生していた。ただ、ブラウザ以外のソフトでは、遅くなるようなことがなかった。&lt;br /&gt;何かの常駐物が悪さをしているか、いわゆるマルウェアとかいうのがいるのか、とか原因を探っていたところ、どうやら、Norton AntiVirusのAuto Protectを無効にすると、遅くならないことが判明した。&lt;/p&gt;&lt;p style="margin:1em 0 0 0"&gt;すなわち、犯人はNorton AntiVirusということであった。しばらくの間、遅いのを我慢するか、どうしてもというときには、Auto Protectを無効にしていたのだが、さすがにウィルス対策なしの状態で使い続け続けるのは、いかがなものかと思い、いろいろ調べてみたところ、次のようなことがわかった。&lt;/p&gt;&lt;dl style="clear:right;margin:1em 0 0 0"&gt;&lt;dt&gt;Javascriptをスキャンさせると遅くなる&lt;/dt&gt;&lt;dd style="margin-left:1em"&gt;プラグインなどでJavascriptを読み書きにいくことが多いため、起きるものだと考えられる。これを回避する方法は、Auto Protectの「除外」リストに「*.js」を追加する。ただし、くれぐれも手動スキャンの除外には追加しないように。&lt;br /&gt;ただし、パフォーマンスは上がるが、安全性は落ちる可能性があることを理解して使うべきである。&lt;/dd&gt;&lt;dt&gt;圧縮ファイルの中身をスキャンすると遅くなる&lt;/dt&gt;&lt;dd style="margin-left:1em"&gt;これは文字通りだが、ブラウザとの関係としては、JARぐらいしか思い当たらないが、これが原因であることがあるらしい。回避方法は、Auto Protectの設定で「圧縮ファイルの内部をスキャンする」という、そのまんまなオプションがあるので、これをオフにする。&lt;br /&gt;ちなみにうちの環境では、このオプションを変えてもほとんど動作に変わりはなかったので、そのままオンの状態にしている。&lt;br /&gt;もし、Eclipseの動作がえらく遅いときは、このオプションを変えてみると効果があるかもしれない。&lt;/dd&gt;&lt;/dl&gt;
&lt;div style="text-align:center"&gt;
&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-5937993488697964";
/* Program Article Link */
google_ad_slot = "5036282279";
google_ad_width = 468;
google_ad_height = 15;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5271173396632814735-4061367885928298802?l=quickprogram.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ZmqpsZtLY2YF7bCXalZP83esSak/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZmqpsZtLY2YF7bCXalZP83esSak/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ZmqpsZtLY2YF7bCXalZP83esSak/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZmqpsZtLY2YF7bCXalZP83esSak/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/quickprogram/~4/_BKD2htmOZA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://quickprogram.blogspot.com/feeds/4061367885928298802/comments/default" title="コメントの投稿" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5271173396632814735&amp;postID=4061367885928298802" title="0 件のコメント" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/4061367885928298802?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5271173396632814735/posts/default/4061367885928298802?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/quickprogram/~3/_BKD2htmOZA/norton-antivirus.html" title="Norton AntiVirusでブラウザが遅くなる" /><author><name>Finky</name><uri>http://www.blogger.com/profile/11508788347096220872</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="15605080797076841346" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://quickprogram.blogspot.com/2007/09/norton-antivirus.html</feedburner:origLink></entry></feed>
