<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; AHK: Получение имени файла под курсором в Проводнике]]></title>
	<link rel="self" href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=5634&amp;type=atom" />
	<updated>2011-03-23T18:23:43Z</updated>
	<generator>PunBB</generator>
	<id>http://forum.script-coding.com/viewtopic.php?id=5634</id>
		<entry>
			<title type="html"><![CDATA[AHK: Получение имени файла под курсором в Проводнике]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=46728#p46728" />
			<content type="html"><![CDATA[<p>Скрипт определяет содержание первой колонки (имя файла/папки) той строки контрола <em>SysListView32</em> проводника Windows, над которой находится курсор. При небольшой задержке курсора над строкой появляется <em>ToolTip</em> с именем файла.</p><p><strong>Принцип работы скрипта</strong>. При остановке курсора над контролом <em>SysListView32</em> определяются координаты курсора, затем определяются координаты всех видимых строк, а также считывается текст из их первых колонок. При пересечении координат курсора и какой-либо из строк содержание её первой колонки показывается в <em>ToolTip</em>&#039;е.</p><p>Координаты строк считываются с помощью посылки контролу <em>SysListView32</em> сообщения <strong><a href="http://msdn.microsoft.com/en-us/library/bb761049%28VS.85%29.aspx">LVM_GETITEMRECT</a></strong>. Некоторая сложность в том, что информацию это сообщение может записать только в буфер, находящийся в виртуальном адресном пространстве процесса, которому принадлежит контрол. Поэтому перед использованием сообщения нужно зарезервировать место в виртуальной памяти процесса под буфер (это делает ф-ция <a href="http://msdn.microsoft.com/en-us/library/aa366890%28VS.85%29.aspx"><em>VirtualAllocEx()</em></a>), а затем уже скопировать информацию из него в буфер, принадлежащий процессу скрипта (<em><a href="http://msdn.microsoft.com/en-us/library/ms680553%28VS.85%29.aspx">ReadProcessMemory()</a></em>).<br /></p><div class="codebox"><pre><code>   LVM_FIRST := 0x1000
   LVM_GETITEMCOUNT := (LVM_FIRST + 4)
   LVM_GETTOPINDEX := (LVM_FIRST + 39)
   LVM_GETITEMRECT := (LVM_FIRST + 14)
   PROCESS_VM_OPERATION := 0x8
   PROCESS_VM_READ := 0x10
   MEM_COMMIT := 0x1000
   PAGE_READWRITE := 0x4
   MEM_RELEASE := 0x8000

   #Persistent
   Process, Priority,, H
   CoordMode, Mouse
   CoordMode, ToolTip
   VarSetCapacity(RECT, 16)   ; буфер в адресном пространстве скрипта
   SetTimer, MouseGetPos, 50
   Return

MouseGetPos:
   MouseGetPos,,,, Control
   if !InStr(Control, &quot;SysListView&quot;)
   {
      ToolTip
      Return
   }

   MouseGetPos, XM, YM, Win_ID, LV_ID, 2
   if (XM != XM_Prev || YM != YM_Prev)
   {
      ToolTip
      SetTimer, GetItem, -100
   }
   XM_Prev := XM, YM_Prev := YM
   Return

GetItem:
   WinGetPos, X_LV, Y_LW,,, ahk_id %LV_ID%
   WinGet, PID, PID, ahk_id %Win_ID%

   SendMessage, LVM_GETITEMCOUNT,,,, ahk_id %LV_ID%
   Rows := ErrorLevel
   SendMessage, LVM_GETTOPINDEX,,,, ahk_id %LV_ID%
   TopIndex := ErrorLevel
   ControlGet, Text, List, Col1,, ahk_id %LV_ID%

   Stop =
   While !Stop &amp;&amp; (A_Index &lt;= Rows - TopIndex)
   {
      CurrentItem := TopIndex + A_Index - 1

      hProcess := DllCall(&quot;OpenProcess&quot;, UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ
                                       , UInt, 0
                                       , UInt, PID)
   ; буфер в адресном пространстве окна проводника:
      pBuffer := DllCall(&quot;VirtualAllocEx&quot;, UInt, hProcess
                                         , UInt, 0
                                         , UInt, 16
                                         , UInt, MEM_COMMIT
                                         , UInt, PAGE_READWRITE)

      SendMessage, LVM_GETITEMRECT, CurrentItem, pBuffer,, ahk_id %LV_ID%
      DllCall(&quot;ReadProcessMemory&quot;, UInt, hProcess
                                 , UInt, pBuffer
                                 , UInt, &amp;RECT
                                 , UInt, 16
                                 , UInt, 0)

      Left := NumGet(RECT), Right := NumGet(RECT, 8)
      Top := NumGet(RECT, 4), Bottom := NumGet(RECT, 12)

      DllCall(&quot;VirtualFreeEx&quot;, UInt, hProcess
                             , UInt, pBuffer
                             , UInt, 0
                             , UInt, MEM_RELEASE)
      DllCall(&quot;CloseHandle&quot;, UInt, hProcess)

      if (XM &gt;= X_LV + Left &amp;&amp; XM &lt;= X_LV + Right &amp;&amp; YM &gt;= Y_LW + Top &amp;&amp; YM &lt;= Y_LW + Bottom)
      {
         Loop, parse, Text, `n
         {
            if (A_Index = CurrentItem + 1)
            {
               ToolTip, %A_LoopField%, XM+20, YM-5   ; в переменной A_LoopField имя файла под курсором
               Stop = 1
               Break
            }
         }
      }
   }
   Return</code></pre></div><p><a href="http://forum.script-coding.com/viewtopic.php?id=5609"><span class="bbu">Тема</span></a> для обсуждения на форуме.</p>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2011-03-23T18:23:43Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=46728#p46728</id>
		</entry>
</feed>
