ウィンドウハンドルHWND型の数値化

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
konkonkitsunejanaiyo

ウィンドウハンドルHWND型の数値化

#1

投稿記事 by konkonkitsunejanaiyo » 9年前

C++の質問です。

ウィンドウハンドルHWND型を数値化する方法をご教授下さい。

何をしたいのかというと、VisualStudio付属のspy++を使用して、
色々な事をしています。

spy++の各ウィンドウの「ウィンドウ」文字列の右にウィンドウハンドルID?のような、
ウィンドウ毎に一意につけられたIDが表示されています。
このIDを取得したいのです。

なのでウィンドウハンドルHWND型を数値化出来れば、上記spy++のウィンドウハンドルID?
と同じ物を取得できると考えました。

よって、ウィンドウハンドルHWND型を数値化する方法をご教授下さい。
※もしかしたら目的と実施しようとしている事が間違っているかもしれません
※その場合は正しくウィンドウハンドルID?を取得できる方法をご教授下さい

かずま

Re: ウィンドウハンドルHWND型の数値化

#2

投稿記事 by かずま » 9年前

konkonkitsunejanaiyo さんが書きました: ウィンドウハンドルHWND型を数値化する方法をご教授下さい。
キャストするだけです。

コード:

#include <iostream>
#include <windows.h>
 
using namespace std;

int main(void)
{
	HWND hWnd = FindWindow("notepad", NULL);
	DWORD i = (DWORD)hWnd;
	DWORD j = DWORD(hWnd);
	DWORD k = reinterpret_cast<DWORD>(hWnd);
	cout << "sizeof(HWND) = " << sizeof(HWND) << endl;
	cout << "hWnd = " << hWnd << endl;
	cout << "i = " << i << endl;
	cout << "j = " << j << endl;
	cout << "k = " << k << endl;
	cout << "k(hex) = " << hex << k << endl;

    return 0;
}
コンパイルします。

コード:

C:\tmp>cl -EHsc a.cpp user32.lib
Microsoft(R) C/C++ Optimizing Compiler Version 18.00.31101 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

a.cpp
Microsoft (R) Incremental Linker Version 12.00.31101.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:a.exe
a.obj
user32.lib
メモ帳を起動して実行すると、

コード:

C:\tmp>a
sizeof(HWND) = 4
hWnd = 00040800
i = 264192
j = 264192
k = 264192
k(hex) = 40800

kaiketsu

Re: ウィンドウハンドルHWND型の数値化

#3

投稿記事 by kaiketsu » 9年前

ありがとうございます解決しました。
.Netの世界の文字列型に変換する必要があるので以下としました。

コード:

String^ hw_id = static_cast<UINT>(reinterpret_cast<UINT_PTR>(this->hw)).ToString("X");

YuO
記事: 947
登録日時: 14年前
住所: 東京都世田谷区

Re: ウィンドウハンドルHWND型の数値化

#4

投稿記事 by YuO » 9年前

64bit化時にいろいろまずそうですが……。

・C/C++の世界の話
HWND等,ハンドルは全て実装としてはポインタ型になっています。
昔はvoid *のtypedefでしたが,現在は適当な構造体へのポインタ型だったりします。
なので,
  • 文字列表現が欲しいならば,snprintfやswprintfに指示子%pを与え,void *へキャストしたハンドルを対応させる
  • 整数表現が欲しいならば,stdint.hまたはcstdintをインクルードし,intptr_tまたはuintptr_tへキャストする
で得られます。

・.NET Frameworkの世界での話
基本的に,ハンドルはSystem::IntPtr (まれにSystem::UIntPtr) を使って表します。
ただし,System::Runtime::InteropServices::SafeHandleの派生クラスを使える場合はそちらを使うことが推奨されます (.NET 2.0以降)。
# GDIハンドルはIntPtr剥き出しで使うことの方が多いでしょう (SafeHandleはKernel系に使われることが多い)。
さて,ハンドルからIntPtrへの変換は,単純にキャストするか,IntPtrのvoid *を引数にとるコンストラクタを使います。
文字列表現は普通にToStringメソッドの呼び出しで得られ,数値表現はToInt32またはToInt64の呼び出しでintまたはlongの値が得られます。
# 桁数を揃えるには,IntPtr::Sizeを参照する必要があります。
kaiketsu さんが書きました: .Netの世界の文字列型に変換する必要があるので以下としました。

コード:

String^ hw_id = static_cast<UINT>(reinterpret_cast<UINT_PTR>(this->hw)).ToString("X");

コード:

auto hw_id = static_cast<IntPtr>(this->hw).ToString("X" + IntPtr::Size * 2);
前の0埋めが不要なら,ToString("X")でよいです。

UINT_PTRまでであれば問題ないのですが,UINTに変換すると,64bitプロセスとして動作している場合に値が欠落する可能性があります。

閉鎖

“C言語何でも質問掲示板” へ戻る