<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=308814&amp;view=findpost&amp;p=2655466</guid>
        <pubDate>Wed, 28 Jul 2010 11:32:23 +0000</pubDate>
        <title>Аналог AllocateWnd</title>
        <link>https://forum.sources.ru/index.php?showtopic=308814&amp;view=findpost&amp;p=2655466</link>
        <description><![CDATA[Fr0sT: Обновление<br><br>+ Возможность присваивать как методы, так и обычные функции<br>+ Освобождение ресурсов в случае ошибок<br>+ Переделан порядок вызова в DefWndProc (убрано дублирование)]]></description>
        <author>Fr0sT</author>
        <category>Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=308814&amp;view=findpost&amp;p=2647811</guid>
        <pubDate>Tue, 20 Jul 2010 07:18:53 +0000</pubDate>
        <title>Аналог AllocateWnd</title>
        <link>https://forum.sources.ru/index.php?showtopic=308814&amp;view=findpost&amp;p=2647811</link>
        <description><![CDATA[Демо: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=308814&view=findpost&p=2647765'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Fr0sT &#064; <time class="tag-quote__quoted-time" datetime="2010-07-20T06:34:17+00:00">20.07.10, 06:34</time></span><div class='quote '>Не требует Classes, зависимости - только Windows<br>
Проще реализована<br>
Не требует вызова финализации DeallocateWnd - достаточно обычного закрытия хэндла. Занятая память освобождается автоматически.</div></div><br>
<br>
+ Безопасна при использовании в многопоточных приложениях в отличие от AllocateHWND.]]></description>
        <author>Демо</author>
        <category>Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=308814&amp;view=findpost&amp;p=2647765</guid>
        <pubDate>Tue, 20 Jul 2010 06:34:17 +0000</pubDate>
        <title>Аналог AllocateWnd</title>
        <link>https://forum.sources.ru/index.php?showtopic=308814&amp;view=findpost&amp;p=2647765</link>
        <description><![CDATA[Fr0sT: <strong class='tag-b'><span class="tag-color tag-color-named" data-value="purple" style="color: purple"><span class='tag-size' data-value='14' style='font-size:14pt;'>AllocateWnd — улучшенная версия</span></span></strong><br>
<br>
Периодически в программах, плотно работающих с WinAPI, а также построенных по асинхронной схеме, требуется повесить обработку Windows сообщений на метод класса. VCL предлагает для этого AllocateWnd, однако моя версия имеет несколько преимуществ:<ul class="tag-list"><li>Не требует Classes, зависимости - только Windows</li><li>Проще реализована</li><li>Не требует вызова финализации DeallocateWnd - достаточно обычного закрытия хэндла. Занятая память освобождается автоматически.</li></ul><br>
Может быть, кому-то пригодится.<br>
<br>
Upd. <br>
* Возможность присваивать как методы, так и обычные функции<br>
* Освобождение ресурсов в случае ошибок<br>
* Переделан порядок вызова в DefWndProc (убрано дублирование)<br>
* Типы приведены к WinAPI-шным, совместимо с x64 (но не проверялось)<br>
<br>
<strong class='tag-b'>Реализация:</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">{$IFDEF MSWINDOWS}</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;// AllocWnd types</div><div class="code_line">&nbsp;&nbsp;TWndProcMethod = function(wnd: HWND; msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT of object;</div><div class="code_line">&nbsp;&nbsp;TWndProc &nbsp; &nbsp; &nbsp; = function(wnd: HWND; msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;</div><div class="code_line">&nbsp;&nbsp;{$ENDIF}</div><div class="code_line">&nbsp;</div><div class="code_line">...</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;{$IFDEF MSWINDOWS}</div><div class="code_line">&nbsp;&nbsp;// message window</div><div class="code_line">&nbsp;&nbsp;function AllocateMsgWnd(Handler: TWndProcMethod): HWND; overload;</div><div class="code_line">&nbsp;&nbsp;function AllocateMsgWnd(Handler: TWndProc): HWND; overload;</div><div class="code_line">&nbsp;&nbsp;procedure DeallocateMsgWnd(Wnd: HWND); inline;</div><div class="code_line">&nbsp;&nbsp;{$ENDIF}</div><div class="code_line">&nbsp;</div><div class="code_line">...</div><div class="code_line">&nbsp;</div><div class="code_line">{$IFDEF MSWINDOWS}</div><div class="code_line">&nbsp;</div><div class="code_line">// ********* AllocWnd *********** \</div><div class="code_line">&nbsp;</div><div class="code_line">// Служит для создания окна, предназначенного для отправки/получения сообщений.</div><div class="code_line">// ! Хэндл окна должен быть закрыт посредством DestroyWindow/DeallocateMsgWnd !</div><div class="code_line">// Метод-обработчик сообщений можно и не указывать, в этом случае сообщения</div><div class="code_line">// будут приходить в message loop потока-владельца</div><div class="code_line">&nbsp;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TWndProcType = (wpMethod, wpProc);</div><div class="code_line">&nbsp;&nbsp;TWndProcInst = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;case ProcType: TWndProcType of</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;wpMethod: (WndProcMethod: TWndProcMethod);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;wpProc &nbsp;: (WndProc &nbsp; &nbsp; &nbsp;: TWndProc);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;PWndProcInst = ^TWndProcInst;</div><div class="code_line">&nbsp;</div><div class="code_line">const WndProcProp = &#39;WndProcProp&#39;;</div><div class="code_line">&nbsp;</div><div class="code_line">// Новая оконная процедура, извлекающая указатель на метод-обработчик из свойства окна</div><div class="code_line">function DefWndProc(wnd: HWND; msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;</div><div class="code_line">var pInst: PWndProcInst;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;pInst := PWndProcInst(GetProp(wnd, PChar(WndProcProp)));</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// вызываем обработчик: метод класса/сохранённая процедура либо дефолтная функция</div><div class="code_line">&nbsp;&nbsp;if pInst = nil</div><div class="code_line">&nbsp;&nbsp; &nbsp;then Result := DefWindowProc(wnd, msg, wParam, lParam)</div><div class="code_line">&nbsp;&nbsp; &nbsp;else case pInst.ProcType of</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wpMethod: Result := pInst.WndProcMethod(wnd, msg, wParam, lParam);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wpProc &nbsp;: Result := pInst.WndProc(wnd, msg, wParam, lParam);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else &nbsp; &nbsp; &nbsp;Result := 0; // make compiler happy</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// если окно уничтожается - удалить свойство и освободить память, выделенную под запись</div><div class="code_line">&nbsp;&nbsp;if msg = WM_DESTROY then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;RemoveProp(wnd, PChar(WndProcProp));</div><div class="code_line">&nbsp;&nbsp; &nbsp;if pInst &#60;&#62; nil then FreeMem(pInst);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">// Создание окна-обработчика сообщений</div><div class="code_line">function InnerAllocateMsgWnd(pInst: PWndProcInst): HWND;</div><div class="code_line">var err: Integer;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result := CreateWindowEx(0, &#39;Button&#39;, nil,0,0,0,0,0, HWND_MESSAGE, 0, HInstance, nil);</div><div class="code_line">&nbsp;&nbsp;if Result = 0 then Exit;</div><div class="code_line">&nbsp;&nbsp;// сохранить указатель на метод класса - обработчик сообщений</div><div class="code_line">&nbsp;&nbsp;if (not SetProp(Result, PChar(WndProcProp), THandle(pInst))) or</div><div class="code_line">&nbsp;&nbsp;// заменить оконную процедуру</div><div class="code_line">&nbsp;&nbsp; &nbsp; (SetWindowLongPtr(Result, GWL_WNDPROC, LONG_PTR(@DefWndProc)) = 0) then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;err := GetLastError;</div><div class="code_line">&nbsp;&nbsp; &nbsp;DestroyWindow(Result);</div><div class="code_line">&nbsp;&nbsp; &nbsp;Result := 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;SetLastError(err);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function AllocateMsgWnd(Handler: TWndProcMethod): HWND;</div><div class="code_line">var pInst: PWndProcInst;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;if not Assigned(Handler) then</div><div class="code_line">&nbsp;&nbsp; &nbsp;pInst := nil</div><div class="code_line">&nbsp;&nbsp;else</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;pInst := AllocMem(SizeOf(TWndProcInst));</div><div class="code_line">&nbsp;&nbsp; &nbsp;pInst.ProcType := wpMethod;</div><div class="code_line">&nbsp;&nbsp; &nbsp;pInst.WndProcMethod := Handler;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Result := InnerAllocateMsgWnd(pInst);</div><div class="code_line">&nbsp;&nbsp;if (Result = 0) and (pInst &#60;&#62; nil) then FreeMem(pInst);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function AllocateMsgWnd(Handler: TWndProc): HWND;</div><div class="code_line">var pInst: PWndProcInst;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;if not Assigned(Handler) then</div><div class="code_line">&nbsp;&nbsp; &nbsp;pInst := nil else</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;pInst := AllocMem(SizeOf(TWndProcInst));</div><div class="code_line">&nbsp;&nbsp; &nbsp;pInst.ProcType := wpProc;</div><div class="code_line">&nbsp;&nbsp; &nbsp;pInst.WndProc := Handler;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;Result := InnerAllocateMsgWnd(pInst);</div><div class="code_line">&nbsp;&nbsp;if (Result = 0) and (pInst &#60;&#62; nil) then FreeMem(pInst);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">// просто обертка для тех, кому привычнее</div><div class="code_line">procedure DeallocateMsgWnd(Wnd: HWND);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;DestroyWindow(Wnd);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{$ENDIF}</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
<br>
<strong class='tag-b'>Использование:</strong><br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">// объявление и создание ( 1 - обработчик - метод класса, 2 - обработчик - обычная функция )</div><div class="code_line">&nbsp;</div><div class="code_line">1)</div><div class="code_line">TSomeClass = class</div><div class="code_line">&nbsp;&nbsp;FHwnd: THandle;</div><div class="code_line">&nbsp;&nbsp;function WndProc(wnd: hWnd; msg, wParam, lParam: Longint): Longint;</div><div class="code_line">end;</div><div class="code_line">2) —</div><div class="code_line">&nbsp;</div><div class="code_line">...</div><div class="code_line">1) SomeObject : TSomeClass;</div><div class="code_line">2)</div><div class="code_line">&nbsp;Hw: HWND;</div><div class="code_line">&nbsp;function SomeWndProc(wnd: hWnd; msg, wParam, lParam: Longint): Longint;</div><div class="code_line">&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; ...</div><div class="code_line">&nbsp;&nbsp; Result := 0;</div><div class="code_line">&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">...</div><div class="code_line">1)</div><div class="code_line">SomeObject.FHwnd := AllocateMsgWnd(SomeObject.WndProc);</div><div class="code_line">if SomeObject.FHwnd = 0 then Log(SysErrorMessage(GetLastError));</div><div class="code_line">2)</div><div class="code_line">Hw := AllocateMsgWnd(SomeWndProc);</div><div class="code_line">if Hw = 0 then Log(SysErrorMessage(GetLastError));</div><div class="code_line">&nbsp;</div><div class="code_line">...</div><div class="code_line">&nbsp;</div><div class="code_line">// Посылка сообщений</div><div class="code_line">1) SendMessage(SomeObject.FHwnd, WM_TIMER, 0, 0);</div><div class="code_line">2) SendMessage(Hw, WM_TIMER, 0, 0);</div><div class="code_line">&nbsp;</div><div class="code_line">...</div><div class="code_line">&nbsp;</div><div class="code_line">// Удаление окна</div><div class="code_line">1) DestroyWindow(SomeObject.FHwnd);</div><div class="code_line">2) DestroyWindow(Hw);</div></ol></div></div></div></div><br>
<br>
Комментарии и предложения приветствуются.]]></description>
        <author>Fr0sT</author>
        <category>Общие вопросы</category>
      </item>
	
      </channel>
      </rss>
	