|
魔界の仮面弁士 さんへ 早速の返答大変ありがとうございます。 しかしかなりハードルが高いです。ただあきらめる訳にはいきませんので、よろしくお願いいたします。
> No95760 のように UIAutomation で拾えないでしょうか (未確認) > https://yizm.work/winactor/uiautomation_combobox_listview/ > 私には、難しくてちょっと手が出ませんでした。
> 相手のプロセスが管理者実行されていて、 > こちらのプロセスはそうではない…という状態にはなっていませんか?
フリーの画像位置情報取得ツールのリストビューの内容を取得したいのですが、管理者実行では 無いと思います
> > 自身のアプリは、x86 / AnyCPU32bitPreferred / AnyCPU / x64 いずれでも良いのですか? > > 64bit プロセスから 64bit プロセスの ListView を読み取ろうとしているのか > 64bit プロセスから 32bit プロセスの ListView を読み取ろうとしているのか > 32bit プロセスから 64bit プロセスの ListView を読み取ろうとしているのか > 32bit プロセスから 32bit プロセスの ListView を読み取ろうとしているのか > 1プロセスにおける32ビットと64ビットの混在のことでしょうか? ネットには以下 ネィティブアプリケーションの場合、プラットフォームの異なるExeとDllは共存できません。 ・x64のExeと x64のDLL ⇒動作する ・x86のExeと x86のDLL ⇒動作する ・x64のExeと x86のDLL ⇒動作しない ・x86のExeと x64のDLL ⇒動作しない とありました。最近は、64OSが主流なので、他のプロセスが32,64であっても動作してもらえると 助かります。どちらかに絞るなら 画像位置情報取得ツールに順じ64でしょうか。
結果ですが、 1) intRc = WriteProcessMemory(hProc, lpShared1, li, Marshal.SizeOf(li), lWritten) '書込み 2) intRc = SendMessageW(hWnd, LVM_GETITEMW, 0, li) '取得依頼 3) intRc = ReadProcessMemory(hProc, lpShared2, strBuffer(0), TEXT_SIZE, 0) '読込 1)intRc の値が1でうまくいってないと思います 2)画像位置情報取得ツールが終了しまいました。何らかの影響を与えた点では、一歩前進です 1)の実行結果が、ポイントとは思いますが、私には、難しくてまた助言して頂けると助かります。 以下の抜粋ですが変更後コードを掲載いたします
'---------------------- ' ウィンドウメッセージ '---------------------- ' 魔界の仮面弁士さんより Private Declare Unicode Function SendMessageW Lib "user32" _ (hWnd As IntPtr, wMsg As Integer, wParam As IntPtr, ByRef lvi As LV_ITEMW) As IntPtr #Const NTDDI_WINXP = &H5010000& #Const NTDDI_VISTA = &H6000000& <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> Private Structure LV_ITEMW Public mask As UInteger Public iItem As Integer Public iSubItem As Integer Public state As UInteger Public stateMask As UInteger <MarshalAs(UnmanagedType.LPTStr)> Public lpszText As String Public cchTextMax As Integer Public iImage As Integer Public lParam As IntPtr #If NTDDI_VERSION >= NTDDI_WINXP Then Public iIndent As Integer Public iGroupId As Integer Public cColumns As UInteger #End If #If NTDDI_VERSION >= NTDDI_VISTA Then Public puColumns As IntPtr Public piColFmt As IntPtr Public iGroup As Integer #End If End Structure
'------------------------------------ ' システム関数 '------------------------------------ 'APIは省略 '------------------------------------ 'リストビュー定義 '------------------------------------
Public Const WC_LISTVIEW As String = "SysListView32"
Private Const LVM_FIRST As Integer = &H1000 Private Const LVM_GETTITEMCOUNT As Integer = (LVM_FIRST + 4) 'アイテムの数を取得 'Private Const LVM_GETITEMW As Integer = &H1005 'アイテムの属性を取得 従来の文 Private Const LVM_GETITEMA As Integer = &H1000 + 5 ' 魔界の仮面弁士さんより変更 Private Const LVM_GETITEMW As Integer = &H1000 + 75 ' 魔界の仮面弁士さんより変更 Private Const LVM_GETHEADER As Integer = &H101F 'ヘッダコントロールを取得 Private Const LVM_GETITEMTEXTA As Decimal = (LVM_FIRST + 45) Private Const HDM_GETITEMCOUNT As Integer = &H1200 Private Const LVIF_TEXT As Integer = &H1 Private Const LVIF_IMAGE As Integer = &H2 Private Const LVIF_PARAM As Integer = &H4 Private Const LVIF_STATE As Integer = &H8
<StructLayout(LayoutKind.Sequential)> Structure LV_TEXT 'データエリア Dim sItemText As Byte End Structure
'------------------------------------ ' キーボード '------------------------------------ 'Public Const VK_ESCAPE As Integer = &H1B 'Escape Public Declare Function GetAsyncKeyState Lib "user32.dll" (ByVal vKey As Integer) As Integer
'------------------------------- ' リストビューボックス文字列取得 '-------------------------------
Public Function MyGetListViewItem(ByRef hWnd As Integer) As String
Dim i, p, k As Integer Dim Dt As String
Dim pid, tid As Integer 'プロセスID,スレッドID Dim hProc As Integer 'プロセスハンドル Dim intRc As Integer
Dim hWndHeader As Integer 'リストビューヘッダのハンドル Dim nCountRow, nCountCol As Integer '行列数
'---------------------- ' 共有メモリアドレス '---------------------- Dim lpShared1 As Long 'パラメータエリア Dim lpShared2 As Integer 'データエリア Dim lWritten As Integer = 0 '書込済バイト数
'---------------------- ' リストビューパラメータ '---------------------- Dim li As New LV_ITEMW 'パラメータ Const TEXT_SIZE As Integer = 80 Dim strBuffer(TEXT_SIZE) As Byte
MyGetListViewItem = ""
'リストビューの項目(行)数取得 nCountRow = SendMessage(hWnd, LVM_GETTITEMCOUNT, 0, 0) If nCountRow = 0 Then Exit Function
'リストビューの列数取得 hWndHeader = SendMessage(hWnd, LVM_GETHEADER, 0, 0) nCountCol = SendMessage(hWndHeader, HDM_GETITEMCOUNT, 0, 0) If (nCountCol = 0) Then Exit Function
'プロセスIDとスレッドID取得 tid = GetWindowThreadProcessId(hWnd, pid)
'共有メモリ確保 lpShared1 = GetSharedMem(pid, Marshal.SizeOf(li), hProc) lpShared2 = GetSharedMem(pid, TEXT_SIZE, hProc)
Dt = ""
For i = 0 To nCountRow - 1 '行数分ループ For k = 0 To nCountCol - 1 '列数分ループ
'メッセージパラメータセット li.iItem = i '行インデックス li.iSubItem = k '列インデックス
li.mask = LVIF_STATE '文字情報取得 li.lpszText = lpShared2 '文字格納アドレス li.cchTextMax = TEXT_SIZE '文字数最大値
intRc = WriteProcessMemory(hProc, lpShared1, li, Marshal.SizeOf(li), lWritten) '書込み intRc = SendMessageW(hWnd, LVM_GETITEMW, 0, li) '取得依頼 SendMessageWに変更 intRc = ReadProcessMemory(hProc, lpShared2, strBuffer(0), TEXT_SIZE, 0) '読込
Dim tmp As String tmp = System.Text.Encoding.Default.GetString(strBuffer) p = InStr(tmp, vbNullChar) - 1 '文字数 If p > 0 Then Dt = Dt & Left(tmp, p) Dt &= vbTab 'タブ追加
Next k Dt &= vbCrLf '改行追加
Next i
'共有メモリ開放 FreeSharedMem(hProc, lpShared1, Marshal.SizeOf(li)) FreeSharedMem(hProc, lpShared2, TEXT_SIZE)
MyGetListViewItem = Dt
End Function
|