DEV_BROADCAST_VOLUME

dbch_devicetypeが、DBT_DEVTYP_VOLUMEなら、DEV_BROADCAST_HDRポインタをDEV_BROADCAST_VOLUMEポインタにキャストできる。

DEV_BROADCAST_VOLUME (dbt.h) - Win32 apps | Microsoft Docs
USBメモリーの挿入などを検出する(UsefullCode.net)

今度は、DEV_BROADCAST_VOLUME構造体としての各要素を見てみる。
DEV_BROADCAST_VOLUME.cppで、

このように各要素をMessageBoxで表示。

これが来たら、OKを押す。
これが来たら、OKを押す。

これが来たら、OKを押す。

ここでさらに、OKを押す。
ここでさらに、OKを押す。

ここでさらに、OKを押す。

で、さらに各要素がわかる。
で、さらに各要素がわかる。

で、さらに各要素がわかる。
DBT_DEVTYP_VOLUMEということは、ボリュームを持つデバイスであり、USBメモリやUSBポータブルHDDなどのリムーバブルディスクはこれ。
実は、dbcv_unitmaskがドライブレターを表しており、例えば、一番下のビットが立っていたら'A'、下から2番目のビットが立っていたら'B'という感じになっている。
ここでは16になっているが、2進数で0x10000だから、'E'ドライブということになる。

Sample/winapi/DEV_BROADCAST_VOLUME/DEV_BROADCAST_VOLUME/src/DEV_BROADCAST_VOLUME at master · bg1bgst333/Sample · GitHub

DEV_BROADCAST_HDR

DBT_DEVICEARRIVALや、DBT_DEVICEREMOVECOMPLETEの時、lParamにはDEV_BROADCAST_HDR構造体のポインタが渡される。

DEV_BROADCAST_HDR (dbt.h) - Win32 apps | Microsoft Docs

渡されたlParamをDEV_BROADCAST_HDR構造体ポインタにキャストして各要素を見てみる。
DEV_BROADCAST_HDR.cppで、

このように各要素をMessageBoxで表示。

DBT_DEVICEARRIVALでOKを押す
DBT_DEVICEARRIVALでOKを押す

DBT_DEVICEARRIVALでOKを押す。

するとこれが出る。dbch_devicetypeは2。
するとこれが出る。dbch_devicetypeは2。

するとこれが出る。dbch_devicetypeは2。
これは、DBT_DEVTYP_VOLUMEにあたる。

Sample/winapi/DEV_BROADCAST_HDR/DEV_BROADCAST_HDR/src/DEV_BROADCAST_HDR at master · bg1bgst333/Sample · GitHub

DBT_DEVICEREMOVECOMPLETE

バイスの削除が完了した時、DBT_DEVICEREMOVECOMPLETEが発生する。

DBT_DEVICEREMOVECOMPLETE event (Dbt.h) - Win32 apps | Microsoft Docs

DBT_DEVICEREMOVECOMPLETE.cppで、

とする。
USBデバイスを接続すると、

"DBT_DEVICEARRIVAL"が発生するが、
"DBT_DEVICEARRIVAL"が発生するが、

"DBT_DEVICEARRIVAL"が発生するが、
USBデバイスを抜くと、

"DBT_DEVICEREMOVECOMPLETE"が発生する。
"DBT_DEVICEREMOVECOMPLETE"が発生する。

"DBT_DEVICEREMOVECOMPLETE"が発生する。
タスクトレイからUSBデバイスの取り出しでも発生する。
で、その後に手動でUSBデバイスを抜いた時は"DBT_DEVNODES_CHANGED"だけ発生する。
だから、論理的な取り外しは"DBT_DEVICEREMOVECOMPLETE"であり、物理的な取り外しはまた違うんだなあ。
この辺の詳細はどうすれば取れるんだろ。取れるんかな。

Sample/winapi/DBT_DEVICEREMOVECOMPLETE/DBT_DEVICEREMOVECOMPLETE/src/DBT_DEVICEREMOVECOMPLETE at master · bg1bgst333/Sample · GitHub

DBT_DEVICEARRIVAL

バイスが接続され使用可能になった時、DBT_DEVICEARRIVALが発生する。

DBT_DEVICEARRIVAL event (Dbt.h) - Win32 apps | Microsoft Docs

DBT_DEVICEARRIVAL.cppで、

とする。
USBデバイスを接続すると、

これが紛れている
これが紛れている

これが紛れている。
抜いた時は、

これはいない
これはいない

これはいない。

Sample/winapi/DBT_DEVICEARRIVAL/DBT_DEVICEARRIVAL/src/DBT_DEVICEARRIVAL at master · bg1bgst333/Sample · GitHub

DBT_DEVNODES_CHANGED

WM_DEVICECHANGEで、さらにwParamがDBT_DEVNODES_CHANGEDの時は、デバイスノードが変更になった時。

DBT_DEVNODES_CHANGED event (Dbt.h) - Win32 apps | Microsoft Docs

DBT_DEVNODES_CHANGED.cppで、

wParamがDBT_DEVNODES_CHANGEDなら、MessageBoxで"DBT_DEVNODES_CHANGED"、そうでないなら、MessageBoxで"Other"と表示。
USBデバイスを挿した時、

いくつか出てくる
いくつか出てくる

いくつか出てくる。
待ってるとさらに出てきたりする。
USBデバイスを抜いた時も、

いくつか出てくる
いくつか出てくる

いくつか出てくる。
この時は1つだが、このあとMessageBoxを閉じたらさらに出てきた。

Sample/winapi/DBT_DEVNODES_CHANGED/DBT_DEVNODES_CHANGED/src/DBT_DEVNODES_CHANGED at master · bg1bgst333/Sample · GitHub

WM_DEVICECHANGE

WM_DEVICECHANGEは、デバイスの状態が変化した時に通知される。

WM_DEVICECHANGE メッセージ (Winuser.h) - Win32 apps | Microsoft Docs

具体的には、例えばUSBデバイスが接続された時などである。
WM_DEVICECHANGE.cppで、

とする。

起動すると、最初はこう。
起動すると、最初はこう。

起動すると、最初はこう。
USBポータブルHDDを挿すと、

3回ぐらい通知が来る。
3回ぐらい通知が来る。

3回ぐらい通知が来る。
メッセージボックスを全部閉じて、抜くと、

2~3回ぐらい通知が来る。
2~3回ぐらい通知が来る。

2~3回ぐらい通知が来る。

Sample/winapi/WM_DEVICECHANGE/WM_DEVICECHANGE/src/WM_DEVICECHANGE at master · bg1bgst333/Sample · GitHub

PRINTER_NOTIFY_INFO_DATA

PRINTER_NOTIFY_INFO構造体の要素aData配列は、PRINTER_NOTIFY_INFO_DATA構造体の配列で、ここでさらに印刷状態などを取得できる。

PRINTER_NOTIFY_INFO_DATA 構造体 (Winspool .h) - Win32 apps | Microsoft Docs

PRINTER_NOTIFY_INFO_DATA.cppで、

とする。

Microsoft Windows [Version 10.0.19043.1415]
(c) Microsoft Corporation. All rights reserved.

C:\Users\bg1>cd C:\Users\bg1\Documents\test

C:\Users\bg1\Documents\test>PRINTER_NOTIFY_INFO_DATA.exe
thread begin before.
thread wait before.
threadproc begin before.
Default Printer: EPSON PX-S06 Series
hPrinter: 0x005bc944
pTI->m_hHandles[0]: 0x00000114
pTI->m_hHandles[1]: 0x00000154
notify!
PRINTER_CHANGE_SET_PRINTER_DRIVER
notify!
PRINTER_CHANGE_SET_PRINTER
PRINTER_CHANGE_ADD_JOB
pPNI->Version = 2
pPNI->Flags = 131072
pPNI->Count = 25
pPNI->aData[0].Id = 00000000
pPNI->aData[0].Type = 00000000
PRINTER_NOTIFY_TYPE
PRINTER_NOTIFY_FIELD_CJOBS: 1
pPNI->aData[1].Id = 00000005
pPNI->aData[1].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_PRINTER_NAME: EPSON PX-S06 Series
pPNI->aData[2].Id = 00000005
pPNI->aData[2].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_MACHINE_NAME: \\DESKTOP-PUSH7HT
pPNI->aData[3].Id = 00000005
pPNI->aData[3].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_PORT_NAME:
pPNI->aData[4].Id = 00000005
pPNI->aData[4].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_USER_NAME: bg1
pPNI->aData[5].Id = 00000005
pPNI->aData[5].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_NOTIFY_NAME: bg1
pPNI->aData[6].Id = 00000005
pPNI->aData[6].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_DATATYPE: NT EMF 1.008
pPNI->aData[7].Id = 00000005
pPNI->aData[7].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_PRINT_PROCESSOR: winprint
pPNI->aData[8].Id = 00000005
pPNI->aData[8].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_PARAMETERS:
pPNI->aData[9].Id = 00000005
pPNI->aData[9].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_DRIVER_NAME: EPSON PX-S06 Series
pPNI->aData[10].Id = 00000005
pPNI->aData[10].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_DEVMODE
pPNI->aData[11].Id = 00000005
pPNI->aData[11].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_STATUS
JOB_STATUS_SPOOLING
pPNI->aData[12].Id = 00000005
pPNI->aData[12].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_STATUS_STRING:
pPNI->aData[13].Id = 00000005
pPNI->aData[13].Type = 00000001
JOB_NOTIFY_TYPE
pPNI->aData[14].Id = 00000005
pPNI->aData[14].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_DOCUMENT: test1.txt - ???
pPNI->aData[15].Id = 00000005
pPNI->aData[15].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_PRIORITY: 1
pPNI->aData[16].Id = 00000005
pPNI->aData[16].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_POSITION: 1
pPNI->aData[17].Id = 00000005
pPNI->aData[17].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_SUBMITTED
pPNI->aData[18].Id = 00000005
pPNI->aData[18].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_START_TIME: 00:00
pPNI->aData[19].Id = 00000005
pPNI->aData[19].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_UNTIL_TIME: 00:00
pPNI->aData[20].Id = 00000005
pPNI->aData[20].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_TIME: 00:00
pPNI->aData[21].Id = 00000005
pPNI->aData[21].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_TOTAL_PAGES: 0
pPNI->aData[22].Id = 00000005
pPNI->aData[22].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_PAGES_PRINTED: 0
pPNI->aData[23].Id = 00000005
pPNI->aData[23].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_TOTAL_BYTES: 0
pPNI->aData[24].Id = 00000005
pPNI->aData[24].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_BYTES_PRINTED: 0
notify!
PRINTER_CHANGE_SET_JOB
PRINTER_CHANGE_WRITE_JOB
pPNI->Version = 2
pPNI->Flags = 131072
pPNI->Count = 11
pPNI->aData[0].Id = 00000005
pPNI->aData[0].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_TOTAL_PAGES: 1
pPNI->aData[1].Id = 00000005
pPNI->aData[1].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_TOTAL_BYTES: 1164
pPNI->aData[2].Id = 00000005
pPNI->aData[2].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_STATUS
pPNI->aData[3].Id = 00000005
pPNI->aData[3].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_STATUS
pPNI->aData[4].Id = 00000005
pPNI->aData[4].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_PORT_NAME: USB001
pPNI->aData[5].Id = 00000005
pPNI->aData[5].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_STATUS
JOB_STATUS_PRINTING
pPNI->aData[6].Id = 00000005
pPNI->aData[6].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_STATUS
JOB_STATUS_PRINTING
pPNI->aData[7].Id = 00000005
pPNI->aData[7].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_STATUS_STRING:
pPNI->aData[8].Id = 00000005
pPNI->aData[8].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_STATUS
JOB_STATUS_PRINTING
pPNI->aData[9].Id = 00000005
pPNI->aData[9].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_PAGES_PRINTED: 0
pPNI->aData[10].Id = 00000005
pPNI->aData[10].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_BYTES_PRINTED: 0
notify!
PRINTER_CHANGE_WRITE_JOB
pPNI->Version = 2
pPNI->Flags = 131072
pPNI->Count = 2
pPNI->aData[0].Id = 00000005
pPNI->aData[0].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_PAGES_PRINTED: 0
pPNI->aData[1].Id = 00000005
pPNI->aData[1].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_BYTES_PRINTED: 1076
notify!
PRINTER_CHANGE_SET_JOB
pPNI->Version = 2
pPNI->Flags = 131072
pPNI->Count = 1
pPNI->aData[0].Id = 00000005
pPNI->aData[0].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_STATUS
JOB_STATUS_PRINTING
notify!
PRINTER_CHANGE_SET_PRINTER
PRINTER_CHANGE_SET_JOB
PRINTER_CHANGE_DELETE_JOB
pPNI->Version = 2
pPNI->Flags = 131072
pPNI->Count = 12
pPNI->aData[0].Id = 00000005
pPNI->aData[0].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_STATUS
JOB_STATUS_PRINTING
pPNI->aData[1].Id = 00000005
pPNI->aData[1].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_STATUS
JOB_STATUS_DELETING
JOB_STATUS_PRINTING
pPNI->aData[2].Id = 00000005
pPNI->aData[2].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_STATUS
JOB_STATUS_DELETING
JOB_STATUS_PRINTING
pPNI->aData[3].Id = 00000005
pPNI->aData[3].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_STATUS
JOB_STATUS_DELETING
JOB_STATUS_PRINTING
pPNI->aData[4].Id = 00000005
pPNI->aData[4].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_STATUS_STRING:
pPNI->aData[5].Id = 00000005
pPNI->aData[5].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_STATUS
JOB_STATUS_DELETING
JOB_STATUS_PRINTING
JOB_STATUS_PRINTED
pPNI->aData[6].Id = 00000005
pPNI->aData[6].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_PORT_NAME:
pPNI->aData[7].Id = 00000005
pPNI->aData[7].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_STATUS
JOB_STATUS_DELETING
JOB_STATUS_PRINTED
pPNI->aData[8].Id = 00000005
pPNI->aData[8].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_PAGES_PRINTED: 1
pPNI->aData[9].Id = 00000005
pPNI->aData[9].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_BYTES_PRINTED: 1076
pPNI->aData[10].Id = 00000000
pPNI->aData[10].Type = 00000000
PRINTER_NOTIFY_TYPE
PRINTER_NOTIFY_FIELD_CJOBS: 0
pPNI->aData[11].Id = 00000005
pPNI->aData[11].Type = 00000001
JOB_NOTIFY_TYPE
JOB_NOTIFY_FIELD_STATUS
JOB_STATUS_DELETING
JOB_STATUS_PRINTED
JOB_STATUS_DELETED
threadproc after before.
thread close before.

C:\Users\bg1\Documents\test>

いろいろ出てきた。

Sample/winapi/PRINTER_NOTIFY_INFO_DATA/P_N_I_D/src/PRINTER_NOTIFY_INFO_DATA at master · bg1bgst333/Sample · GitHub