前提・実現したいこと
Windowsのデスクトップアイコンの位置とファイル名を取得するマクロを作成しています。
発生している問題・エラーメッセージ
Windows7ではうまく動いたのですが、Windows10ではファイル名が取得できません。(ブランクになってしまう)
該当のソースコード
Excel
1Option Explicit 2 3'ウィンドウ検索 4Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _ 5 (ByVal lpClassName As String, _ 6 ByVal lpWindowName As String) As Long 7 8'ウィンドウ取得 9Private Declare Function GetWindow Lib "user32" _ 10 (ByVal hwnd As Long, _ 11 ByVal uCmd As Long) As Long 12 13'ウィンドウへのメッセージ送付 14Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _ 15 (ByVal hwnd As Long, _ 16 ByVal wMsg As Long, _ 17 ByVal wParam As Long, _ 18 ByVal lParam As Any) As Long 19 20'ウィンドウのプロセスIDとスレッドIDを取得 21Private Declare Function GetWindowThreadProcessId Lib "user32" _ 22 (ByVal hwnd As Long, _ 23 lpdwProcessId As Long) As Long 24 25'プロセスOpen 26Private Declare Function OpenProcess Lib "kernel32" _ 27 (ByVal dwDesiredAccess As Long, _ 28 ByVal bInheritHandle As Long, _ 29 ByVal dwProcessId As Long) As Long 30 31'仮想メモリ確保 32Private Declare Function VirtualAllocEx Lib "kernel32" _ 33 (ByVal hProcess As Long, _ 34 ByVal lpAddress As Long, _ 35 ByVal dwSize As Long, _ 36 ByVal flAllocationType As Long, _ 37 ByVal flProtect As Long) As Long 38 39'仮想メモリ解放 40Private Declare Function VirtualFreeEx Lib "kernel32" _ 41 (ByVal hProcess As Long, _ 42 lpAddress As Any, _ 43 ByVal dwSize As Long, _ 44 ByVal dwFreeType As Long) As Long 45 46'ハンドルクローズ 47Private Declare Function CloseHandle Lib "kernel32" _ 48 (ByVal hObject As Long) As Long 49 50'ウィンドウ位置・サイズ取得 51Private Declare Function GetWindowRect Lib "user32" _ 52 (ByVal hwnd As Long, _ 53 lpRect As RECT) As Long 54 55'メモリへの書込み 56Private Declare Function WriteProcessMemory Lib "kernel32" _ 57 (ByVal hProcess As Long, _ 58 lpBaseAddress As Any, _ 59 lpBuffer As Any, _ 60 ByVal nSize As Long, _ 61 lpNumberOfBytesWritten As Long) As Long 62 63'メモリからの読込み 64Private Declare Function ReadProcessMemory Lib "kernel32" _ 65 (ByVal hProcess As Long, _ 66 lpBaseAddress As Any, _ 67 lpBuffer As Any, _ 68 ByVal nSize As Long, _ 69 lpNumberOfBytesWritten As Long) As Long 70 71'============== 72' ユーザ定義型 73'============== 74 75'リストビューアイテム構造体 76Private Type LV_ITEM 77 mask As Long 78 iItem As Long 79 iSubItem As Long 80 state As Long 81 stateMask As Long 82 lpszText As Long 83 cchTextMax As Long 84 iImage As Long 85 lParam As Long 86 iIndent As Long 87End Type 88 89'データエリア構造体 90Type LV_TEXT 91 sItemText As String * 80 92End Type 93 94'サイズ・位置情報構造体 95Public Type RECT 96 Left As Long 97 Top As Long 98 Right As Long 99 Bottom As Long 100End Type 101 102 103'========== 104' 定数定義 105'========== 106 107Private Const LVM_GETITEMCOUNT As Long = &H1004 108Private Const LVM_GETITEM As Long = &H1005 109Private Const LVM_GETITEMRECT As Long = &H100E 110Private Const LVM_SETITEMPOSITION As Long = &H100F 111Private Const LVM_SETEXTENDEDLISTVIEWSTYLE = &H1036 112Private Const LVM_GETEXTENDEDLISTVIEWSTYLE = &H1037 113 114Private Const LVS_EX_SNAPTOGRID = &H80000 115 116Private Const GW_CHILD As Long = 5 117 118Private Const LVIR_BOUNDS As Long = 0 119Private Const LVIR_ICON As Long = 1 120Private Const LVIR_LABEL As Long = 2 121Private Const LVIR_SELECTBOUNDS As Long = 3 122 123Private Const LVIF_TEXT = &H1 124 125Private Const PROCESS_VM_OPERATION = &H8 126Private Const PROCESS_VM_READ = &H10 127Private Const PROCESS_VM_WRITE = &H20 128 129Private Const MEM_COMMIT = &H1000 130Private Const MEM_RESERVE = &H2000 131Private Const MEM_DECOMMIT = &H4000 132Private Const MEM_RELEASE = &H8000 133 134Private Const PAGE_READWRITE = &H4& 135 136 137'共有メモリ確保 138Public Function GetSharedMem(ByVal pid As Long, ByVal memSize As Long, hProc As Long) As Long 139 hProc = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, pid) 140 GetSharedMem = VirtualAllocEx(ByVal hProc, ByVal 0&, ByVal memSize, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE) 141End Function 142 143'共有メモリ開放 144Public Sub FreeSharedMem(ByVal hProc As Long, ByVal MemAddress As Long, ByVal memSize As Long) 145 Call VirtualFreeEx(hProc, ByVal MemAddress, memSize, MEM_RELEASE) 146 CloseHandle hProc 147End Sub 148 149 150Sub get_icon_pos_name() 151 152 '変数定義 153 Dim lngTopWindow As Long 'Topウィンドウのウィンドウハンドル 154 Dim lngChildWindow As Long '子ウィンドウのウィンドウハンドル 155 Dim lngSysListView32 As Long 'デスクトップのウィンドウハンドル 156 Dim rc As RECT '位置・サイズ格納用 157 158 Dim pid As Long 'プロセスID 159 Dim tid As Long 'スレッドID 160 Dim hProc As Long 'プロセスハンドル 161 Dim li As LV_ITEM 'パラメータ 162 Dim lt As LV_TEXT 'テキストエリア 163 Dim lpShared1 As Long 'パラメータエリア 164 Dim lpShared2 As Long 'データエリア 165 Dim lpShared3 As Long '位置 166 Dim lWritten As Long '書込済バイト数 167 Dim lngRC As Long '処理結果格納用 168 Dim maxitem As Long 'デスクトップのアイコン数 169 Dim i As Long 'ループカウンタ 170 Dim p As Long 'テキスト終端文字列の位置 171 Dim iconName As String 'アイコンの名前 172 Dim NetObj As Object 'NetworkObject 173 Dim strCompName As String 'コンピュータ名 174 175 'ExplorerのTopウィンドウを見つける 176 lngTopWindow = FindWindow("Progman", "Program Manager") 177 178 'Topウィンドウが見つかった時 179 If lngTopWindow Then 180 181 '子ウィンドウを取得 182 lngChildWindow = GetWindow(lngTopWindow, GW_CHILD) 183 184 '子ウィンドウが取得できたとき 185 If lngChildWindow Then 186 187 'さらにその子ウィンドウを取得(これがデスクトップ) 188 lngSysListView32 = GetWindow(lngChildWindow, GW_CHILD) 189 190 'デスクトップのウィンドウが取得できたとき 191 If lngSysListView32 Then 192 193 'デスクトップサイズの取得 194 GetWindowRect lngSysListView32, rc 195 196 197 'デスクトップアイコンの数を取得 198 maxitem = SendMessage(lngSysListView32, _ 199 LVM_GETITEMCOUNT, _ 200 0&, _ 201 ByVal 0&) 202 203 'コンピュータ名を取得 204 Set NetObj = CreateObject("WScript.Network") 205 strCompName = NetObj.ComputerName 206 Set NetObj = Nothing 207 208 'デスクトップのプロセスIDとスレッドIDを取得 209 tid = GetWindowThreadProcessId(lngSysListView32, pid) 210 211 'デスクトップとの共有メモリを確保(アドレスが返ってくる) 212 lpShared1 = GetSharedMem(pid, LenB(li), hProc) 'リストビュー構造体 213 lpShared2 = GetSharedMem(pid, LenB(lt), hProc) '取得文字列用 214 lpShared3 = GetSharedMem(pid, LenB(rc), hProc) 'アイコン位置用 215 216 217 'デスクトップのアイコン数分ループする 218 For i = 0 To maxitem - 1 219 220 'LVM_GETITEMへSendMessageする際のパラメータを設定 221 li.mask = LVIF_TEXT '文字情報取得 222 li.iItem = i '行インデックス 223 li.iSubItem = 0 '列インデックス 224 li.lpszText = lpShared2 '文字格納アドレス 225 li.cchTextMax = LenB(lt) '文字数最大値 226 227 'ローカル変数の値を共有メモリに書き込み 228 lngRC = WriteProcessMemory(hProc, ByVal lpShared1, li, LenB(li), lWritten) 229 lngRC = WriteProcessMemory(hProc, ByVal lpShared2, lt, LenB(lt), lWritten) 230 231 'デスクトップに対して情報の取得依頼(ファイル名) 232 lngRC = SendMessage(lngSysListView32, LVM_GETITEM, 0, ByVal lpShared1) 233 234 '共有メモリからローカル変数に読み込み 235 lngRC = ReadProcessMemory(hProc, ByVal lpShared2, lt, LenB(lt), lWritten) 236 237 'アイコン名を初期化 238 iconName = "" 239 240 '文字数を取得(終端文字がNullCharなのでその前まで) 241 p = InStr(lt.sItemText, vbNullChar) - 1 242 243 '空っぽでなければ 244 If p > 0 Then 245 246 'アイコン名を取得 247 iconName = Left(lt.sItemText, p) 248 249 End If 250 251 'LVM_GETITEMRECTへSendMessageする際のパラメータを設定 252 rc.Left = LVIR_ICON 'アイコンの外接する四角形サイズ取得 253 254 'ローカル変数の値を共有メモリに書き込み 255 lngRC = WriteProcessMemory(hProc, ByVal lpShared3, rc, LenB(rc), lWritten) '書込み 256 257 'デスクトップに対して情報の取得依頼(アイコン位置) 258 lngRC = SendMessage(lngSysListView32, LVM_GETITEMRECT, i, ByVal lpShared3) '取得依頼 259 260 '共有メモリからローカル変数に読み込み 261 lngRC = ReadProcessMemory(hProc, ByVal lpShared3, rc, LenB(rc), lWritten) '読込 262 263 Debug.Print "No. :" & i 264 Debug.Print "TOP :" & rc.Top 265 Debug.Print "LEFT :" & rc.Left 266 Debug.Print "RIGHT :" & rc.Right 267 Debug.Print "BOTTOM :" & rc.Bottom 268 Debug.Print "iconName:" & iconName 269 270 Next 271 272 '共有メモリ開放 273 FreeSharedMem hProc, lpShared1, LenB(li) 274 FreeSharedMem hProc, lpShared2, LenB(lt) 275 FreeSharedMem hProc, lpShared3, LenB(rc) 276 277 End If 278 End If 279 End If 280End Sub 281 282
試したこと
共有メモリの使い方等、色々調べてみたのですが、原因が分からないので質問させていただきました。
補足情報(FW/ツールのバージョンなど)
Excel 2010 VBA
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/04/09 13:48