画像の階調特性を入力しようとしたら会長特製とか出た。いや,プログラム関係ないけど。

Perl。引数を処理しようとしてうまく行かない。

if(@argv < 5)
{
}

とかやっていたが,引数を表すのは @ARGV つまり大文字だった。

ふとある .cpp を見てみると,

#ifndef XXX_CPP
#define XXX_CPP

とか書いてあった。いつの間にこんなの書いたのか。


TeX で表に番号とキャプションを付ける。tabular を begin{table} end{table} で囲み,label と caption を付ける。はずだが,うまく出ない。参照すると節番号になってしまう。でネットをあさって原因が判明。label は caption の後に書くらしい。確かに既にうまくいってる「図」はそうなっている。で,そのようにして XXX.aux を消し,再コンパイルすると見事に正常に表示された。

# でも TeX でこういう順番気にしなきゃいけない事なんてなかったからなあ。普通気にしないような。

ある 2 つのビューがあり,A はマウスのクリックでマウスをキャプチャーする。B はフォーカスがなくなった時にダイアログを出すとする。(B にエディットボックスがあり,そこで編集を行うが,フォーカスがなくなったら値チェックを行う,など。もっと分かりやすい例は後で。)

ここで,B で編集をし,そのまま A をクリックするとどうなるかという問題である。この場合,

  • B のフォーカスが失われる
  • ダイアログが出現し,OK ボタンを押す
  • A に WM_LBUTTONDOWN メッセージが来て,マウスがキャプチャーされる

という具合になるのだが,ここで問題が生じる。A の WM_LBUTTONUP が呼ばれないのだ。よってマウスのリリースができず,困った状況になる。で,解決するために結構悩んだんだが,そういえばエクスプローラも同じ事をやっている。以下の手順で試してみて欲しい。

  • ツリービューでフォルダ名を編集し,* とかにする
  • 編集中のままリストビューをクリック
  • エラーが出るので,OK。

さて,どうなっただろうか。答えは「マウスボタンは離しているのにラバーバンドが現れる」だ。なあんだ。エクスプローラもできてないのか。

もう 1 つエクスプローラの問題。同様に

  • リストビューでファイル名を編集し,* とかにする
  • 編集中のまま真ん中の境界線をクリックし,素早くサイズ変更
  • エラーが出るので,OK。

さて,今度はどうなっただろうか。境界を右に動かした方はリストビューが欠けてしまい,逆に左に動かした方は白い変な領域ができたと思う。これは誰も気付かなかったバグなのか,それとも対応不可能なバグなのか。ちなみに私が試したのは Win98 だけなので他ではどうなるか分からない。

#後で試したところ,NT も同様だった。

Install Sield,ファイルコピー中のファイル名で,カタカナのア・カ行辺りが文字化けする。

Enable(INDVFILESTATUS);

を消し,表示そのものを行わないようにする。

いつか hr みたいな線の作り方を書いたけど,それよりよさそうな方法。

  • ピクチャーコントロールを貼り付ける
  • スタイルのくぼみをチェックする

これだけ。

MFC 利用スタティックライブラリで

定義されていない基本クラス

とか言われる。StdAfx.h に

#include <afxext.h>

を追加。


複数のプロジェクトを扱う時,他のプロジェクトを変更したときにリコンパイルする方法。プロジェクトの依存関係で依存するプロジェクトをチェック。


libjpeg を入れる。

  1. VC98bin にある Vcvars32.bat を実行。
  2. jconfig.vc を jconfig.h に,makefile.vc を makefile に直す。
  3. nmake でデバッグ版が完成。
  4. namke nodebug=1 でリリース版が完成。

ちなみに環境変数の領域が足りない場合は config.sys に

shell=c:command.com /e:4096 /p

を追加。(前書いたっけ?)

修正追加。内部コードを EUC に変更したので,ismbblead,ismbbtrail(自作)を EUC にした。

VC++ + SQL Server で作っていたクラス群を Linux + Postgres へ移植。Turbo Linux 4.0 の gcc とかなり違っていて大変だが,今回修正が必要だった部分を書いておく。以下,gcc と書いたら Turbo Linux 4.0 付属のものとする(多分現時点で最新だと思う)。

  1. VC では ios_base があるが,gcc では古い ios しかない。
  2. ソースファイルは EUC にしないと変なエラーが出ることがある。
  3. stringstream がない。代わりに古い(?)strstream がある。ちなみに istrstream のコンストラクタは string ではなく char * をとる。
  4. basic_string::compare(size_type, size_type, const string &) がない。これは const string & が最初の引数になっていた。
  5. VC では <cxxx> が std 名前空間になっていないが,gcc ではちゃんと std 名前空間になっている。
  6. stream の ! 演算子がない(* もかな?)。good() などで代用。
  7. VC の stricmp は gcc では strcasecmp になっている。
  8. VC の itoa がない(と思う)。
  9. <iostream> がなく,<iostream.h>。

全体的には,コンパイラは gcc の方が標準に準拠しているが,標準 C++ ライブラリ,STL は VC++ の方が新しいという感じ。てことは STL だけ Linux でコンパイルすれば最高の環境になるのか,な。どうだろ。

失敗。

class a
{
    a{f()};

    virtual f() = 0;
};

class b
{
    b{};

    virtual f(){};
};

とかやって b::f() が呼ばれなくて悩んだ。原因はコンストラクタからは派生クラスの仮想関数が呼ばれないから。っていうか前もこんなことやったような気がする。

ワケあって NT を再びインストール。HD を換装した際に 3GB の方が余ったのでそれにインストール。

で,今回はサービスパックを入れる前にディスプレイドライバを入れたが,うまくいった。ちゃんと 800×600 24bpp になった。でその後サービスパック 4 を入れると起動しなくなる。結局サービスパックとは相性が悪いのかな。

環境移行終了。3GB の内蔵 HD から 4GB の内蔵 HD に移行した,って地味に聞こえますが。2GB-2GB に分けて Win98 と Linux を入れたのだ。以前は FIPS で分割できなかったパーティションもさすがに入れたばっかりの Win98 は分割でき,快適インストール。

Turbo Linux のウィンドウマネージャ(だっけ)は KDE にしてみる。今まで Gnome + Enlightenment だったが,KDE は何か日本語でいい。さらにエクスプローラみたいのとかいろんなところがウィンドウズっぽくて割と使いやすい。これからはこれにしよう。その内 Java + Swing でエディタを作りたい。

今回初めて LILO を使う。LILO は Linux とウィンドウズとかを起動時に切り替えるものだが,最初はデフォルトで Turbo Linux になっていた。で,/etc/lilo.conf の中身をデフォルトウィンドウズに書き換えるが,変更されない。結局 Linux 上で lilo と打ち込んで LILO を書き込むことで変更できた。考えてみればそりゃそうな気がするが,できればマニュアルに書いて欲しかった。

今回の移行でウィンドウズ環境を大きく変える。内蔵 2GB は OS のみにし,外付けにユーザーデータと開発環境その他ツールを思う存分入れる。本当はユーザーデータとツールを内蔵に入れたいが,さすがに 2GB では不安なので。その内 8GB が出回ったら乗り換えを考えたい。


ついでにオフィス 2000 をインストール。メニューが「普段使うもの」と「あんまり使わないもの」に分かれているのがなかなか面白いと思う。

PostgreSQL。今までどうしてもホスト名を指定するとできなかったが,PostMaster の起動時に,-i オプションを付けると,ネットワーク経由でアクセスできるようになる。

/etc/rc.d/init.d/postgresql
su -l postgres -c '/usr/bin/postmaster -S -i -D/var/lib/pgsql'

でも localhost ではいいんだけど Lelie じゃダメ。何故?


PostgreSQL を使用する C++ プログラムのコンパイル。

gcc pgtest.cpp -o pgtest -I/usr/include/pgsql -lpq -lcrypt -ftemplate-depth-30 -lstdc++

ちなみに -ftemplate-depth-30 -lstdc++ はいらなければ必要ない。

総統から電話。「ウィンドウズが起動しない」とか。グラフィックアクセラレータの設定をいじったということなので,Safe Mode で起動。

  • DOS モードでなんとか起動させる
  • ATTRIB -s -h msdos.sys で msdos.sys を DOS から見えるようにする
  • EDIT で msdos.sys の [options] に以下を追加

    BootMenu=1
    BootMenuDefault=1
    BootMenuDelay=10
  • ATTRIB +s +h msdos.sys で属性を元に戻す
  • Safe Mode で起動し,設定を元に戻す

で完了。ていうか Win95 だと起動時に F8 でメニューが出てきたハズなんだけど出てこなかったので上のようにした。また Win98 だと起動時に Help らしいけどうちのメビウスには Help キーがありません。

内蔵 HD を換装。I・O データの HDNV-N4.3 を買ってくる。6GB とか 8GB とかが欲しいんだけど見あたらないし高そうなのでこれ。で WindowsNT と Linux を入れようとしたんだけど,うまくいかない。

まず HD を入れ替える。ウチの内蔵 HD はリムーバブルなので,スコンと取ってパチンと付けられると思ってたが,結局ネジはいるのね。気軽にってワケにはいかないのか。まあ普通のよりは入れ替えやすいけど。ちなみに外し方は,HD のカバーを開けて中の爪を上げたまま思いっきりカバーを引く。なかなか外れないが,輪っか状になっている金具とかで引っかかりに引っかけるとまあ楽。

NT インストール。インストール自体はすぐできた。途中ネットワークカードのインストールもまあうまくいく。で間髪入れずサービスパック 5 を入れる。

次に Sharp の Web ページからダウンロードしたドライバを 1 コ 1 コ試す。だいたいうまくいったが,ディスプレイドライバだけ起動時にエラーになって,どうしてもうまくいかない。ウチの機種用って書いてあって NT も入れたばっかりなのにダメとはどういうことなのだろう。さすがに 16 色では開発も何もできないので中断。

Linux。前までは外付けの HD に入れて PCMCIA カード経由で無理矢理起動していたが,内蔵に移そうかという感じでインストール。インストール自体は何度もやってるので問題ない。で,起動すると何にもでてこない。下のメニューとかはどうやって起動するんでしょうか。前の時は自動で出てきたんだけどな。とりあえずそのまま。

#後で分かったが,これはウィンドウマネージャの選択で Enlightenment を選択していたからで,Gnome(+ Enlightenment?)にすれば前のになった。

てとこで忙しくなってきたので,とりあえず元に戻して封印しておく。

Turbo Linux で X 使用のプログラムをコンパイル。

gcc -lm -L /usr/X11R6/lib -lX11

Turbo Linux に PostgreSQL のインストールをする。postgresql,postgresql-client,postgresql-devel をインストールし,手元の本(石井 達夫「PC UNIX ユーザのための PostgreSQL 完全攻略ガイド」(技術評論社,1999))のような設定を行っただけで使えるようになった。日本語もちゃんと使えるし起動時に postmaster を起動してくれるし。便利。


今まで ls を白黒(?)で使っていたが,色で表示するようにする。.bashrc にあるコメントどうりにコメントを外したりするだけでできた。

メビウス購入以来ずーっと悩んでたことだが,エクスプローラの動作が異常に重いというのがある。とにかくフォルダの中身を表示するの
に時間がかかるのだ。最初は普通だが,使っていくうちに遅くなり,最終的にはフォルダ開くのに 10 秒とかかかるのだ。ハードが原因とは思えないので,OS か IE の問題っぽい。でも他にこんな症例は聞いたことがない。とりあえず Win98 を捨てて NT にでもしてみようかと思っていた。

しかし,今ふとハードディスクを全共有(もちろんパスワード付きだが)して,ネットワーク越しにアクセスしてみた。するとみちがえるように早く! なったのかはしばらく使ってみないと分からないんだが,感覚的には早いような気がする。ネットワークで使うのでパスが UNC になるのが心配だが,まあ問題ないだろう。これで解決すればこれでいこうと思う。

実はこの問題は今までメビウス使ってて最大最高の問題であり,これが解決したら私のメビウスは完全無欠仕事効率も 150% アップ,世界が変わる! ってくらいの非常に重要な問題なワケで。

# でも NT 計画は実行するかも。唯一の問題 DirectX は Windows2000 で解決するらしいし。

おっきなファイルを送る。が,何故か途中でサーバーからの応答がなくなる。まあこれは仕方がないとして,途中で強制切断されてしまう。で,もう一回やってみて原因が判明。接続後 20 分たつと自動的に「切断しますか?」と聞かれ,答えないと切断されるらしい。ウーン。確かにそれでいいんだけど,20 分もつないでるってことは何かしてるわけで,その間本読んでて気付かないかもしれないのに。って警告音とか全て OFF にしてるのがまずいのか。実は。


プログラムではないが。エクセルの行を固定する方法。固定したい行の次の行を選択し,[ウィンドウ]-[ウィンドウ枠の固定] を選択。

あるウィンドウで IME 入力を禁止する方法

ImmAssociateContext

で,第 1 引数をハンドル,第 2 引数を NULL にして呼び出す。

リサイズ時のちらつきをなくす。PreCreateWindow を以下のようにする。

if(!CView::PreCreateWindow(cs))
{
return FALSE;
}

// CS_HREDRAW,CS_VREDRAW を外す
cs.lpszClass = AfxRegisterWndClass(CS_DBLCLKS, AfxGetApp()->LoadStandardCursor(IDC_ARROW), (HBRUSH)(COLOR_WINDOW + 1));

これをビューに対して行うときは,メインフレームにも追加すること。今回はこれをしないで悩んだ。


リストボックスに水平スクロールバーを表示させる。リストボックスは勝手に付けてくれないので,自分で大きさを計算する必要がある。

int nSize = 0;

CClientDC dc(&m_listboxFile);
CFont *pOldFont = dc.SelectObject(m_listbox.GetFont());
for(int i = 0; i < m_listbox.GetCount(); i++)
{
CString str;
m_listbox.GetText(i, str);
if(dc.GetTextExtent(str).cx > nSize)
{
nSize = dc.GetTextExtent(str).cx;
}
}

nSize += LIST_MARGIN;

m_listbox.SetHorizontalExtent(nSize);
dc.SelectObject(pOldFont);

こんな感じ。この際なかなかサイズが合わず,とりあえずフォントを設定したらやっとうまくいった。CClientDC では自動でフォントを合わせてくれないのね。


スクロールバーの右下のやつ。最初は自分で描画していたが,どうしても更新がうまくいかないので独立したウィンドウにしてしまう。しかし Spy++ で VS を調べると ScrollBar になっている。なんかもっとちゃんとした方法があるのだろうか。

アイコンの 16×16 とかの削除。リソースエディタで [イメージ]-[デバイスイメージの削除] で削除できる。

ウィンドウの破棄。今更って感じだが,実は詳しく知らなかった。ウィンドウは通常外部から直接 delete はせず,以下の手順で行う。詳細はMSDN「テクニカル ノート 17: ウィンドウ オブジェクトの破棄」参照。

  • CWnd::PostNcDestroy をオーバーライドし,delete this を行う(親クラスの呼び出しはいらない。)
  • 破棄するときは pWnd->DestroyWindow() のように行う。その際,子ウィンドウの場合は親ウィンドウの破棄時に自動的の行われるので考えなくてよい。

Install Shield。ライセンスの文字列を変える。が,ファイルを修正しても一向に反映されない。かなり悩んだが,[ビルド]-[メディア]-[ビルド] を行うことで解決。ていうか VS そっくりにするんだったらこの項目は [ビルド]-[コンパイル] の下にもってきて欲しい。


ファイルの関連づけがうまくいかない。

aaa.Documentshellopencommand

に実行ファイル名とパラメータを設定しているのだが。起動はするんだが,ちゃんとファイルを読み込まない。で 1 回起動するとうまくいく。レジストリの違いは,自分で設定したものはロングファイル名だが,自動で設定されたものはショートファイル名ってとこ。で,自動でショートファイル名を指定したらうまくいった。ウーム。他にないんですかね。ちなみにファイル名をダブルクォーテーションで囲ってもダメだった。


開発環境の入っていないソーテックマシンでインストールを試みる。で関連づけを試す。が,どうしてもメモ帳が立ち上がる。何故だろう。と思ったら,ファイル名の最後に .txt が付けられてた。「登録されている拡張子は表示しない」になっていたのだ。うぅ。

スプラッシュスクリーンを追加。スプラッシュってのはアプリケーションが開始する時に出る,タイトル画面みたいなアレである。自分で作ると結構手間がかかりそうだが,VC のコンポーネントギャラリから追加したのでほとんど何もせずにできた。まあ後でフルカラー対応にしたりとかするかも知れないけどとりあえず完了。

ツールバーアイコンをフルカラーにする。さてどうしようと悩んでダイアログバーでオーナードローボタンでもつけるか,とか考えたが,めんどくさすぎてあきらめる。いろいろ調べていると新しいコモンコントロールで,ツールバーに直接イメージリストをセットできることが判明。CMainFrame::OnCreate に,

// ツールバーを作成
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC))
{
TRACE0("Failed to create toolbarn");
return -1;      // 作成に失敗
}

// イメージリストの作成
CBitmap bitmap;
bitmap.LoadBitmap(IDB_TOOLBAR);

m_pImageToolBar->Create(32, 32, ILC_COLOR24 | ILC_MASK, TOOLBAR_MAX, 1);
m_pImageToolBar->Add(&bitmap, RGB(255, 255, 255));

m_wndToolBar.SetSizes(CSize(39, 39), CSize(32, 32));
m_wndToolBar.GetToolBarCtrl().SetImageList(m_pImageToolBar);

// ボタンの追加
UINT command[] =
{
ID_FILE_NEW,
...
};

m_wndToolBar.SetButtons(command, TOOLBAR_MAX);

てな感じで ok。透明色とかももちろんやってくれるので簡単。ちなみにこの際,最初イメージリストをスタックに作ってて反映されなかった。これはメンバに持つことで解決。

アプリケーションのアイコンとメインフレームのアイコンを別のものにする。というかまだしてなくて調べただけだが。IDR_MAINFRAME はあくまでメインフレームのアイコンであり,一番リソース ID の小さいアイコンが EXE のアプリケーションのアイコンとなる。らしい。

# その後確認しました。

ダイアログのエディットボックス内のテキストが最初に選択されない。選択されるものもあるので調べると,最初にフォーカスがないのが原因だった。タブオーダーでエディットボックスを最初にして解決。


相対パスから絶対パスへの変換。真面目にやろうとするとかなり大変だが,_fullpath という関数があった。ワーイ。

マルチスレッド。ウィンドウを AfxBeginThread パラメータで渡し,メンバ関数を呼ぶが ASSERT。そういえば CWnd を他のスレッドに渡せないんだっけ。ということは今まで CWnd をマルチスレッドのパラメータにしたことなかったのか。一応上のはハンドルを渡し,ウィンドウメッセージを使うことで解決。


FTP クライアントを作成。しかしデバッグのために Hi-HO へダイヤルアップしてたらアレなのでフリーの FTP サーバー,WAR-FTPD をインストール。ローカルで試すだけなので割合設定は楽だったが,一応設定を。

  • [Property]-[Security]-[Edit User] で mortarco を作成,FileAccess で FTP 用の pub ディレクトリを指定。パーミッションも適当に設定。
  • [Property]-[Option]-[Virtual File System] で仮想ディレクトリを作成。AutoStart にし,パスを c:pub,pub のように設定。

以上で FTP クライアントから接続ができた。

もう 1 台 LAN で接続してるんだから Linux で,って手もあるけどやっぱりローカルで手軽にって方がいいですな。


でクライアント本体の話。MFC の FTP クラスを使っててメモリリーク。調べてみると CInternetSession::GetFtpConnection で得たオブジェクトは自分で解放しなければならないらしい。ってヘルプにそんなこと書いてあったっけ? サンプル見れってことか。

ウィザードの作り方。CPropertySheet を普通に作成し,SetWizardMode を呼ぶだけ。

で,「次へ」とかを無効にするのに EnableWindow を使っていたが,反映されたりされなかったりで悩む。結局,CPropertySheet::SetWizardButtons を理解してなかったのが原因。この関数でボタンを作成し,EnableWindow で有効,無効を設定するんだと思っていたが,CPropertySheet::SetWizardButtons で引数を 0 にすると「次へ」「戻る」が無効。PSWIZB_BACK だと「次へ」が無効になる,という意味だった。ので,EnableWindow を使う必要はない。

HTML ヘルプに挑戦。しようかと思う。とりあえず Help WorkShop を探すが,手元にはないので MS のサイトへ。しかしどこにあるのかさっぱりだが,いろいろ調べて

http://msdn.microsoft.com/workshop/author/htmlhelp/download.asp

からダウンロードできることを発見。4MB。ダウンロードするか,と思ったが,Visual Studio の SP3 に入っていることが分かったので,そっからインストール。したが,まだインストールしただけ。

クラスの新規作成。今まで MFC クラスからの派生でないクラスを作成するときは *.h,*.cpp を手動で作成していたが,IDE のツリーの「*クラス」の右クリックメニューにあるクラスの新規作成でできることを発見。ていうかこの機能って VC5.0(以前)にもあったっけ?