コードで作成したコントロールのイベントハンドラー – プログラミング – Home

コードで作成したコントロールのイベント...
 
通知
すべてクリア

[解決済] コードで作成したコントロールのイベントハンドラー


傾奇者
 傾奇者
(@傾奇者)
ゲスト
結合: 14年前
投稿: 35
Topic starter  

Visual Studio 2019 community、MFC、SDI アプリです。

ダイアログ上にリストビューをコードで作成し、リストビュー上でクリックして、ある機
能を行います。
Buildすると、「ビルド: 1 正常終了」にはなりますが、次の警告が出て、カーソルが
コードの ON_NOTIFY の行に移動して、”ここだよ”と知らせてくれます。

”warning C4310: キャストによって定数値が切り捨てられました。”

以下のコードのどこが不適切なのでしょうか?
どうぞよろしくご教授ください。お願いいたします。

<CDlgKabuki.h>
public:
void OnClickLvKabuki(NMHDR* pNMHDR, LRESULT* pResult);

<CDlgKabuki.coo>

BEGIN_MESSAGE_MAP(CDlgKabuki, CDialogEx)
ON_NOTIFY(NM_CLICK, IDC_LV_KABUKI, &CDlgKabuki::OnClickLvKabuki)
END_MESSAGE_MAP()

int CDlgKabuki::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
m_lvKabuki = new CListCtrl();
m_lvKbuki->Create(LVS_REPORT | WS_VISIBLE | WS_BORDER, CRect(0, 0,
rcClient.right, rcClient.bottom), this, IDC_LV_KABUKI);

以下省略
}

void OnClickLvKabuki(NMHDR* pNMHDR, LRESULT* pResult)
{
UNREFERENCED_PARAMETER(*pNMHDR);

ここのコードは省略
}


引用未解決
トピックタグ
傾奇者
 傾奇者
(@傾奇者)
ゲスト
結合: 14年前
投稿: 35
Topic starter  

自力解決しました。

原因は、IDC_LV_KABUKI に 90000台の値を定義していました。
これを 3000台の数字に変えたら警告は出なくなりました。
境界点を調べたら、おおよそ 65500以下ならOKのようです。
UINT の最大値は 4294967295 なのに、不思議です。


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 4年前
投稿: 828
 

ON_NOTIFY(・・・)の定義では第二引数のidはWORD型が要求されています。
これはコントロールのIDを意味しますが、WindowsではコントロールのIDの
上限はWORDの最大値となります。つまり0xFFFF=65535ですね。
これが警告が出る理由です。

以下は蛇足です。
では「なぜWORDに制限されているのか」ですが、
Windowsでは、あるコントロールのアクション、例えばクリックされた場合には
WM_COMMANDがポストされるわけですが、この時引数のWPARAM(=64bit)には

1.上位のWORDにNotifyコードを保持(0と1は特殊な意味を持つ)
2.下位のWORDにコマンドのID(=コントロールのID)を保持

となっているわけです。
つまり、構築時には64bitのIDを与えても警告されませんが、
そのIDがコマンドIDとして処理される場合はWORD=32bitの値しか
扱えないわけですね。WM_NOTIFYも原理的に同じとなります。

つまり、以下の事が言えます。
(A)コントロールのIDには64bitを与えることができるが、
(B)もしそのコントロールが他にWM_COMMAND、WM_NOTIFY等を
  送付するならば、32bitまでのIDでなければ、機能しない。

というわけです。
Windowsの歴史的経緯でこの仕様になっているので、注意しましょう。


返信引用
傾奇者
 傾奇者
(@傾奇者)
ゲスト
結合: 14年前
投稿: 35
Topic starter  

仲澤@失業者様

解り易い解説を有難うございました。
理屈を理解しないでIDを定義していました。

メニュー(リボンバー)のコントロールのIDは、ON_COMMAND に渡されますが、理屈は知
知らずに3000台にしていたので、良かった訳ですね。
ダイアログ上のコントロールのIDは大きな数値にしています。
ON_BN_CLICKED、ON_EN_CHANGE等に渡されますが、これらは64bitでいいのですね。

勉強になりました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました