1999年11月のエントリ

あるウィンドウで 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(以前)にもあったっけ?