<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>MikeSoft &#187; Delphi</title>
	<atom:link href="http://mikesoft.ws/tag/delphi/feed/" rel="self" type="application/rss+xml" />
	<link>http://mikesoft.ws</link>
	<description>Practical Software</description>
	<lastBuildDate>Mon, 28 Nov 2011 18:09:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>MDI и Windows Vista</title>
		<link>http://mikesoft.ws/2009/08/13/mdi-windows-vista/</link>
		<comments>http://mikesoft.ws/2009/08/13/mdi-windows-vista/#comments</comments>
		<pubDate>Thu, 13 Aug 2009 09:53:53 +0000</pubDate>
		<dc:creator>Smike</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Советы]]></category>
		<category><![CDATA[Статьи]]></category>
		<category><![CDATA[MDI]]></category>
		<category><![CDATA[Windows Vista]]></category>

		<guid isPermaLink="false">http://mikesoft.ws/?p=202</guid>
		<description><![CDATA[В Windows Vista во многих MDI приложениях часто наблюдается баг (субъективно &#8212; в SP1/SP2 значительно реже) при максимизации дочернего окна &#8212; оно занимает не всю отведенную ему область. Справа остается небольшое пространство. Ответ был найден на MSDN форуме, но применительно к MFC. Но в Delphi эта проблема также встречается и решается аналогично. Вот исходный код, [...]]]></description>
			<content:encoded><![CDATA[<p>В Windows Vista во многих MDI приложениях часто наблюдается баг (субъективно &#8212; в SP1/SP2 значительно реже) при максимизации дочернего окна &#8212; оно занимает не всю отведенную ему область. Справа остается небольшое пространство.<span id="more-202"></span></p>
<p>Ответ был найден на MSDN форуме, но применительно к MFC. Но в Delphi эта проблема также встречается и решается аналогично. Вот исходный код, который поможет исправить проблему. Его нужно добавить к дочернему окну (FormStyle = fsMDIChild).</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">type</span>
  TMDIChild <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">class</span><span style="color: #000066;">&#40;</span>TForm<span style="color: #000066;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span>
    <span style="color: #000000; font-weight: bold;">procedure</span> WMGetMinMaxInfo<span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> Message<span style="color: #000066;">:</span> TWMGetMinMaxInfo<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> message WM_GETMINMAXINFO<span style="color: #000066;">;</span>
  <span style="color: #000066;">...</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #000066;">...</span>
<span style="color: #808080; font-style: italic;">(*
Оригинальный комментарий к решению:
--------------------------------------------------------------------------------
Заплатка на MFC версий ниже 8.0
&nbsp;
В MFC версиях 8.0 на Vista есть проблема, когда
окно дочернего MDI фрейма максимизируется при максимизированном
родительском MDI фрейме. В этом случаи максимальный размер окна ограничивается
данными структуры MINMAXINFO, которые были вычесленны ранее
системой при заданных стилях окна.
&nbsp;
Однако сам MFC в процессе ресайза этого окна любит менять ему
стили на ходу в результате система путается и MINMAXINFO содержит неправильные
данные.
&nbsp;
Это было не критично на XP и более старых системах, т.к. ошибка
была в 1 пиксель, теперь же на Vista, когда бордюр имеет занчительную ширину (4
пикселя), эта ошибка стала заметна (как раз на эту ширину - 4 пикселя).
&nbsp;
Чтобы исправить ошибу я вручную правлю структуру MINMAXINFO под
максимально возможный размер окна.
--------------------------------------------------------------------------------
&nbsp;
Smike: Похоже этот баг перенесли и в Delphi :)
*)</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">procedure</span> TMDIChild<span style="color: #000066;">.</span><span style="color: #006600;">WMGetMinMaxInfo</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> Message<span style="color: #000066;">:</span> TWMGetMinMaxInfo<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #000000; font-weight: bold;">if</span> WindowState &lt;&gt; wsMaximized <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #000000; font-weight: bold;">inherited</span>
  <span style="color: #000000; font-weight: bold;">else</span>
    <span style="color: #000000; font-weight: bold;">with</span> Message<span style="color: #000066;">.</span><span style="color: #006600;">MinMaxInfo</span><span style="color: #000066;">^</span> <span style="color: #000000; font-weight: bold;">do</span>
    <span style="color: #000000; font-weight: bold;">begin</span>
      <span style="color: #000000; font-weight: bold;">if</span> ptMaxTrackSize<span style="color: #000066;">.</span><span style="color: #006600;">X</span> &lt; ptMaxSize<span style="color: #000066;">.</span><span style="color: #006600;">X</span> <span style="color: #000000; font-weight: bold;">then</span> ptMaxTrackSize<span style="color: #000066;">.</span><span style="color: #006600;">X</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> ptMaxSize<span style="color: #000066;">.</span><span style="color: #006600;">X</span><span style="color: #000066;">;</span>
      <span style="color: #000000; font-weight: bold;">if</span> ptMaxTrackSize<span style="color: #000066;">.</span><span style="color: #006600;">Y</span> &lt; ptMaxSize<span style="color: #000066;">.</span><span style="color: #006600;">Y</span> <span style="color: #000000; font-weight: bold;">then</span> ptMaxTrackSize<span style="color: #000066;">.</span><span style="color: #006600;">Y</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> ptMaxSize<span style="color: #000066;">.</span><span style="color: #006600;">Y</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #808080; font-style: italic;">{ // Если не жалко пару десятков килобайт
  // в исполняемом файле - можно использовать функции модуля Math
  if WindowState &lt;&gt; wsMaximized then
    inherited
  else
    with Message.MinMaxInfo^ do
    begin
      ptMaxTrackSize.X := Max(ptMaxTrackSize.X, ptMaxSize.X);
      ptMaxTrackSize.Y := Max(ptMaxTrackSize.Y, ptMaxSize.Y);
    end;}</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://mikesoft.ws/2009/08/13/mdi-windows-vista/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Directory MD5 CRC Calculator</title>
		<link>http://mikesoft.ws/2009/08/13/directory-md5-crc-calculator/</link>
		<comments>http://mikesoft.ws/2009/08/13/directory-md5-crc-calculator/#comments</comments>
		<pubDate>Thu, 13 Aug 2009 09:12:15 +0000</pubDate>
		<dc:creator>Smike</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Новости]]></category>
		<category><![CDATA[Примеры]]></category>
		<category><![CDATA[FileEnum]]></category>
		<category><![CDATA[MD5]]></category>
		<category><![CDATA[Total Commander]]></category>
		<category><![CDATA[VirtualTreeView]]></category>

		<guid isPermaLink="false">http://mikesoft.ws/?p=192</guid>
		<description><![CDATA[Последнее время я занимался спасением архива сайта http://nevzorov.org, принадлежавшего погибшему Виталию Невзорову. На этом сайте больше 300 000 файлов. И, как оказалось, Total Commander, мой любимый файл-менеджер, плохо справляется с проверкой контрольных сумм такого количества файлов (файл с контрольными суммами он сгенерировал нормально, он занял почти 40 мегабайт). Такое впечатление, что он просто почему-то зависает [...]]]></description>
			<content:encoded><![CDATA[<p>Последнее время я занимался спасением архива сайта http://nevzorov.org, принадлежавшего <a href="http://dykepole.com/index.php?showtopic=10571">погибшему Виталию Невзорову</a>. На этом сайте больше 300 000 файлов. И, как оказалось, Total Commander, мой любимый файл-менеджер, плохо справляется с проверкой контрольных сумм такого количества файлов (файл с контрольными суммами он сгенерировал нормально, он занял почти 40 мегабайт). Такое впечатление, что он просто почему-то зависает на этапе загрузки файла &#8212; до проверки контрольных сумм даже не доходит.</p>
<p>Поэтому пришлось написать свою программу, которой удалось проверить контрольные суммы всего этого архива. И решил выложить ее вместе с исходными кодами, в качестве примера и в память о Виталие Невзорове (Vit-е). Код MD5 был взят из его Delphi Russian Knowledge Base.</p>
<p><a href="http://mikesoft.ws/?page_id=189">http://mikesoft.ws/samples/md5-crc-calculator/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://mikesoft.ws/2009/08/13/directory-md5-crc-calculator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Пример работы с модулем FileEnum</title>
		<link>http://mikesoft.ws/2009/02/15/fileenum-sample/</link>
		<comments>http://mikesoft.ws/2009/02/15/fileenum-sample/#comments</comments>
		<pubDate>Sun, 15 Feb 2009 02:38:17 +0000</pubDate>
		<dc:creator>Smike</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Новости]]></category>
		<category><![CDATA[Примеры]]></category>
		<category><![CDATA[FileEnum]]></category>

		<guid isPermaLink="false">http://mikesoft.ws/?p=154</guid>
		<description><![CDATA[Добавлен пример работы с модулем FileEnum. Небольшая полезная программа, которая удаляет папки резервных копий IDE Delphi (&#171;__history&#187;). http://mikesoft.ws/components/fileenum/]]></description>
			<content:encoded><![CDATA[<p>Добавлен пример работы с модулем FileEnum. Небольшая полезная программа, которая удаляет папки резервных копий IDE Delphi (&#171;__history&#187;).</p>
<p><a href="http://mikesoft.ws/?page_id=30">http://mikesoft.ws/components/fileenum/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://mikesoft.ws/2009/02/15/fileenum-sample/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Отправим Goto на пенсию!</title>
		<link>http://mikesoft.ws/2008/01/12/goto/</link>
		<comments>http://mikesoft.ws/2008/01/12/goto/#comments</comments>
		<pubDate>Sat, 12 Jan 2008 14:30:34 +0000</pubDate>
		<dc:creator>Smike</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Статьи]]></category>
		<category><![CDATA[программирование]]></category>

		<guid isPermaLink="false">http://mikesoft.ws/?p=119</guid>
		<description><![CDATA[Все кто учил язык BASIC, наверно помнят оператор безусловного перехода GOTO. Почему BASIC? Не только он, конечно, просто в ранних реализациях BASIC (например, Microsoft QuickBasic, входивший в свое время в поставку MS-DOS) он применялся действительно часто. Ведь там не было ни классов, ни операторов обрыва циклов и выполнения вроде Break, Exit, Continue, а также исключений. [...]]]></description>
			<content:encoded><![CDATA[<p>Все кто учил язык BASIC, наверно помнят оператор безусловного перехода GOTO. Почему BASIC? Не только он, конечно, просто в ранних реализациях BASIC (например, Microsoft QuickBasic, входивший в свое время в поставку MS-DOS) он применялся действительно часто. Ведь там не было ни классов, ни операторов обрыва циклов и выполнения вроде Break, Exit, Continue, а также исключений. В современных же языках с полноценными средствами структурного программирования, использование Goto считается крайне дурным тоном, так как затрудняет чтение и делает код непредсказуемым. <em>Доводы против оператора goto</em> четко выписаны в одноименной <a href="http://khpi-iip.mipk.kharkiv.edu/library/extent/dijkstra/pp/ewd215.html">статье Эдсгера Дейкстры</a>. Но я решил идти не по тропе теоретических изысканий, а показать на практике, что код БЕЗ GOTO может быть не только красивее и логичнее, но и в разы быстрее.</p>
<p><span id="more-119"></span></p>
<p>Существовала когда-то библиотека компонентов для Delphi под названием RX Library. Для своего времени это была отличная библиотека, содержала множество полезных компонентов и функций. Со временем библиотека перестала разиваться, теперь она только адаптируется к новым версиям Delphi, для поддержания обратной совместимости (<a href="http://rx.delphiplus.org/">http://rx.delphiplus.org/</a>, <a title="http://sourceforge.net/projects/rxlib/" href="http://sourceforge.net/projects/rxlib/">http://sourceforge.net/projects/rxlib/</a>). Код этой библиотеки без существенных изменений (кроме названий компонентов) был перенесен в <a href="http://homepages.borland.com/jedi/jvcl/">JEDI VCL</a>.</p>
<p>Вместе с множеством полезных RTL-функций была унаследована и функция перевода чисел из десятичной системы счисления в римскую. История этой функции мне неизвестна, но её главной особенностью является наличие оператора безусловного перехода goto (модули <a href="http://rxlib.svn.sourceforge.net/viewvc/*checkout*/rxlib/trunk/Units/rxStrUtils.pas?revision=17">rxStrUtils</a>, <a href="http://jvcl.svn.sourceforge.net/viewvc/*checkout*/jvcl/trunk/jvcl/run/JvJCLUtils.pas">JvJCLUtils</a>):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
</pre></td><td class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> IntToRoman<span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Longint</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">Label</span>
  A500<span style="color: #000066;">,</span> A400<span style="color: #000066;">,</span> A100<span style="color: #000066;">,</span> A90<span style="color: #000066;">,</span> A50<span style="color: #000066;">,</span> A40<span style="color: #000066;">,</span> A10<span style="color: #000066;">,</span> A9<span style="color: #000066;">,</span> A5<span style="color: #000066;">,</span> A4<span style="color: #000066;">,</span> A1<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #ff0000;">''</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">while</span> Value &gt;<span style="color: #000066;">=</span> <span style="color: #0000ff;">1000</span> <span style="color: #000000; font-weight: bold;">do</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> <span style="color: #0000ff;">1000</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'M'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">if</span> Value &lt; <span style="color: #0000ff;">900</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">goto</span> A500
  <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> <span style="color: #0000ff;">900</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'CM'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">goto</span> A90<span style="color: #000066;">;</span>
A400<span style="color: #000066;">:</span>
  <span style="color: #000000; font-weight: bold;">if</span> Value &lt; <span style="color: #0000ff;">400</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">goto</span> A100
  <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> <span style="color: #0000ff;">400</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'CD'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">goto</span> A90<span style="color: #000066;">;</span>
A500<span style="color: #000066;">:</span>
  <span style="color: #000000; font-weight: bold;">if</span> Value &lt; <span style="color: #0000ff;">500</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">goto</span> A400
  <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> <span style="color: #0000ff;">500</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'D'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
A100<span style="color: #000066;">:</span>
  <span style="color: #000000; font-weight: bold;">while</span> Value &gt;<span style="color: #000066;">=</span> <span style="color: #0000ff;">100</span> <span style="color: #000000; font-weight: bold;">do</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> <span style="color: #0000ff;">100</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'C'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
A90<span style="color: #000066;">:</span>
  <span style="color: #000000; font-weight: bold;">if</span> Value &lt; <span style="color: #0000ff;">90</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">goto</span> A50
  <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> <span style="color: #0000ff;">90</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'XC'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">goto</span> A9<span style="color: #000066;">;</span>
A40<span style="color: #000066;">:</span>
  <span style="color: #000000; font-weight: bold;">if</span> Value &lt; <span style="color: #0000ff;">40</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">goto</span> A10
  <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> <span style="color: #0000ff;">40</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'XL'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">goto</span> A9<span style="color: #000066;">;</span>
A50<span style="color: #000066;">:</span>
  <span style="color: #000000; font-weight: bold;">if</span> Value &lt; <span style="color: #0000ff;">50</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">goto</span> A40
  <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> <span style="color: #0000ff;">50</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'L'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
A10<span style="color: #000066;">:</span>
  <span style="color: #000000; font-weight: bold;">while</span> Value &gt;<span style="color: #000066;">=</span> <span style="color: #0000ff;">10</span> <span style="color: #000000; font-weight: bold;">do</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> <span style="color: #0000ff;">10</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'X'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
A9<span style="color: #000066;">:</span>
  <span style="color: #000000; font-weight: bold;">if</span> Value &lt; <span style="color: #0000ff;">9</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">goto</span> A5
  <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">begin</span>
    Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'IX'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
  <span style="color: #000066;">Exit</span><span style="color: #000066;">;</span>
A4<span style="color: #000066;">:</span>
  <span style="color: #000000; font-weight: bold;">if</span> Value &lt; <span style="color: #0000ff;">4</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">goto</span> A1
  <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">begin</span>
    Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'IV'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
  <span style="color: #000066;">Exit</span><span style="color: #000066;">;</span>
A5<span style="color: #000066;">:</span>
  <span style="color: #000000; font-weight: bold;">if</span> Value &lt; <span style="color: #0000ff;">5</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">goto</span> A4
  <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> <span style="color: #0000ff;">5</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'V'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">goto</span> A1<span style="color: #000066;">;</span>
A1<span style="color: #000066;">:</span>
  <span style="color: #000000; font-weight: bold;">while</span> Value &gt;<span style="color: #000066;">=</span> <span style="color: #0000ff;">1</span> <span style="color: #000000; font-weight: bold;">do</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #ff0000;">'I'</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

<p>Была ли эта функция переведена дословно с языка BASIC или написана с нуля &mdash; теперь это не так уж важно. Главное, что в современном программировании GOTO нет места. И эта моя публикация нацелена на то, чтобы в очередной раз это подтвердить. Несмотря на отдельные доводы в пользу оператора GOTO: например, что он обеспечивают лучшую производительность по сравнению со стандартными методами структурного программирования.</p>
<p>Если не смотреть на вышеприведенный код (так как в нем с трудом можно что-то понять, только сбить себя с толку), а задаться целью написать функцию перевода в римскую систему счисления с нуля, то она будет выглядеть примерно так:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
</pre></td><td class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> IntToRoman<span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Longint</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">type</span>
  TRomanRec <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">record</span>
    <span style="color: #000066;">Str</span><span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
    Amount<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">const</span>
  Roman<span style="color: #000066;">:</span> <span style="color: #000000; font-weight: bold;">array</span> <span style="color: #000066;">&#91;</span><span style="color: #0000ff;">1</span><span style="color: #000066;">..</span><span style="color: #0000ff;">13</span><span style="color: #000066;">&#93;</span> <span style="color: #000000; font-weight: bold;">of</span> TRomanRec <span style="color: #000066;">=</span> <span style="color: #000066;">&#40;</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span>  <span style="color: #ff0000;">'M'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span> <span style="color: #0000ff;">1000</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span> <span style="color: #ff0000;">'CM'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>  <span style="color: #0000ff;">900</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span>  <span style="color: #ff0000;">'D'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>  <span style="color: #0000ff;">500</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span> <span style="color: #ff0000;">'CD'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>  <span style="color: #0000ff;">400</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span>  <span style="color: #ff0000;">'C'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>  <span style="color: #0000ff;">100</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span> <span style="color: #ff0000;">'XC'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>   <span style="color: #0000ff;">90</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span>  <span style="color: #ff0000;">'L'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>   <span style="color: #0000ff;">50</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span> <span style="color: #ff0000;">'XL'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>   <span style="color: #0000ff;">40</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span>  <span style="color: #ff0000;">'X'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>   <span style="color: #0000ff;">10</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span> <span style="color: #ff0000;">'IX'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>    <span style="color: #0000ff;">9</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span>  <span style="color: #ff0000;">'V'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>    <span style="color: #0000ff;">5</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span> <span style="color: #ff0000;">'IV'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>    <span style="color: #0000ff;">4</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#40;</span><span style="color: #000066;">Str</span><span style="color: #000066;">:</span>  <span style="color: #ff0000;">'I'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>    <span style="color: #0000ff;">1</span><span style="color: #000066;">&#41;</span>
  <span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">var</span>
  R<span style="color: #000066;">:</span> TRomanRec<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #ff0000;">''</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">for</span> R <span style="color: #000000; font-weight: bold;">in</span> Roman <span style="color: #000000; font-weight: bold;">do</span>
    <span style="color: #000000; font-weight: bold;">while</span> Value &gt;<span style="color: #000066;">=</span> R<span style="color: #000066;">.</span><span style="color: #006600;">Amount</span> <span style="color: #000000; font-weight: bold;">do</span>
    <span style="color: #000000; font-weight: bold;">begin</span>
      Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> R<span style="color: #000066;">.</span><span style="color: #000066;">Str</span><span style="color: #000066;">;</span>
      <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> R<span style="color: #000066;">.</span><span style="color: #006600;">Amount</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

<p>Здесь реализован простейший алгоритм перевода. Последовательно вычитая из исходного числа значения римских чисел или их сочетаний, мы получаем строковое представление данного числа. Что касается производительности, то эта функция действительно несколько медленнее варианта с GOTO. От 8% до 30% в зависимости от диапазона чисел (чем больше &mdash; тем меньше разница, 8% на переводе чисел от единицы до миллиона). Сторонники GOTO радостно возликовали бы на этом месте и успокоились, продолжая использовать функцию с GOTO. Но я как сторонник структурного программирования решил на этом не останавливаться, а проанализировать внимательно алгоритм.</p>
<p>Первое узкое место, которое бросается в глаза &mdash; формирование строки в цикле. Мало того, что такая операция является ресурсоемкой, приводя к лишним операциям выделения памяти, она гораздо медленнее, чем простая функция div, которую было бы достаточно выполнить всего один раз для одной римской цифры. Она возвратила бы количество римских чисел, а сформировать строку можно было бы функцией StringOfChar (модуль SysUtils), которая написана на ассемблере и имеет отличную производительность.</p>
<p>Но здесь всплывает иная сложность: как формировать строку из нескольких символов (таких как промежуточные значения CM=900, CD=400 и т.д.). Здесь два варианта: либо писать универсальную функцию, которая будет формировать строку не из символов, а из одинаковых строковых фрагментов, либо отказаться от промежуточных значений. Первый вариант существенно снизит производительность, поэтому возьмемся за другой вариант. В нем не все так сложно, как могло бы показаться на первый взгляд. Если внимательно посмотреть на ряд римских чисел</p>
<pre>
I, V, X, L, C, D, M</pre>
<p>то можно заметить, что отниматься от большего числа могут только числа через одно (на нечетных местах). Это правило не касается только тысячи (M), так как нету большего числа в римской системе счисления. Такой алгоритм несложно реализовать:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
</pre></td><td class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> IntToRomanOptimized<span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Longint</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">type</span>
  TRomanRec <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">record</span>
    Symbol<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Char</span><span style="color: #000066;">;</span>
    Amount<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Word</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">const</span>
  <span style="color: #808080; font-style: italic;">// Отмеченные &quot;+&quot; элементы используются для уменьшения предыдущих значений,</span>
  <span style="color: #808080; font-style: italic;">// все они на нечетных местах </span>
  Roman<span style="color: #000066;">:</span> <span style="color: #000000; font-weight: bold;">array</span> <span style="color: #000066;">&#91;</span><span style="color: #0000ff;">1</span><span style="color: #000066;">..</span><span style="color: #0000ff;">7</span><span style="color: #000066;">&#93;</span> <span style="color: #000000; font-weight: bold;">of</span> TRomanRec <span style="color: #000066;">=</span> <span style="color: #000066;">&#40;</span>
    <span style="color: #000066;">&#40;</span>Symbol<span style="color: #000066;">:</span> <span style="color: #ff0000;">'M'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span> <span style="color: #0000ff;">1000</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>  <span style="color: #808080; font-style: italic;">// 1</span>
    <span style="color: #000066;">&#40;</span>Symbol<span style="color: #000066;">:</span> <span style="color: #ff0000;">'D'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>  <span style="color: #0000ff;">500</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>  <span style="color: #808080; font-style: italic;">// 2</span>
    <span style="color: #000066;">&#40;</span>Symbol<span style="color: #000066;">:</span> <span style="color: #ff0000;">'C'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>  <span style="color: #0000ff;">100</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>  <span style="color: #808080; font-style: italic;">// 3 +</span>
    <span style="color: #000066;">&#40;</span>Symbol<span style="color: #000066;">:</span> <span style="color: #ff0000;">'L'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>   <span style="color: #0000ff;">50</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>  <span style="color: #808080; font-style: italic;">// 4</span>
    <span style="color: #000066;">&#40;</span>Symbol<span style="color: #000066;">:</span> <span style="color: #ff0000;">'X'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>   <span style="color: #0000ff;">10</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>  <span style="color: #808080; font-style: italic;">// 5 +</span>
    <span style="color: #000066;">&#40;</span>Symbol<span style="color: #000066;">:</span> <span style="color: #ff0000;">'V'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>    <span style="color: #0000ff;">5</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>  <span style="color: #808080; font-style: italic;">// 6</span>
    <span style="color: #000066;">&#40;</span>Symbol<span style="color: #000066;">:</span> <span style="color: #ff0000;">'I'</span><span style="color: #000066;">;</span> Amount<span style="color: #000066;">:</span>    <span style="color: #0000ff;">1</span><span style="color: #000066;">&#41;</span>   <span style="color: #808080; font-style: italic;">// 7 +</span>
  <span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">var</span>
  I<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">;</span>
  R<span style="color: #000066;">:</span> TRomanRec<span style="color: #000066;">;</span>  
<span style="color: #000000; font-weight: bold;">begin</span>
  Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #ff0000;">''</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">for</span> I <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">Low</span><span style="color: #000066;">&#40;</span>Roman<span style="color: #000066;">&#41;</span> <span style="color: #000000; font-weight: bold;">to</span> <span style="color: #000066;">High</span><span style="color: #000066;">&#40;</span>Roman<span style="color: #000066;">&#41;</span> <span style="color: #000000; font-weight: bold;">do</span>
  <span style="color: #000000; font-weight: bold;">begin</span>
    R <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Roman<span style="color: #000066;">&#91;</span>I<span style="color: #000066;">&#93;</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">if</span> Value &gt;<span style="color: #000066;">=</span> R<span style="color: #000066;">.</span><span style="color: #006600;">Amount</span> <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #000000; font-weight: bold;">begin</span>
      Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> <span style="color: #000066;">StringOfChar</span><span style="color: #000066;">&#40;</span>R<span style="color: #000066;">.</span><span style="color: #006600;">Symbol</span><span style="color: #000066;">,</span> Value <span style="color: #000000; font-weight: bold;">div</span> R<span style="color: #000066;">.</span><span style="color: #006600;">Amount</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
      <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> Value <span style="color: #000000; font-weight: bold;">div</span> R<span style="color: #000066;">.</span><span style="color: #006600;">Amount</span> <span style="color: #000066;">*</span> R<span style="color: #000066;">.</span><span style="color: #006600;">Amount</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">if</span> R<span style="color: #000066;">.</span><span style="color: #006600;">Amount</span> &gt; <span style="color: #0000ff;">1</span> <span style="color: #000000; font-weight: bold;">then</span>
      <span style="color: #000000; font-weight: bold;">with</span> Roman<span style="color: #000066;">&#91;</span>I <span style="color: #000066;">+</span> <span style="color: #000066;">Ord</span><span style="color: #000066;">&#40;</span><span style="color: #000066;">Odd</span><span style="color: #000066;">&#40;</span>I<span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span> <span style="color: #000066;">+</span> <span style="color: #0000ff;">1</span><span style="color: #000066;">&#93;</span> <span style="color: #000000; font-weight: bold;">do</span>
        <span style="color: #000000; font-weight: bold;">if</span> Value &gt;<span style="color: #000066;">=</span> R<span style="color: #000066;">.</span><span style="color: #006600;">Amount</span> <span style="color: #000066;">-</span> Amount <span style="color: #000000; font-weight: bold;">then</span>
        <span style="color: #000000; font-weight: bold;">begin</span>
          Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Result <span style="color: #000066;">+</span> Symbol <span style="color: #000066;">+</span> R<span style="color: #000066;">.</span><span style="color: #006600;">Symbol</span><span style="color: #000066;">;</span>
          <span style="color: #000066;">Dec</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">,</span> R<span style="color: #000066;">.</span><span style="color: #006600;">Amount</span> <span style="color: #000066;">-</span> Amount<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
        <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

<p>Новый вариант функции готов, теперь перейдем к тестированию производительности. И она не может не радовать! На переводе чисел от 1 до 100 000 оптимизированный вариант работает в 2 раза быстрее, чем с GOTO. На 200&nbsp;000 &mdash; в 3 раза быстрее, на 300&nbsp;000 &mdash; в 4 раза, а на числах до миллиона &mdash; более чем в 13 (!) раз быстрее. И это еще раз подтверждает, что GOTO пора на пенсию, время грамотного программирования!</p>
]]></content:encoded>
			<wfw:commentRss>http://mikesoft.ws/2008/01/12/goto/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>И снова о пользе Windows Vista</title>
		<link>http://mikesoft.ws/2007/11/22/windows-vista-usability/</link>
		<comments>http://mikesoft.ws/2007/11/22/windows-vista-usability/#comments</comments>
		<pubDate>Thu, 22 Nov 2007 09:58:42 +0000</pubDate>
		<dc:creator>Smike</dc:creator>
				<category><![CDATA[Советы]]></category>
		<category><![CDATA[Статьи]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[TFileOpenDialog]]></category>
		<category><![CDATA[Windows Vista]]></category>

		<guid isPermaLink="false">http://mikesoft.ws/?p=97</guid>
		<description><![CDATA[Во время разработки своей новой программы я решил вплотную взглянуть на новый компонент Delphi 2007 — TFileOpenDialog, который инкапсулирует современный диалог открытия файлов в Windows Vista. Те функции, что я в нем увидел, меня приятно удивили. В первую очередь, я нашел в нем ту функциональность, которая как раз была мне нужна. В приложении необходимо создавать [...]]]></description>
			<content:encoded><![CDATA[<p>Во время разработки своей новой программы я решил вплотную взглянуть на новый  компонент Delphi 2007 — <span style="font-weight: bold;">TFileOpenDialog</span>,  который инкапсулирует современный диалог открытия файлов в <span style="font-weight: bold;">Windows Vista</span>. Те функции, что я в нем увидел,  меня приятно удивили.<span id="more-97"></span></p>
<p>В первую очередь, я нашел в нем ту  функциональность, которая как раз была мне нужна. В приложении необходимо  создавать и выбирать файлы в определенной папке и её подпапках. В TOpenDialog  нельзя запретить смену каталога. В TFileOpenDialog — можно! Появилось событие  <span style="font-weight: bold;">OnFolderChanging</span>, где вот таким вот  простым кодом мы можем запретить, например, переходить в папки нижнего уровня по  сравнению с начальной:</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">procedure</span> TForm1<span style="color: #000066;">.</span><span style="color: #006600;">FolderChangingEvent</span><span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">var</span> CanChange<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Boolean</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  CanChange <span style="color: #000066;">:</span><span style="color: #000066;">=</span> AnsiStartsText<span style="color: #000066;">&#40;</span>FileOpenDialog1<span style="color: #000066;">.</span><span style="color: #006600;">DefaultFolder</span><span style="color: #000066;">,</span>
                              FileOpenDialog1<span style="color: #000066;">.</span><span style="color: #006600;">FileName</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></div></div>

<p>Это  как раз реализует нужную мне функциональность. Это одна из тех &#171;мелочей&#187;,  которыми наполнена Windows Vista, но которые так приятно облегчают работу и  программистов, и пользователей.</p>
<p>Какие же еще возможности приподносит нам  TFileOpenDialog? Это события <span style="font-weight: bold;">OnFileOkClick</span>, которое позволяет запретить  закрывать диалог в случае неудовлетворительного выбора, и <span style="font-weight: bold;">OnShareViolation</span>, позволяющее задавать реакцию  на выбор файлов, используемых другими приложениями.</p>
<p>Сравним также свойства <span style="font-weight: bold;">Options</span> старого и нового  диалогов. Визуальное сравнение возможных значений этих свойств дало понять, что  большинство параметров имеют аналоги и в старом диалоге (выделены жирным):</p>
<pre>TFileDialogOption = (
 <span style="font-weight: bold;">fdoOverWritePrompt</span>,
 fdoStrictFileTypes,
 <span style="font-weight: bold;">fdoNoChangeDir</span>,
 fdoPickFolders,
 fdoForceFileSystem,
 fdoAllNonStorageItems,
 <span style="font-weight: bold;">fdoNoValidate</span>,
 <span style="font-weight: bold;">fdoAllowMultiSelect</span>,
 <span style="font-weight: bold;">fdoPathMustExist</span>,
 <span style="font-weight: bold;">fdoFileMustExist</span>,
 <span style="font-weight: bold;">fdoCreatePrompt</span>,
 <span style="font-weight: bold;">fdoShareAware</span>,
 <span style="font-weight: bold;">fdoNoReadOnlyReturn</span>,
 <span style="font-weight: bold;">fdoNoTestFileCreate</span>,
 fdoHideMRUPlaces,
 fdoHidePinnedPlaces,
 <span style="font-weight: bold;">fdoNoDereferenceLinks</span>,
 <span style="font-weight: bold;">fdoDontAddToRecent</span>,
 <span style="font-weight: bold;">fdoForceShowHidden</span>,
 fdoDefaultNoMiniMode,
 fdoForcePreviewPaneOn
);</pre>
<p>Остановимся на значениях, не имеющих аналогов. Часть из  них настраивает вид самого диалога:</p>
<ul>
<li><span style="font-weight: bold;">fdoForcePreviewPaneOn</span> отображает  панель предварительного просмотра;</li>
<li><span style="font-weight: bold;">fdoDefaultNoMiniMode</span> запрещает  открытие диалога в сжатом виде (только строка ввода имени файла) — только для  диалогов сохранения;</li>
<li><span style="font-weight: bold;">fdoHidePinnedPlaces</span> убирает <span style="font-style: italic;">стандартные</span> избранные ссылки, собственные мы  по прежнему можем задавать (!);</li>
<li><span style="font-weight: bold;">fdoHideMRUPlaces</span> описывается как  &#171;Hide places of recently opened or saved items&#187;, но реально мне не удалось пока  понять, о чем идет речь.</li>
</ul>
<p>Значение <span style="font-weight: bold;">fdoPickFolders</span> позволяет использовать диалог  открытия файлов как диалог выбора папок, а <span style="font-weight: bold;">fdoStrictFileTypes</span> позволяет указать, что нужно  сохранять файл только с одним из предопределенных расширений.</p>
<p>А вот  свойство <span style="font-weight: bold;">fdoNoChangeDir</span> хоть и есть среди  возможных значений, но как уверяет справочная система, это значение не  используется. Это и не удивительно, ведь есть более гибкое событие OnFolderChanging.</p>
<p>В новом диалоге есть и другие полезные свойства и  методы. С помощью коллекции <span style="font-weight: bold;">FavoriteLinks</span> можно добавлять собственные избранные ссылки. Свойства <span style="font-weight: bold;">FileNameLabel</span>, <span style="font-weight: bold;">OKButtonLabel</span>, <span style="font-weight: bold;">Title</span> позволяют изменить названия отдельных  элементов интерфейса диалога (текст перед полем ввода файла, текст кнопки OK и  заголовок диалога). Старый TOpenDialog позволял изменять только собственный  заголовок. Коллекция <span style="font-weight: bold;">FileTypes</span> более  наглядно, чем свойство Filter из TOpenDialog позволяет задавать фильтры для  диалога. Особенно удобно, что это индексированный список, таким образом легко  можно проверить, какому расширению соответствует тот или иной тип, используя  свойство <span style="font-weight: bold;">FileTypeIndex</span>.</p>
]]></content:encoded>
			<wfw:commentRss>http://mikesoft.ws/2007/11/22/windows-vista-usability/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Баги в imouse.pas</title>
		<link>http://mikesoft.ws/2007/11/10/imouse/</link>
		<comments>http://mikesoft.ws/2007/11/10/imouse/#comments</comments>
		<pubDate>Sat, 10 Nov 2007 10:30:43 +0000</pubDate>
		<dc:creator>Smike</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Советы]]></category>
		<category><![CDATA[IntelliMouse]]></category>

		<guid isPermaLink="false">http://mikesoft.ws/?p=109</guid>
		<description><![CDATA[С грустью только что узнал, что в imouse.pas CodeGear RAD Studio 2007 остались старые баги с неосвобождаемой памятью, что конечно не особо страшно, но неприятно и может здорово затруднить отладку при ReportMemoryLeaksOnShutdown := True. Поэтому решил выложить свой, давно уже исправленный на свой вкус, модуль imouse, который я назвал MousePan. Скачать модифицированный вариант можно здесь: [...]]]></description>
			<content:encoded><![CDATA[<p>С грустью только что узнал, что в imouse.pas CodeGear RAD Studio 2007 остались  старые баги с неосвобождаемой памятью, что конечно не особо страшно, но  неприятно и может здорово затруднить отладку при ReportMemoryLeaksOnShutdown :=  True. Поэтому решил выложить свой, давно уже исправленный на свой вкус, модуль  imouse, который я назвал MousePan.</p>
<p>Скачать модифицированный вариант можно здесь:<br />
<a href="http://mikesoft.ws/?page_id=28">http://mikesoft.ws/components/mousepan/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://mikesoft.ws/2007/11/10/imouse/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Автоматически скрывающееся меню</title>
		<link>http://mikesoft.ws/2007/09/20/auto-closing-menu/</link>
		<comments>http://mikesoft.ws/2007/09/20/auto-closing-menu/#comments</comments>
		<pubDate>Thu, 20 Sep 2007 20:55:30 +0000</pubDate>
		<dc:creator>Smike</dc:creator>
				<category><![CDATA[Статьи]]></category>
		<category><![CDATA[Delphi]]></category>

		<guid isPermaLink="false">http://mikesoft.ws/?p=48</guid>
		<description><![CDATA[В дизайне современных приложений меню занимает уже далеко не главное место, уступив первенство панелям инструментов. Такие тенденции наблюдаются например в Internet Explorer 7 и Windows Vista Explorer (Проводник). В то же время меню у этих приложений есть, его можно показать, нажав клавишу Alt. Удобство такого подхода очевидно. На панели инструментов все команды на виду, их [...]]]></description>
			<content:encoded><![CDATA[<p>В дизайне современных приложений меню занимает уже далеко не главное место,  уступив первенство панелям инструментов. Такие тенденции наблюдаются например в  Internet Explorer 7 и Windows Vista Explorer (Проводник).</p>
<p><a href="http://mikesoft.ws/wp-content/uploads/2009/02/vistamenu_explorer.png"><img class="alignnone size-medium wp-image-52" title="Windows Vista Explorer" src="http://mikesoft.ws/wp-content/uploads/2009/02/vistamenu_explorer-300x214.png" alt="Windows Vista Explorer" width="250" height="178" /></a> <a href="http://mikesoft.ws/wp-content/uploads/2009/02/vistamenu_ie7.png"><img class="alignnone size-medium wp-image-53" title="Internet Explorer 7 under Windows Vista" src="http://mikesoft.ws/wp-content/uploads/2009/02/vistamenu_ie7-300x215.png" alt="Internet Explorer 7 under Windows Vista" width="250" height="179" /></a></p>
<p><a href="http://mikesoft.ws/wp-content/uploads/2009/02/vistamenu_ie7.png"><span id="more-48"></span></a></p>
<p>В то же время меню у этих приложений есть, его можно показать, нажав клавишу  Alt. Удобство такого подхода очевидно. На панели инструментов все команды на  виду, их удобно искать и пользоваться ими. В то же время все команды, в том  числе и отсуствующие на панели инструментов, доступны в полном меню, которое  можно при необходимости отобразить на экране. При этом строка меню не отнимает  место на экране. Особенно это актуально на широкоэкранных мониторах или для  миниатюрных приложений, где даже пару десятков пикселей меню — лишнее место.</p>
<p>В Delphi VCL сделать такую возможность совсем не сложно. За отображение  главного меню приложения отвечает компонент TMainMenu и свойство TForm.Menu. В  компоненте хранятся элементы меню, а в свойстве указывается ссылка на этот  компонент. Соотвественно, если указано свойство TForm.Menu, то меню отображается  и наоборот.</p>
<p>Решение данной задачи можно разбить на следующие пункты:</p>
<ul>
<li>обеспечение простого способа скрытия и отображения меню;</li>
<li>отображение и скрытие меню по нажатию клавиши Alt;</li>
<li>скрытие меню при клике мышью в окне приложения.</li>
</ul>
<p>Чтобы обеспечить удобную возможность скрытия меню, можно написать свойство  <strong>MenuVisible</strong> для формы. Код получения значения данного свойства  будет проверять, задано ли свойство TForm.Menu:</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">type</span>
  TMyForm <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">class</span><span style="color: #000066;">&#40;</span>TForm<span style="color: #000066;">&#41;</span>
    MainMenu<span style="color: #000066;">:</span> TMainMenu<span style="color: #000066;">;</span>
<span style="color: #000066;">...</span>
  <span style="color: #000000; font-weight: bold;">private</span>
    <span style="color: #000000; font-weight: bold;">function</span> GetMenuVisible<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Boolean</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">procedure</span> SetMenuVisible<span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Value<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Boolean</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">public</span>
    <span style="color: #000000; font-weight: bold;">property</span> MenuVisible<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Boolean</span> <span style="color: #000066;">read</span> GetMenuVisible
                                 <span style="color: #000066;">write</span> SetMenuVisible<span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">implementation</span>
&nbsp;
<span style="color: #008000; font-style: italic;">{$R *.dfm}</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> TMyForm<span style="color: #000066;">.</span><span style="color: #006600;">GetMenuVisible</span><span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Boolean</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">Assigned</span><span style="color: #000066;">&#40;</span>Menu<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></div></div>

<p>Код установки значения свойства MenuVisible будет изменять свойство TForm.Menu,  чтобы отобразить или скрыть главное меню. Вдобавок, если приложение не  развернуто на весь экран, было бы удобно увеличивать высоту окна при появлении  меню и уменьшать его при скрытии. Таким образом установленный пользователем  размер рабочей области окна приложения не будет изменяться. Чтобы во время  данных операций не наблюдалось мерцание, вышеописанный код следует обрамить  блоком DisableAlign-EnableAlign.</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">procedure</span> TMyForm<span style="color: #000066;">.</span><span style="color: #006600;">SetMenuVisible</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Value<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Boolean</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #000000; font-weight: bold;">if</span> Value <span style="color: #000066;">=</span> MenuVisible <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000066;">Exit</span><span style="color: #000066;">;</span>
&nbsp;
  DisableAlign<span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">try</span>
    <span style="color: #000000; font-weight: bold;">if</span> Value <span style="color: #000000; font-weight: bold;">then</span>
      Menu <span style="color: #000066;">:</span><span style="color: #000066;">=</span> MainMenu
    <span style="color: #000000; font-weight: bold;">else</span>
      Menu <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">nil</span><span style="color: #000066;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">if</span> WindowState &lt;&gt; wsMaximized <span style="color: #000000; font-weight: bold;">then</span>
      Height <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Height <span style="color: #000066;">+</span> GetSystemMetrics<span style="color: #000066;">&#40;</span>SM_CYMENU<span style="color: #000066;">&#41;</span> <span style="color: #000066;">*</span>
                <span style="color: #000066;">&#40;</span><span style="color: #000066;">Ord</span><span style="color: #000066;">&#40;</span>Value<span style="color: #000066;">&#41;</span> <span style="color: #000000; font-weight: bold;">or</span> <span style="color: #000066;">Ord</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">not</span> Value<span style="color: #000066;">&#41;</span> <span style="color: #000066;">*</span> <span style="color: #000066;">-</span><span style="color: #0000ff;">1</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">finally</span>
    EnableAlign<span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></div></div>

<p>Решение следующего пункта состоит в обработке нажатия клавиши Alt в событии  OnKeyUp формы. Это решается простым кодом:</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">procedure</span> TMyForm<span style="color: #000066;">.</span><span style="color: #006600;">FormKeyUp</span><span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">;</span> <span style="color: #000000; font-weight: bold;">var</span> Key<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Word</span><span style="color: #000066;">;</span>
  Shift<span style="color: #000066;">:</span> TShiftState<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #000000; font-weight: bold;">case</span> Key <span style="color: #000000; font-weight: bold;">of</span>
    VK_MENU<span style="color: #000066;">:</span> MenuVisible <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">not</span> MenuVisible<span style="color: #000066;">;</span>
    VK_ESCAPE<span style="color: #000066;">:</span> MenuVisible <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">False</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></div></div>

<p>В этом коде также добавлена обработка клавиши Esc, после нажатия которой меню  скрывается. Почему именно OnKeyUp? Дело в том что обе клавиши, Alt и Esc,  используются в самом меню, поэтому обработка OnKeyDown будет работать  неправильно, а точнее через раз.</p>
<p>Следует обратить внимание, что в коде для обработки нажатия Alt используется  не состояние служебных клавиш, передаваемое в параметре Shift типа TShiftState,  а значение нажатой клавиши, передаваемое в параметре Key. Чтобы это событие  работало не зависимо от того, какие и сколько компонентов на форуме, следует  установить свойство TForm.KeyPreview в True.</p>
<p>Ну и последний вопрос — как обработать клик мыши в окне приложения, чтобы  скрывать при этом меню. В этом нет ничего сложного и возможностей VCL здесь  вполне достаточно. Нужно обработать свойство TForm.OnMouseActivate.</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">procedure</span> TMyForm<span style="color: #000066;">.</span><span style="color: #006600;">FormMouseActivate</span><span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">;</span>
  Button<span style="color: #000066;">:</span> TMouseButton<span style="color: #000066;">;</span> Shift<span style="color: #000066;">:</span> TShiftState<span style="color: #000066;">;</span> X<span style="color: #000066;">,</span> Y<span style="color: #000066;">,</span> HitTest<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">var</span> MouseActivate<span style="color: #000066;">:</span> TMouseActivate<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #000000; font-weight: bold;">if</span> MenuVisible <span style="color: #000000; font-weight: bold;">then</span>
    MenuVisible <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">False</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://mikesoft.ws/2007/09/20/auto-closing-menu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Удобство, о котором раньше приходилось только мечтать</title>
		<link>http://mikesoft.ws/2007/09/16/dreamed-usability/</link>
		<comments>http://mikesoft.ws/2007/09/16/dreamed-usability/#comments</comments>
		<pubDate>Sun, 16 Sep 2007 09:09:51 +0000</pubDate>
		<dc:creator>Smike</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Статьи]]></category>
		<category><![CDATA[TFileOpenDialog]]></category>
		<category><![CDATA[Windows Vista]]></category>

		<guid isPermaLink="false">http://mikesoft.ws/?p=85</guid>
		<description><![CDATA[Наверняка перед многими когда-либо вставала задача: открыть ряд файлов одного типа, но расположенных в различных подкаталогах. Если у вас есть Total Commander, то это конечно не составляет труда. Там можно просмотреть все файлы в данной папке и её подпапках, можно вывести результат поиска на панель: Во многих случаях этого достаточно. Эти файлы можно перетянуть в [...]]]></description>
			<content:encoded><![CDATA[<p>Наверняка перед многими когда-либо вставала задача: открыть ряд файлов одного  типа, но расположенных в различных подкаталогах.</p>
<p><span id="more-85"></span></p>
<p>Если у вас есть Total  Commander, то это конечно не составляет труда. Там можно просмотреть все файлы в  данной папке и её подпапках, можно вывести результат поиска на  панель:</p>
<p><a href="http://mikesoft.ws/wp-content/uploads/2009/02/tc.png"><img height="129" width="250" class="alignnone size-medium wp-image-86" title="Total Commander Search" alt="Total Commander Search" src="http://mikesoft.ws/wp-content/uploads/2009/02/tc-250x129.png" /></a></p>
<p>Во многих случаях этого достаточно. Эти файлы можно перетянуть в редактор, браузер или другую программу, поддерживающую вставку файлов с помощью Drag&#8217;n'Drop. Но если программа не поддерживает Drag&#8217;n'Drop? Да и Total Commander может попросту не оказаться под рукой.</p>
<p>В Windows Vista можно легко и просто сразу открыть группу файлов. В диалоге открытия, как и во всех окнах Проводника, есть встроенный поиск.</p>
<p><a href="http://mikesoft.ws/wp-content/uploads/2009/02/opendialog.png"><img height="196" width="250" class="alignnone size-medium wp-image-87" title="opendialog" alt="opendialog" src="http://mikesoft.ws/wp-content/uploads/2009/02/opendialog-250x196.png" /></a></p>
<p>Введя в строку поиска фильтр файлов мы получим список всех нужных файлов во всех вложенных каталогах:</p>
<p><a href="http://mikesoft.ws/wp-content/uploads/2009/02/filter.png"><img height="198" width="250" class="alignnone size-medium wp-image-88" title="filter" alt="filter" src="http://mikesoft.ws/wp-content/uploads/2009/02/filter-250x198.png" /></a></p>
<p><a href="http://mikesoft.ws/wp-content/uploads/2009/02/test.png"><img height="185" width="250" class="alignright size-medium wp-image-89" title="test" alt="test" src="http://mikesoft.ws/wp-content/uploads/2009/02/test-250x185.png" /></a>Проверим, как это работает. Дано: Delphi 2007 &mdash; 1 шт., компоненты TButton, TMemo и новый компонент TFileOpenDialog с закладки Vista Dialogs &mdash; тоже по 1 шт. А также прямые руки &mdash; 2 шт. TFileOpenDialog &mdash; это новый компонент, который представляет собой программный интерфейс для нового диалога открытия файлов в Windows Vista. Чтобы эксперимент удался, нужно выставить у компонента свойство Options := [fdoAllowMultiSelect], остальные значения нас не интересуют. Ну и под конец, чтобы эксперимент удался, пишем следующий код для события клика по кнопке:</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">procedure</span> TForm2<span style="color: #000066;">.</span><span style="color: #006600;">Button1Click</span><span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #000000; font-weight: bold;">if</span> FileOpenDialog1<span style="color: #000066;">.</span><span style="color: #006600;">Execute</span> <span style="color: #000000; font-weight: bold;">then</span>
    Memo1<span style="color: #000066;">.</span><span style="color: #006600;">Lines</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> FileOpenDialog1<span style="color: #000066;">.</span><span style="color: #006600;">Files</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></div></div>

<p>После этого запускаем пример, выбираем какую-нибудь папку, вводим фильтр и получаем следующую картину:</p>
<p><a href="http://mikesoft.ws/wp-content/uploads/2009/02/result.png"><img height="250" width="229" class="alignnone size-medium wp-image-91" title="result" alt="result" src="http://mikesoft.ws/wp-content/uploads/2009/02/result-229x250.png" /></a></p>
<p>Вот так просто решается данная задача в Windows Vista. Все найденные файлы корректно можно получить из диалога, вместе с правильными путями. Так что несмотря на все разговоры об отсутствии чего-либо нового и удобного в этой ОС, здесь полно разных удобств, которые хоть и не всегда заметно, но облегчают нашу работу.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://mikesoft.ws/2007/09/16/dreamed-usability/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>О пользе MSBuild в Delphi</title>
		<link>http://mikesoft.ws/2007/09/01/delphi-msbuild/</link>
		<comments>http://mikesoft.ws/2007/09/01/delphi-msbuild/#comments</comments>
		<pubDate>Sat, 01 Sep 2007 08:46:34 +0000</pubDate>
		<dc:creator>Smike</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Советы]]></category>
		<category><![CDATA[Статьи]]></category>
		<category><![CDATA[MSBuild]]></category>

		<guid isPermaLink="false">http://mikesoft.ws/?p=81</guid>
		<description><![CDATA[Рано или поздно в любых, более или менее серьезных проектах встает необходимость в автоматической компиляции или компиляции в один шаг. Зачем? Самая элементарная причина: чтобы быстро скомпилировать проект, не открывая его в среде. Например, был разработан крупный проект, включающий не один десяток компонентов, модулей, библиотек. Среда во время разработки сильно обросла посторонними и собственными компонентами [...]]]></description>
			<content:encoded><![CDATA[<p>Рано или поздно в любых, более или менее  серьезных проектах встает необходимость в автоматической компиляции или <a href="http://russian.joelonsoftware.com/Articles/TheJoelTest.html">компиляции в  один шаг</a>. Зачем? Самая элементарная причина: чтобы быстро скомпилировать  проект, не открывая его в среде. Например, был разработан крупный проект,  включающий не один десяток компонентов, модулей, библиотек. Среда во время  разработки сильно обросла посторонними и собственными компонентами и становится  трудно различить, какой компонент используется в данном проекте, а какой — нет.  Переносимости у проекта в данном случае никакой. На другом компьютере с  установленной средой Delphi его не получится скомпилировать: придется переносить  и устанавливать все необходимые компоненты, причем вспоминать, какой из них  нужен, а какой нет. Это крайне неудобно, а если еще принять во внимание, что  данный процесс подвержен ошибкам, то становится совсем невесело.</p>
<p><span id="more-81"></span></p>
<p>Издревле  эту проблему решали с помощью <a href="http://en.wikipedia.org/wiki/Makefile">make-файлов</a>, которые были  придуманы в <a title="Bell Labs" href="http://en.wikipedia.org/wiki/Bell_Labs">Bell Labs</a>, вероятно для сборки  первых юниксов. Вместе с Delphi поставлялась и поставляется консольная утилита  make.exe, которая и занимается сборкой проекта используя makefile. Но данный  подход имеет существенный недостаток: makefile нужно писать вручную, в Delphi  нет инструментов для его написания. А это значит, что придется задавать вручную  пути ко всем компонентам, описывать параметры компиляции, директории для вывода  промежуточных (DCU, OBJ) и конечных файлов (EXE, DLL) файлов.</p>
<p>К сожалению, такой подход долгое время был единственным возможным способом  автоматической компиляции проектов. Несмотря на то, что все параметры,  использующиеся средой Delphi для компиляции, всегда сохранялись вместе с  проектом. До Delphi 7 включительно это были *.cfg и *.dof-файлы. В первом  сохранялись параметры компиляции, а во втором все опции диалога Project Options.  Потом появились файлы *.bdsproj, где хранилась вся информация о проекте. Но это  не дало никаких преимуществ: компилятор DCC32 не понимает этих файлов и  соответственно автоматическая компиляция невозможна.</p>
<p>Серьезный сдвиг  произошел в Delphi 2007, где используется <a href="http://en.wikipedia.org/wiki/MSBuild"><span style="font-weight: bold;">MSBuild Engine</span></a> для компиляции проектов. Как  оказалось, это дает именно то что нужно.</p>
<p>В Delphi 2007 на смену файлам  *.bdsproj пришли файлы *.dproj (Delphi-проекты, для C++ Builder 2007 они имеют  расширение *.cbproj). Эти файлы не просто содержат параметры проекта, они заодно  и являются файлами инструкций сборки для MSBuild. &#171;Скормив&#187; такой файл MSBuild  мы сможем скомпилировать проект так же, как если бы мы компилировали его в среде  Delphi: с учетом всех путей, конфигураций, опций компилятора и используемых  директорий.</p>
<p>С помощью MSBuild процесс автоматической сборки проекта  становится до элементарного простым. Составляем файл Build.cmd примерно такого  содержимого:</p>
<pre>call rsvars.bat

msbuild MyProject.dproj /p:configuration=Release</pre>
<p>Первая  строчка вызывает файл rsvars.bat. Он находится в $(BDS)Bin и содержит  переменные среды для MSBuild. Затем вызывается сам MSBuild, причем указывается  конфигурация Release.</p>
<p>Таким образом мы получили простой и удобный  инструмент, который позволяет легко, в один шаг скомпилировать проект любой  сложности точно так же просто, как это делается в среде Delphi.</p>
<p>Замечание: в <strong>Delphi 2009</strong> конфигурация передается параметром config вместо configuration. Таким образом комманда компиляции будет выглядеть:</p>
<pre>call rsvars.bat

msbuild MyProject.dproj /p:config=Release</pre>
]]></content:encoded>
			<wfw:commentRss>http://mikesoft.ws/2007/09/01/delphi-msbuild/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Использование мультимедийной клавиатуры в Delphi-приложениях</title>
		<link>http://mikesoft.ws/2007/05/09/multimedia-keys/</link>
		<comments>http://mikesoft.ws/2007/05/09/multimedia-keys/#comments</comments>
		<pubDate>Wed, 09 May 2007 11:25:38 +0000</pubDate>
		<dc:creator>Smike</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Статьи]]></category>
		<category><![CDATA[клавиатура]]></category>

		<guid isPermaLink="false">http://mikesoft.ws/?p=114</guid>
		<description><![CDATA[Многие из нас пользуются мультимедийными или расширенными клавиатурами, где кроме обычных 100 с чем-то клавиш есть клавиши, упрощающие доступ к часто используемым функциям. Например, навигацию в браузере (Home, Back, Forward, Refresh, Stop), проигрывание музыки и фильмов в плеере, вызов калькулятора, почтового клиента и т.д. Эти дополнительные клавиши действительно часто упрощают вызов постоянно используемых действий. Как [...]]]></description>
			<content:encoded><![CDATA[<p>Многие из нас пользуются мультимедийными или расширенными клавиатурами, где  кроме обычных 100 с чем-то клавиш есть клавиши, упрощающие доступ к часто  используемым функциям. Например, навигацию в браузере (Home, Back, Forward,  Refresh, Stop), проигрывание музыки и фильмов в плеере, вызов калькулятора,  почтового клиента и т.д.</p>
<p>Эти дополнительные клавиши действительно часто упрощают вызов постоянно  используемых действий. Как же сделать поддержку этих клавиш в Delphi, чтобы  пользователю было удобнее пользоваться нашей программой?<span id="more-114"></span></p>
<p>Все дело в том, что дополнительные клавиши не эмулируют нажатие той или иной  комбинации, а имеют собственные коды:</p>
<table border="1">
<tbody>
<tr>
<th>Название</th>
<th>Код</th>
<th style="text-align: center;">Вызываемое приложение (по-умолчанию)</th>
</tr>
<tr>
<td style="text-align: center;" colspan="3">Группа Internet</td>
</tr>
<tr>
<td>Back</td>
<td>166</td>
<td></td>
</tr>
<tr>
<td>Forward</td>
<td>167</td>
<td></td>
</tr>
<tr>
<td>Stop</td>
<td>169</td>
<td></td>
</tr>
<tr>
<td>Favorites</td>
<td>171</td>
<td></td>
</tr>
<tr>
<td>Search</td>
<td>170</td>
<td>Windows Search</td>
</tr>
<tr>
<td>Refresh</td>
<td>168</td>
<td></td>
</tr>
<tr>
<td>Home</td>
<td>172</td>
<td>Internet Explorer или другой браузер по-умолчанию</td>
</tr>
<tr>
<td>Mail</td>
<td>180</td>
<td>Windows Mail или другой почтовый клиент по-умолчанию</td>
</tr>
<tr>
<td style="text-align: center;" colspan="3">Audio</td>
</tr>
<tr>
<td>Mute</td>
<td>173</td>
<td>Включает/выключает звук в системе</td>
</tr>
<tr>
<td>-Vol</td>
<td>174</td>
<td>Уменьшает уровень звука в системе</td>
</tr>
<tr>
<td>+Vol</td>
<td>175</td>
<td>Увеличивает уровень звука в системе</td>
</tr>
<tr>
<td>Media</td>
<td>181</td>
<td>Windows Media Player</td>
</tr>
<tr>
<td>Stop</td>
<td>178</td>
<td></td>
</tr>
<tr>
<td>Play/pause</td>
<td>179</td>
<td></td>
</tr>
<tr>
<td>Next</td>
<td>176</td>
<td></td>
</tr>
<tr>
<td>Prev</td>
<td>177</td>
<td></td>
</tr>
<tr>
<td style="text-align: center;" colspan="3">Другие</td>
</tr>
<tr>
<td>Calculator</td>
<td>183</td>
<td>Калькулятор</td>
</tr>
<tr>
<td>My Computer</td>
<td>182</td>
<td>Мой компьютер</td>
</tr>
</tbody>
</table>
<p>Кроме того, как видно из таблицы, некоторые клавиши вызывают определенные  программы или выполняют какие-то действия в системе, независимо от активного  приложения. Видимо это происходит из-за того, что этим действиям назначены  глобальные горячие клавиши, лично я этот вопрос не изучал.</p>
<p>Нажатия дополнительных клавиш можно перехватить в событии <em>OnKeyDown</em> формы или компонентов, параметр <em>Key</em> которого будет в этом случае  содержать какой-то из приведенных в таблице кодов. Но что делать если все  горячие клавиши приложения построены на специально предназначенном для этого  механизме — <em>Actions</em>? Здесь не все так тривиально, так как  мультимедийные клавиши не имеют названий и занести их в свойства  <em>TAction.Shortcut</em> или <em>TAction.SecondaryShortcuts</em> не выйдет. Но  это только в <strong>Object Inspector</strong>. На самом деле свойство  <em>SecondaryShortcuts</em> представляет собой список особого вида: класс  <em>TShortCutList</em>, наследник <em>TStringList</em>. В его свойстве  <em>Items</em> хранятся названия горячих клавиш: те, которые вводятся в  <strong>Object Inspector</strong>. А в свойстве <em>Objects</em> список  «закодированных» в тип <em>TShortCut</em> горячих клавиш, соответствующих тем,  что находятся в свойстве <em>Items</em>. Таким образом можно добавить  дополнительные горячие клавиши к экшену программно:</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;">  <span style="color: #808080; font-style: italic;">(* Action1 будет реагировать на нажатие
   &quot;интернетного&quot; Next на мультимедийной клавиатуре *)</span>
  Action1<span style="color: #000066;">.</span><span style="color: #006600;">SecondaryShortCuts</span><span style="color: #000066;">.</span><span style="color: #006600;">AddObject</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">''</span><span style="color: #000066;">,</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#40;</span>ShortCut<span style="color: #000066;">&#40;</span><span style="color: #0000ff;">167</span><span style="color: #000066;">,</span> <span style="color: #000066;">&#91;</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #808080; font-style: italic;">(* Action2 будет реагировать на нажатие
     Back на мультимедийной клавиатуре *)</span>
  Action2<span style="color: #000066;">.</span><span style="color: #006600;">SecondaryShortCuts</span><span style="color: #000066;">.</span><span style="color: #006600;">AddObject</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">''</span><span style="color: #000066;">,</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#40;</span>ShortCut<span style="color: #000066;">&#40;</span><span style="color: #0000ff;">166</span><span style="color: #000066;">,</span> <span style="color: #000066;">&#91;</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></pre></div></div>

<p>Добавив такой код в событие <em>TForm.OnCreate</em>, можно обеспечить  поддержку мультимедийных горячих клавиш для любых действий.</p>
]]></content:encoded>
			<wfw:commentRss>http://mikesoft.ws/2007/05/09/multimedia-keys/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

