English || XKeymacs | 7 つ道具 | Tips | JavaHelp | LilyPond | SlickEdit | 書評 | 落書 | リンク集

Tips

Windows

Microsoft Visual C++ 6.0

Linux

著作権

ルータ


Windows

パスにまつわる環境変数

%SYSTEMDRIVE%
C:\
%SYSTEMROOT%
%WINDIR%
C:\WINNT
C:\Windows
%SYSTEM%
C:\Windows\System (Windows 9x)
C:\WinNT\System32 (Windows NT/2000)
C:\Windows\System32 (Windows XP)
%ProgramFiles%
C:\Program Files
%CommonProgramFiles%
C:\Program Files\Common Files
%TEMP%
%TMP%
C:\Windows\Temp (Windows 9x)
C:\Profiles\<user_name>\TEMP (Windows NT)
C:\Documents and Settings\<user_name>\Local Settings\TEMP (Windows 2000/XP)
%ComSpec%
C:\WINNT\system32\cmd.exe
%ALLUSERSPROFILE%
C:\Documents and Settings\All Users
%USERPROFILE%
C:\Documents and Settings\<user_name>
%APPDATA%
C:\Documents and Settings\<user_name>\Application Data

参考文献
「%SYSTEMROOT%」、「%SYSTEM%」、「%TEMP%」とは?
@IT:Windows TIPS -- Tips:OSの種類によってバッチ・ファイルの処理を切り替える方法
エンタープライズ Windows Tips - 一般化された環境変数表現によるアクセス

XKeymacs の設定

XKeymacs の設定方法は他のドキュメントにまかせるとし、ここでは私の好みの設定を羅列。

プロパティ
オプション
キーボードレイアウト

SKK95 のインストール手順

  1. SKK95 をダウンロード (本手順は SKK95 α13 で確認)
  2. skk95a13.lzh を解凍
  3. skk95.REG をメモ帳で開いて、"UseEmacsLikeKey"=dword:00000001 を全て "UseEmacsLikeKey"=dword:00000000 に変更。他も適宜変更
  4. SKKSETUP.exe をダブルクリックし、Enter を連打
  5. タスクバーの SKK アイコンを右クリックしプロパティを選択
  6. SKK を選択し既定値に設定ボタンを押す
  7. IME の設定ボタンを押し、適当に設定
  8. もし skk95.REG をデフォルトのまま使用したときは、スタートメニューの [ファイル名を指定して実行] から regedit を起動し、UseEmacsLikeKey を全て検索し値を 0 にし Windows 2000 を再起動する (そうしないと XKeymacs とコンフリクトする)

参考文献
SKK95 α13附属のマニュアル

SKK95 で SKK の辞書を利用する方法

  1. %SYSTEM%\skk95l.dic (ex. C:\WINDOWS\system32\skk95l.dic) の名前を skk95l.dic.org に変更。
  2. SKK辞書 SKK-JISYO.L.unannotated.zip をダウンロード
  3. SKK-JISYO.L.unannotated.zip を解凍
  4. SKK-JISYO.L.unannotated のエンコードを EUC から Shift-JIS に、改行コードを LF から CR+LF に変更
  5. SKK-JISYO.L.unannotated の名前を skk95l.dic と変更し %SYSTEM% へコピー
  6. Windows を再起動

参考文献
SKK

SKK95 のトラブルと解決方法

SKK95 で変換時に次のエラーが出ることがある。(ダイアログの絵のつもり)
+----------------------------------------------------
| skk95dic.exe - アプリケーション エラー
+----------------------------------------------------
| (X) "0x0040778c" の命令が "0x00000000" のメモリを参照しました。メモリが "read" になることはできませんでした。
|
| プログラムを終了するには [OK] をクリックしてください
| プログラムをデバッグするには [キャンセル] をクリックしてください
| [ OK ] [ キャンセル ]
+------------------------------------------------------
再現条件は不明。復旧するには、SKK95 をインストールし直す必要がある。手順は次の通り。

  1. タスクバーの SKK icon を右クリックしプロパティを選択
  2. [地域のオプション] ダイアログの [入力ロケール] タブのインストールされている入力ロケールで MS-IME2000 (または他の適当な IME) を選択し [既定値に設定] ボタンを押す
  3. SKK95 を選択し、[削除] ボタンを押す
  4. [地域のオプション] ダイアログの [OK] ボタンを押す
  5. Windows 2000 を再起動
  6. 上述の手順通りに SKK95 をインストール

SKKIMEのインストール手順

  1. SKKIME をダウンロード (本手順は Windows XP + SNAPSHOT 2005/11/14 で確認)
  2. skkime1.0-winxp-bin-snap20051114.tar.gz を解凍
  3. 解凍した snap20051114.wxp ディレクトリの中にある SKKI1_0U.INF を右クリックし、インストールを選択
  4. SKK辞書 SKK-JISYO.L.unannotated.zip をダウンロード
  5. SKK-JISYO.L.unannotated.zip を解凍
  6. コントロールパネルの [地域と言語のオプション] の [言語] タブの [詳細] ボタンを押し、[テキスト サービスと入力言語] を開く。
  7. [テキスト サービスと入力言語] で SKKIME を既定の言語に設定
  8. SKK IME のプロパティダイアログを開く
  9. SKK IME のプロパティダイアログの [辞書設定] タブで、解凍した辞書 SKK-JISYO.L.unannotated を追加 (その際、[この辞書はソートされている。] にチェック。また、ユーザ辞書の優先順位を SKK-JISYO.L.unannotated より上げておく)

バージョンアップを行うには、新しい SKKIME (例えば SNAPSHOT 2006/01/25) に対し、上記の Step 1 〜 3 を実行すれば良い。

参考文献
[技術情報SKKIME] System Design and Research Institute Co., Ltd.

SKKIME の設定

準備
SKKIME のアイコンを右クリックし、[設定] を選択
-> [テキスト サービスと入力言語] ダイアログが開く
[インストールされているサービス] で [SKKIME ver. 1.0] を選択し [プロパティ] ボタンを押す
-> [SKKIME1.0(build:20060125) のプロパティ] ダイアログが開く (当然ながら build 番号は利用している SKKIME により異なる)
"NONNda" を "呑んだ" と変換
[ローマ字仮名変換ルールの設定] タブ上の [追加] ボタンを押す
[現状態] に "nN"、[次状態] は空白のまま、[平仮名出力] に "ん"、[片仮名出力] に "ン" を入力し、[OK] ボタンを押す
SNAPSHOT 2006/01/25 以降の SKKIME を利用する必要がある。またこの設定を行わないと "NONN" が "呑ん" ではなく "▽の*んn" となる。
"MINA" を "見な" と変換
[ローマ字仮名変換ルールの設定] タブ上の [追加] ボタンを押す
[現状態] に "nA"、[次状態] は空白のまま、[平仮名出力] に "な"、[片仮名出力] に "ナ" を入力し、[OK] ボタンを押す
nI, nU, nE, nO についても、同様に設定する。
※ この設定を行わないと "MINA" が "▼見な" ではなく "▼見んあ" となる。ちなみにデフォルトで SKK は "▼見んあ"、SKK95 は "▼見な"。
@ が押されたときに、日付の変わりに @ を入力
[キー設定] タブ上で key @ を選択し [変更] ボタンを押す
-> [キー割り当ての変更] ダイアログが開く
[j-map の機能] を [j-today] から [j-self-insert] に変更し [OK] ボタンを押す
[入力ベクトルの設定] タブで [追加] ボタンを押す
-> [入力ベクトルの変更] ダイアログが開く
[入力文字] で @ を選択、出力に @ を入力し、[OK] ボタンを押す
未変換文字列、変換文字列の色の変更
[色設定] タブの [変更箇所] で [未変換文字列] を選択し、[下線] を [ディザ細線] から [なし] に変更
[色設定] タブの [変更箇所] で [変換文字列] を選択し、[文字色] を [選択項目(文字)] から [自動(文字)] へ、[背景色] を [選択項目(背景)] から [3Dオプジェクト] へ変更
言語バーに入力モードだけ表示
[言語バー] タブで [キーボード] と [入力方式] の表示設定を [表示] から [非表示] に変更
上記の変更を適用
[SKKIME1.0(build:20060125) のプロパティ] ダイアログの [OK] ボタンを押す
[テキスト サービスと入力言語] ダイアログの [OK] ボタンを押す

SKK95 と SKKIME の違い

SKK95 の挙動は (私にとっては) 完璧。たまに (年に一度くらい?!) 変換ができなくなり再インストールを強いられることを除けば特に不満はない。SKK とは異なり、デフォルトで "MINA" が "見な" に変換されるのも良い。
SKKIME は @ で日付ではなく@を入力することができる。XKeymacs と一緒に使うと挙動がおかしくなる問題も修正され、今後の更なる発展が期待される。

Meadow2 で SKK を利用する方法

Meadow2SKK を利用するためには、インストール時に skk のみならず apel もインストールしておく必要がある。インストールさえすれば、C-x C-j で SKK が起動する。

Windows XP 上で、Ctrl+Shift で IME が切り替わらないようにする方法

Windows XP では、特に何も設定しなくても Ctrl+Shift で IME が切り替わる。また、コントロールパネルから設定を確認しても、この機能は Off になっているように見える。この問題は次の手順で解消できる。

  1. [コントロールパネル] の [日付、時刻、地域と言語のオプション] にある [地域と言語のオプション] を選択
    -> [地域と言語のオプション] ダイアログが開く
  2. [地域と言語のオプション] ダイアログの [言語] タブにある [詳細] ボタンを押す
    -> [テキストサービスと入力言語] ダイアログが開く
  3. [テキストサービスと入力言語] ダイアログの [設定] タブの [基本設定] にある [キーの設定] ボタンを押す
    -> [詳細なキー設定] ダイアログが開く
  4. [入力言語を切り替える] を選択し、[キーシーケンスの変更] ボタンを押す
    -> [キーシーケンスの変更] ダイアログが開く
  5. [キーシーケンスの変更] ダイアログにある [キーボードレイアウトの切り替え] をチェックし、[OK] ボタンを押す
  6. [入力言語を切り替える] を選択し、[キーシーケンスの変更] ボタンを押す
    -> [キーシーケンスの変更] ダイアログが開く
  7. [キーシーケンスの変更] ダイアログにある [キーボードレイアウトの切り替え] のチェックを外し、[OK] ボタンを押す

参考文献
[IME] 入力方式の変更に割り当てられたキーが設定と異なる

アプリケーション起動時に出る警告を抑制する方法

Windows XP SP2 を導入すると、インターネットから取得した実行ファイルなどを実行しようとすると次のようなダイアログが表示されます。

+--------------------------------------------------------------------------------+
| 開いているファイル - セキュリティの警告                                    [X] |
+--------------------------------------------------------------------------------+
| 発行元を確認できませんでした。このソフトウェアを実行しますか?                 |
|   名前: foo.exe                                                                |
| 発行元: 不明な発行元                                                           |
|   種類: アプリケーション                                                       |
| 発信元: C:\Program Files\foo                                                   |
|                           [実行(R)] [キャンセル]                               |
| [x] この種類のファイルであれば常に警告する                                     |
+--------------------------------------------------------------------------------+
| ___ このファイルには、発行元を検証できる有効なデジタル署名がありません。信頼で |
| \x/ きる発行元のソフトウェアのみ実行してください。                             |
|  ~  実行することのできるソフトウェアの詳細を表示します                         |
+--------------------------------------------------------------------------------+

この警告は、"発行元を検証できる有効なデジタル署名" が foo.exe にされていないために表示されています。 デジタル署名を行うことは簡単なのですが、発行元を検証できる有効なデジタル署名の維持に年額 10 万円程度の費用が継続的にかかるようで、 特にフリーソフトウェアなどに署名を付けることは現実的ではありません。 foo.exe を起動したときに警告を出さなくするためには、foo.exe のプロパティダイアログにある全般タブ上の [ブロックの解除] ボタンを押してから [OK] ボタンを押す必要があります。

参考文献
インターネットからダウンロードしたファイルを実行したときに表示されるセキュリティの警告画面と、警告の解除方法

Windows XP でファイルを共有する方法

Windows XP の [フォルダ オプション] で [簡易ファイルの共有を使用する (推奨)] にチェックが入っていると管理用共有リソース (\\<host_name>\c$ など) にアクセスしようとしたときに (Guest でアクセスしようとするため) アクセスできなくなる。以下の手順でチェックを外せば問題なくアクセスできるようになる。
# c$ など管理用共有リソース へのアクセスはセキュリティの面から賛否あるが、少なくとも閉じた環境で利用する分には便利な機能である。

  1. エクスプローラの [ツール] メニューの [フォルダ オプション] を選択し [フォルダ オプション] ダイアログを開く
  2. [フォルダ オプション] ダイアログの [表示] タブを選択
  3. [表示] タブの [詳細設定] にある [簡易ファイルの共有を使用する (推奨)] チェックボックスのチェックを外す
  4. [フォルダオプション] ダイアログの [OK] ボタンを押す

参考文献
Windows XP でファイル共有を構成する方法

他の場所にあるコンピュータにアクセスする方法

NetMeeting のリモートデスクトップ共有機能を利用すると、他の場所にあるコンピュータにアクセスすることができる。NetMeeting は特にインストールしなくても (最近の Windows では大抵) 使うことができる。

サーバ側 (共有される側、つまり、突つかれる側) の設定
  1. [スタートメニュー] の [プログラム] の [アクセサリ] に入っている [NetMeeting] を起動
    # Windows XP では %ProgramFiles%\NetMeeting\conf.exe を起動
    -> [NetMeeting] のウィンドウが開く
    # 初回はウィザードが立ち上がるが、デフォルトの設定で特に問題はない
  2. [NetMeeting] ウィンドウの [ツール] メニューから [リモートデスクトップ共有] を選択
    -> [リモートデスクトップ共有の設定] ダイアログが開く
    # 初回はウィザードが起動し、スクリーンセーバーのパスワードについて聞かれる
  3. ダイアログの [リモートデスクトップ共有をこのコンピュータで有効にする] がチェックされていることを確認し、[OK] ボタンを押す
  4. [NetMeeting] ウィンドウの [ツール] メニューから [オプション] を選択
    -> [オプション] ダイアログが開く
  5. [オプション] ダイアログの [セキュリティ] タブにある [すべての通信通話をセキュリティで保護します] にチェックし、[OK] ボタンを押す
  6. [通話] メニューから [終了してリモートデスクトップ共有をアクティブにする] を選択
# 一度設定すれば、Windows を再起動してもリモートデスクトップ共有はアクティブになっている。もとい、リモートからアクセスできる。
クライアント側 (共有する側、つまり、突つく側) の設定
  1. NetMeeting を起動する
    -> [NetMeeting] のウィンドウが開く
  2. [オプション] ダイアログの [セキュリティ] タブにある [すべての通信通話をセキュリティで保護します] にチェックし、[OK] ボタンを押す
    # 一度設定したら、何度も行う必要はない
  3. ホスト名を入力し、[通話する] ボタンを押す
    -> [リモートデスクトップ共有のパスワード] ダイアログが開く
  4. [ユーザー名] と [パスワード] を入力し、[OK] ボタンを押す

100 Mbps で繋がった隣のマシンにアクセスしても、画面の表示はかなりもたつく。そのためちょっとした操作をするには複数のキーボードを操作する必要がないので手軽で良いが、込み入ったことをするには現実的とは言い難い。
他に似たような機能を実現するソフトウェアとして VNC もあるが、機能的に然程差異はなく、NetMeeting が使える環境で敢えて VNC をインストールして利用する必要性は感じられない。

参考文献
@IT:Windows TIPS -- Tips:リモートからWindowsデスクトップを制御する方法(NetMeetingを利用する方法)

コマンド プロンプト (Cmd.exe) の自動補完を有効にする方法

Windows NT/2000 のコマンドプロンプトは、ファイルやディレクトリ名を入力する際に自動補完機能を利用することができる。ただしデフォルトでは、この機能は disable になっている。この機能を利用するためには、レジストリを変更する必要がある。レジストリの
HKEY_CURRENT_USER/Software/Microsoft/Command Processor
にある
CompletionChar
の値を 9 にする
と、ファイルやディレクトリ名を途中まで入力し、Tab key を押す、もしくは C-i を押すことで、ファイル名等が補完されるようになる。ただし、コマンドの補完、検索等は相変わらずできない。この設定は XKeymacs のオプションダイアログからも行える。Tab key 以外のキーで補完したいという方は参考文献を参照して欲しい。

参考文献
244407 - コマンド プロンプト (Cmd.exe) の自動補完を有効にする方法
244407 - How to Enable Automatic Complete for the Command Prompt (Cmd.exe)
Windows 2000 TIPS -- TIPS:コマンド プロンプトで入力補完機能を使う方法

コマンドプロンプトからレジストリを変更する方法

コマンドプロンプトからジレストリを変更するには、レジストリデータをテキストに書き出し、テキストデータを変更し、変更したデータをレジストリに反映すれば良い。

書き出し
regedit /e filename.reg HKEY_CURRENT_USER\Software\foo\bar
取り込み (マージ)
regedit filename.reg
置換
regedit /c filename.reg

参考文献
131352 - Using Registry Editor in Real Mode
168589 - How To Export WinNT Registry Entries from a Command Prompt

Cygwin の bash で Delete キーを押すと ~ が入力されてしまう

ノートパソコンなどで特殊なキーボードが使用されてると起こる。~/.inputrc に以下の行を加えると直る。
"\e[3~": delete-char

Emacs におけるキーボードマクロの保存及び書き出し方法

キーボードマクロに名前を付ける
M-x name-last-kbd-macro
キーボードマクロの定義を書き出す
M-x insert-kbd-macro

Visual SlickEdit の設定

Visual SlickEdit とはエディタである、らしい。どちらかというと IDE のような気もするが。
その Visual SlickEdit インストール直後に設定しておくと良い (と、私が勝手に思う) 設定。

設定の初期化
Visual SlickEdit の設定 (の多く?!) は
%USERPROFILE%\My Documents\My Visual SlickEdit Config
(Ex. C:\Documents and Settings\<user_name>\My Documents\My Visual SlickEdit Config)

に保存されている。(<user_name> は "Windows へのログオン" に用いられた "ユーザー名"。)

次の手順で、デフォルトの設定に戻すことができる。
  1. Visual SlickEdit を終了
  2. My Visual SlickEdit Config ディレクトリを削除
  3. Visual SlickEdit を起動
余談ながら、My Visual SlickEdit Config ディレクトリに保存された設定は、手で直接編集するには少し難解である。
Emacs をエミュレート
Tools メニューの Options -> Emulation を選択
-> Emulation ダイアログが開く
CUA (default) から GNU Emacs へ変更
set-mark-command, delete-backward-char, newline
Tools メニューの Options -> Key Bindings を選択
-> Bind Command to Key ダイアログが開く
Command の emacs-select-char を選択し、Add Key or Mouse Click ボタンを押し、Ctrl キーを押しながら Space キーを押し、Bind ボタンを押す
-> C-Space に割り当てられたコマンドが codehelp-complete から emacs-select-char へ変更される [set-mark-command]
同様の方法で、
C-h のコマンドを gnu-help から linewrap-rubout に変更 [delete-backward-char]
C-m のコマンドを wh から split-insert-line に変更 [newline]
Ctrl+F4 でファイルを閉じる
Tools メニューの Options -> Key Bindings を選択
-> Bind Command to Key ダイアログが開く
Command の quit を選択し、Add Key or Mouse Click ボタンを押し、Ctrl キーを押しながら F4 キーを押し、Bind ボタンを押す
-> C-Space に割り当てられたコマンドが lowcase-selection から quit へ変更される
Ctrl+Tab でウィンドウの遷移
Tools メニューの Options -> Key Bindings を選択
-> Bind Command to Key ダイアログが開く
Command の next-buff-tab を選択し、Add Key or Mouse Click ボタンを押し、Ctrl キーを押しながら Tab キーを押し、Bind ボタンを押す
-> C-Tab に割り当てられたコマンドが next-window から next-buff-tab へ変更される
Command の prev-buff-tab を選択し、Add Key or Mouse Click ボタンを押し、Ctrl キーと Shift キーを押しながら Tab キーを押し、Bind ボタンを押す
-> C-S-Tab に割り当てられたコマンドが prev-window から prev-buff-tab へ変更される
フォントの変更
Tools メニューの Options -> Font を選択
-> Font Configuration ダイアログが開く
Font を "OEM Fixed Font" から "MS ゴシック" へ変更し、Size を 10 から 9 に変更
書式を変更
Tools メニューの Options -> Color を選択
-> Color Settings ダイアログが開く
Screen element で Comment の Style を Italic から Normal へ、Keyword, Preprocessor, Library Symbol, Function, Attribute の Style を Bold から Normal へ変更
タブの表示
View メニューの Tab Chars を選択
-> タブが "・アアア" (但し全て半角文字) と表示される
Search メニューの Find を Grep に
Tools メニューの Options -> General を選択
-> General Options ダイアログが開く
Search タブを選択し、Initialization options の Expand dialog をチェック
Find ダイアログで前回の検索文字列を選択
Tools メニューの Options -> General を選択
-> General Options ダイアログが開く
Search タブを選択し、Selected text (if exists) をチェック

以下、推奨はしないが、TPO に応じ必要となることがある設定。

行番号表示
View メニューの Line Numbers を選択
-> 行頭に行番号が表示されるようになる
# ステータスバーにカレント行の行番号は表示されるので普段は不要だが、行頭表示になれた人と共同作業をする際に必要となる
タブの変わりにスペースでインデント
Tools メニューの Options -> File Extension Setup を選択
-> Extension Options ダイアログが開く
Extention: のコンボボックスで c を選択し、Indent タブを選択し、Indent with tabs のチェックを外す
# 私はインデントにはタブを用いるべきだと考えるので、この設定は推奨しない
# しかし、タブを用いないコーディングスタイルを採用するプロジェクトに参加する際、この設定は役立つ
拡張子 foo を追加
Tools メニューの Options -> File Extension Setup を選択
-> Extension Options ダイアログが開く
開いた Extention Options ダイアログの下にある New ボタンを押す
Extentions エディットボックスに foo だけ入力して OK ボタンを押す

※ IDE: Integrated Development Environment の略。統合開発環境。Eclipse や Microsoft Visual Studio 等の総称。
※ CUA: Common User Access の略。メモ帳のような Windows の一般的なキーバインドのこと。
※ TPO: Time, Place, Occasion の略。時、場所、場合。

Visual SlickEdit のトラブルと解決方法

Visual SlickEdit が起動しない
Visual SlickEdit を起動しようとした際、まれに下載のようなダイアログが表示されることがある。
+----------------------------------------------------------------------------------------------------------+
|Visual SlickEdit                                                                                       [X]|
+----------------------------------------------------------------------------------------------------------+
|   Run the vsupdatw program as shown below (Start, Run) to transfer serial number and license information.|
|                                                                                                          |
|   Usage:                                                                                                 |
|             vsupdatw old-exe-name new-exe-name                                                           |
|                                                                                                          |
|             old-exe-name       Name of original executable to take license info from.                    |
|             new-exe-name       Name of new executable to transfer license info to.                       |
|                                                                                                          |
|                                        [      OK       ]                                                 |
+----------------------------------------------------------------------------------------------------------+
もちろん(?!) OK ボタンを押して閉じても、SlickEdit は起動しない。
スタートメニューをプログラム -> Visual SlicEdit -> Set License と辿り、開いた Set License ダイアログで、Key code: を入力してから OK すると、無事起動するようになる。
Project Toolbar (Class Brower 等が含まれる) が表示されない
任意の Toolbar の縁を右クリック
-> ポップアップメニューが開く
もし Project の項目にチェックが付いているときは、Project を選択し、再度任意の Toolbar の縁を右クリック
ポップアップメニュー上の Project にチェックが付いていないことを確認し、Project を選択
-> Visual SlickEdit ウィンドウからキーボードフォーカスが失われる
Alt キーを押しながら、スペースキーを押す
-> 見慣れた下記のポップアップメニューが (私が実行したときはディスプレイの下端に) 表示される
+-----------------------+
|[] 元のサイズに戻す(R) |
|   移動(M)             |
|   サイズ変更(S)       |
|__ 最小化(N)           |
|[] 最大化(X)           |
+-----------------------+
移動を選択
カーソルキーを用いて、Project Toolbar をディスプレイの表示域内に移動
必要に応じ、Project Toolbar をマウスでドラッグし、適当な縁にへばりつかせる

秀丸エディタの設定

秀丸エディタインストール直後に設定しておくと良い (と、私が勝手に思う) 設定。
ファイルタイプ別の設定を適用
foo.c を開き、[その他] メニューの [ファイルタイプ別の設定] を選択し、冒頭のコンボボックスで [C言語ソースファイル] を選択し、[OK] ボタンを押す。
インクリメンタルサーチ
Emacs風インクリメンタルサーチマクロ Ver1.0.0
[マクロ] メニューの [マクロ登録] でタイトルに "isearch" の様な適当な名前を、ファイル名に X:\hidemaru-isearch-1_0_0-full\emacs-isearch-forward(backward).mac を入力する。その後、[その他] メニューの [キー割り当て] の [Ctrl] チェックボックスをチェックし、キー [Ctrl+S] を選択し、コマンド [メニュー/マクロ] の [マクロ1:isearch] を選択し [OK] ボタンを押す。Ctrl+R も同様な手順で割り当てる。(XKeymacs のプロパティダイアログを起動し、秀丸に [独自の設定を使用する] ようにし、C-s と C-r のチェックボックスのチェックを外す。)
これを利用すると、あるウィンドウで検索中に他のウィンドウでも検索を行おうとすると「他の秀丸がマクロ実行中です」というエラーメッセージが表示され、検索が行えなくなる。場合に依ってはこのマクロは使用せずに、[その他] メニューの [動作環境] の [検索での表示] の [リアルタイム検索 (Emacs 風)] チェックボックスにチェックした方が良いかもしれない。
上端/下端に近づけるようにする
[その他] メニューの [動作環境] の [高度なカーソル] の [画面の先頭と最後の数行にカーソルがあるとき自動的にスクロールする] のチェックボックスのチェックを外す。
チェックしたままだと、XKeymacs の Retop コマンドが期待通りに動かない。
スクロール
[その他] メニューの [動作環境] の [スクロール] の [スクロールする行数] の [1 行ずつ] ラジオボタンをチェックする。
デフォルトの [2 行ずつ] だと、XKeymacs の recenter コマンドが期待通りに動かないことがある。
縦に最大化して起動
[その他] メニューの [動作環境] の [ウィンドウ] の [起動時のウィンドウ配置] の [サイズを指定する] チェックボックスをチェックし、高さを十分に大きい数字 (ex. 100) を指定する。
横スクロール
[その他] メニューの [動作環境] の [ウィンドウ] の [横スクロールバー] チェックボックスをチェックする。
カーソル
[その他] メニューの [動作環境] の [カーソル] の [スクロールしてもカーソル位置は固定] をチェックする。
チェックしないと、XKeymacs の recenter コマンドが期待通りに動かない。
改行表示
[その他] メニューの [ファイルタイプ別の設定] を選択し、[表示] タブの [EOF(ファイルの末尾)表示] チェックボックスと、[改行文字を起動で表示] チェックボックスのチェックを外す。
対応する括弧の強調表示
[その他] メニューの [ファイルタイブ別の設定] を選択し、[表示] タブの [対応する括弧を強調表示] チェックボックスをチェックする。
バックアップファイルの作成をしないようにする
[その他] メニューの [ファイルタイプ別の設定] を選択し、[保存・読込み] タブの [バックアップファイルの作成] チェックボックスのチェックを外す。
バックアップファイルが存在すると、grep するときに、*.bak を除かなければならず面倒。

秀丸エディタの使い方

秀丸エディタ使用時に頻繁に利用されるにも関わらず頻繁に実行方法を忘れるコマンド。
grep
[検索] メニューの [grepの実行] を選択する。
タグジャンプ
grep の検索結果の適当なところにカーソルを置き、F10 を押すと、その文書のその場所に飛んでいける。
関数一覧
F11 を押し、開いた [強調一覧] ダイアログで [関数一覧] ラジオボタンをクリックすると、ファイルに含まれる関数一覧が表示される。複数のファイルの関数を一覧することはできなそうな雰囲気。
ダイレクトタグジャンプ
Ctrl+F10 すると、関数の使用場所から定義へ移動する。事前に [その他] メニューの [tagsファイルの作成] から tags ファイルを作成しておく必要がある。
バックタグジャンプ
Ctrl+Shift+F10 で戻れる。
行番号表示
F12 を押すと行番号が表示/非表示される。(ステータスバーにでもカーソル行のみ表示されれば十分なのにと感じるのは、Emacs 中毒な証拠か?)
単語をコピー
F5。
関数の冒頭/末尾へ移動
Ctrl+Shift+P/N で関数の冒頭/末尾へ移動できる。

ホームページ・ビルダーのソース編集でウィンドウにあわせて自動改行する方法

  1. HTML ソースウィンドウを右クリック
  2. ソース編集オプションメニューを選択
  3. ソース編集タブを選択
  4. ソースの自動改行をチェック

Windows 95 で Ctrl と Caps Lock を入れ換える方法

  1. Windows 95 Kernel Toys Set を入手
  2. 適当な名前のディレクトリを作成し、その中で W95KRNLTOYS.EXE を実行
  3. Keyremap.inf を右クリックし、インストールを選択
  4. コントロールパネルのキーボードを開き、remap tab を選択
  5. When the key is pressed リストで CapsLock を、Act as if this key is pressed リストで Left Ctrl を選択し、適用ボタンを押す

私の手元では Windows 98 日本語版上で Windows 95 Keyboard Remap が問題なく動作しているが、Windows 95 Kernel Toys Set のサイトには次のような記述がある。
--- Windows 95 Kernel Toys Set [Windows 95, downloads, download, updates, update, kernel toys] ---
NOTE: This download is not intended for use on computers running Microsoft Windows 98.
---

CapsLock キーのないキーボード使用時に CapsLock を押す方法

物理的に CapsLock キーの存在しない Windows 用のキーボードはないと思われるが、論理的に CapsLock キーの存在しないキーボードを利用している方は、(このサイトの読者の中では) 少なくないと思われる。そのような環境でもふとしたはずみに Caps Lock が On になってしまうことがある。そのような際は、スタートメニューから プログラム -> アクセサリ ->ユーザ補助 -> スクリーンキーボード と辿り、開いたスクリーンキーボードの CapsLock キーをクリックすることで、CapsLock を解除することができる。

Press any key

ご存知のように any という key はなく、「なにかキーを押してください」ということなのだが、以下のキーは "any key" ではない。
Alt, Caps Lock, Ctrl, Fn, NumLock, Pause, PrintScreen, ScrollLock, Shift, ひらがな, 変換, 無変換

余談ながら、長時間の離席等でディスプレイの電源が落ちているときは、Shift キーを押すように習慣付けておくと、万一押されたキーがキーボードのフォーカスを持つアプリケーションに渡されても (何も起こらないので) 慌てずにすむ。

MS-DOS プロンプトでコマンドの再呼び出しを有効にする方法

MS-DOS プロンプトで
DOSKEY
を実行。
MS-DOS プロンプトのショートカットのプロパティのプログラムタブのバッチファイルのところに DOSKEY と書いておくと便利である。

MS-DOS プロンプトにおけるドライブ指定方法

C:\>FOO /?
Usage FOO drive:
なとき、
C:\>FOO X:
という形式で指定。
C:\>FOO X
でも
C:\>FOO drive:X
でもない。

MS-DOS プロンプトの文字色及び背景色の変更方法

特定の MS-DOS プロンプトでのみ変更するには:
MS-DOS プロンプト を起動し、次のコマンドを実行
X:\>prompt $e[07m$p$g
X:\>cls
任意の MS-DOS プロンプトで変更するには:
autoexec.bat に次の記述を追加
prompt $e[07m$p$g

これで、背景が灰色、文字色が黒になる。07 のところを 00-08, 30-37, 40-47 にすると、色が変化する。番号と色の対応は、Google で "MS-DOS プロンプト 色 変更" といったキーワードで検索するといろいろみつかる。どのサイトも微妙に情報が違うのが面白い。

ファイルまたはフォルダのコピーエラー

ネットワーク先のディレクトリにファイルをコピーしようとすると、以下のようなエラーが出ることがある。

+-------------------------------------------------------------------------+
|ファイルまたはフォルダのコピー エラー                                 [X]|
+-------------------------------------------------------------------------+
|(X)    foo をコピーできません。指定されたネットワーク名は利用できません。|
|                        [       OK       ]                               |
+-------------------------------------------------------------------------+

私の場合は某 Firewall を終了したら、問題なくコピーできるようになった。 その後、Firewall を再起動しても問題なくコピーができた。Firewall がいたずらしていたか?! 複数のマシンで再現するも、いずれも Firewall の再起動で直る。 直ったので良しとする。

正確には以下のような感じ。

ある時点で Firewall の設定がオンラインから更新されるかなにかしたために起きたものと思われるが、正確なところは不明。Firewall を再起動すれば直ることもあるということで。

\WINNT\SYSTEM32\CONFIG\SYSTEM が存在しないかまたは壊れているため、Windows を起動できませんでした

Windows がフリーズした際など強制的に電源を落としたときに、次のようなエラーが出て OS が起動しなくなることがある。

次のファイルが存在しないかまたは壊れているため、Windows を
起動できませんでした:
\WINNT\SYSTEM32\CONFIG\SYSTEM

オリジナル セットアップ CD-ROM から Windows セットアップ
を起動して、このファイルを修復できます。
修復するには、最初の画面で 'R' キーを押してください。

これはレジストリが壊れたために Windows が起動できないということを示している。%SystemRoot%\Repair フォルダにある SYSTEM を %SystemRoot%\System32\Config フォルダへコピーすれば (大抵?!) 起動できるようになる。上述のアドバイスに従って CD-ROM から修復を試みるときは、[手動修復] ではなく [高速修復] を試みる必要がある。この方法はシステム修復ディスクを作成していないと実行できない (ことが多い?!)。デュアルブートの環境があったり、ディスクを他のマシンに繋げたりしてファイルにアクセスできるときは、直接 SYSTEM ファイルを %SystemRoot%\Repair フォルダから %SystemRoot%\System32\Config フォルダへコピーすれば良い。ただし、レジストリが古い状態に戻るため、行った設定がなかったことになっていたり、ドライバが認識されなかったりすることがある。
これを避けるためには "こまめにレジストリのバックアップを取りましょう" という賢者の言、つまり、極めて有効ながら非現実的な策を励行するしかない。

参考文献
エラー メッセージ 次のファイルが存在しないかまたは壊れているため、Windows 2000 を起動できませんでした WinntSystem32ConfigSystem
Windows の手動修復と高速修復の違い

プロファイルのアンロードに関する問題

Windows XP でイベントビューアのアプリケーションのところを覗いてみると、OS 終了時に次のような警告が出ていることがある。

種類 : 警告
ソース : Userenv
分類 : なし
イベント ID : 1517
ユーザー : NT AUTHORYTY\SYSTEM

説明 :
ログオフ時にアプリケーションまたはサービスがレジストリをまだ使用している間に、Windows はユーザー ComputerName\UserName のレジストリを保存しました。ユーザーのレジストリによって使用されたメモリは解放されていません。レジストリは使用されなくなったときにアンロードされます。

ユーザー アカウントとしてサービスを実行していることが原因と考えられます。 LocalService または NetworkService アカウントでサービスを構成してみてください。

詳細な情報は、http://go.microsoft.com/fwlink/events.asp の [ヘルプとサポート センター] を参照してください。
Windows XP を起動して終了しただけではこの警告は記録されないが、起動した後でタスクバーの電源アイコンをダブルクリックし、開いたダイアログを閉じてから OS を終了すると、この警告が表示される。(最初に気付いたときは、たまたま XKeymacs のプロパティダイアログを触った後で表示されたので、 XKeymacs のバグかと疑ったのだが、XKeymacs を起動しなくても前述の手順で警告が表示された。) プロファイルのアンロードに関する問題のトラブルシューティングには
原因
ログオフ時に、Microsoft Windows またはプリンタ ドライバやウイルス スキャナなどのサードパーティ製プログラムが、リソースを停止して開放しない場合に、この問題が発生することがあります。

解決方法
この問題を解決するには、Microsoft User Profile Hive Cleanup Service (UPHClean) を使用します。 UPHClean は、Windows がユーザー プロファイルをアンロードしているときに、コンピュータを監視し、開いているリソースを強制的に閉じます。 このため、コンピュータはユーザー プロファイルをアンロードして整合性をとることができます。

UPHClean をダウンロードしてインストールするには、次のマイクロソフト Web サイトを参照してください。
http://www.microsoft.com/downloads/details.aspx?FamilyId=1B286E6D-8912-4E18-B570-42470E2F3582

詳細
UPHClean の詳細については、Readme.txt ファイルを参照してください。このファイルをダウンロードするには、次のマイクロソフト Web サイトを参照してください。
http://www.microsoft.com/downloads/details.aspx?FamilyId=1B286E6D-8912-4E18-B570-42470E2F3582
と書かれている。これでも解決できるかもしれないけど、これは違うと思う。なんというか、傷口にバンソーコーを貼り付けるような策で、本質を直していない。 各プログラムがリソースを開放するように変更するべき。また、この解決策が Windows Update において提供されていないところも、使用を躊躇わせる。 XKeymacs の問題かと思い、いろいろ調べてみたものの、どうやら Windows XP の問題で、かつ、然程被害はないので、ダチョウアルゴリズムを適用することに。

cf. Troubleshooting profile unload issues

Windows saved user ComputerName\UserName registry while an application or service was still using the registry during log off. The memory used by the user's registry has not been freed. The registry will be unloaded when it is no longer in use. This is caused by services running as a user account, try configuring the services to run in either the LocalService or NetworkService account.

Microsoft Word で文書を保存しようとすると「ディスクがいっぱいです。」と言われ保存できない

Word で文書を保存しようとすると、ディスクの空き容量は十分にあるにもかかわらず、次のエラーに遭遇することがある。

ディスクがいっぱいです。空き容量を増やすか、
文書を他のドライブに保存してください
このエラーが出ると、他のドライブにも保存できなくなる。Microsoft に依ると
> 文書を閉じるまでの間に保存した回数を数え、20 回程度保存したところで一度文書を閉じることにより、エラーを回避させることができます。
だそうだ。下記のリンクは Apple の Macintosh 用の Word に関する文書だが、Windows 上でも同様のエラーに遭遇することがある。回避方法も同様である。

参考文献
[WD2001] 文書保存時に「ディスクがいっぱいです。」エラーが表示される

液晶ディスプレイの焼き付き

長年使っている液晶ディスプレイ (ADTEC AD-AT17X) に、気付くと焼き付きが発生していた。4 隅周辺に黒っぽくなっている部分がある。液晶に焼き付けは起きないと固く信じていたし、光の具合かと自己暗示をかけていたのだが、どうやら気のせいではなさそう。スクリーンセーバーを使わず、真っ黒を表示させていたのが原因か。改めて、Google でいろいろ調べてみたところ、CRT に限らず LCD でも焼き付きは起きるらしい。幸い CRT と違い、液晶では直るようなので、遅ればせながらスクリーンセーバー (3D パイプ) を走らせて 1 年ほど放っておいたところ、いつのまにか焼き付きが消えた。半年程度では症状が改善した形跡は見られなかった。いつごろ直ったかは不明だが、実際に直ることを体験。

ちなみにメーカのサイトに載っている今回の件に関連しそうな記述は下記くらい。
よくある質問と回答 : 株式会社アドテック
---
Q. 画面の四隅が黒くなります。どのようにすれば回避できますか。
A. コントロールパネル内にある画面の設定をダブルクリック、設定タブをクリックして 15インチなら1024×768、17インチなら1280×1024に再設定を行います。
---
実際やってみるも、当然ながら全く変わらず。これは焼き付きの話ではなく、不必要に低い解像度を選んだときに上下左右が黒い額縁みたいになったときの対応。

Windows 2000 における EPSON PM-600C の利用方法

EPSON の PM-600C というインクジェット式のプリンタには Windows 2000 用のドライバは用意されてない。が、PM-670C には Windows 2000/XP 用のドライバが存在する。Windows 2000 Professional にこのドライバをインストールし、PM-600C を繋げて印刷してみたところ、問題なく印刷できることが判明。もちろん無保証ですが、FYI ということで。

NT のセットアップディスクの作り方

NT の CD の i386 ディレクトリにある winnt32.exe を用いて、コマンドプロンプトで次のコマンドを実行。
X:\> winnt32 /ox

参考文献
Windowsの修復と対策 (InternetとWindowsの最新技術をやさしく)

wucrtupd.exe

Microsoft Windows Critical Update Notification がインストールされてると、デフォルトでは 5 分おきに更新されたデータがないか探しに行く。その度にマウスカーソルは砂時計になる。コントロールパネルの「アプリケーションの追加と削除」からアンインストールすれば、この現象は起きなくなる。また、更新を探しにいく間隔を変更することもできる。詳細は参考文献参照。

参考文献
PC Japan 2000年10月号 - 特集1:最後のWindows98裏マニュアル WindowsMe対応編 「Windows重要な更新の通知」の自動ダイヤルアップを停止する

SourceForge のアクセス方法

shell のアクセス:
X:\>ssh -l USERNAME shell.sourceforge.net
ex.
X:\>ssh -l xkeymacs shell.sourceforge.net

ファイルのアップロード
X:\>scp SOURCE_PATH DESTINATION_PATH
ex.
X:\>scp xkeymacs100.zip xkeymacssrc100.zip xkeymacs100.msi xkeymacsins100.zip xkeymacs@shell.sourceforge.net:/home/groups/x/xk/xkeymacs/htdocs/archive

※ Windows 上で cygwin の scp/ssh を利用するには、openssh を明示的に選択する必要がある。(Default ではインストールされない)

SourceForge の ML にメールを送れない

SourceForge の ML にメールを送ろうとすると、以下のようなエラーメールが帰ってくることがある。これは ISP (下記の例では Panasonic Hi-HO) が postmaster というアドレスを用意していないことが原因である。RFC では、postmaster 常に用意する (か 554 を返す) ことになっているのだが、RFC に準拠していないためにはじかれている。Panasonic Hi-HO には電話で postmaster@cam.hi-ho.ne.jp を用意してもらえるよう交渉したのだが、「いままで長い間、そのようなアドレスは用意しなくても問題なかった。そのようなアドレスを新たに作成すると、現在公開している問い合わせ用のアドレスに加え postmaster@cam.hi-ho.ne.jp に来たメールにも対応する必要が出てきて対応のパスが面倒になる。」という理由で、対応してもらうことはできなかった。SourceForge の ML にメールを出すためには、postmaster のアドレスが用意された ISP のメールアドレスを用いてメールを送信する必要がある。

Subject
Delivery Notification: Delivery has failed
Body
This report relates to a message you sent with the following header fields:
(snip)
Your message cannot be delivered to the following recipients:

Recipient address: foo@lists.sourceforge.net
Reason: Remote SMTP server has rejected address
Diagnostic code: smtp;550-Postmaster verification failed while checking <oishi@cam.hi-ho.ne.jp> Called: xxx.xxx.xxx.xxx Sent: RCPT TO:<postmaster@cam.hi-ho.ne.jp> Response: 550 User unknown Several RFCs state that you are re
Remote system: dns;mail.sourceforge.net (snip)
m/delivery-status
Reporting-MTA: dns;smaster5.hi-ho.ne.jp (tcp-daemon)

Original-recipient: rfc822;foo@lists.sourceforge.net
Final-recipient: rfc822;foo@lists.sourceforge.net
Action: failed
Status: 5.0.0 (Remote SMTP server has rejected address)
(snip)

参考文献
http--www.ietf.org-rfc-rfc0822.txtnumber=822 RFC # 822 STANDARD FOR THE FORMAT OF ARPA INTERNET TEXT MESSAGES
http--www.ietf.org-rfc-rfc2821.txtnumber=2821 Request for Comments: 2821 Simple Mail Transfer Protocol
http--www.ietf.org-rfc-rfc2822.txtnumber=2822 Request for Comments: 2822 Internet Message Format

iTunes の移行方法

古いマシンから新しいマシンに iTunes を移行する方法

  1. 新しいマシンに iTunes をインストールする。
  2. "マイ ドキュメント"\"マイ ミュージック"\iTunes i.e. %USERPROFILE%\My Documents\My Music\iTunes e.c. C:\Documents and Settings\<user_name>\My Documents\My Music\iTunes をコピーする。
  3. もし、曲をほかの場所に保存しているときは、そのデータもコピーする。

参考文献
アップル - サポート - TIL

「更新用に選択されたすべてのプレイリストが存在しないため、iPod [iPod] の曲を更新できません。」

iPod をパソコンに接続しても、次のようなエラーメッセージが表示され、更新が行なわれないことがある。

更新用に選択されたすべてのプレイリストが存在しないため、iPod [iPod] の曲を更新できません。
ソースリストに表示された iPod を右クリックし、[iPod オプション] を選択し、 ミュージックタブで [選択したプレイリストのみ自動的に更新] ラジオボタンが選択されているようであれば、 [すべての曲とプレイリストを自動的に更新] ラジオボタンを選択し OK ボタンを押すと、全ての曲が更新されるようになる。
音楽ライブラリの数が多すぎてすべての曲を iPod に入れることができない場合、iPod セレクション (だったかしら?) というプレイリストが作成され そのプレイリストに登録された曲だけが iPod に更新されるようになる。 その後ライブラリの曲を減らし、勝手にそのプレイリストを削除したところ、このエラーに遭遇した。

エクスプローラにステータスバーを表示する方法

Microsoft Windows XP Service Pack 2 (SP2) をインストールした後、エクスプローラウィンドウにステータスバーが表示されなくなる。[表示] メニューの [ステータスバー] をチェックすれば再び表示されるようになる。

参考文献
Windows XP Service Pack 2 のインストール後、エクスプローラのステータス バーが表示されない

Windows XP がインストールされたマシンに Windows 2000 をインストールする方法

Windows XP と Windows 2000 をデュアルブートさせる場合、Windows XP がインストールされたマシンに Windows 2000 をインストールする時は下記の操作が必要となる。

  1. XP の %SYSTEMDRIVE% (普通は C:) にある bootfont.bin、NTDETECT.COM、ntldr をバックアップする
  2. Windows 2000 を XP とは別のドライブにインストールする
  3. ステップ 1 でバックアップした 3 つのファイルを元の場所に戻す

参考文献
Windows.FAQ - Windows デュアルブートの基礎知識


Microsoft Visual C++ 6.0

String Table の文字列リソース使用方法

I18N のため、文字列リソースは直接ソースコードに埋め込むのではなく String Table に登録し利用することが推奨されている。ここでは、既存の関数 void foo(LPCTSTR szFoo) へ String Table の文字列を渡す方法について考える。String Table の文字列リソースを利用するために LoadString という API が用意されており、次のように利用できる。

        CString szFoo;
        szFoo.LoadString(IDS_FOO);
        foo(szFoo);
この書き方は誤りではないが、CString には CString(LPCSTR lpsz) というコンストラクタが存在するので、
        CString szFoo(MAKEINTRESOURCE(IDS_FOO));
        foo(szFoo);
という書き方をした方がスマートである。さらに、明示的にコンストラクタを呼びだすことで、
        foo(CString(MAKEINTRESOURCE(IDS_FOO));
と書くこともできる。MSDN の「明示的に呼び出されたコンストラクタ」には、
ある型のオブジェクトを作成するために、プログラムでコンストラクタを明示的に呼び出すことができます。
(snip)
コンストラクタを明示的に呼び出して作成したオブジェクトは無名であり、これを作成した式の中だけに存在します。
とある。この例では、String Table から読み込んだ文字列を持つオブジェクトの寿命は短いに如くは無いので、意味的には一番最後の書き方が最適であると言える。

キーワード: ストリングテーブル、文字列リソース、コンストラクタ、無名オブジェクト、一時オブジェクト
Keywords: String Table, String Resource, Constructor, Anonymous Object, Temporary Object

※ I18N: Internationalization の略。最初の I から最後の n までの間に 18 文字アルファベットがあることから I18N と略す。国際化。

既存のアプリケーションへのダイアログの追加

  1. リソースでダイアログ作成
  2. クラスを作成し、1. で作ったダイアログに対応づける

1 と 2 の順が逆だと寂しい思いをする。

拡張 DLL におけるクラスのエクスポート

拡張 DLL のクラスを実行ファイルにエクスポートするには、AFX_EXT_CLASS を用い、次のようにクラスを定義する必要がある。

class AFX_EXT_CLASS CFoo
{
    // ...
};

参考文献
MFC ライブラリ リファレンス テクニカル ノート 33: MFC の DLL バージョン

exe, dll 間におけるデータの共有方法

static なメンバ変数を定義する際、下記のように #pragma data_seg("foo") で囲ってやれば、複数のプロセスで変数を共有できる。

#pragma data_seg("foo")
int class_name::m_foo = 0;
#pragma data_seg()

値を初期化しないと変数は共有されない。static なメンバ変数ではなくグローバル変数であっても同様の手順で共有できる。以下の方法を用いれば、未初期化データを共有することもできる。

__declspec(allocate("foo")) int bar;

上述の方法でデータを共有するためには、.DEF ファイルに下記の記述を追加する必要がある。

SECTIONS
	foo	READ WRITE SHARED

この方法は便利で有用だが、Adevanced Windows によると Microsoft は以下の 2 つの理由により、この方法を推奨していない。

  1. この方法でメモリを共有すると、セキュリティを危険にさらす可能性がある。
  2. 変数を共有すると、でたらめな書き込みをするアプリケーションからデータを保護する方法がないので、1 つのアプリケーションのエラーが別のアプリケーションに影響を与えることがある。

データを共有する手段として、この方法の他に、メモリマップトファイルを使う方法がある。

参考文献
Advanced Windows 17.1.2 .exe、DLL の複数のインスタンスの間での静的データの共有
DLL 内のデータをアプリケーションまたはほかの DLL と共有する方法
DLL の別のマッピングの間の操作方法共有データ
DLL のすべてのデータを共有する方法。

ショートカットメニューを表示するタイミング

ショートカットメニュー (マウスで右クリックしたときに表示されるメニュー。ポップアップメニューと呼ばれることもある) は、マウスの右ボタンが離されたときに表示されることになっている。これはデスクトップでも、メモ帳でも、タスクバーのステータス領域にあるサウンドのアイコンでも同様である。Windowsユーザーインターフェイスデザインガイドでも、次のようにガイドされている。

7.1.4 ポップアップメニューの操作
  マウスを使ってポップアップメニューを表示するには、オブジェクトをボタン 2 でクリックする。マウスボタンを押し下げることによって、オブジェクトが選択される。ボタンを離すと、ポインタのホットスポットの右下にメニューが表示されるが、メニューが画面の外にはみ出してしまう場合には表示位置が調節される。 (後略)
# この本ではマウスの右ボタンを [ボタン 2] と呼んでいる。これはマウスを "左きき用" に設定したときに、「右ボタンが左ボタンになる」からである。

注. タスクバーのステータス領域にある IME 関係のアイコンだけは、なぜかマウスの右ボタンが押されたときにショートカットメニューが表示される。

参考文献
Windowsユーザーインターフェイスデザインガイド
Visual C++-MFC Frequently Asked Questions "How do I implement a right-mouse pop-up menu?"

エクスプローラ終了時におけるタスクバーのアイコン再登録方法

エクスプローラがなんらかの事情で終了・再起動すると、常駐型アプリケーション等が表示しているタスクバーのステータス領域に登録されたアイコンは消える。これを防ぐためには、アプリケーション側で、次のコードを実装する必要がある。

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
    static UINT s_uTaskbarRestart;

    switch(uMessage) {
    case WM_CREATE:
        s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
        break;
    default:
        if(uMessage == s_uTaskbarRestart) {
            AddTaskbarIcons();
        }
        break;
    }

    return DefWindowProc(hWnd, uMessage, wParam, lParam);
}

参考文献
The Taskbar

API の使用可能判定方法

VerifyVersionInfo や SendInput の例を挙げるまでもなく、特定の Windows (例えば Windows 2000 以降など) でしか利用できない API も少なくない。それらの API を利用する場合、GetVersionEx を利用して現在動作しているオペレーティングシステムのバージョンを取得し、利用したい API の要求を満たしていることを確認することは良い方法ではない。なぜならば DLL の更新により、API の要求を満たしていないバージョンの Windows でもその API が利用できるようになっている可能性があるからである。

API が使用できるか確認するためには次の手順を用いるべきである。

  1. LoadLibrary で、その API を含む DLL をロードする。
  2. GetProcAddress で、その DLL が持つ API のアドレスを取得する。

この方法で API のアドレスが取得できれば、その API は利用できる。

唯一、気を付けるべき点は GetProcAddress で指定する API 名が、必ずしもコード中で利用する名前と一致しないことである。これは、SDK のヘッダーファイル内で使われるマクロが原因である。GetProcAddress で指定すべき名前は、その API が定義されているヘッダーファイルを参照することで得られる。

以下に簡単なサンプルコードを載せる。

BOOL IsVerifyVersionInfoPresent()
{
        FARPROC procAddress = NULL;
        HMODULE hModule = LoadLibrary("kernel32.dll");
        if (hModule) {
#ifdef UNICODE
                procAddress = GetProcAddress(hModule, "VerifyVersionInfoW");
#else
                procAddress = GetProcAddress(hModule, "VerifyVersionInfoA");
#endif // !UNICODE
        }
        return procAddress != NULL;
}

参考文献
[Platform SDK: Windows System Information] Operating System Version

プロファイルの実行方法

  1. VC++ のプロジェクトメニューの設定を開き、リンクタブを選択
  2. E を押して、プロジェクトオプションに /profile を追加
    # 日本語版の VC++ では、check box は利用できない
  3. リビルド
  4. ビルドメニューのプロファイルを選択

参考文献
[プロジェクトの設定] ダイアログで [プロファイルを行う] が選択できない−VC++−水無瀬の部屋

プロファイルを実行時のエラー「PREP : fatal error PRF1011」の対処方法

SDK and/or DDK をインストールしていると、SDK や DDK の profile.exe が呼ばれて、アウトプットウィンドウに次のエラーが出ることがある。
PREP : fatal error PRF1011: X:\<project_directory>\debug\<project_name>.pbo を開けません
VC++ において、profile.exe を絶対パスで指定できるかどうかは不明だが、SDK や DDK の profile.exe の名前を変更することで問題を回避できることは確認。

CWnd::MessageBox と AfxMessageBox と ::MessageBox と ::MessageBoxEx と ::MessageBoxIndirect と

CWnd::MessageBox の解説では AfxMessageBox の使用を推奨。::MessageBox は AfxMessageBox よりも細かい指定、もとい Window Text の書き換えができる。::MessageBoxEx では ::MessageBox に加え、言語識別子を指定できる。::MessageBoxIndirect では、アイコンも任意のものが使用できる。というわけで、一般的には AfxMessageBox を用い、必要に応じて SDK の API を利用することが期待されているように思われる。MFC を用いずに SDK で開発してるときは、当然ながら、CWnd::MessageBox, AfxMessageBox は利用できない。

GetKeyState (GetKeyboardState) と GetAsyncKeyState の違い

要約
GetKeyState と GetAsyncKeyState には下記のような違いがある。基本的には GetKeyState を使用する。SetKeyboardState で変更した状態を参照する必要があるときには GetKeyState を使用しなければならない。逆に GetAsyncKeyState を使うことで SetKeyboardState で行った変更を無視することはできるが、これはあまり良い実装とは思えない。keybd_event を利用する場合も、一般的なアプリケーションであれば基本的に GetKeyState を使用すれば問題ない。WH_KEYBOARD を用いてキーボードをフックしている Dll の中で keybd_event により変更された状態を参照する場合には GetAsyncKeyState を使用しなければならない。
各関数の定義
GetAsyncKeyState は現在の、もとい、この関数が呼ばれた時点でのキーの状態を、GetKeyState はこの関数が呼ばれる直前にスレッドがメッセージキューからキーメッセージを読み出したときのキーの状態を取得する。つまり GetKeyState で取得した情報は必ずしも現在の状態と一致しない。GetKeyboardState は、本質的には GetKeyState と同じである。
キーボード ユーザー インターフェイス設計のガイドライン
Microsoft の「キーボード ユーザー インターフェイス設計のガイドライン」では、次のように記述されている。

キーのステータスの取得

キーまたはマウス ボタンのステータスを取得する場合、やむを得ない場合以外は GetAsyncKeyState 関数の使用は避けてください。GetAsyncKeyState はハードウェアに対するクエリを実行し、物理キーまたはボタンのステータスを特定しますが、プログラムによって押されたキーやユーザー補助ツールによってシミュレートされたキーは無視します。
可能な場合は、シミュレートされた入力も正しく反映する GetKeyState 関数を使用します。ただし、ユーザーが長過ぎる処理タスクを中断するためにキー入力を行った場合などの特定の条件下では GetAsyncKeyState を使用することも可能です。
マウスのドラッグ操作を処理するとき、マウス ボタンの解放を検知するために GetAsyncKeyState 関数を使用することは避けてください。代わりに、SetCapture 関数を使用してボタンアップのメッセージを待ちます。
GetAsyncKeyState 関数を使用すると、他の Windows 関数とメッセージを使用した場合とは異なる結果になる可能性があります。そうなると、アプリケーションの動作がシステム上の他のソフトウェアと不整合を起こす原因になります。
※ここで述べられている "プログラムによって押されたキーやユーザー補助ツールによってシミュレートされたキー" とは SetKeyboardState で状態が変更されたキーのことだと思う。keybd_event などで押されたキーは GetAsyncKeyState でも無視されることはない。
SetKeyboardState が及ぼす影響
SetKeyboardState を使うと、GetKeyState (や GetKeyboardState) がアクセスするスレッドのキーボード入力状態テーブルを書き変えることができる。この関数はGetAsyncKeyState の結果には何の影響も及ぼさない。SetKeyboardState はテーブルを書き変えるだけで、キーストロークを合成、もとい、WM_KEYUP または WM_KEYDOWN メッセージを生成するわけではない。そのため、積極的に GetKeyState を用いてテーブルを参照しに行かない限りテーブルが書き変えられた事にアプリケーションは気付かないので、SetKeyboardState が有用な機会は限られている。

簡単なサンプルコードとその実行結果を下に示す。このサンプルは、2 度 Ctrl の状態 (BYTE) の最上位ビットを反転させ、そのそれぞれの前後で GetKeyState と GetAsyncKeyState が返す値を表示する。 実行結果を見ると、アプリケーション実行時に Ctrl キーが押されているかどうかによらず SetKeyboardState で行った設定に伴い GetKeyState の返り値は変わり、また GetAsyncKeyState の返り値は SetKeyboardState の影響を受けていないことが分かる。

#include <stdio.h>
#include <windows.h>

int main() {
        static const int VIRT_KEY = VK_CONTROL;
        BYTE keyState[256] = {'0'};

        printf("\t\t\tGetKeyState(%#x)\tGetAsyncKeyState(%#x)\n", VIRT_KEY, VIRT_KEY);
        printf("inital status:\t\t%#010x\t\t%#010x\n", GetKeyState(VIRT_KEY), GetAsyncKeyState(VIRT_KEY));

        GetKeyboardState(keyState);
        keyState[VIRT_KEY] ^= 0x80;
        SetKeyboardState(keyState);
        printf("SetKeyboardState:\t%#010x\t\t%#010x\n", GetKeyState(VIRT_KEY), GetAsyncKeyState(VIRT_KEY));

        GetKeyboardState(keyState);
        keyState[VIRT_KEY] ^= 0x80;
        SetKeyboardState(keyState);
        printf("ResetKeyboardState:\t%#010x\t\t%#010x\n", GetKeyState(VIRT_KEY), GetAsyncKeyState(VIRT_KEY));

        return 0;
}
--- 実行時に Ctrl が押されていなかったときの実行結果 ---
                        GetKeyState(0x11)       GetAsyncKeyState(0x11)
inital status:          0000000000              0000000000
SetKeyboardState:       0xffffff80              0000000000
ResetKeyboardState:     0000000000              0000000000
--- 実行時に Ctrl が押されていたときの実行結果 ---
                        GetKeyState(0x11)       GetAsyncKeyState(0x11)
inital status:          0xffffff80              0xffff8000
SetKeyboardState:       0000000000              0xffff8000
ResetKeyboardState:     0xffffff80              0xffff8000
---
keybd_event が及ぼす影響
keybd_event (や SendInput) を使うと、キーストロークを合成、もとい、WM_KEYUP または WM_KEYDOWN メッセージを生成することができる。アプリケーションの中で keybd_event を実行すると、GetKeyState と GetAsyncKeyState の結果が変わる。一方 WH_KEYBOARD (KeyboardProc) を用いてキーボードをフックしている Dll の中で keybd_event を実行すると、GetAsyncKeyState の結果は変化するが、GetKeyState の結果は変化しない。

アプリケーションにおける簡単なサンプルコードとその実行結果を下に示す。 このアプリケーションは keybd_event で CTLR キーを押したり離したりするたびに GetKeyState と GetAsyncKeyState が返す値を表示する。 実行結果を見ると、アプリケーション実行時に Ctrl キーが押されているかどうかによらず、GetKeyState と GetAsyncKeyState が返す値 (SHORT) の最上位ビット、もとい、キーが押されているかどうかという状態は一致していることが分かる。

#include <stdio.h>
#include <windows.h>

int main() {
        static const int VIRT_KEY = VK_CONTROL;

        printf("\t\tGetKeyState(%#x)\tGetAsyncKeyState(%#x)\n", VIRT_KEY, VIRT_KEY);
        printf("inital status:\t%#010x\t\t%#010x\n", GetKeyState(VIRT_KEY), GetAsyncKeyState(VIRT_KEY));

        keybd_event(VIRT_KEY, 0, 0, GetMessageExtraInfo());
        printf("depress CTRL:\t%#010x\t\t%#010x\n", GetKeyState(VIRT_KEY), GetAsyncKeyState(VIRT_KEY));

        keybd_event(VIRT_KEY, 0, KEYEVENTF_KEYUP, GetMessageExtraInfo());
        printf("release CTRL:\t%#010x\t\t%#010x\n", GetKeyState(VIRT_KEY), GetAsyncKeyState(VIRT_KEY));

        keybd_event(VIRT_KEY, 0, 0, GetMessageExtraInfo());
        printf("depress CTRL:\t%#010x\t\t%#010x\n", GetKeyState(VIRT_KEY), GetAsyncKeyState(VIRT_KEY));

        keybd_event(VIRT_KEY, 0, KEYEVENTF_KEYUP, GetMessageExtraInfo());
        printf("release CTRL:\t%#010x\t\t%#010x\n", GetKeyState(VIRT_KEY), GetAsyncKeyState(VIRT_KEY));

        return 0;
}
--- 実行時に Ctrl が押されていなかったときの実行結果 ---
                GetKeyState(0x11)       GetAsyncKeyState(0x11)
inital status:  0000000000              0000000000
depress Ctrl:   0xffffff81              0xffff8001
release Ctrl:   0x00000001              0000000000
depress Ctrl:   0xffffff80              0xffff8001
release Ctrl:   0000000000              0000000000
--- 実行時に Ctrl が押されていたときの実行結果 ---
                GetKeyState(0x11)       GetAsyncKeyState(0x11)
inital status:  0xffffff81              0xffff8000
depress Ctrl:   0xffffff81              0xffff8001
release Ctrl:   0x00000001              0000000000
depress Ctrl:   0xffffff80              0xffff8001
release Ctrl:   0000000000              0000000000
---

次に WH_KEYBOARD を用いてキーボードをフックしている Dll の中で keybd_event を実行したときの状態遷移の一例を下に示す。 これは keybd_event で種々のキー (bVk) を押したり離したりした直前直後に GetKeyState と GetAsyncKeyState が返した値を表示させた結果である。 実行時、Alt と Shift が物理的に押されていた。 keybd_event により GetAsyncKeyState が返す値は変化しているが、GetKeyState は keybd_event によらずもともと押されていたキーの状態を返していることが分かる。

bVk   GetKeyState(bVk) GetAsyncKeyState(bVk)
0x11, 0000000000,      0000000000
// Depress Ctrl (0x11)
0x11, 0000000000,      0xffff8001
0x12, 0xffffff80,      0xffff8000
// Release Alt (0x12)
0x12, 0xffffff80,      0000000000
0x10, 0xffffff80,      0xffff8000
// Release Shift (0x10)
0x10, 0xffffff80,      0000000000
0x24, 0x00000001,      0000000000
// Depress Home (0x24)
0x24, 0x00000001,      0xffff8001
0x24, 0x00000001,      0xffff8000
// Release Home (0x24)
0x24, 0x00000001,      0000000000
0x10, 0xffffff80,      0000000000
// Depress Shift (0x10)
0x10, 0xffffff80,      0xffff8001
0x12, 0xffffff80,      0000000000
// Depress Alt (0x12)
0x12, 0xffffff80,      0xffff8001
0x11, 0000000000,      0xffff8000
// Release Ctrl (0x11)
0x11, 0000000000,      0000000000

この 2 つの結果は、アプリケーションでは keybd_event が呼ばれると直ちにスレッドがメッセージキューからキーメッセージを読み出すが、WH_KEYBOARD を用いてキーボードをフックしている Dll では keybd_event を呼んだスレッドがメッセージキューからキーメッセージを直ちに読み出すわけではないということを示している。

参考文献
Advanced Windows 第 27 章 ハードウェア入力モデルとローカル入力状態 27.2.1 キーボード入力とフォーカス

keybd_event における、仮想キーコード、及び、ハードウェアスキャンコードの指定方法

第 3 引数に KEYEVENTF_SCANCODE、もとい、0x8 を指定しない
第 1 引数に指定した仮想キーコードが利用され、第 2 引数は無視される。
第 3 引数に KEYEVENTF_SCANCODE、もとい、0x8 を指定する
第 1 引数は無視され、第 2 引数に指定したハードウェアスキャンコードが利用される。

上述の事実は、あくまで、Microsoft Visual C++ 6.0、及び、Microsoft Visual C++ .NET 2003 で利用される keybd_event がそのように実装されているというだけである。MSDN には上記の事実に該当する記述は存在しない。また、上述の振舞いが今後も利用できる保証もない。

MSDN に依ると、keybd_event の第 3 引数は次の 2 つのフラグ KEYEVENTF_EXTENDEDKEY と KEYEVENTF_KEYUP を組み合わせて指定するとしか書かれていない。また、第 2 引数は「このパラメータは未使用です。」と解説されている。
MSDN の keybd_event のサンプルコードにおいて、第 2 引数に適当な値が用いられていることは不可解ではあるが、未使用の引数に任意の値をセットすることは、論理的には間違いではない。

KEYEVENTF_SCANCODE は MSDN の KEYBDINPUT のところで触れられている。
KEYEVENTF_* は Winuser.h において次のように定義されている。
--- VC++ 6.0 の Winuser.h ---
#define KEYEVENTF_EXTENDEDKEY 0x0001
#define KEYEVENTF_KEYUP 0x0002
---
--- VC++ .NET 2003 の Windows.h ---
#define KEYEVENTF_EXTENDEDKEY 0x0001
#define KEYEVENTF_KEYUP 0x0002
#if(_WIN32_WINNT >= 0x0500)
#define KEYEVENTF_UNICODE 0x0004
#define KEYEVENTF_SCANCODE 0x0008
#endif /* _WIN32_WINNT >= 0x0500 */
---
※ 2001 年 10 月版の MSDN、つまり VC++ 6.0 用の最後の MSDN でも KEYEVENTF_SCANCODE について触れられているが、VC++ 6.0 の Winuser.h では KEYEVENTF_SCANCODE は宣言されてない。

最後に私が上述の事実を確認するために用いたコードを掲載しておく。
--- 仮想キーコードを利用するコード ---

#include <windows.h>
main()
{
        keybd_event(VK_NUMLOCK, 0, 0, 0);
        keybd_event(VK_NUMLOCK, 0, KEYEVENTF_KEYUP, 0);
        return 0;
}

---
--- ハードウェアスキャンコードを利用するコード ---

#define KEYEVENTF_SCANCODE 0x0008 // for VC++ 6.0
#include <windows.h>
main()
{
        keybd_event(0, 0x45, KEYEVENTF_SCANCODE, 0);
        keybd_event(0, 0x45, KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP, 0);
        // 0x45 は NumLock のハードウェアスキャンコード
        return 0;
}

---
Microsoft Visual C++ 6.0 と Microsoft Visual C++ .NET 2003 でコンパイルしてみたが、いずれの環境においても挙動に差異は見られず、双方とも実行する毎に NumLock が ON/OFF されることを確認できた。
※ ただし、ハードウェアスキャンコードを利用するコードの方は IDE 上から Ctrl+F5 で実行すると必ずしも期待通りに動かない (正確にはコードを変更しビルドした直後は期待通りに動くが、その後 Ctrl+F5 しても NumLock が ON/OFF されない?!) という現象に遭遇した。生成された実行ファイルを直接起動した場合は、問題なく動いた。

以下余談ながら、誰もが keybd_event のサンプルプログラムで NumLock キーを利用したがるのは、テストプログラムが終了した後でもキーボードの LED を眺めることで keybd_event の効果を確認できるからに他ならない。

KEYBDINPUT 及び keybd_event における KEYEVENTF_EXTENDEDKEY の持つ意味

拡張キー (Extended-Key) を利用する際、KEYEVENTF_EXTENDEDKEY を指定する必要がある。具体的には、下記のキーが拡張キーにあたる。

これらのキーが拡張キーと呼ばれるのは、昔のキーボードにはこれらのキーがなかったからである。

参考文献
About Keyboard Input
キーボードコレクション

Windows が何語版かの見分け方

まれに、アプリケーションの動作を、Windows が何語版かによって変えたくなることがある。だが Windows が何語版かを取得する API は私の知る限り存在しない。しかし、explorer.exe の言語を参照することで、Windows が何語版か類推することはできる。explorer.exe が何語版かは VerQueryValue() で取得・判別できる。サンプルコードを下に示す。

--- ソースコード ---
#include <stdio.h>
#include <windows.h>

int main()
{
    char lptstrFilename[MAX_PATH] = {'\0'};
    _makepath(lptstrFilename, NULL, getenv("windir"), "explorer", "exe");
    DWORD dwLen = GetFileVersionInfoSize(lptstrFilename, NULL);

    if (dwLen) {
        LPVOID lpData = malloc(dwLen);

        if (lpData && GetFileVersionInfo(lptstrFilename, NULL, dwLen, lpData)) {
            struct Translate {
                WORD wLanguage;
                WORD wCodePage;
            } *lpTranslate;
            UINT cbTranslate = 0;

            if (VerQueryValue(lpData, "\\VarFileInfo\\Translation", (LPVOID*)&lpTranslate, &cbTranslate) && sizeof(Translate) <= cbTranslate) {
                printf("wLanguage = %#06x, wCodePage = %#06x\n", lpTranslate->wLanguage, lpTranslate->wCodePage);
            }
        }

        free(lpData);
    }

    return 0;
}
--- 実行結果例 ---
wLanguage = 0x0411, wCodePage = 0x04b0
---

ここで wLanguage が 0x0411 であることが、explorer.exe が、もとい、Windows が日本語版であることを示している。英語版では 0x0409 となる。その他の言語と数値の対応は、参考文献を参照して欲しい。

参考文献
Metabase Configuration Service Provider
Microsoft Office Assistance Creating international number formats

101 キーボードと 106 キーボードの見分け方

Windows 95, 98, Me では、System.ini の [keyboard] のところにある subtype の値で、
Windows NT, 2000, XP では、レジストリの
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters
にある
OverrideKeyboardSubtype
の値で判別できる。
subtype (OverrideKeyboardSubtype) とキーボードの間には、次の関係がある。

101 (104, 107) キーボード:
subtype & 0x02 == 0
106 (109, 112) キーボード:
subtype & 0x02 != 0

101 キーボード: IBM-PC/ATの標準キーボード。
104 キーボード: 101 + Left Windows key + Right Windows key + Application key
107 キーボード: 104 + ACPI Power key + ACPI Sleep key + ACPI Wake key
106, 109, 112 キーボード: 101, 104, 107 + ひらがな key + 変換 key + 無変換 key + \- key + \ろ key

IME のオン/オフ

IME を開いたり閉じたりするには、一般には ImmSetOpenStatus という API を利用する。この API が利用できないときは、keybd_event を利用して VK_KANJI キーを押すことで IME の状態を切り替えることができる。

enum INPUT_METHOD_OPEN_STATUS {CLOSE_INPUT_METHOD, OPEN_INPUT_METHOD, TOGGLE_INPUT_METHOD};
void SetInputMethodOpenStatus(INPUT_METHOD_OPEN_STATUS status)
{
    HKL hKL = GetKeyboardLayout(0);
    if (ImmIsIME(hKL)) {
        HWND hWnd = GetFocus();
        HIMC hIMC = ImmGetContext(hWnd);
        switch (status) {
        case CLOSE_INPUT_METHOD:
            ImmSetOpenStatus(hIMC, FALSE);
            break;
        case OPEN_INPUT_METHOD:
            ImmSetOpenStatus(hIMC, TRUE);
            break;
        case TOGGLE_INPUT_METHOD:
            ImmSetOpenStatus(hIMC, !ImmGetOpenStatus(hIMC));
            break;
        }
        ImmReleaseContext(hWnd, hIMC);
    } else {
        // always toggle input method
        keybd_event(VK_KANJI, 0, 0, 0);
        keybd_event(VK_KANJI, 0, KEYEVENTF_KEYUP, 0);
    }
}

IME のファイル名を取得

IME のファイル名を取得するには、ImmGetIMEFileName という API を利用する。

char m_szIMEName[0x100];
void GetIMEName()
{
    HKL hKL = GetKeyboardLayout(0);
    if (ImmIsIME(hKL)) {
        ImmGetIMEFileName(hKL, m_szIMEName, sizeof(m_szIMEName));
    }
}

注: 固定長文字列を用いてるのはコードの簡略化のためである。実際の実装時は最初にバッファ長を 0 に指定することでファイル名を受け取るために必要となるバッファサイズを取得し、その値をもとにメモリを確保しファイル名を所得すべきである。

IME で変換中かどうかの見分け方

IME で変換中かどうかを見分けるには、WM_IME_STARTCOMPOSITION 及び WM_IME_ENDCOMPOSITION に着目すれば良い。但し、CallWndProc と GetMsgProc の双方で、これらをチェックする必要がある。

コンソールなコマンドの実行方法、もとい、CreateProcess の単純な使用方法

たとえば dir を実行したければ、次のようにすれば良い。 実行することに意味 and/or 意義があるかは、また別の話。

#include <Windows.h>

main()
{
    STARTUPINFO si;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);

    PROCESS_INFORMATION pi;
    ZeroMemory(&pi, sizeof(pi));

    if (CreateProcess(NULL, "dir", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
        // WaitForSingleObject( pi.hProcess, INFINITE );

        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
    }
    return 0;
}

参考文献
Creating Processes

関連付けされているファイルタイプを用いたアプリケーションの起動方法

任意のファイルを "関連付け" されたアプリケーションで起動させるためには CreateProcess ではなく ShellExecute を利用する必要がある。 たとえば、foo.txt を、.txt に関連付けられたエディタで開きたいときは、次のようにすれば良い。

#include <windows.h>

int main()
{
    ShellExecute(NULL, NULL, "foo.txt", NULL, NULL, SW_SHOWNORMAL);
    return 0;
}

指定されたパス (ここではカレントディレクトリ) に foo.txt が存在しないときは、何も起こらない。

フックプロシージャが呼ばれる順番

SetWindowsHookEx を用いると、アプリケーション定義のフックプロシージャをフックチェーン内にインストールすることができる。 指定されたフックタイプがスレッドとグローバルの両方をサポートしている場合、最初にスレッドフックが呼び出され、次にグローバルフックが呼び出される。 複数のグローバルなフックプロシージャがフックチェーン内にインストールされている場合、後にインストールされたフックプロシージャから順に実行される。

参考文献
SetWindowsHookEx

For a specified hook type, thread hooks are called first, then global hooks.
About Hooks
The SetWindowsHookEx function always installs a hook procedure at the beginning of a hook chain.

デフォルト引数に利用できるもの、利用できないもの

デフォルト引数に利用できるもの
定数式
グローバル変数
グローバル関数
定数メンバ (ex. static const int)
静的メンバ (ex. static int)
静的メンバ関数
デフォルト引数に利用できないもの
static でないメンバ変数
static でないメンバ関数

デフォルト引数にメンバ変数、const メンバなど static でないメンバが利用できないのは、デフォルト引数が関数と静的に結合していることに起因する。関数がデフォルト引数と静的に結合するのは、実行効率から決められた C++ の仕様による。

参考文献
Effective C++ アスキーアジソンウェスレイシリーズ―Ascii Addison Wesley programming series 項目 38 継承した関数のデフォルト引数の値を変えてはいけない
デフォルト引数の式

文字定数の型

文字定数 ('A' とか '\n' とか '\0' とか……) の型は C++ では char だが C では int である。つまり sizeof('A') は C++ では sizeof(char) つまり 1 と等しいが、C では sizeof(int) と等しくなる。

参考文献
プログラミング言語C++第3版 B.2 C/C++ の互換性 B.2.1 "静かな"差異
C FAQ 8

メモリ管理 (静的メモリ、スタック、ヒープ)

C++ でメモリを使うための基本的な方法として、次の 3 つの方法があげられる。

静的メモリ: static memory
グローバル変数、クラスの static メンバ、関数内の static 変数が格納される。
スタック: stack (自動メモリ: automatic memory)
関数引数とローカル変数が格納される。
余談ながら、stack を使うことを明示するために auto というキーワードがある。auto は関数の中でのみ使える。
ヒープ: heap (動的メモリ、ダイナミックメモリ: dynamic memory、自由記憶領域: free store)
new と delete (malloc, calloc, realloc, free も) が利用する領域。

一般的なプロセスのメモリ空間には、次のような領域がある。

※ 大きな構造体や配列をローカル変数として利用しようとしたときなどにスタックのサイズを越える領域を確保してしまうと、越えた部分にアクセスしたときにスタックオーバーフロー (Stack Overflow) の例外が発生する。スタックのデフォルトの大きさは 1MB である。リンクするときに /STACK オプションを使うことで、スタックの大きさを変更することができる。
※ メモリマップトファイルはメモリマップドファイルと誤読 (?!) されることもある。(Microsoft のサイトでも双方の呼び名が混在している)

参考文献
プログラミング言語 C++ 第 3 版 C.9 メモリ管理
Advanced Windows 第 3 部 メモリ管理 第 16 章 スレッドのスタック
プログラミングMicrosoft Visual C++ 6.0 第 10 章 Win32 メモリ管理
プログラミング言語 C A8.1 記憶クラス指定子

VC++ (Microsoft Visual C++ 6.0) の表示フォント変更方法

ソースウィンドウなどでは、デフォルトで FixedSys の 14 ポイントのフォントが使われている。若者には (?!) 字が大き過ぎるが、下記の方法で変更できる。

  1. [ツール] メニューの [オプション] を選択し [オプション] ダイアログを開く
  2. [オプション] ダイアログの [書式] タブ (一番右端にある) を選択
  3. [書式] タブの [カテゴリ] リストから [ソースウィンドウ] を選択
  4. フォントを [MS ゴシック] に、サイズを [9] ポイントに変更
  5. [アウトプットウィンドウ] にも同様の変更を行う
  6. [オプション] ダイアログの [OK] ボタンを押す

VSS (Microsoft Visual SourceSafe) の表示フォント変更方法

VSS でファイルを比較する際、デフォルトでは Proportional Font で表示されるためタブやらなんやらがずれて醜くてしょうがない。 Fixed Font に変更するには、次のようにすれば良い。

  1. [ツール] メニューの [オプション] を選択
    -> [Visual SourceSafe オプション] ダイアログが開く
  2. [相違点] タブを選択
  3. [フォント] グループの [変更] ボタンを押す
    -> [フォント] ダイアログが開く
  4. フォント名 [MS ゴシック] を選択
  5. [フォント] ダイアログの OK ボタンを押す
  6. [Visual SourceSafe オプション] ダイアログの OK ボタンを押す

WinDiff の種類

%ProgramFiles%\Microsoft Visual Studio\Common\Tools\WINDIFF.EXE (of Visual Studio 6.0) と %ProgramFiles%\Microsoft SDK\Bin\WinDiff.Exe (Platform SDK February 2003) で中身が異なり、後者の方が使いやすい。ただし、この情報は Version に依存する可能性が高く、obsolete かも。

デジタル署名をする方法

アプリケーションにデジタル証明書を用いてデジタル署名を行うことができる。本来デジタル証明書は自分で作るものではないのだが、ここではテストのために自分で証明書を作成し、それを用いて署名してみた。

自作ルート証明書の作成
X:\>"%ProgramFiles%\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\makecert" -n CN=FooCA -sv fooCA.pvk -r fooCA.cer
Succeeded
自作証明書の作成
X:\>"%ProgramFiles%\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\makecert" -n "CN=Foo,O=Bar,C=JP" -sv foo.pvk -ic fooCA.cer -iv fooCA.pvk foo.cer
Succeeded
自作ソフトウェア発行者証明書の作成
X:\>"%ProgramFiles%\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\cert2spc" foo.cer fooCA.cer foo.spc
Succeeded
自作証明書を用いた Exe の署名
X:\>"%ProgramFiles%\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\signcode" -spc foo.spc -v foo.pvk -n Foo -i http://www.cam.hi-ho.ne.jp/oishi/ -$ individual foo.exe
Warning: This file is signed, but not timestamped.
Succeeded
X:\>"%ProgramFiles%\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\signcode" -x -t http://timestamp.verisign.com/scripts/timstamp.dll foo.exe
Succeeded

実は、これを行うことで、Windows XP 上でインターネットからダウンロードしたアプリケーションを実行しようとしたときに出てくる警告の内容が軽減されるのではないかと期待していたのだが、結果的に何も変わらなかった。まじめに証明書を取得・維持するには年間 10 万円程かかるようなので、個人的趣味としては現実的ではない。自作のソフトウェアにデジタル署名を行おうかとも考えていたのだが、自作の証明書を用いる分には手間の割にメリットがなさそうなのでひとまず棚上げに。

参考文献
コードサイニング証明書 - Authenticode対応Digital ID
デジタル証明書を作ろう
デジタル署名をしよう


Linux

X Window System で CapsLock を Ctrl に

  1. ~/.Xmodmap に次の記述を追加
    remove Control = Control_L
    keysym Caps_Lock = Control_L
    add Control = Control_L
  2. # xmodmap .Xmodmap

~/.bashrc に
xmodmap .Xmodmap
と書き加えておけば、X 起動時に自動的に反映される。(ディストリビューションによっては、書き加えなくとも反映される)

X Window System で Emacs の Keybind を利用

keyfake というソフトウェアを利用すると、X Window System 上で XKeymacs と似た機能を実現できる、らしい。(私は未確認。最近 X を利用する機会がないので……。)

Shift + Space による kinput2 起動の無効化

最近の Linux では、インストールしたままの状態で利用してると Shift+Space と押しただけで canna や wnn が (正確には kinput2 が) 起動する。私は SKK しか使わない (使えない?!) から kinput2 は不要。ちょっとプログラムを書いてるときに ") {" と打とうとしただけで kinput2 に起動されると迷惑なので Shift+Space による kinput2 の起動を無効にすることに。
Shift+Space で kinput2 が起動しないようにするには
/usr/lib/X11/app-defaults/Kinput2

*ConversionStartKeys: Shift<Key>space
をコメントアウトする、つまり、冒頭に ! を付ければ良い。
# 設定ファイルの場所は、当然システムに依存する (と思う)

CD-ROM のマウント

Mount
# mount -t iso9660 /dev/cdrom /mnt/cdrom
Unmount
# umount /mnt/cdrom

Windows の共有フォルダのマウント

ユーザ: foo
コンピュータ名: bar
のとき、
# mount -t smbfs -o username=foo //bar/share /mnt/bar
とすると bar で共有フォルダになってる share フォルダを /mnt/bar にマウントできる。

圧縮・解凍

$ tar cvf foo.tar ~/
ホームディレクトリを圧縮して foo.tar と名付ける
$ tar tvf archive.tar
archive.tar の内容を表示
$ tar xvf archive.tar
archive.tar を解凍
$ tar xzvf archive.tgz
$ tar -xZvf archive.taz
archive.tgz, archive.taz を解凍
tar で z または Z option が利用できないときは、gunzip で解凍する。
$ gunzip foo.tgz
$ gunzip foo.taz
.tgz: .tar.gz の省略形
.taz: .tar.Z の省略形
-c, --create
新しいアーカイブを作成する
-t, --list
アーカイブ内容の一覧を表示する
-x, --extract, --get
アーカイブからファイルを抽出する
-v, --verbose
処理したファイルの一覧を詳しく出力する
-f, --file [HOSTNAME:]F
F というアーカイブ・ファイルまたはデバイスを使う (デフォルトは /dev/rmt0)
-z, --gzip, --ungzip
アーカイブを gzip にフィルターする
-Z, --compress, --uncompress
アーカイブを compress にフィルターする

rpm

# rpm -ivh file_name
インストール
# rpm -Uvh file_name
アップデート
# rpm -e packge_name
アンインストール
# rpm -qa
インストール済みパッケージ一覧
# rpm -qi packge_name
パッケージ情報
# rpm -ql pkg_name
パッケージに含まれるファイルを表示

ディレクトリのコピー方法

$ cp -r SOURCE DEST

ディレクトリの削除方法

$ rm -r directory_name

Emacs で置換を実行するには

stringをすべてnewstringで置換:
M-x replace-string RET string RET newstring RET

参考文献
GNU Emacs Manual - Table of Contents

.emacs

凝りだすときりがない Emacs の設定だが、最低このくらい書いておけば (私は) ストレスなく使える。
--- ~/.emacs ---
(global-set-key "\C-h" 'backward-delete-char)
(setq next-line-add-newlines nil)
(display-time)
(setq-default tab-width 4 indent-tabs-mode nil)
(set-frame-height (selected-frame) 50)
---


著作権

著作権表示の必要性

日本やアメリカを始めとする多くの国では、著作権は著作物を作った時点で自動的に発生し保護されるため、著作権表示、もとい「(C) 2001-2003 oishi@cam.hi-ho.ne.jp」の様な表示は、一般的には必要ない。

参考文献
はじめての著作権講座 「外国の著作物の保護は?」(社団法人 著作権情報センター)

無断リンクは著作権侵害?!

無断リンクは、著作権侵害とはならない。逆にリンクに許可を求めるのは、法的には無効。

参考文献
マルチメディアと著作権 「無断でリンクを張ることは著作権侵害となるでしょうか。」(社団法人 著作権情報センター)


ルータ

IP フィルタ設定

ADSL を利用するために MegaBit Gear TE4000 (正確には MegaBit Gear TE4111C) という ADSL ルータタイプモデムを使用している。このルータは基本的に全てのポートが開いているので、下記の様に設定した。

---
IPフィルタ設定
No. 優先度 インタフェース  送信元IPアドレス 送信先アドレス プロトコル 送信元ポート 送信先ポート アクション
 1  1      接続先1から受信 0.0.0.0/0        Hi-HO(PPP取得) TCP        *            www          非通過 
 2  2      接続先1から受信 0.0.0.0/0        Hi-HO(PPP取得) TCP        *            20-21        非通過
 3  3      接続先1から受信 192.168.0.0/16   0.0.0.0/0      *          *            *            非通過
 4  4      接続先1へ送信   0.0.0.0/0        192.168.0.0/16 *          *            *            非通過
 5  5      接続先1から受信 0.0.0.0/0        0.0.0.0/0      *          *            137-139      非通過
 6  6      接続先1から受信 0.0.0.0/0        0.0.0.0/0      *          137-139      *            非通過
 7  7      接続先1から受信 0.0.0.0/0        0.0.0.0/0      *          *            445          非通過
 8  8      接続先1から受信 0.0.0.0/0        0.0.0.0/0      *          445          *            非通過
 9  9      LANから受信     0.0.0.0/0        0.0.0.0/0      *          *            137-139      非通過
10 10      LANから受信     0.0.0.0/0        0.0.0.0/0      *          137-139      *            非通過
11 11      LANから受信     0.0.0.0/0        0.0.0.0/0      *          *            445          非通過
12 12      LANから受信     0.0.0.0/0        0.0.0.0/0      *          445          *            非通過
13 13      接続先1から受信 x.x.x.x/x        Hi-HO(PPP取得) TCP-SYN    ftpdata      *            通過
(snip)
32 32      接続先1から受信 0.0.0.0/0        0.0.0.0/0      TCP-SYN    *            *            非通過
---

- 1. 2. はスタートアップマニュアルに上述の様にするようにという記述が。32 があれば 1. 2. はいらない気もするが、消すこともないので放ってある。
- 3. 4. は WAN からアドレスを偽装してアタックされたときのための対策。
- 5. 6. 9. 10. で NetBIOS を利用してファイル共有を WAN から利用されるのを禁止。
- 7. 8. 11. 12. でダイレクト・ホスティング SMB サービスを利用してファイル共有等を WAN から利用されるのを禁止。
- 13. は FTP クライアントが動けるように。送信元 IP アドレスは私が常用してる ftp 先のアドレスを決め打ち (伏せる必要があるのかどうかについては理解が追いついてないが、伏せたために私が被害を被ることがないことだけは理解してます :-) )。
- 32. で WAN から TCP でつつかれるのを防ぐ。
せいぜい、ブラウザとメーラと FTP クライアントくらいしか使ってないが、上述の設定で副作用はない模様。ひとまずは、これで良いのではないかと考えている。改善案等ご存知の方は御教示して頂ければ幸いである。

参考文献
TE4111C 取扱説明書 Ver eA-S1


(C) 2001-2006 oishi@cam.hi-ho.ne.jp