2013/05/31

バックトゥザフューチャーPart2

バック・トゥ・ザ・フューチャー Part 2」テレビでやってたので見ました。
2は未来行ったり過去行ったりで内容が多いので良いですね。1、3に比べて人気は無いみたいだけど。
3は子供の頃に電気屋さんでほぼ全編立ち見した気がする。


全く関係ないがこれは北海道限定の屋台十八番。もっとも美味しいインスタントラーメンだと思う。食べたい~

2013/05/23

HTMLのcheckboxをReadOnlyにする方法

<input type="checkbox" onclick="return false;"  ...>
これチェックボックスのReadOnlyの代わりになります。
チェックボックス以外のtextとかはreadonly=""でもreadonly="true"でも付ければOKですが、何故かチェックボックスにはreadonly属性は付けられないようです。(SelectタグもReadonly出来ませんでした。他にもreadonlyにならないのはあるかも。Selectを無理やりReadonlyにする方法。)

readonlyはユーザに見せながら、変更不可能な項目を作りたいときに使います。
hiddenは変更不可能ですが見えないし、disabledは項目が無いのと同じ(FormのSubmitで値が送られない)なので動作が違いますね。
出来ればボックス内を灰色にしたいところですが簡単には出来なさそうです(背景色を灰色にして変更不可能を強調するので誤魔化してます)。
例:

 チェックするときはchecked="true"をつけて


ちなみに「onclick」なのでもしかしたらフォーカスをチェックボックスに当ててスペースキーを押すと値が変更されるのでは、と思われそうですがスペースキーでも変更不可です。onclickはスペースキーのイベントと無関係だと思うのでスペースキーのイベントがonclickを呼んでるんだと思います(予想)。

WebページをJavaScriptでちょっと便利にする、という場面は非常に多いでしょう。
JavaScript: The Good Parts (Douglas Crockford)
この本はオライリーにしてはすごくページが薄く、簡単に読める内容です。でもこんなに役に立ったのを実感した本は少ないです。JavaScriptは適当な書き方でも動いてしまい、最良な書き方、というのが身に付きにくいですがこの本をザッとでも読めばスパっと分かるようになるはずです。
トップページへ

チェックボックスがらみでもう一つ、VBなどで作られた普通のアプリケーションのUIではチェックボックスの横の文字列をクリックしてもチェックされます。しかしHTMLフォームのUIはあまりこうなってません。
文字列もクリック出来た方が便利そうです。spanを被せてonclickにチェックボックスのonclickを呼ぶようにすれば出来そうかなぁ、でも全部にそれやるのはめんどくさそうだなぁとか思ってましたが、実は標準でLabelというタグがあるようです。
<label>
   <input type="checkbox">チェックできる
</label>
とか
<input type="checkbox" id="check01">
<label for="check01">チェックできる</label>  

 
となります。

メール文例検索しまくり

久々にビジネスメールのやり取りすると色々焦って間違って送ってしまうなぁ
別に失礼になるようなミスでは無いんだけど、「こいつ最高におっちょこちょい!!」とか思われてそうでヤだなー
今回やったミスはズレた署名が付いたまま、 とか他で送るつもりのメッセージをコピペして消し忘れとか
GMailはスレッドになると引用とか署名の表示が省略されるから注意だ。見るときは見やすいんだけど。
あとなんかGMailの署名の設定はズレやすい気がするんだけど気のせい?

2013/05/21

ATLでRegistry(VC++でレジストリを弄る方法)

C++でレジストリを弄るプログラムを作っていました(といってもReadだけ)。
ATLを使うことで、APIを直に使うより(少しだけ)簡単に書けることが分かりました。
#include "atlbase.h"

CRegKey cRegistry;
ULONG bufSize = 100;
_TCHAR regValue[100];
LONG resOpen;
resOpen = cRegistry.Open(HKEY_LOCAL_MACHINE,
                  _T("SOFTWARE\\Microsoft\\Windows NT\\xxx"),
                  KEY_WOW64_64KEY | KEY_READ);
// 32ビットOSにおいてはKEY_WOW64_64KEYフラグの指定は影響しない
if (resOpen == NO_ERROR) {
   LONG resQuery;
   resQuery = cRegistry.QueryStringValue(_T("some_key"), regValue, &bufSize);
   // バイナリの場合は cRegistry.QueryBinaryValue(... 
   if (resQuery == NO_ERROR) {
      regValue; // レジストリの値
   }
   cRegistry.Close();
}

cRegistry.Open時の「KEY_WOW64_64KEY」の指定について。
今回は「HKEY_LOCAL_MACHINE」の「SOFTWARE\Microsoft\Windows NT」以下のキーを読みたかったのですが32ビットアプリで64ビット版WindowsのHKEY_LOCAL_MACHINEを読むと「レジストリリダイレクタ」により自動的に「Wow6432」のキーになってしまいます。

今回欲しい「SOFTWARE\Microsoft\Windows NT」以下のキーは64ビット用のエントリにあるので32ビットアプリからも64ビット用エントリを読む必要がありました。
で「KEY_READ」に「KEY_WOW64_64KEY」というフラグを一つ追加しました(「KEY_READ」もビットフラグなのでORで連結)。
このフラグは32ビットOSで動作した時には影響ありません。

逆に、64ビットアプリからWow6432Nodeのレジストリを読みたい(32ビットアプリは当然32ビット用エントリを読みたい)場合、「KEY_WOW64_32KEY」を追加で良いようです。

2013/05/17

一言ずつ

以前見た、見ようとした映画について。
一言ずつでもメモっておくと後で思い出せるから。

メトロに乗って
→個人的にシナリオが合わなさすぎた。糞映画。

長崎ぶらぶら節
→これも個人的に面白くなかったので途中で止めたが、渡哲也さんが好きな人には良いんじゃないですか?

ブリッジ
→重たーいドキュメント映画。自殺幇助じゃ?
(しかし作品の出来云々より日本版の予告だけ落ちるときにSEを入れてるのが信じられない。人が死んでるのに)

サウンド・オブ・サンダー
→B級SF 割り切ればかなり楽しめる。SF好きなら余裕で佳作判定。

エンロン 巨大企業はいかにして崩壊したのか?
→頭いい人たちが大金持ち!!

ロサンゼルス決戦
→宇宙人が攻めてきてるのに市街戦とか、、しょぼ!

2013/05/15

Le Chat botté

長靴をはいた猫」見ました。
そっち!?みたいなw
古いけど全然見れるクオリティ。
声優の演技が今と全然違って受ける。脱力した発声とか。
金曜ロードショーでカリオストロ城をヘビーローテーションするくらいならこれ放送した方が絶対受けるのにw
魔王ルシファがすごい悪者でもなくて、行動に人間味がかなりあるのも良い。ちょとかわいそう。
つかドリームワークス版は見ないの?

デバッグ時の_tcscpy_s

VC++で、_tcscpy_s(dst, dstLength, src); とやったとき、デバッグビルドしたモジュールではdstの先頭からdstLengthまでしっかり「0xDF」で埋められる。

つまり、dstを確保したサイズよりも大きくdstLengthをやっちゃうと関係ないとこのメモリの内容が「0xDF」で埋められる…

みごとに重要な(でも無関係な)データをぶっ壊しており、違うとこでバグになってた。違うとこでバグってのが厄介なんだよね。
しかもリリースビルドモジュールでは問題が起こらない。リリースモジュールはうまくいくのにデバッグモジュールはダメなとき、知識として知ってないと分かりにくいバグになるんじゃないかな。

dstLengthが分かんないとき、_tcscpyで動いてるとこを適当なdstLengthを指定して_tcscpy_sに置き換えるとバグになるってことだ。
まぁdstLengthがいい加減だとセキュアの意味が全くなくなるから良いんだけど。

2013/05/14

__stdcall付けましたか?

この記事はInstallShieldで作るインストーラー(もアプリケーションの一種だけど)からDLLを呼び出すことを書いてるので普通にVBのアプリからDLLを呼び出すのとは少し違うかもしれない。でも多少参考になれば幸いだ。

インストールスクリプトは何で落ちる?
外部DLLを読込み、そのDLLの関数を呼び出すところで落ちてしまうといったい何が悪いのかさっぱり分からんことになりがち。
チェックポイントは

■prototype宣言の引数の種類が違う

DLLを作ってる間はCの関数宣言でコンパイル時エラーが出るが、prototype宣言は例えば引数の宣言が「STRING」、「BYREF STRING」などの宣言が間違っている場合は実行時に落ちる、という形で現れる。
改行やインデントを工夫して見た目で間違いが無さそうだと分かるようにしておくと良いだろう。

■DLL内部で落ちている

という可能性もモチロンあるのでDLL単体では正常に動作することは確かめよう。

■UseDLLが失敗している

呼出すDLLのパス指定が間違っていてDLLのロードが失敗しているとき(エラーチェックしてないと)、ロード時ではなく関数呼び出し時に落ちる。
デバッグで実行時のファイルパスにちゃんとDLLがあることを確かめ、UseDLLのリターンコードも0であることを確かめよう(DLLロードエラーなのか関数のエラーなのかを切り分ける)。
ちなみにリターンコードが失敗の場合にエラー処理に入るようにしても良いが、完成後にUseDLLが失敗することは無い、としてエラー処理は入れていない(問題が起こったことは無い…)。

■DLL関数のエントリポイント?

DLLのビルド時にモジュール定義ファイル(defファイル)を使って関数名を綺麗にエクスポートする。
かなりあいまいな理解だがdefファイルを使った関数エクスポートでないと、インストールスクリプト側でうまく読み込めない感じ。まぁ対した手間でもないので付けましょう。
判断基準は「dependency walker」でDLLを開いたときに関数名に「_」や「@」が付いてない綺麗な形になっていること。

■__stdcall付けましたか?さもなくばcdecl付けましたか?

今回嵌ったのはこれ… インストールスクリプトは
スクリプト中の最初の例外

エラー番号: 0x80040704
説明: dll関数の呼び出しは誤ったスタックを返しました。
誤ったプロトタイプが宣言されている可能性があります。: 
というエラーを示していた。DLL関数を宣言する際に、__stdcallを付け忘れていたら起きた。
解決するには「prototype宣言にcdeclを付けるか、関数宣言に__stdcallを付ける」とある。
つまり、
//C用
extern "C" {
    __declspec(dllexport) int IsContainsMbs(const char* path);
}
//Install Shield
prototype cdecl PathStringCheck.IsContainsMbs(BYREF STRING);
か、
//C用
extern "C" {
    __declspec(dllexport) int __stdcall IsContainsMbs(const char* path);
}
//Install Shield
prototype PathStringCheck.IsContainsMbs(BYREF STRING);
のどちらかにすれば良い
stdcall(スタンダードコール)とは確か引数をスタックに積む順番の指定で、、、
まぁ前に習えば良いので__stdcallを付けて解決させた。

2013/05/13

Class名はcase sensitive

いろいろ試しつつ2,3時間かけてデバッグしてました。
現象としてはFireFoxやChromeでは左上に寄るのにIE8標準モードではインデントされて表示されるというもの。
結果的には「スタイルシートのclass、大文字・小文字の違いに注意」ということ。HTMLソース中のclass名は「treebox」、CSSの指定では「treeBox」となっていた。大文字小文字区別しないで表示してくれるブラウザも多いがIE8は厳密に区別するという話。

どのタグにどんなスタイルを追加すればいいのか(どのスタイルが効いてないのか)判明するのに2時間くらいかかった。
ulに「padding:0」を追加すれば良いと分かる→そのスタイルは「class="treebox"」で既に指定されてるはずなのに何故か効いてない→大文字小文字が違う…

・リストを左上に寄せるにはul要素に「padding:0」と「margin:0」を追加する
・class名の大文字小文字は(ブラウザによっては)厳密に区別される
という知識が有れば1分くらいで修正できた話でしょう。
2時間 vs 1分
よくプログラマの生産性は10倍以上とか言うが、こういう一件一件の事例では120倍にもなりますよと。

2013/05/08

劇場版xxxHOLiC

劇場版 XXX HOLiC 真夏ノ夜ノ夢」見ました。
とくに驚くような展開は無く、TVアニメの続きのような普通の内容で、それがまぁ良いといえば良かった。
向日葵ちゃんがあまり出ないのが特徴と言えば特徴かな?
これTVアニメより前の作品らしい?
TVアニメを先に見たけど、どちらも世界観が統一されてるので全く違和感は無い。

実写映画版「カムイ外伝」見ました。
ワイヤーアクションでの大ジャンプとかCGで動くサメとかが違和感ありまくり。
でも海が不自然に群青色なのは悪くない感じ。ナレーションで技の説明が入るなど独特のノリは漫画を読んで知っていたので変に感じなかった(むしろカムイと言えばこれという感じ)。
その時代の町民のほのぼのとした暮らしぶりとか、昨日の仲間が今日は敵のようなカムイの話の特徴が出てて良かったんではないかと思う。
amazonのレビューでは辛口が多いが、漫画に比べて描写が難しいのは仕方ないと思う。
確かに漫画版のように追忍に比べてカムイが圧倒的に強いという描写は足りなかった気がする。
あと敵に追われてる時に死んだように眠って気配を消すという技も実写で見たかったw

2013/05/07

Black Gold

休みボケが治らないのでメモ
おいしいコーヒーの真実」見ました。
この映画を見るずっと前にスターバックスコーヒーと経済に関する新書を読んでいて、コーヒーを買うときにフェアトレードのコーヒーがあればそれを選ぶようにしていた。
知らないなら仕方がないが、事実を知ってしまったからには行動を変えなければならないとどこかで読んだので。
しかもカルディコーヒーのフェアトレードは他と比べて特に高いわけではないのでいつも買っていた。ファミリーマートのレインフォレストアライアンスのブラックコーヒーも普通の値段だし美味しいので以前は毎日買っていた。

今はカルディが近くにないのでスーパーで豆を買い、缶コーヒーは買わずにネスレのインスタントコーヒーにしてしまった。
さすがにノンカフェインのインスタントコーヒーでフェアトレードorレインフォレストアライアンスのものは入手が難しいし、豆を買うのにわざわざカルディまで足を運ぶのも現実的じゃないので。
しかし結構重たい問題だと思うんだけどみんな行動しないのか?
カルディなんてフェアトレードが1種類とそれ以外(10種類以上?)が同価格帯で並んでる。その状況でフェアトレード以外が売れるものなのかと?(「他のはフェアなトレードをしてません」って意味に見えたが…)
スーパーとかスタバとか各所でフェアトレード、レインフォレストアライアンスの商品があんまり売ってないのは何なんだろう。
http://www.fairtrade-jp.org/
http://www.rainforest-alliance.org/

スタバとかUCCとかもフェアトレード商品を少しは扱っているようだ。
また、フェアトレードに対して「ただ高く売りたいだけじゃないか」という批判もあるらしい。たしかにフェアトレードだから3倍も高いという商品は避けた方が良いような気がする。
そもそも1杯売った利益に対して、販売者が利益の9割を取り、残りの1割が配送者や生産者、という分配が問題なので、分配の比率さえ変えられれば値段を変えずとも良い、というものじゃないのか?
それを1杯の値段を3倍にして販売者はもっと儲け、生産者は少しマシになるってのは全然違うよね…
1杯300円という値段は生豆1キロ20円でしか売れない生産者にとっては十分高額なんだから、間の誰かが取り過ぎなんだよ…

フェアトレードはインチキ臭いから、普通のを買って差額をユニセフなどに寄付しようという考えもあるが全然賛同できない。生産者はいくら良いコーヒーを作っても安く買い叩かれ、その代わりに君らは貧しいから援助をあげようなんて言われるのは嫌だろう。

2013/05/02

InstallShieldのインストールする機能をコントロール

インストールスクリプト(Setup.rul)を使うことが多いが、前からあってどうも分かってなかったコードについてメモ。
 MsiSetFeatureState(hMSI, "機能名", INSTALLSTATE_ABSENT);
で「機能名」の機能はインストールしないという命令になる。
でこの機能は「編成」-「機能」のもそうなのだが、実態はその上「編成」-「セットアップデザイン」にあり、そこで「機能名」にコンポーネントを関連付けが出来る。

何か知らないが新しくファイルとかを追加した場合、適当な機能に勝手に関連付けられるような気がする。
今回の問題も全く意図していない機能にまとめて全部関連付けられて、しかもツリーの下の方だったので発見が出来なかった。
結果的に機能をインストールするとかしないとかのコントロールがうまくいかなくなるので、そいった場合は「セットアップデザイン」のツリーを全部展開してよーく見てみること。

ERROR_SUCCESSとNO_ERRORの違い

//
// MessageId: ERROR_SUCCESS
//
// MessageText:
//
// The operation completed successfully.
//
#define ERROR_SUCCESS     0L

#define NO_ERROR          0L      // dderror
#define SEC_E_OK          ((HRESULT)0x00000000L)
なような定義になってる。
さてWindows関数の成否比較に「ERROR_SUCCESS」はエラーなのかサクセスなのか名称から分からないので出来れば使いたくない。
   if (ret == ERROR_SUCCESS) {
      /* これはエラーなの?サクセスなの? */
   }
素直に考えるとその下に定義されている「NO_ERROR」を使いたい。
   if (ret == NO_ERROR) {
      /* ふふん エラーでない場合の処理だね */
   }
では「ERROR_SUCCESS」を「NO_ERROR」に書き換えるのは問題があるか?

現時点で「ERROR_SUCCESS NO_ERROR 使い分け」でGoogle検索をすると8件しか引っ掛からない。誰も同じことを悩んでないのか…?
英語で「ERROR_SUCCESS NO_ERROR difference 」で検索すると 2,830件。
しかしこの疑問に関して説明するものは見当たらなかった。
一応、MSDNのGetAdaptersInfoという関数の説明に、"If the function succeeds, the return value is ERROR_SUCCESS (defined to the same value as NO_ERROR)."という記述があることが分かった。
「ERROR_SUCCESS」というのは絶対におかしい命名だと思うが何故かこちらを使うのが主流らしい。というかAPIのドキュメントにも明確に「成功の場合は『ERROR_SUCCESS』が返る」と書かれている。でも「NO_ERROR」も同じ値であることはほぼ間違いないので、自分のプログラムだけでも「NO_ERROR」で比較するのが良い。
気持ちの問題だけど「NO_ERROR」の方がすごく読み易いので。

「NO_ERROR」はWinAPIのエラーコードだがこれを自作関数の成功値に使うのは良いことか?
なんかいちいち「○○_OK」とか自分で専用の定数を定義するのは面倒だと思うし、「NO_ERROR」なんて汎用的な名称だし、ステータスも明らかなので悪くないと思うが…
やはり自分で成功ステータスも定義するのが普通なのか?
なんかJavaには無い悩みかも。

ちなみに0Lで定義されている定数は他に「S_OK」があるがこれは定義されている場所も用途も少し違うらしい(Com系のリターンコード?)。
(「NO_ERROR」も悪くないけどやっぱり「SUCCESS」が一番しっくりくるよね?)