LoginSignup
4
6

プログラムを動かして理解するWindowメッセージ

Last updated at Posted at 2024-05-12

はじめに

ウィンドウメッセージについて理解するために、実際にプログラムを動かして確認してみました。なお、C言語やC言語を使用したWindowsプログラミングのことは詳しくないため、間違っている点があるかもしれません。

メッセージについて

Windowsアプリケーションはイベントドリブンであり、システムがメッセージを渡すのを待ちます。

ウィンドウメッセージ一覧

システム定義メッセージの表の一番下のWMの箇所

メッセージ識別子
0x0000 WM_NULL
0x0001 WM_CREATE
0x0002 WM_DESTROY
0x0003 WM_MOVE
0x0005 WM_SIZE
0x0006 WM_ACTIVATE
0x0007 WM_SETFOCUS
0x0008 WM_KILLFOCUS
0x000A WM_ENABLE
0x000B WM_SETREDRAW
0x000C WM_SETTEXT
0x000D WM_GETTEXT
0x000E WM_GETTEXTLENGTH
0x000F WM_PAINT
0x0010 WM_CLOSE
0x0011 WM_QUERYENDSESSION
0x0012 WM_QUIT
0x0013 WM_QUERYOPEN
0x0014 WM_ERASEBKGND
0x0015 WM_SYSCOLORCHANGE
0x0016 WM_ENDSESSION
0x0018 WM_SHOWWINDOW
0x001A WM_WININICHANGE
0x001B WM_DEVMODECHANGE
0x001C WM_ACTIVATEAPP
0x001D WM_FONTCHANGE
0x001E WM_TIMECHANGE
0x001F WM_CANCELMODE
0x0020 WM_SETCURSOR
0x0021 WM_MOUSEACTIVATE
0x0022 WM_CHILDACTIVATE
0x0023 WM_QUEUESYNC
0x0024 WM_GETMINMAXINFO
0x0026 WM_PAINTICON
0x0027 WM_ICONERASEBKGND
0x0028 WM_NEXTDLGCTL
0x002A WM_SPOOLERSTATUS
0x002B WM_DRAWITEM
0x002C WM_MEASUREITEM
0x002D WM_DELETEITEM
0x002E WM_VKEYTOITEM
0x002F WM_CHARTOITEM
0x0030 WM_SETFONT
0x0031 WM_GETFONT
0x0032 WM_SETHOTKEY
0x0033 WM_GETHOTKEY
0x0037 WM_QUERYDRAGICON
0x0039 WM_COMPAREITEM
0x003D WM_GETOBJECT
0x0041 WM_COMPACTING
0x0044 WM_COMMNOTIFY
0x0046 WM_WINDOWPOSCHANGING
0x0047 WM_WINDOWPOSCHANGED
0x0048 WM_POWER
0x004A WM_COPYDATA
0x004B WM_CANCELJOURNAL
0x004E WM_NOTIFY
0x0050 WM_INPUTLANGCHANGEREQUEST
0x0051 WM_INPUTLANGCHANGE
0x0052 WM_TCARD
0x0053 WM_HELP
0x0054 WM_USERCHANGED
0x0055 WM_NOTIFYFORMAT
0x007B WM_CONTEXTMENU
0x007C WM_STYLECHANGING
0x007D WM_STYLECHANGED
0x007E WM_DISPLAYCHANGE
0x007F WM_GETICON
0x0080 WM_SETICON
0x0081 WM_NCCREATE
0x0082 WM_NCDESTROY
0x0083 WM_NCCALCSIZE
0x0084 WM_NCHITTEST
0x0085 WM_NCPAINT
0x0086 WM_NCACTIVATE
0x0087 WM_GETDLGCODE
0x0088 WM_SYNCPAINT
0x00A0 WM_NCMOUSEMOVE
0x00A1 WM_NCLBUTTONDOWN
0x00A2 WM_NCLBUTTONUP
0x00A3 WM_NCLBUTTONDBLCLK
0x00A4 WM_NCRBUTTONDOWN
0x00A5 WM_NCRBUTTONUP
0x00A6 WM_NCRBUTTONDBLCLK
0x00A7 WM_NCMBUTTONDOWN
0x00A8 WM_NCMBUTTONUP
0x00A9 WM_NCMBUTTONDBLCLK
0x00AB WM_NCXBUTTONDOWN
0x00AC WM_NCXBUTTONUP
0x00AD WM_NCXBUTTONDBLCLK
0x00FE WM_INPUT_DEVICE_CHANGE
0x00FF WM_INPUT
0x0100 WM_KEYDOWN
0x0101 WM_KEYUP
0x0102 WM_CHAR
0x0103 WM_DEADCHAR
0x0104 WM_SYSKEYDOWN
0x0105 WM_SYSKEYUP
0x0106 WM_SYSCHAR
0x0107 WM_SYSDEADCHAR
0x0108 WM_KEYLAST
0x0109 WM_UNICHAR
0x010D WM_IME_STARTCOMPOSITION
0x010E WM_IME_ENDCOMPOSITION
0x010F WM_IME_COMPOSITION
0x0110 WM_INITDIALOG
0x0111 WM_COMMAND
0x0112 WM_SYSCOMMAND
0x0113 WM_TIMER
0x0114 WM_HSCROLL
0x0115 WM_VSCROLL
0x0116 WM_INITMENU
0x0117 WM_INITMENUPOPUP
0x0119 WM_GESTURE
0x011A WM_GESTURENOTIFY
0x011F WM_MENUSELECT
0x0120 WM_MENUCHAR
0x0121 WM_ENTERIDLE
0x0122 WM_MENURBUTTONUP
0x0123 WM_MENUDRAG
0x0124 WM_MENUGETOBJECT
0x0125 WM_UNINITMENUPOPUP
0x0126 WM_MENUCOMMAND
0x0127 WM_CHANGEUISTATE
0x0128 WM_UPDATEUISTATE
0x0129 WM_QUERYUISTATE
0x0132 WM_CTLCOLORMSGBOX
0x0133 WM_CTLCOLOREDIT
0x0134 WM_CTLCOLORLISTBOX
0x0135 WM_CTLCOLORBTN
0x0136 WM_CTLCOLORDLG
0x0137 WM_CTLCOLORSCROLLBAR
0x0138 WM_CTLCOLORSTATIC
0x0200 WM_MOUSEMOVE
0x0201 WM_LBUTTONDOWN
0x0202 WM_LBUTTONUP
0x0203 WM_LBUTTONDBLCLK
0x0204 WM_RBUTTONDOWN
0x0205 WM_RBUTTONUP
0x0206 WM_RBUTTONDBLCLK
0x0207 WM_MBUTTONDOWN
0x0208 WM_MBUTTONUP
0x0209 WM_MBUTTONDBLCLK
0x020A WM_MOUSEWHEEL
0x020B WM_XBUTTONDOWN
0x020C WM_XBUTTONUP
0x020D WM_XBUTTONDBLCLK
0x020E WM_MOUSEHWHEEL
0x0210 WM_PARENTNOTIFY
0x0211 WM_ENTERMENULOOP
0x0212 WM_EXITMENULOOP
0x0213 WM_NEXTMENU
0x0214 WM_SIZING
0x0215 WM_CAPTURECHANGED
0x0216 WM_MOVING
0x0218 WM_POWERBROADCAST
0x0219 WM_DEVICECHANGE
0x0220 WM_MDICREATE
0x0221 WM_MDIDESTROY
0x0222 WM_MDIACTIVATE
0x0223 WM_MDIRESTORE
0x0224 WM_MDINEXT
0x0225 WM_MDIMAXIMIZE
0x0226 WM_MDITILE
0x0227 WM_MDICASCADE
0x0228 WM_MDIICONARRANGE
0x0229 WM_MDIGETACTIVE
0x0230 WM_MDISETMENU
0x0231 WM_ENTERSIZEMOVE
0x0232 WM_EXITSIZEMOVE
0x0233 WM_DROPFILES
0x0234 WM_MDIREFRESHMENU
0x0238 WM_POINTERDEVICECHANGE
0x0239 WM_POINTERDEVICEINRANGE
0x023A WM_POINTERDEVICEOUTOFRANGE
0x0240 WM_TOUCH
0x0241 WM_NCPOINTERUPDATE
0x0242 WM_NCPOINTERDOWN
0x0243 WM_NCPOINTERUP
0x0245 WM_POINTERUPDATE
0x0246 WM_POINTERDOWN
0x0247 WM_POINTERUP
0x0249 WM_POINTERENTER
0x024A WM_POINTERLEAVE
0x024B WM_POINTERACTIVATE
0x024C WM_POINTERCAPTURECHANGED
0x024D WM_TOUCHHITTESTING
0x024E WM_POINTERWHEEL
0x024F WM_POINTERHWHEEL
0x0251 WM_POINTERROUTEDTO
0x0252 WM_POINTERROUTEDAWAY
0x0253 WM_POINTERROUTEDRELEASED
0x0281 WM_IME_SETCONTEXT
0x0282 WM_IME_NOTIFY
0x0283 WM_IME_CONTROL
0x0284 WM_IME_COMPOSITIONFULL
0x0285 WM_IME_SELECT
0x0286 WM_IME_CHAR
0x0288 WM_IME_REQUEST
0x0290 WM_IME_KEYDOWN
0x0291 WM_IME_KEYUP
0x02A0 WM_NCMOUSEHOVER
0x02A1 WM_MOUSEHOVER
0x02A2 WM_NCMOUSELEAVE
0x02A3 WM_MOUSELEAVE
0x02B1 WM_WTSSESSION_CHANGE
0x02E0 WM_DPICHANGED
0x02E2 WM_DPICHANGED_BEFOREPARENT
0x02E3 WM_DPICHANGED_AFTERPARENT
0x02E4 WM_GETDPISCALEDSIZE
0x0300 WM_CUT
0x0301 WM_COPY
0x0302 WM_PASTE
0x0303 WM_CLEAR
0x0304 WM_UNDO
0x0305 WM_RENDERFORMAT
0x0306 WM_RENDERALLFORMATS
0x0307 WM_DESTROYCLIPBOARD
0x0308 WM_DRAWCLIPBOARD
0x0309 WM_PAINTCLIPBOARD
0x030A WM_VSCROLLCLIPBOARD
0x030B WM_SIZECLIPBOARD
0x030C WM_ASKCBFORMATNAME
0x030D WM_CHANGECBCHAIN
0x030E WM_HSCROLLCLIPBOARD
0x030F WM_QUERYNEWPALETTE
0x0310 WM_PALETTEISCHANGING
0x0311 WM_PALETTECHANGED
0x0312 WM_HOTKEY
0x0317 WM_PRINT
0x0318 WM_PRINTCLIENT
0x0319 WM_APPCOMMAND
0x031A WM_THEMECHANGED
0x031D WM_CLIPBOARDUPDATE
0x031E WM_DWMCOMPOSITIONCHANGED
0x031F WM_DWMNCRENDERINGCHANGED
0x0320 WM_DWMCOLORIZATIONCOLORCHANGED
0x0321 WM_DWMWINDOWMAXIMIZEDCHANGE
0x0323 WM_DWMSENDICONICTHUMBNAIL
0x0326 WM_DWMSENDICONICLIVEPREVIEWBITMAP
0x033F WM_GETTITLEBARINFOEX
0x0345 WM_TOOLTIPDISMISS

メッセージの流れ

Windowsアプリケーションに送られたメッセージは最終的にウィンドウプロシージャに送られて処理されますが、そこに行くまでの経路にはメッセージキューを経由するものとそうでないものの2つがあります。

flow.png
table.png

メッセージの値

ウィンドウ メッセージ (Win32 と C++ の概要) - Win32 apps | Microsoft Learn

メッセージは、特定のイベントを指定する単なる数値コードです。

例えば、マウスの左ボタンが押された場合は0x0201という値が送られてきます。winuser.hにはこの値に対応した記号定数が#defineされています。0x0201であればWM_LBUTTONDOWNになります。

...
#define WM_MOUSEMOVE 0x0200
#define WM_LBUTTONDOWN 0x0201
#define WM_LBUTTONUP 0x0202
...

値の範囲

メッセージにはWM_LBUTTONDOWN0x0201)のようにシステムで定義されているものだけでなく、アプリケーションが独自に使うためにアプリケーションによって作成されるものもあります。メッセージの値は以下のように用途によって使用できる範囲が定められています。

アプリケーション定義のメッセージ / WM_USER / WM_APP
メッセージの共有 / RegisterWindowMessage関数

value.png

実際に確認する

開発環境は以下と同じです。
MinGW+C言語でWindows用Dllを作成する #Windows - Qiita

  • 確認用のプレーンコードは最小限のwindowsプログラムを参照。
  • ソースコードのファイル名はwinlog.cppとし、コンパイルはg++ winlog.cpp -mwindows -o winlog.exe

全てのメッセージを確認する

Windows 10で始めるC言語開発(31) WindowsでC言語開発! メッセージループを追っていく | TECH+(テックプラス)

確認用のプレーンコードに対して、ログをファイルに出力するように変更しています。全コードについては、全てのメッセージを出力するプログラムを参照願います。

ファイル名 出力する内容
AllLog.txt ウィンドウプロシージャが受け取ったメッセージ
及び、Win32API関数名(関数を呼ぶ前に出力)
MessageLoopLog.txt メッセージループで受け取ったメッセージ

実際にコンパイルして動作させると、例えば以下のように出力されます。

//AllLog.txt
Before RegisterClass
Before CreateWindowEx
[#0000] message: 0x0024
[#0001] message: 0x0081
[#0002] message: 0x0083
[#0003] message: 0x0001
Before ShowWindow
...

//MessageLoopLog.txt
...
[#0059] message: 0x0200
[#0062] message: 0x0200
[#0065] message: 0x0200
...

数値では分かりにくいのでメッセージの数値を文字列に変換します。

//AllLog_fix.txt
Before RegisterClass
Before CreateWindowEx
[#0000] message: WM_GETMINMAXINFO
[#0001] message: WM_NCCREATE
[#0002] message: WM_NCCALCSIZE
[#0003] message: WM_CREATE
Before ShowWindow
...

//MessageLoopLog_fix.txt
...
[#0059] message: WM_MOUSEMOVE
[#0062] message: WM_MOUSEMOVE
[#0065] message: WM_MOUSEMOVE
...

CreateWindowExWを呼び出すと、WM_CREATEなどのメッセージが送信されていることが分かります。また、WM_CREATEに記載の通り、CreateWindow関数が戻る前に、WM_CREATEが送信されていることも分かります。

WinMerge等でAllLog_fix.txtMessageLoopLog_fix.txtを比較すると、基本的に「ウィンドウプロシージャの受け取ったメッセージ」=「メッセージループで受け取ったメッセージ」+αでしたが、そうでないものもありました。また、0xC*** というアプリケーション間通信用のメッセージもありました。やはり実際に確認してみると理解が深まると思います。

GetMessageの挙動を確認する

ウィンドウ メッセージ (Win32 と C++ の概要) - Win32 apps | Microsoft Learn

キューが空の場合、関数は別のメッセージがキューに登録されるまでブロックします。

と記載されているので、実際にGetMessageの挙動を確認してみます。確認用のプレーンコードを変更し、メッセージループに入った回数をアプリケーションウィンドウのタイトルに表示するようにしています。全コードについては、メッセージループ突入回数を表示するプログラムを参照願います。

アプリケーションを起動して、マウスカーソルを動かすと回数がアップしていることが分かります。但し、何もしないと回数は変わりません。

TranslateMessageの挙動を確認する

キーボード入力 (はじめに Win32 および C++ を使用) - Win32 apps | Microsoft Learn

キーボード入力について考える場合は、キー ストロークが文字と同じではないことに注意することが重要です。 たとえば、A キーを押すと、次のいずれかの文字が発生する可能性があります。
a A á

キー ストロークは、... TranslateMessage 関数によって文字に変換されます。 この関数は、キーダウン メッセージを調べて、それらを文字に変換します。

TranslateMessageによって、例えばShiftを押しながらAを押すと文字"A"のWM_CHARメッセージが生成され、Shiftを押さずにAを押すと文字"a"のWM_CHARメッセージが生成されるとのことなので、実際にTranslateMessageの挙動とTranslateMessageがあるときとないときのメッセージを比較してみます。

確認用のプレーンコードを変更し、

  • キー入力にかかわるメッセージのみを出力するようにしています。
  • WM_KEYDOWNメッセージに付加されて送られてくる仮想キーコードの情報や、WM_CHARメッセージに付加されて送られてくる文字コードの情報も併せて出力するようにしています。
  • ANSI版も作成できるように文字列の定義を変更しています。詳細は文字列の操作を参照。

全コードについては、TranslateMessageの挙動を確認するプログラムを参照願います。

実際にコンパイルして動作させ、メッセージの数値を文字列に変換すると、

//a
message: WM_KEYDOWN 0x41 //Aキーダウン
message: WM_CHAR 0x61    //"a"文字メッセージ
message: WM_KEYUP 0x41   //Aキーアップ

//A
message: WM_KEYDOWN 0x10 //Shiftダウン
message: WM_KEYDOWN 0x41 //Aキーダウン
message: WM_CHAR 0x41    //"A"文字メッセージ
message: WM_KEYUP 0x41   //Aキーアップ
message: WM_KEYUP 0x10   //Shiftアップ

//か
message: WM_KEYDOWN 0xE5 //IME PROCESS キー
message: WM_KEYUP 0x4B   //Kキーアップ
message: WM_KEYDOWN 0xE5 //IME PROCESS キー
message: WM_KEYUP 0x41   //Aキーアップ
message: WM_KEYDOWN 0xE5 //IME PROCESS キー
message: WM_CHAR 0x304B  //"か"文字メッセージ

文字メッセージが生成されているのが分かります。このプログラムはUNICODEdefineしており、RegisterClassWでウィンドウクラス登録されるためUnicodeで文字を受け取ります。IMEオンでK Aと入力するとUnicodeの「か」である304Bを受け取っていることが分かります。なおUNICODEdefineせず、

#ifdef UNICODE
#undef UNICODE
#endif

とすると文字メッセージはShift-JISの「か」である82A9になっていました。

//Shift-JISの「か」
message: WM_CHAR 0x82
message: WM_CHAR 0xA9

TranslateMessage(&msg);を削除した場合は、

//a
message: WM_KEYDOWN 0x41 //Aキーダウン
message: WM_KEYUP 0x41   //Aキーアップ

文字メッセージWM_CHARが生成されていないことが分かります。

参考URL

用語説明

イベント駆動

メッセージとメッセージ キューについて - Win32 apps | Microsoft Learn
イベント駆動型プログラミング - Wikipedia

例えば、Windowsアプリケーション上でキーが押された場合、システム(Windows)はアプリケーションに対し「キーが押された」というメッセージを渡します。Windowsアプリケーションはこのメッセージを受け取ることでキーが押されたことを認識し、押されたときの処理を行います。

このように何かの事象、動作が起こったことをトリガーとして処理を実行する場合、「イベントドリブン(イベント駆動)です」と表現します。Windowsアプリケーションはイベントドリブンです。システムがメッセージを渡すのを待ちます。

ウィンドウプロシージャ

ウィンドウ プロシージャについて - Win32 apps | Microsoft Learn

Windowsアプリケーションを作成する場合、「ウィンドウプロシージャ」と呼ばれるアプリケーション※に送られてきたすべてのメッセージを処理する関数を実装します。システム(Windows)はアプリケーションに対するメッセージがある場合、この関数を呼びます。

Windowsアプリケーションでは、「マウスがクリックされた場合はこのような処理をする」といったコードをこの関数内に記述することでマウスクリックに応答する動作を実現できます。

上記で「Windowsアプリケーションはメッセージを受け取ることでキーが押されたことを認識し」と記載しましたが、実際にアプリケーション作成時にすることはメッセージに応答する処理を関数内に記載するだけです。関数の呼び出しはシステム(Windows)が行います。

※より丁寧に言うとアプリケーションローカルクラス、つまり実行可能ファイルが通常1つ持つウィンドウクラスに紐づくウィンドウ

ウィンドウクラス

ウィンドウ クラスについて - Win32 apps | Microsoft Learn
ウィンドウの作成 - Win32 apps | Microsoft Learn

ウィンドウクラスという名前ですが、C++でいうクラスではありません。ウィンドウクラスという概念は分かりにくいですが、アプリケーションウィンドウであれ、ボタンウィンドウであれウィンドウを作成するには、何はともあれ先立ってウィンドウクラスが必要です。ウィンドウクラスを登録するにはRegisterClassを使用します。

間違った理解にはなりますが、メッセージに関して理解するだけであれば、

  • ウィンドウクラス :町
  • ウィンドウプロシージャ:町に唯一ある郵便局
  • ウィンドウ:住人
  • メッセージ:郵便物

くらいの捉え方でよいと思います。住人宛ての郵便物を処理するためには受け取って処理する郵便局が必要ですが、そのためには郵便局を持つ町を作って町に住む必要があります。ウィンドウを作成する場合、まずはウィンドウプロシージャを持つウィンドウクラスを登録します。その後、それに紐づかせる形でウィンドウを作成します。ウィンドウクラスの持つウィンドウプロシージャはそのクラスに紐づくウィンドウに対する全てのメッセージを処理します。

実際は現実のように郵便局(ウィンドウプロシージャ)が受け取った郵便物(メッセージ)がその後住人(ウィンドウ)のもとに行くわけではないですし、ウィンドウクラスを登録するときに使う「ウィンドウクラスの属性を格納するWNDCLASS構造体」にはウィンドウプロシージャ以外の様々な設定が必要であるため、「ウィンドウクラスとはそれに紐づくウィンドウが共通で持つ仕様を定義しているもの」というような理解のほうが、より正しい理解になるとは思います。

参考URL

ウィンドウ

ウィンドウとは - Win32 apps | Microsoft Learn

一般的にウィンドウといえば、例えばメモ帳を起動したときなどに表示されるウィンドウのことを想像します。実際にこれはアプリケーションウィンドウと呼ばれるウィンドウですが、Windowsプログラミングの場合はボタンなどのコントロールもウィンドウです。

メッセージループ

ウィンドウ メッセージ (Win32 と C++ の概要) - Win32 apps | Microsoft Learn
Windows Messaging Architecture | Xavier's space

キーボードやマウスなどのユーザー操作によって発生するメッセージはメッセージキューに投稿(POST)されます。このメッセージキューにメッセージがあれば取得し、それをウィンドウプロシージャに送ることを繰り返すのがメッセージループです。具体的にはGetMessageでメッセージキューからメッセージを取得し、DispatchMessageでメッセージをウィンドウプロシージャに送ります。

例えばC#ではApplication.Runメソッドによってメッセージループを開始させます。

参考URL

ソースコード

最小限のWindowsプログラム

確認用プログラムのひな型となる最小限のWindowsアプリケーション用コードです。

モジュール 1 初めての Windows プログラム - Win32 apps | Microsoft Learn

  1. アプリケーションウィンドウを作成する前に、まずはRegisterClassを使用してウィンドウクラスを登録します。

    1. まずはRegisterClassの引数であるWNDCLASSW構造体を作成します。
    2. WNDCLASSEX 構造体の未使用のメンバーは、0 または NULL に初期化する必要があるため初期化子で初期化します。
    3. クラス名、ウィンドウプロシージャ、インスタンスのみが必須設定項目であるためこの3つを設定します。
    4. 必須項目の設定だけでも問題ありませんが、マウスカーソルは通常の矢印カーソルとしたいため、カーソルについてはLoadCursorを使用して矢印カーソルに設定します。
  2. CreateWindowExを使用してウィンドウを作成します。

  3. ShowWindowUpdateWindowを使用してウィンドウを表示します。ShowWindowの引数にはWinMainアプリケーションのエントリポイントの引数であるnCmdShowを指定します。

  4. メッセージループを作成します。Windowsアプリケーションも例えばコンソールアプリケーションである、

    #include <stdio.h>
    
    int main(void)
    {
        printf("Hello World");
        return 0;
    }
    

    と同じで、最後まで行くとプログラムが終了しますが、メッセージループがあることでこのループを抜けない限りプログラムは終了しません。メッセージループでは、

    while (GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    
    1. GetMessageでメッセージキューからメッセージを取得
    2. TranslateMessageで文字メッセージを生成
    3. ウィンドウプロシージャにメッセージを送るようにDispatchMessageでシステムに指示

    を繰り返します。GetMessageの戻り値は、

    • WM_QUITメッセージ以外を取得した場合は0以外
    • WM_QUITメッセージを取得した場合は0
    • エラーが発生した場合は-1

    のため、WM_QUIT以外のメッセージを受け取っている限り(>0の場合)ループを繰り返します。

  5. ウィンドウプロシージャを記載します。基本的にDefWindowProcを使用して、処理しないメッセージには既定の処理を実施しますウィンドウが破棄されると、WM_DESTROYメッセージを受け取るので、PostQuitMessageを使ってWM_QUITメッセージをメッセージキューに投稿(POST)します。

/*
winlog.cpp
g++ winlog.cpp -mwindows -o winlog.exe
*/
#ifndef UNICODE
#define UNICODE
#endif

#include <windows.h>

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow)
{
    // 1.ウィンドウクラスの登録
    const wchar_t CLASS_NAME[] = L"ClassName";

    WNDCLASS wc = {};                         // メンバの初期化
    wc.lpszClassName = CLASS_NAME;            // クラス名
    wc.lpfnWndProc = WindowProc;              // ウィンドウ プロシージャ のアドレス
    wc.hInstance = hInstance;                 // インスタンス ハンドル
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); // カーソル

    RegisterClass(&wc);

    // 2.ウィンドウの作成
    HWND hwnd = CreateWindowEx(
        0,                            // 拡張ウィンドウ スタイル
        CLASS_NAME, L"WindowName",    // クラス名、ウィンドウ名
        WS_OVERLAPPEDWINDOW,          // ウィンドウスタイル
        CW_USEDEFAULT, CW_USEDEFAULT, // ウィンドウの表示位置(x,y)
        CW_USEDEFAULT, CW_USEDEFAULT, // ウィンドウの幅と高さ
        NULL,                         // 親ウィンドウのハンドル
        NULL,                         // メニューのハンドル
        hInstance,                    // インスタンスハンドル
        NULL);                        // 追加のデータ

    if (hwnd == NULL)
    {
        return 0;
    }

    // 3.ウィンドウの表示
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // 4.メッセージループ
    MSG msg = {};
    while (GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

// 5.ウィンドウプロシージャ
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

全てのメッセージを出力するプログラム

/*
winlog.cpp
g++ winlog.cpp -mwindows -o winlog.exe
*/
#ifndef UNICODE
#define UNICODE
#endif

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

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void LogMessage(LPCWSTR fPath, UINT uMsg);
void LogString(LPCWSTR fPath, LPCWSTR str);

int counter = 0;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow)
{
    // 1.ウィンドウクラスの登録
    const wchar_t CLASS_NAME[] = L"ClassName";

    WNDCLASS wc = {};                         // メンバのゼロ初期化
    wc.lpszClassName = CLASS_NAME;            // クラス名
    wc.lpfnWndProc = WindowProc;              // ウィンドウ プロシージャ のアドレス
    wc.hInstance = hInstance;                 // インスタンス ハンドル
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); // カーソル

    LogString(L"AllLog.txt", L"Before RegisterClass\n");
    RegisterClass(&wc);

    // 2.ウィンドウの作成
    LogString(L"AllLog.txt", L"Before CreateWindowEx\n");
    HWND hwnd = CreateWindowEx(
        0,                            // 拡張ウィンドウ スタイル
        CLASS_NAME, L"WindowName",    // クラス名、ウィンドウ名
        WS_OVERLAPPEDWINDOW,          // ウィンドウスタイル
        CW_USEDEFAULT, CW_USEDEFAULT, // ウィンドウの表示位置(x,y)
        CW_USEDEFAULT, CW_USEDEFAULT, // ウィンドウの幅と高さ
        NULL,                         // 親ウィンドウのハンドル
        NULL,                         // メニューのハンドル
        hInstance,                    // インスタンスハンドル
        NULL);                        // 追加のデータ

    if (hwnd == NULL)
    {
        return 0;
    }

    // 3.ウィンドウの表示
    LogString(L"AllLog.txt", L"Before ShowWindow\n");
    ShowWindow(hwnd, nCmdShow);
    LogString(L"AllLog.txt", L"Before UpdateWindow\n");
    UpdateWindow(hwnd);

    // 4.メッセージループ
    LogString(L"AllLog.txt", L"Before Message Loop\n");
    MSG msg = {};
    while (GetMessage(&msg, NULL, 0, 0) > 0)
    {
        LogMessage(L"MessageLoopLog.txt", msg.message);
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

// 5.ウィンドウプロシージャ
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    LogMessage(L"AllLog.txt", uMsg);
    counter++;
    switch (uMsg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

// ファイルにログを出力(メッセージ出力用)
void LogMessage(LPCWSTR fPath, UINT uMsg)
{
    FILE *fp;
    if (_wfopen_s(&fp, fPath, L"a, ccs=UTF-8") == 0)
    {
        fwprintf_s(fp, L"[#%04d] message: 0x%04X\n", counter, uMsg);
        fclose(fp);
    }
}

// ファイルにログを出力(Win32API関数名出力用)
void LogString(LPCWSTR fPath, LPCWSTR str)
{
    FILE *fp;
    if (_wfopen_s(&fp, fPath, L"a, ccs=UTF-8") == 0)
    {
        fwprintf_s(fp, str);
        fclose(fp);
    }
}

メッセージループ突入回数を表示するプログラム

/*
winlog.cpp
g++ winlog.cpp -mwindows -o winlog.exe
*/
#ifndef UNICODE
#define UNICODE
#endif

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

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow)
{
    // 1.ウィンドウクラスの登録
    const wchar_t CLASS_NAME[] = L"ClassName";

    WNDCLASS wc = {};                         // メンバの初期化
    wc.lpszClassName = CLASS_NAME;            // クラス名
    wc.lpfnWndProc = WindowProc;              // ウィンドウ プロシージャ のアドレス
    wc.hInstance = hInstance;                 // インスタンス ハンドル
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); // カーソル

    RegisterClass(&wc);

    // 2.ウィンドウの作成
    HWND hwnd = CreateWindowEx(
        0,                            // 拡張ウィンドウ スタイル
        CLASS_NAME, L"WindowName",    // クラス名、ウィンドウ名
        WS_OVERLAPPEDWINDOW,          // ウィンドウスタイル
        CW_USEDEFAULT, CW_USEDEFAULT, // ウィンドウの表示位置(x,y)
        CW_USEDEFAULT, CW_USEDEFAULT, // ウィンドウの幅と高さ
        NULL,                         // 親ウィンドウのハンドル
        NULL,                         // メニューのハンドル
        hInstance,                    // インスタンスハンドル
        NULL);                        // 追加のデータ

    if (hwnd == NULL)
    {
        return 0;
    }

    // 3.ウィンドウの表示
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // 4.メッセージループ
    MSG msg = {};
    int counter = 0;
    while (GetMessage(&msg, NULL, 0, 0) > 0)
    {
        // メッセージループ突入回数を表示
        if (counter <= 10000)
        {
            counter++;
        }
        wchar_t str_counter[256];
        swprintf_s(str_counter, L"%d", counter);
        SetWindowTextW(hwnd, str_counter);

        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

// 5.ウィンドウプロシージャ
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

TranslateMessageの挙動を確認するプログラム

/*
winlog.cpp
g++ winlog.cpp -mwindows -o winlog.exe
*/
#ifndef UNICODE
#define UNICODE
#endif

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

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void LogMessage(LPCWSTR fPath, UINT uMsg, WPARAM wParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow)
{
    // 1.ウィンドウクラスの登録
    const TCHAR CLASS_NAME[] = TEXT("ClassName");

    WNDCLASS wc = {};                         // メンバの初期化
    wc.lpszClassName = CLASS_NAME;            // クラス名
    wc.lpfnWndProc = WindowProc;              // ウィンドウ プロシージャ のアドレス
    wc.hInstance = hInstance;                 // インスタンス ハンドル
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); // カーソル

    RegisterClass(&wc);

    // 2.ウィンドウの作成
    HWND hwnd = CreateWindowEx(
        0,                              // 拡張ウィンドウ スタイル
        CLASS_NAME, TEXT("WindowName"), // クラス名、ウィンドウ名
        WS_OVERLAPPEDWINDOW,            // ウィンドウスタイル
        CW_USEDEFAULT, CW_USEDEFAULT,   // ウィンドウの表示位置(x,y)
        CW_USEDEFAULT, CW_USEDEFAULT,   // ウィンドウの幅と高さ
        NULL,                           // 親ウィンドウのハンドル
        NULL,                           // メニューのハンドル
        hInstance,                      // インスタンスハンドル
        NULL);                          // 追加のデータ

    if (hwnd == NULL)
    {
        return 0;
    }

    // 3.ウィンドウの表示
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // 4.メッセージループ
    MSG msg = {};
    while (GetMessage(&msg, NULL, 0, 0) > 0)
    {
        if (WM_KEYFIRST <= msg.message && msg.message <= WM_KEYLAST)
        {
            LogMessage(L"KeyMessage.txt", msg.message, msg.wParam);
        }
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

// 5.ウィンドウプロシージャ
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

// ファイルにログを出力(メッセージ出力用)
void LogMessage(LPCWSTR fPath, UINT uMsg, WPARAM wParam)
{
    FILE *fp;
    if (_wfopen_s(&fp, fPath, L"a, ccs=UTF-8") == 0)
    {
        INT16 key = 0;
        if (wParam)
        {
            UIntPtrToInt16(wParam, &key);
        }
        fwprintf_s(fp, L"message: 0x%04X 0x%02X\n", uMsg, key);
        fclose(fp);
    }
}

メッセージの数値を文字列に変換

hex2string.csというファイル名で保存して、コマンドライン上で

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe hex2string.cs

でコンパイルします。hex2string.exeにテキストファイルをドロップすると0x0200などの数値をWM_MOUSEMOVEに置き換えます。

/*
hex2string.cs
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe hex2string.cs
*/
using System.Text;
using System.IO;

namespace hex2string
{
    internal class Program
    {
        static void Main(string[] args)
        {
            foreach (string arg in args)
            {
                string filepath = arg;
                string text = File.ReadAllText(filepath, new UTF8Encoding(false));

                text = text.Replace("0x0000", "WM_NULL");
                text = text.Replace("0x0001", "WM_CREATE");
                text = text.Replace("0x0002", "WM_DESTROY");
                text = text.Replace("0x0003", "WM_MOVE");
                text = text.Replace("0x0005", "WM_SIZE");
                text = text.Replace("0x0006", "WM_ACTIVATE");
                text = text.Replace("0x0007", "WM_SETFOCUS");
                text = text.Replace("0x0008", "WM_KILLFOCUS");
                text = text.Replace("0x000A", "WM_ENABLE");
                text = text.Replace("0x000B", "WM_SETREDRAW");
                text = text.Replace("0x000C", "WM_SETTEXT");
                text = text.Replace("0x000D", "WM_GETTEXT");
                text = text.Replace("0x000E", "WM_GETTEXTLENGTH");
                text = text.Replace("0x000F", "WM_PAINT");
                text = text.Replace("0x0010", "WM_CLOSE");
                text = text.Replace("0x0011", "WM_QUERYENDSESSION");
                text = text.Replace("0x0012", "WM_QUIT");
                text = text.Replace("0x0013", "WM_QUERYOPEN");
                text = text.Replace("0x0014", "WM_ERASEBKGND");
                text = text.Replace("0x0015", "WM_SYSCOLORCHANGE");
                text = text.Replace("0x0016", "WM_ENDSESSION");
                text = text.Replace("0x0018", "WM_SHOWWINDOW");
                text = text.Replace("0x001A", "WM_WININICHANGE");
                text = text.Replace("0x001B", "WM_DEVMODECHANGE");
                text = text.Replace("0x001C", "WM_ACTIVATEAPP");
                text = text.Replace("0x001D", "WM_FONTCHANGE");
                text = text.Replace("0x001E", "WM_TIMECHANGE");
                text = text.Replace("0x001F", "WM_CANCELMODE");
                text = text.Replace("0x0020", "WM_SETCURSOR");
                text = text.Replace("0x0021", "WM_MOUSEACTIVATE");
                text = text.Replace("0x0022", "WM_CHILDACTIVATE");
                text = text.Replace("0x0023", "WM_QUEUESYNC");
                text = text.Replace("0x0024", "WM_GETMINMAXINFO");
                text = text.Replace("0x0026", "WM_PAINTICON");
                text = text.Replace("0x0027", "WM_ICONERASEBKGND");
                text = text.Replace("0x0028", "WM_NEXTDLGCTL");
                text = text.Replace("0x002A", "WM_SPOOLERSTATUS");
                text = text.Replace("0x002B", "WM_DRAWITEM");
                text = text.Replace("0x002C", "WM_MEASUREITEM");
                text = text.Replace("0x002D", "WM_DELETEITEM");
                text = text.Replace("0x002E", "WM_VKEYTOITEM");
                text = text.Replace("0x002F", "WM_CHARTOITEM");
                text = text.Replace("0x0030", "WM_SETFONT");
                text = text.Replace("0x0031", "WM_GETFONT");
                text = text.Replace("0x0032", "WM_SETHOTKEY");
                text = text.Replace("0x0033", "WM_GETHOTKEY");
                text = text.Replace("0x0037", "WM_QUERYDRAGICON");
                text = text.Replace("0x0039", "WM_COMPAREITEM");
                text = text.Replace("0x003D", "WM_GETOBJECT");
                text = text.Replace("0x0041", "WM_COMPACTING");
                text = text.Replace("0x0044", "WM_COMMNOTIFY");
                text = text.Replace("0x0046", "WM_WINDOWPOSCHANGING");
                text = text.Replace("0x0047", "WM_WINDOWPOSCHANGED");
                text = text.Replace("0x0048", "WM_POWER");
                text = text.Replace("0x004A", "WM_COPYDATA");
                text = text.Replace("0x004B", "WM_CANCELJOURNAL");
                text = text.Replace("0x004E", "WM_NOTIFY");
                text = text.Replace("0x0050", "WM_INPUTLANGCHANGEREQUEST");
                text = text.Replace("0x0051", "WM_INPUTLANGCHANGE");
                text = text.Replace("0x0052", "WM_TCARD");
                text = text.Replace("0x0053", "WM_HELP");
                text = text.Replace("0x0054", "WM_USERCHANGED");
                text = text.Replace("0x0055", "WM_NOTIFYFORMAT");
                text = text.Replace("0x007B", "WM_CONTEXTMENU");
                text = text.Replace("0x007C", "WM_STYLECHANGING");
                text = text.Replace("0x007D", "WM_STYLECHANGED");
                text = text.Replace("0x007E", "WM_DISPLAYCHANGE");
                text = text.Replace("0x007F", "WM_GETICON");
                text = text.Replace("0x0080", "WM_SETICON");
                text = text.Replace("0x0081", "WM_NCCREATE");
                text = text.Replace("0x0082", "WM_NCDESTROY");
                text = text.Replace("0x0083", "WM_NCCALCSIZE");
                text = text.Replace("0x0084", "WM_NCHITTEST");
                text = text.Replace("0x0085", "WM_NCPAINT");
                text = text.Replace("0x0086", "WM_NCACTIVATE");
                text = text.Replace("0x0087", "WM_GETDLGCODE");
                text = text.Replace("0x0088", "WM_SYNCPAINT");
                text = text.Replace("0x00A0", "WM_NCMOUSEMOVE");
                text = text.Replace("0x00A1", "WM_NCLBUTTONDOWN");
                text = text.Replace("0x00A2", "WM_NCLBUTTONUP");
                text = text.Replace("0x00A3", "WM_NCLBUTTONDBLCLK");
                text = text.Replace("0x00A4", "WM_NCRBUTTONDOWN");
                text = text.Replace("0x00A5", "WM_NCRBUTTONUP");
                text = text.Replace("0x00A6", "WM_NCRBUTTONDBLCLK");
                text = text.Replace("0x00A7", "WM_NCMBUTTONDOWN");
                text = text.Replace("0x00A8", "WM_NCMBUTTONUP");
                text = text.Replace("0x00A9", "WM_NCMBUTTONDBLCLK");
                text = text.Replace("0x00AB", "WM_NCXBUTTONDOWN");
                text = text.Replace("0x00AC", "WM_NCXBUTTONUP");
                text = text.Replace("0x00AD", "WM_NCXBUTTONDBLCLK");
                text = text.Replace("0x00FE", "WM_INPUT_DEVICE_CHANGE");
                text = text.Replace("0x00FF", "WM_INPUT");
                text = text.Replace("0x0100", "WM_KEYDOWN");
                text = text.Replace("0x0101", "WM_KEYUP");
                text = text.Replace("0x0102", "WM_CHAR");
                text = text.Replace("0x0103", "WM_DEADCHAR");
                text = text.Replace("0x0104", "WM_SYSKEYDOWN");
                text = text.Replace("0x0105", "WM_SYSKEYUP");
                text = text.Replace("0x0106", "WM_SYSCHAR");
                text = text.Replace("0x0107", "WM_SYSDEADCHAR");
                text = text.Replace("0x0108", "WM_KEYLAST");
                text = text.Replace("0x0109", "WM_UNICHAR");
                text = text.Replace("0x010D", "WM_IME_STARTCOMPOSITION");
                text = text.Replace("0x010E", "WM_IME_ENDCOMPOSITION");
                text = text.Replace("0x010F", "WM_IME_COMPOSITION");
                text = text.Replace("0x0110", "WM_INITDIALOG");
                text = text.Replace("0x0111", "WM_COMMAND");
                text = text.Replace("0x0112", "WM_SYSCOMMAND");
                text = text.Replace("0x0113", "WM_TIMER");
                text = text.Replace("0x0114", "WM_HSCROLL");
                text = text.Replace("0x0115", "WM_VSCROLL");
                text = text.Replace("0x0116", "WM_INITMENU");
                text = text.Replace("0x0117", "WM_INITMENUPOPUP");
                text = text.Replace("0x0119", "WM_GESTURE");
                text = text.Replace("0x011A", "WM_GESTURENOTIFY");
                text = text.Replace("0x011F", "WM_MENUSELECT");
                text = text.Replace("0x0120", "WM_MENUCHAR");
                text = text.Replace("0x0121", "WM_ENTERIDLE");
                text = text.Replace("0x0122", "WM_MENURBUTTONUP");
                text = text.Replace("0x0123", "WM_MENUDRAG");
                text = text.Replace("0x0124", "WM_MENUGETOBJECT");
                text = text.Replace("0x0125", "WM_UNINITMENUPOPUP");
                text = text.Replace("0x0126", "WM_MENUCOMMAND");
                text = text.Replace("0x0127", "WM_CHANGEUISTATE");
                text = text.Replace("0x0128", "WM_UPDATEUISTATE");
                text = text.Replace("0x0129", "WM_QUERYUISTATE");
                text = text.Replace("0x0132", "WM_CTLCOLORMSGBOX");
                text = text.Replace("0x0133", "WM_CTLCOLOREDIT");
                text = text.Replace("0x0134", "WM_CTLCOLORLISTBOX");
                text = text.Replace("0x0135", "WM_CTLCOLORBTN");
                text = text.Replace("0x0136", "WM_CTLCOLORDLG");
                text = text.Replace("0x0137", "WM_CTLCOLORSCROLLBAR");
                text = text.Replace("0x0138", "WM_CTLCOLORSTATIC");
                text = text.Replace("0x0200", "WM_MOUSEMOVE");
                text = text.Replace("0x0201", "WM_LBUTTONDOWN");
                text = text.Replace("0x0202", "WM_LBUTTONUP");
                text = text.Replace("0x0203", "WM_LBUTTONDBLCLK");
                text = text.Replace("0x0204", "WM_RBUTTONDOWN");
                text = text.Replace("0x0205", "WM_RBUTTONUP");
                text = text.Replace("0x0206", "WM_RBUTTONDBLCLK");
                text = text.Replace("0x0207", "WM_MBUTTONDOWN");
                text = text.Replace("0x0208", "WM_MBUTTONUP");
                text = text.Replace("0x0209", "WM_MBUTTONDBLCLK");
                text = text.Replace("0x020A", "WM_MOUSEWHEEL");
                text = text.Replace("0x020B", "WM_XBUTTONDOWN");
                text = text.Replace("0x020C", "WM_XBUTTONUP");
                text = text.Replace("0x020D", "WM_XBUTTONDBLCLK");
                text = text.Replace("0x020E", "WM_MOUSEHWHEEL");
                text = text.Replace("0x0210", "WM_PARENTNOTIFY");
                text = text.Replace("0x0211", "WM_ENTERMENULOOP");
                text = text.Replace("0x0212", "WM_EXITMENULOOP");
                text = text.Replace("0x0213", "WM_NEXTMENU");
                text = text.Replace("0x0214", "WM_SIZING");
                text = text.Replace("0x0215", "WM_CAPTURECHANGED");
                text = text.Replace("0x0216", "WM_MOVING");
                text = text.Replace("0x0218", "WM_POWERBROADCAST");
                text = text.Replace("0x0219", "WM_DEVICECHANGE");
                text = text.Replace("0x0220", "WM_MDICREATE");
                text = text.Replace("0x0221", "WM_MDIDESTROY");
                text = text.Replace("0x0222", "WM_MDIACTIVATE");
                text = text.Replace("0x0223", "WM_MDIRESTORE");
                text = text.Replace("0x0224", "WM_MDINEXT");
                text = text.Replace("0x0225", "WM_MDIMAXIMIZE");
                text = text.Replace("0x0226", "WM_MDITILE");
                text = text.Replace("0x0227", "WM_MDICASCADE");
                text = text.Replace("0x0228", "WM_MDIICONARRANGE");
                text = text.Replace("0x0229", "WM_MDIGETACTIVE");
                text = text.Replace("0x0230", "WM_MDISETMENU");
                text = text.Replace("0x0231", "WM_ENTERSIZEMOVE");
                text = text.Replace("0x0232", "WM_EXITSIZEMOVE");
                text = text.Replace("0x0233", "WM_DROPFILES");
                text = text.Replace("0x0234", "WM_MDIREFRESHMENU");
                text = text.Replace("0x0238", "WM_POINTERDEVICECHANGE");
                text = text.Replace("0x0239", "WM_POINTERDEVICEINRANGE");
                text = text.Replace("0x023A", "WM_POINTERDEVICEOUTOFRANGE");
                text = text.Replace("0x0240", "WM_TOUCH");
                text = text.Replace("0x0241", "WM_NCPOINTERUPDATE");
                text = text.Replace("0x0242", "WM_NCPOINTERDOWN");
                text = text.Replace("0x0243", "WM_NCPOINTERUP");
                text = text.Replace("0x0245", "WM_POINTERUPDATE");
                text = text.Replace("0x0246", "WM_POINTERDOWN");
                text = text.Replace("0x0247", "WM_POINTERUP");
                text = text.Replace("0x0249", "WM_POINTERENTER");
                text = text.Replace("0x024A", "WM_POINTERLEAVE");
                text = text.Replace("0x024B", "WM_POINTERACTIVATE");
                text = text.Replace("0x024C", "WM_POINTERCAPTURECHANGED");
                text = text.Replace("0x024D", "WM_TOUCHHITTESTING");
                text = text.Replace("0x024E", "WM_POINTERWHEEL");
                text = text.Replace("0x024F", "WM_POINTERHWHEEL");
                text = text.Replace("0x0251", "WM_POINTERROUTEDTO");
                text = text.Replace("0x0252", "WM_POINTERROUTEDAWAY");
                text = text.Replace("0x0253", "WM_POINTERROUTEDRELEASED");
                text = text.Replace("0x0281", "WM_IME_SETCONTEXT");
                text = text.Replace("0x0282", "WM_IME_NOTIFY");
                text = text.Replace("0x0283", "WM_IME_CONTROL");
                text = text.Replace("0x0284", "WM_IME_COMPOSITIONFULL");
                text = text.Replace("0x0285", "WM_IME_SELECT");
                text = text.Replace("0x0286", "WM_IME_CHAR");
                text = text.Replace("0x0288", "WM_IME_REQUEST");
                text = text.Replace("0x0290", "WM_IME_KEYDOWN");
                text = text.Replace("0x0291", "WM_IME_KEYUP");
                text = text.Replace("0x02A0", "WM_NCMOUSEHOVER");
                text = text.Replace("0x02A1", "WM_MOUSEHOVER");
                text = text.Replace("0x02A2", "WM_NCMOUSELEAVE");
                text = text.Replace("0x02A3", "WM_MOUSELEAVE");
                text = text.Replace("0x02B1", "WM_WTSSESSION_CHANGE");
                text = text.Replace("0x02E0", "WM_DPICHANGED");
                text = text.Replace("0x02E2", "WM_DPICHANGED_BEFOREPARENT");
                text = text.Replace("0x02E3", "WM_DPICHANGED_AFTERPARENT");
                text = text.Replace("0x02E4", "WM_GETDPISCALEDSIZE");
                text = text.Replace("0x0300", "WM_CUT");
                text = text.Replace("0x0301", "WM_COPY");
                text = text.Replace("0x0302", "WM_PASTE");
                text = text.Replace("0x0303", "WM_CLEAR");
                text = text.Replace("0x0304", "WM_UNDO");
                text = text.Replace("0x0305", "WM_RENDERFORMAT");
                text = text.Replace("0x0306", "WM_RENDERALLFORMATS");
                text = text.Replace("0x0307", "WM_DESTROYCLIPBOARD");
                text = text.Replace("0x0308", "WM_DRAWCLIPBOARD");
                text = text.Replace("0x0309", "WM_PAINTCLIPBOARD");
                text = text.Replace("0x030A", "WM_VSCROLLCLIPBOARD");
                text = text.Replace("0x030B", "WM_SIZECLIPBOARD");
                text = text.Replace("0x030C", "WM_ASKCBFORMATNAME");
                text = text.Replace("0x030D", "WM_CHANGECBCHAIN");
                text = text.Replace("0x030E", "WM_HSCROLLCLIPBOARD");
                text = text.Replace("0x030F", "WM_QUERYNEWPALETTE");
                text = text.Replace("0x0310", "WM_PALETTEISCHANGING");
                text = text.Replace("0x0311", "WM_PALETTECHANGED");
                text = text.Replace("0x0312", "WM_HOTKEY");
                text = text.Replace("0x0317", "WM_PRINT");
                text = text.Replace("0x0318", "WM_PRINTCLIENT");
                text = text.Replace("0x0319", "WM_APPCOMMAND");
                text = text.Replace("0x031A", "WM_THEMECHANGED");
                text = text.Replace("0x031D", "WM_CLIPBOARDUPDATE");
                text = text.Replace("0x031E", "WM_DWMCOMPOSITIONCHANGED");
                text = text.Replace("0x031F", "WM_DWMNCRENDERINGCHANGED");
                text = text.Replace("0x0320", "WM_DWMCOLORIZATIONCOLORCHANGED");
                text = text.Replace("0x0321", "WM_DWMWINDOWMAXIMIZEDCHANGE");
                text = text.Replace("0x0323", "WM_DWMSENDICONICTHUMBNAIL");
                text = text.Replace("0x0326", "WM_DWMSENDICONICLIVEPREVIEWBITMAP");
                text = text.Replace("0x033F", "WM_GETTITLEBARINFOEX");
                text = text.Replace("0x0345", "WM_TOOLTIPDISMISS");

                string dir = Path.GetDirectoryName(filepath);
                string filename = Path.GetFileNameWithoutExtension(filepath);

                File.WriteAllText(dir + @"\" + filename + "_fix.txt", text, new UTF8Encoding(false));
            }
        }
    }
}

その他参考URL

メッセージについて

HTMLテーブル作成

ログ出力用

4
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
6