ab.com コミュニティ

ActiveBasicを通したコミュニケーション
現在時刻 - 2024年3月28日(木) 18:47

全ての表示時間は UTC+09:00 です




新しいトピックを投稿する  トピックへ返信する  [ 4 件の記事 ] 
作成者 メッセージ
投稿記事Posted: 2021年10月31日(日) 00:57 
自分のソフトから他のアプリのlistviewの値を取得したいのですがうまくいきません。
手順としては、
目的のウィンドウを見つける。
そこから目的のlistviewを見つける
プロセスIDを取得
プロセスハンドルを取得
VirtualAllocEXでlistviewの値取得用の共有メモリAを確保
構造体LVITEMを設定、共有メモリAのアドレス等を設定する。
VirtualAllocEXでLVITEMのサイズの共有メモリBを確保
共有メモリBに先ほど設定した構造体LVITEMをWriteProcessMemoryにてコピーする。
SendMessage(hWnd,LVM_GETITEMTEXT,ほしい行,共有メモリB)をする。
ReadProcessMemoryで、通常のメモリに共有メモリAからデータを移す。
順次解放する。
手順は良いと思うのですが、取得したいアプリからはできませんでした。
自分で作成した、Listviewを持つ別アプリを作成し、それからは取得できました。
どちらも、64bitOS上の32bitで動く(?)アプリです。
何か原因があればご指摘願いたく思います。
コードと結果を置いておきます。
どうもSendMessageで取得長さ0で返ってきます。
独学なので、表現の名前など間違いもあるとは存じますがご了承ください。

windows10 64bit版
ActiveBasic ver4.24

-------結果---------
Count 2
GetWindowThreadProcessId>5096
プロセスID pid>4268
hProcess->396 processMemoryA->&h2A40000<-
pszText -> &h2A40000
WriteProcessMemoryB->1 > 40
SendMessage > answer Read length->0
ReadProcessMemory->1 > 2550/2550
VirtualFreeEX processMemoryA >1
VirtualFreeEX LVITEMMemoryB>1
text>
--------------------
コード:
Declare Function EnumWindows Lib "user32" (lpEnumFunc As DWord, lParam As DWord) As Long
Declare Function ReadProcessMemory Lib "kernel32" Alias "ReadProcessMemory" (hProcess as HANDLE , lpBaseAddress As VoidPtr, lpBuffer As VoidPtr, nSize As SIZE_T, lpNumberOfBytesWritten As DWordPtr) As BOOL
Declare Function WriteProcessMemory Lib "kernel32" Alias "WriteProcessMemory" (hProcess as HANDLE , lpBaseAddress As VoidPtr, lpBuffer As VoidPtr, nSize As SIZE_T, lpNumberOfBytesWritten As DWordPtr) As BOOL
Declare Function VirtualAllocEX Lib "kernel32" Alias "VirtualAllocEx" (hProcess as HANDLE , lpAddress As VoidPtr, dwSize As SIZE_T, flAllocationType As DWord, flProtect As DWord) As VoidPtr
Declare Function VirtualFreeEX Lib "kernel32" Alias "VirtualFreeEx" (hProcess as HANDLE , lpAddress As VoidPtr , dwSize As SIZE_T , dwFreeType As DWord) As BOOL


Function Get_LVM_GetItemTextEEXX(hWnd As HWND, y As Long, x As Long ) as BytePtr

	Dim text as BytePtr
	'プロセスIDを取得
	Dim pid As DWord				'プロセスID
	Dim hProcess As HANDLE			'プロセスハンドル
	Dim processMemoryA as VoidPtr
	Dim LVITEMMemoryB as VoidPtr
	Dim textlengthA as long			'取得文字列の長さ
	Dim LVITEMlengthB as long			'構造体の長さ
	Dim lvi As LVITEM				
	Dim count as DWord

	ADText(GetDlgItem(hMainWnd,EditBox1) , "Count " +Str$(ListView_GetItemCount( hWnd )) +ex"\r\n")
	       
	text = 0
	pid = 0
	hProcess = 0
	processMemoryA = 0
	textlengthA = 0
	'指定されたプロセスの仮想アドレス空間内のメモリ領域の状態を予約
	ADText(GetDlgItem(hMainWnd,EditBox1) , ex"GetWindowThreadProcessId>"+Str$(GetWindowThreadProcessId( hWnd  ,VarPtr(pid)))+ex"\r\n")	'プロセスIDを取得
	hProcess=OpenProcess( PROCESS_VM_OPERATION + PROCESS_VM_READ + PROCESS_VM_WRITE, FALSE, pid)						'プロセスハンドルを取得
	ADText(GetDlgItem(hMainWnd,EditBox1) , ex"プロセスID pid>"+Str$(pid)+ex"\r\n")
	'メモリを確保
	processMemoryA = VirtualAllocEX( hProcess , NULL 	   , MaxPath      , MEM_COMMIT + MEM_RESERVE , PAGE_READWRITE)		'共有メモリAを確保
	ADText(GetDlgItem(hMainWnd,EditBox1) , "hProcess->" + Str$(hProcess as Long)+" processMemoryA->&h"+Hex$(processMemoryA as Long)+ex"<-\r\n")	'確認
								lvi.mask		=LVIF_TEXT 
								lvi.iItem		=y
								lvi.iSubItem	=x				
								lvi.cchTextMax	=MaxPath			
								lvi.pszText		=processMemoryA 	'共有メモリAを設定
	ADText(GetDlgItem(hMainWnd,EditBox1) , "pszText -> &h" + Hex$(lvi.pszText	) + ex"\r\n" )		'確認
	LVITEMlengthB = SizeOf(LVITEM)
	LVITEMMemoryB = VirtualAllocEX( hProcess , NULL 	   , LVITEMlengthB      , MEM_COMMIT + MEM_RESERVE , PAGE_READWRITE)	'共有メモリBを確保
	'共有メモリBに構造体をコピー
	ADText(GetDlgItem(hMainWnd,EditBox1) , "WriteProcessMemoryB->" + Str$(WriteProcessMemory(hProcess , LVITEMMemoryB , VarPtr(lvi) , LVITEMlengthB ,  VarPtr(count) )) + " > "+ Str$(count) +ex"\r\n" )
	textlengthA = SendMessage(hWnd,LVM_GETITEMTEXT,y,LVITEMMemoryB)	'listviewに指示
	ADText(GetDlgItem(hMainWnd,EditBox1) , "SendMessage > answer Read length->" + Str$(textlengthA) +ex"\r\n" )	'確認
	text=calloc( MaxPath+1 )										'通常メモリを確保
	'共有メモリから通常メモリに回収
	ADText(GetDlgItem(hMainWnd,EditBox1) , "ReadProcessMemory->" + Str$(ReadProcessMemory(hProcess, processMemoryA , text , MaxPath , VarPtr(count) ) ) + " > "+ Str$(count) + "/" + Str$(MaxPath) +ex"\r\n" )
	'解放
	ADText(GetDlgItem(hMainWnd,EditBox1) , ex"VirtualFreeEX processMemoryA  >"+Str$(VirtualFreeEX(hProcess , processMemoryA   , 0 , MEM_RELEASE)) +ex"\r\n")
	ADText(GetDlgItem(hMainWnd,EditBox1) , ex"VirtualFreeEX LVITEMMemoryB>"+Str$(VirtualFreeEX(hProcess , LVITEMMemoryB , 0 , MEM_RELEASE)) +ex"\r\n")
	LVITEMMemoryB=0
	processMemoryA=0
	'プロセスハンドルを閉じる
	CloseHandle(hProcess)
	hProcess=0
	ADText(GetDlgItem(hMainWnd,EditBox1) , ex"text>"+MakeStr(text) +ex"\r\n")
	Get_LVM_GetItemTextEEXX = text

End function


通報する
ページトップ
   
 記事の件名: ちょっと進展
投稿記事Posted: 2021年11月01日(月) 23:51 
詳しく調べると全て取得できないのではなく
ウィンドウ内に存在する一部ListViewだけが取得できないようです。
できないところは意識的に、取得できないようになっているのか?
と感じています。そんなことはあるのでしょうか・・大切なものだとありそうですね。
そうか否かでも判断方法はあるのでしょうか。
または、なにか見落としているのでしょうか

取得できないところ
WindowText: なにもない
ClassName: SysListView32
ウィンドウハンドル1835126
ListView のハンドル 2556452
選択行->0<- 一番上
Count 2
GetWindowThreadProcessId>5096
プロセスID pid>4268
hProcess->436 processMemoryA->&h10210000<-
pszText -> &h10210000
WriteProcessMemoryB->1 > 40
SendMessage > answer Read length->0 読込が零
ReadProcessMemory->1 > 2550/2550
VirtualFreeEX processMemoryA >1
VirtualFreeEX LVITEMMemoryB>1
text>取得できない

取得できるところ
WindowText: なにもない
ClassName: SysListView32
ウィンドウハンドル 1835126
ListView のハンドル 2818836
選択行->2<-
Count 6
GetWindowThreadProcessId>5096
プロセスID pid>4268
hProcess->440 processMemoryA->&h10210000<-
pszText -> &h10210000
WriteProcessMemoryB->1 > 40
SendMessage > answer Read length->26  取得長さ
ReadProcessMemory->1 > 2550/2550
VirtualFreeEX processMemoryA >1
VirtualFreeEX LVITEMMemoryB>1
text>シグナル  ←取得できる


通報する
ページトップ
   
 記事の件名: もうちょっと進展
投稿記事Posted: 2021年11月02日(火) 23:00 
取得できないところは、どうも仮想リストビューだという事がわかりました。
仮想の場合はgetitemtextが使えないとわかりました。
仮想からすべてのアイテムの取得方法があれば
ご教授いただけないものかと思います。
しかしながら、ここも人が減ってしまったようなので
自分自身でも再度、方法を探ります。
なにかわかりましたらまた書き込みます。


通報する
ページトップ
   
投稿記事Posted: 2021年11月04日(木) 23:27 
結論からいうと通常の方法では無理とわかりました。
SysListView32 で OwnerDraw が設定されている場合 LVM_GETITEMTEXT は
反応しません。
OwnerDrawの場合、表示されているだけでそこにデータは無いそうです。
テキストととして見えている気がしますが、読み取れるものではないようです。
なので、別の方法を考えることにします。
読み取りたい元の方にも、コードを組みこめることが判明したことと、
最悪、キャプチャーはできるので、絵として照合して文字起こしをすることとします。
また、なにかありましたらご相談させていただきたいと思います。
ありがとうございます。


通報する
ページトップ
   
期間内表示:  ソート  
新しいトピックを投稿する  トピックへ返信する  [ 4 件の記事 ] 

全ての表示時間は UTC+09:00 です


オンラインデータ

このフォーラムを閲覧中のユーザー: Ahrefs [Bot], Baidu [Spider], Google [Bot] & ゲスト[23人]


トピック投稿:  可
返信投稿:  可
記事編集: 不可
記事削除: 不可
ファイル添付: 不可

検索:
ページ移動:  
Powered by phpBB® Forum Software © phpBB Limited
Japanese translation principally by ocean