<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; AHK: Class Gui ObjBindMethod блокирует деструктор __Delete]]></title>
	<link rel="self" href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=16828&amp;type=atom" />
	<updated>2021-12-22T15:41:52Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.script-coding.com/viewtopic.php?id=16828</id>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Class Gui ObjBindMethod блокирует деструктор __Delete]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=151365#p151365" />
			<content type="html"><![CDATA[<p>Идея была в том, что OnMessage для каждого сообщения вызывается только один (самый первый) раз, а не при каждом создании инстанса класса. Но здесь ошибка, должно быть:<br /></p><div class="codebox"><pre><code>if (TestClass.DerivedObjectsCount = 0)
{
   OnMessage(0x201, this.LBUTTONDOWNFunc)  ; activate the message handler
   OnMessage(0x208, this.MBUTTONUPFunc)  ; activate the message handler
}
TestClass.DerivedObjectsCount += 1</code></pre></div><p>При создании инстанса увеличивается свойство DerivedObjectsCount, которое принадлежит самому классу, то-есть читается во всех инстансах. Соответственно при удалении инстанса это значение уменьшается, при достижении нуля удаляется обработчик сообщения.</p>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2021-12-22T15:41:52Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=151365#p151365</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Class Gui ObjBindMethod блокирует деструктор __Delete]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=151363#p151363" />
			<content type="html"><![CDATA[<p>Вот такое решение нашлось форуме официального сайта:<br /><a href="https://www.autohotkey.com/boards/viewtopic.php?t=6966">https://www.autohotkey.com/boards/viewtopic.php?t=6966</a></p><p>А вот пример переделанного кода:<br /></p><div class="codebox"><pre><code>
#SingleInstance, force

Test1 := new TestClass(&quot;Test1&quot;, 300, 200)
Test2 := new TestClass(&quot;Test2&quot;, 450, 200)
Test3 := new TestClass(&quot;Test3&quot;, 600, 200)
return

Esc::ExitApp

class TestClass {
    static DerivedObjectsCount := 0, DerivedObjects := {}
    static LBUTTONDOWNFunc := ObjBindMethod(TestClass, &quot;WM_LBUTTONDOWN&quot;)    ; store the BoundFunc object so you may remove the message handler
    static MBUTTONUPFunc := ObjBindMethod(TestClass, &quot;WM_MBUTTONUP&quot;)    ; store the BoundFunc object so you may remove the message handler
    __New(Name, x, y) {
        Gui, New, +Hwndhwnd
        Gui %hwnd%: -Caption +AlwaysOnTop +ToolWindow +OwnDialogs
        Gui %hwnd%: Add, Text, x5 y5 w100 h20, % Name
        Gui %hwnd%: Add, Text, x5 y30 w100 h20 hwndhPos, % x &quot;, &quot; y
        Gui %hwnd%: Show, % &quot;x&quot; x &quot; y&quot; y &quot; w110 h55 NA&quot;
        this.hPos := hPos, this.hwnd := hwnd, this.Name := Name
        TestClass.DerivedObjectsCount += 1 			; пояснить
        if (TestClass.DerivedObjectsCount &gt; 0)
        {
            OnMessage(0x201, this.LBUTTONDOWNFunc)  ; activate the message handler
            OnMessage(0x208, this.MBUTTONUPFunc)  ; activate the message handler
        }

        TestClass.DerivedObjects[hwnd] := &amp;this     ; store object&#039;s address
    }

    WM_LBUTTONDOWN() {
        if (TestClass.DerivedObjects.HasKey(A_Gui)) { ; GUI which belongs to object derived from this class
            PostMessage, 0xA1, 2
            KeyWait, LButton
            obj := Object(TestClass.DerivedObjects[A_Gui])
            WinGetPos, x,y,,, % &quot;ahk_id &quot; obj.hwnd
            GuiControl, % obj.hwnd &quot;:&quot;, % obj.hPos, % x &quot;, &quot; y
            return 0    ; no need to call any other message handlers
        }
    }

    WM_MBUTTONUP()
    {
        if (TestClass.DerivedObjects.HasKey(A_Gui)) { ; GUI which belongs to object derived from this class
            obj := Object(TestClass.DerivedObjects[A_Gui])
            obj.__Delete()

            return 0    ; no need to call any other message handlers
        }
    }

    __Delete() {
        hwnd := this.hwnd
        if(WinExist(&quot;ahk_id &quot; . hwnd))
        {
            Gui %hwnd%: Destroy 	; если гуи был уничтожен &quot;извне&quot;
            stdout(hwnd . &quot; deleted&quot;)
        }

        TestClass.DerivedObjects.Delete(hwnd)           ; Lexikos: &quot;Use .Delete(hwnd) or .Remove(hwnd, &quot;&quot;) and not .Remove(hwnd).&quot;
        TestClass.DerivedObjectsCount -= 1
        if (TestClass.DerivedObjectsCount = 0)          ; if no more derived objects
        {
            OnMessage(0x201, this.LBUTTONDOWNFunc, 0)   ; remove message handler
            OnMessage(0x208, this.MBUTTONUPFunc, 0)   ; remove message handler
        }
    }
}
</code></pre></div><p>Уважаемого <strong>teadrinker</strong> прошу пояснить использование имени класса в конструкторе (комментарий &quot;пояснить&quot;).</p>]]></content>
			<author>
				<name><![CDATA[Шикарная услуга плана]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=40534</uri>
			</author>
			<updated>2021-12-22T13:49:18Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=151363#p151363</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Class Gui ObjBindMethod блокирует деструктор __Delete]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=151231#p151231" />
			<content type="html"><![CDATA[<p>Вроде никак, можно просто удалить ресурсы.</p>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2021-12-17T08:30:51Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=151231#p151231</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Class Gui ObjBindMethod блокирует деструктор __Delete]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=151228#p151228" />
			<content type="html"><![CDATA[<p><strong>__Михаил__</strong>, да<br /><strong>teadrinker</strong> ого, спасибо, это работает, держи плюс в карму!</p><p>Вот еще задачка, а как по средней кнопке мыши закрывать интерфейс,&nbsp; как сослаться в функции обрабатывающей событие на деструктор этого объекта?<br />Код для примера:<br /></p><div class="codebox"><pre><code>
#SingleInstance force


gui1 := new myClass(&quot;gui1&quot;)
gui1.Show(100, 200)

gui2 := new myClass(&quot;gui2&quot;)
gui2.Show(100, 300)

Sleep, 4000

; уничтожение объектов
gui1 := {}
gui2 := 1



class myClass
{
   __New(name)
   {
      this.name := name
      Gui, % this.name . &quot;: New&quot;
      Gui, % this.name . &quot;: Add&quot;, Text,, % &quot;this is Gui named: &quot; . this.name
      this.OnMessage := new this._OnMessage
   }

   Show(x := &quot;Center&quot;, y := &quot;Center&quot;)
   {
      Gui, % this.name . &quot;: Show&quot;, % &quot;x&quot; . x . &quot;y&quot; . y, NA
   }

   __Delete()
   {
      Gui, % this.name . &quot;: Destroy&quot;
      this.OnMessage.Clear()
      stdout(&quot;destroy &quot; . this.name)
   }

   class _OnMessage {
      __New() {
         this.fn := ObjBindMethod(this, &quot;onMouseMove&quot;)
         this.fn2 := ObjBindMethod(this, &quot;onMButtonUp&quot;)
         OnMessage(0x200, this.fn)
         OnMessage(0x0208, this.fn2)
      }

      onMouseMove( wparam, lparam, msg, hwnd ) ; добавляет возможность перетаскивать мышкой в любом месте интерфейса
      {
         if wparam = 1 ; LButton
            PostMessage, 0xA1, 2,,, A ; WM_NCLBUTTONDOWN
      }

      onMButtonUp( wparam, lparam, msg, hwnd )
      {
         ; по нажатию средней кнопки мыши - закрывать интерфейс
         stdout(&quot;wparam: &quot; . wparam . &quot;, lparam: &quot; . lparam . &quot;, msg: &quot; . Format(&quot;{1:#x}&quot;, msg) . &quot;, hwnd: &quot; . Format(&quot;{1:#x}&quot;, hwnd) )
      }

      Clear() {
         OnMessage(0x200, this.fn, 0)
         OnMessage(0x0208, this.fn2, 0)
      }
   }
}


Esc::ExitApp
</code></pre></div>]]></content>
			<author>
				<name><![CDATA[Шикарная услуга плана]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=40534</uri>
			</author>
			<updated>2021-12-17T07:17:42Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=151228#p151228</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Class Gui ObjBindMethod блокирует деструктор __Delete]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=151218#p151218" />
			<content type="html"><![CDATA[<p>Примерно так:<br /></p><div class="codebox"><pre><code>#SingleInstance force


gui1 := new myClass(&quot;gui1&quot;) 
gui1.Show(100, 200)

gui2 := new myClass(&quot;gui2&quot;)
gui2.Show(100, 300)

Sleep, 4000

; уничтожение объектов
gui1 := {} 
gui2 := 1



class myClass
{
   __New(name)
   {
      this.name := name
      Gui, % this.name . &quot;: New&quot;
      Gui, % this.name . &quot;: Add&quot;, Text,, % &quot;this is Gui named: &quot; . this.name
      this.OnMessage := new this._OnMessage
   }

   Show(x := &quot;Center&quot;, y := &quot;Center&quot;)
   {
      Gui, % this.name . &quot;: Show&quot;, % &quot;x&quot; . x . &quot;y&quot; . y, NA
   }

   __Delete()
   {
      Gui, % this.name . &quot;: Destroy&quot;
      this.OnMessage.Clear()
      Msgbox, % &quot;destroy &quot; . this.name
   }
   
   class _OnMessage {
      __New() {
         this.fn := ObjBindMethod(this, &quot;onMouseMove&quot;)
         OnMessage(0x200, this.fn)
      }

      onMouseMove( wparam, lparam, msg, hwnd ) ; добавляет возможность перетаскивать мышкой в любом месте интерфейса
      {
         if wparam = 1 ; LButton
            PostMessage, 0xA1, 2,,, A ; WM_NCLBUTTONDOWN
      }
      
      Clear() {
         OnMessage(0x200, this.fn, 0)
      }
   }
}


Esc::ExitApp</code></pre></div>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2021-12-16T15:05:29Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=151218#p151218</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Class Gui ObjBindMethod блокирует деструктор __Delete]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=151217#p151217" />
			<content type="html"><![CDATA[<p>Обязательно через класс создавать окна?</p>]]></content>
			<author>
				<name><![CDATA[__Михаил__]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=40928</uri>
			</author>
			<updated>2021-12-16T15:05:07Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=151217#p151217</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[AHK: Class Gui ObjBindMethod блокирует деструктор __Delete]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=151216#p151216" />
			<content type="html"><![CDATA[<p>По всей видимости если применить ObjBindMethod к методу того же объекта, то он блокирует деструктор класса.<br />Вот код, который иллюстрирует проблему:</p><div class="codebox"><pre><code>
#SingleInstance force


gui1 := new myClass(&quot;gui1&quot;) 
gui1.Show(100, 200)

gui2 := new myClass(&quot;gui2&quot;)
gui2.Show(100, 300)

Sleep, 4000

; уничтожение объектов
gui1 := {} 
gui2 := 1



class myClass
{
    __New(name)
    {
        this.name := name
        Gui, % this.name . &quot;: New&quot;
        Gui, % this.name . &quot;: Add&quot;, Text,, % &quot;this is Gui named: &quot; . this.name
        ; OnMessage( 0x200, ObjBindMethod(this, &quot;onMouseMove&quot;) ) ; если расскомментировать, хрен ты удалишь обьект
    }

    Show(x := &quot;Center&quot;, y := &quot;Center&quot;)
    {
        Gui, % this.name . &quot;: Show&quot;, % &quot;x&quot; . x . &quot;y&quot; . y, NA
    }

    __Delete()
    {
        Gui, % this.name . &quot;: Destroy&quot;
        Msgbox, % &quot;destroy &quot; . this.name
    }

    onMouseMove( wparam, lparam, msg, hwnd ) ; добавляет возможность перетаскивать мышкой в любом месте интерфейса
    {
        if wparam = 1 ; LButton
            PostMessage, 0xA1, 2,,, A ; WM_NCLBUTTONDOWN
    }
}


Esc::ExitApp

</code></pre></div><p>Вероятно требуется какая-то хитрость, но я пока не могу понять какая.</p>]]></content>
			<author>
				<name><![CDATA[Шикарная услуга плана]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=40534</uri>
			</author>
			<updated>2021-12-16T14:53:00Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=151216#p151216</id>
		</entry>
</feed>
