ab.com コミュニティ https://www.activebasic.com/forum/ |
|
他のアプリのListView (SysListView32)の取得ができない https://www.activebasic.com/forum/viewtopic.php?t=4652 |
ページ 1 / 1 |
作成者: | kb2021 [ 2021年10月31日(日) 00:57 ] |
記事の件名: | 他のアプリのListView (SysListView32)の取得ができない |
自分のソフトから他のアプリの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 |
作成者: | kb2021 [ 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>シグナル ←取得できる |
作成者: | kb2021 [ 2021年11月02日(火) 23:00 ] |
記事の件名: | もうちょっと進展 |
取得できないところは、どうも仮想リストビューだという事がわかりました。 仮想の場合はgetitemtextが使えないとわかりました。 仮想からすべてのアイテムの取得方法があれば ご教授いただけないものかと思います。 しかしながら、ここも人が減ってしまったようなので 自分自身でも再度、方法を探ります。 なにかわかりましたらまた書き込みます。 |
作成者: | kb2021 [ 2021年11月04日(木) 23:27 ] |
記事の件名: | Re: 他のアプリのListView (SysListView32)の取得ができない |
結論からいうと通常の方法では無理とわかりました。 SysListView32 で OwnerDraw が設定されている場合 LVM_GETITEMTEXT は 反応しません。 OwnerDrawの場合、表示されているだけでそこにデータは無いそうです。 テキストととして見えている気がしますが、読み取れるものではないようです。 なので、別の方法を考えることにします。 読み取りたい元の方にも、コードを組みこめることが判明したことと、 最悪、キャプチャーはできるので、絵として照合して文字起こしをすることとします。 また、なにかありましたらご相談させていただきたいと思います。 ありがとうございます。 |
ページ 1 / 1 | 全ての表示時間は UTC+09:00 です |
Powered by phpBB® Forum Software © phpBB Limited https://www.phpbb.com/ |