<?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>BBProject.net &#187; delphi</title>
	<atom:link href="http://www.bbproject.net/tag/delphi/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.bbproject.net</link>
	<description>Programowanie, webmastering, informatyka</description>
	<lastBuildDate>Tue, 03 Aug 2010 08:22:56 +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>Co to jest Sender w procedurach zdarzeń?</title>
		<link>http://www.bbproject.net/2010/06/co-to-jest-sender-w-procedurach-zdarzen/</link>
		<comments>http://www.bbproject.net/2010/06/co-to-jest-sender-w-procedurach-zdarzen/#comments</comments>
		<pubDate>Sun, 27 Jun 2010 03:22:06 +0000</pubDate>
		<dc:creator>M@ster</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[events]]></category>
		<category><![CDATA[sender]]></category>
		<category><![CDATA[zdarzenie]]></category>

		<guid isPermaLink="false">http://www.bbproject.net/?p=380</guid>
		<description><![CDATA[Mały wpis dla początkujących programistów Delphi. Co to jest i do czego służy parametr Sender, występujący niemal zawsze przy procedurach zdarzeń (np.: naciśnięcia przycisku)? W skrócie, jest to wskaźnik na obiekt który wywołuje dane zdarzenie. Jeśli widzimy to w zdarzeniu OnClick przycisku, to jest to właśnie wskaźnik na ten przycisk (oczywiście trzeba go rzutować na [...]]]></description>
			<content:encoded><![CDATA[<p>Mały wpis dla początkujących programistów Delphi. Co to jest i do czego służy parametr <em>Sender</em>, występujący niemal zawsze przy procedurach zdarzeń (np.: naciśnięcia przycisku)?</p>
<p>W skrócie, jest to wskaźnik na obiekt który wywołuje dane zdarzenie. Jeśli widzimy to w zdarzeniu <em>OnClick</em> przycisku, to jest to właśnie wskaźnik na ten przycisk (oczywiście trzeba go rzutować na <em>TButton</em> aby odnieść się do jego własności).</p>
<p><span id="more-380"></span>Ktoś może zapytać, po co mi coś takiego, skoro dobrze wiem które zdarzenie przypisane jest któremu przyciskowi? Ano po to, że istnieje możliwość przypisania tego samego zdarzenia kilku obiektom, a nie tylko jednemu.</p>
<p>Weźmy prosty przykład, mam na formie 3 przyciski o różnych etykietach. Załóżmy że chcę, po kliknięciu w każdy z nich, aby na belce okna wyświetlała się etykieta tego klikniętego. W tradycyjnym podejściu należało by oprogramować 3 zdarzenia kliknięcia. My zrobimy to w jednym, wykorzystując parametr <em>Sender</em>, oraz przypisując owe zdarzenie do wszystkich przycisków:</p>
<pre class="brush: delphi">procedure TForm1.ButtonClick(Sender: TObject);
begin
  Caption := TButton(Sender).Caption;
end;
</pre>
<p>I to już wszystko! Przy pierwszym przycisku utworzyłem nowy event (zmieniając nieco jego nazwę), przy kolejnych wybrałem go z rozwijanej listy dla zdarzenia <em>OnClick</em>. Szybko, łatwo i bez zbędnego kodu.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bbproject.net/2010/06/co-to-jest-sender-w-procedurach-zdarzen/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Optymalizacja działań matematycznych w Delphi</title>
		<link>http://www.bbproject.net/2010/06/optymalizacja-dzialan-matematycznych-w-delphi/</link>
		<comments>http://www.bbproject.net/2010/06/optymalizacja-dzialan-matematycznych-w-delphi/#comments</comments>
		<pubDate>Tue, 01 Jun 2010 05:29:36 +0000</pubDate>
		<dc:creator>M@ster</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[optymalizacja]]></category>
		<category><![CDATA[potęgowanie]]></category>
		<category><![CDATA[power]]></category>
		<category><![CDATA[sqr]]></category>
		<category><![CDATA[sqrt]]></category>

		<guid isPermaLink="false">http://www.bbproject.net/?p=353</guid>
		<description><![CDATA[Mnożenie, potęgowanie, pierwiastkowanie, wszystkie te operacje trwają ułamek sekundy na obecnych maszynach, ułamek sekundy do czasu gdy nie musimy wykonać tysięcy czy miliony iteracji danego działania. W takiej sytuacji odpowiedni dobór użytych funkcji może mieć duży wpływ na czas trwania całej operacji. W tym wpisie pokaże jakich błędów unikać pisząc w Delphi skomplikowane działania, aby [...]]]></description>
			<content:encoded><![CDATA[<p><img class="size-thumbnail wp-image-354 alignleft" title="Sqrt" src="http://www.bbproject.net/wp-content/uploads/2010/05/sqrt-160x87.png" alt="" width="160" height="87" />Mnożenie, potęgowanie, pierwiastkowanie, wszystkie te operacje trwają ułamek sekundy na obecnych maszynach, ułamek sekundy do czasu gdy nie musimy wykonać tysięcy czy miliony iteracji danego działania. W takiej sytuacji odpowiedni dobór użytych funkcji może mieć duży wpływ na czas trwania całej operacji.</p>
<p>W tym wpisie pokaże jakich błędów unikać pisząc w Delphi skomplikowane działania, aby nie marnować czasu użytkownika końcowego naszej aplikacji. Do dzieła!</p>
<p><span id="more-353"></span></p>
<h4>Stałe</h4>
<p>Zacznijmy od rzeczy najprostszej, wykluczania operacji których wynik jest zawsze taki sam. Głupota? Prosty przykład, obliczenia w których występuje liczba PI podniesiona do kwadratu. Wartość tego wyrażenia jest zawsze taka sama, gdyż PI wynosi zawsze tyle samo.</p>
<pre class="brush: delphi">procedure TForm1.Button1Click(Sender: TObject);
var
  k: Double;
begin
  k := GetTickCount * Sqr(PI) + 4;
end;</pre>
<p>W takiej sytuacji zamiast podnosić 3,14 za każdym razem do kwadratu, najlepiej wyliczyć sobie tą wartość chociażby na systemowym kalkulatorze i zadeklarować nową stałą. Rzecz jasna, jak wcześniej wspomniałem, ma to sens tylko gdy wykonujemy naprawdę dużo obliczeń &#8211; inaczej jest to sztuka dla sztuki.</p>
<pre class="brush: delphi">procedure TForm1.Button1Click(Sender: TObject);
const
  PI_2 = 9.8696044010893586188344909998762;
var
  k: Double;
begin
  k := GetTickCount * PI_2 + 4;
end;
</pre>
<h4>Unikanie dzielenia</h4>
<p>Swego czasu, wyczytałem iż lepiej jest przykładowo mnożyć razy 0,5 niż dzielić przez 2. Próbowałem potwierdzić to różnymi testami, ale za każdym razem dostawałem identyczny wynik. Strzelam że obecne procesory lepiej sobie radzą z dzieleniem w stosunku do mnożenia liczb zmiennoprzecinkowych niż kiedyś.</p>
<p>Dlatego też porada ta nie ma dzisiaj większego sensu, ale warto o niej pamiętać.</p>
<h4>Power, Sqr, Sqrt</h4>
<p>Funkcja <em>Power</em>, analogicznie do swojej nazwy kryje w sobie dużą moc <img src='http://www.bbproject.net/wp-includes/images/smilies/icon_wink.png' alt=';)' class='wp-smiley' /> , nie mniej, należy się jej wystrzegać jak ognia. <em>Power</em> przyjmuje 2 argumenty, pierwszym jest liczba którą chcemy podnieść do potęgi, a drugim wykładnik potęgi.</p>
<p>Daje to ogromne możliwości z uwagi na fakt iż jest to liczba zmiennoprzecinkowa. Nie mniej, w sytuacji w której podnosimy liczbę do potęgi drugiej, bądź wyciągamy pierwiastek stopnia drugiego bezwzględnie stosujmy funkcje <em>Sqr</em> oraz <em>Sqrt</em>. Pierwiastek 4 stopnia? Zagnieżdżone dwie funkcję <em>Sqrt</em> będą na pewno szybsze niż jeden <em>Power</em>.</p>
<p>Oto małe porównanie szybkości wykonywania się poszczególnych operacji:</p>
<table>
<tbody>
<tr>
<th>Funkcja</th>
<th>Czas wykonania</th>
</tr>
<tr>
<td>Sqr(x)</td>
<td>0,0547ms</td>
</tr>
<tr>
<td>Sqrt(x)</td>
<td>0,6396ms</td>
</tr>
<tr>
<td>Power(x, 2)</td>
<td>0,8642ms</td>
</tr>
<tr>
<td>Power(x, 0.5)</td>
<td>3,9702ms</td>
</tr>
</tbody>
</table>
<p>I na koniec wynik testu z pierwiastkiem czwartego stopnia:</p>
<table>
<tbody>
<tr>
<th>Funkcja</th>
<th>Czas wykonania</th>
</tr>
<tr>
<td>Sqrt(Sqrt(x))</td>
<td>1,7472ms</td>
</tr>
<tr>
<td>Power(x, 0.25)</td>
<td>4,5896ms</td>
</tr>
</tbody>
</table>
<h4>Podsumowanie</h4>
<p>Liczę że te kilka porad pozwoli Wam na optymalizację wielokrotnie wykonywanych działań matematycznych w Delphi. Oczywiście należy też pamiętać o doprowadzeniu danego równania do jak najprostszej postaci przed przystąpieniem do implementacji w programie.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bbproject.net/2010/06/optymalizacja-dzialan-matematycznych-w-delphi/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Czym różni się TTabControl od TPageControl?</title>
		<link>http://www.bbproject.net/2010/05/czym-rozni-sie-ttabcontrol-od-tpagecontrol/</link>
		<comments>http://www.bbproject.net/2010/05/czym-rozni-sie-ttabcontrol-od-tpagecontrol/#comments</comments>
		<pubDate>Sat, 22 May 2010 19:42:20 +0000</pubDate>
		<dc:creator>M@ster</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[interface]]></category>
		<category><![CDATA[komponent]]></category>
		<category><![CDATA[tpagecontrol]]></category>
		<category><![CDATA[ttabcontrol]]></category>
		<category><![CDATA[zakładki]]></category>

		<guid isPermaLink="false">http://www.bbproject.net/?p=340</guid>
		<description><![CDATA[Oba są komponentami do tworzenia zakładek w środowisku Delphi. Czym się różnią? Zasadą organizacji treści i związanym z tym zastosowaniem. TTabControl to komponent w którym operujemy na samych zakładkach, z kolei TPageControl zarządza całymi stronami wraz z przypisaną do nich zawartością. W TTabControl cała umieszczona zawartość na komponencie jest wspólna dla wszystkich zakładek. Po co [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-344" title="Delphi - Komponenty Win32" src="http://www.bbproject.net/wp-content/uploads/2010/05/delphi_win32_components.png" alt="" width="239" height="111" />Oba są komponentami do tworzenia zakładek w środowisku Delphi. Czym się różnią? Zasadą organizacji treści i związanym z tym zastosowaniem.</p>
<p><strong><em>TTabControl</em></strong> to komponent w którym operujemy na samych zakładkach, z kolei <strong><em>TPageControl</em></strong> zarządza całymi stronami wraz z przypisaną do nich zawartością.</p>
<p>W <em>TTabControl</em> cała umieszczona zawartość na komponencie jest<strong> wspólna dla wszystkich zakładek</strong>. Po co nam coś takiego? Otóż w sytuacji w której zmieniają się jedynie dane między zakładkami a nie cały układ komponentów. Załóżmy że mamy naniesiony na owym komponencie wykres wraz z kilkoma przyciskami do jego zarządzania. Na każdej zakładce chcemy zatem mieć te same elementy a zmieniać jedynie zawartość wykresu i akcję przycisków. Możemy to uczynić przy pomocy zdarzenia <em>OnChange</em>.</p>
<p><span id="more-340"></span>Dodatkowo, w bardzo łatwy sposób możemy dynamicznie (lub na etapie projektowania) zmieniać ilość zakładek dzięki właściwości <em>Tabs</em> będącej typu <em>TStrings</em>.</p>
<p style="text-align: center;"><img class="alignnone size-full wp-image-341" title="TTabControl - edycja zakładek" src="http://www.bbproject.net/wp-content/uploads/2010/04/ttabcontrol_tabs.png" alt="" width="445" height="315" /></p>
<p>W opozycji do w/w komponentu, <em>TPageControl</em> posiada <strong>unikalną zawartość każdej zakładki</strong>. Jest to wygodne w sytuacji w której chcemy umieścić różne komponenty na każdej stronie.</p>
<p>Kolejne zakładki dodajemy w równie łatwy sposób na etapie projektowania. Są one w odróżnieniu od <em>TPageControl</em> osobnymi komponentami klasy <em>TTabSheet</em> a nie jedynie wpisem na liście.</p>
<p style="text-align: center;"><img class="alignnone size-full wp-image-342" title="TPageControl - dodawanie zakładki" src="http://www.bbproject.net/wp-content/uploads/2010/04/tpagecontrol_tabs.png" alt="" width="303" height="207" /></p>
<p>Komponent ten stosujemy wszędzie tam gdzie każda strona ma inną zawartość, np.: kategorie opcji programu.</p>
<p>Liczę że ten mały poradnik pomoże wszystkich początkującym programistom dostrzec różnicę między tymi komponentami i wybrać ten właściwy, którego w danej sytuacji potrzebują.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bbproject.net/2010/05/czym-rozni-sie-ttabcontrol-od-tpagecontrol/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>32-bitowe ikony w Delphi</title>
		<link>http://www.bbproject.net/2010/05/32-bitowe-ikony-w-delphi/</link>
		<comments>http://www.bbproject.net/2010/05/32-bitowe-ikony-w-delphi/#comments</comments>
		<pubDate>Tue, 04 May 2010 09:20:19 +0000</pubDate>
		<dc:creator>M@ster</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[32bit]]></category>
		<category><![CDATA[alpha]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[ikona]]></category>
		<category><![CDATA[timagelist]]></category>

		<guid isPermaLink="false">http://www.bbproject.net/?p=326</guid>
		<description><![CDATA[O ile nowsze edycje środowiska RAD jakim jest Delphi, posiadają pełne wsparcie dla 32-bitowych ikon czy nawet plików PNG, o tyle w starszych edycjach ich użycie jest mocno ograniczone. Jedyną opcją wykorzystania ikony z kanałem alpha jest wstawienie komponentu TImage i załadowanie do niego pliku ikony. Co jeśli chcemy użyć przeźroczystego obrazka w menu, pasku [...]]]></description>
			<content:encoded><![CDATA[<p><img class="size-thumbnail wp-image-327 alignright" title="Delphi - Form1" src="http://www.bbproject.net/wp-content/uploads/2010/05/delphi_form-160x132.png" alt="" width="160" height="132" />O ile nowsze edycje środowiska RAD jakim jest Delphi, posiadają pełne wsparcie dla 32-bitowych ikon czy nawet plików PNG, o tyle w starszych edycjach ich użycie jest mocno ograniczone.</p>
<p>Jedyną opcją wykorzystania ikony z kanałem alpha jest wstawienie komponentu <em>TImage</em> i załadowanie do niego pliku ikony. Co jeśli chcemy użyć przeźroczystego obrazka w menu, pasku narzędzi czy zakładce? Tutaj jedynym komponentem który nam to umożliwia jest <em>TImageList</em>, który niestety gubi informacje o kolorach powyżej 24 bitów.</p>
<p>W tym wpisie pokaże jak sobie z tym poradzić i mimo to użyć ładnych plików ikon w naszych aplikacjach.</p>
<p><span id="more-326"></span>Rozwiązanie z racji stosowania pewnego tricku ma pewną wadę. Wszystkie zasoby do <em>TImageList</em> musimy ładować w trakcie działania aplikacji a nie na etapie projektowania &#8211; innymi słowy, musimy osobno do pliku wykonywalnego dołączać pliki ikon których użyjemy.</p>
<p><img class="alignright size-full wp-image-328" title="ImageIndex" src="http://www.bbproject.net/wp-content/uploads/2010/05/imageindex.png" alt="" width="238" height="98" />Drugą niewygodą, która jest następstwem pierwszej, jest fakt że przypisując konkretnemu elementowi <em>ImageIndex</em> musimy wpisać go nie widząc załadowanej ikony &#8211; wymusza to nas nas ładowanie ikon zawsze w tej samej kolejności i trzymania pozycji danego obrazka zawsze pod tym samym numerkiem.</p>
<p style="text-align: center;">
<p>Są to pewne wady który uprzykrzają proces pisania programu, ale jak to mówią, coś za coś.</p>
<p>Przejdźmy zatem do czynów. Mając umieszczony na formie <em>TImageList</em> musimy go dostosować do przyjmowania 32-bitowych ikon. Skorzystajmy z tej oto procedury:</p>
<pre class="brush: delphi">procedure ConvertTo32BitImageList(ImageList: TImageList);
const
  MASK: array[Boolean] of Longint = (0, ILC_MASK);
var
  templist: TImageList;
begin
  if Assigned(ImageList) then
  begin
    templist := TImageList.Create(nil);
    try
      templist.Assign(ImageList);
      with ImageList do
      begin
        Handle := ImageList_Create(Width, Height, ILC_COLOR32 or MASK[Masked], 0, AllocBy);
        if not HandleAllocated then
          raise EInvalidOperation.Create(SInvalidImageList);
      end;
      Imagelist.AddImages(templist);
    finally
      FreeAndNil(templist);
    end;
  end;
end;</pre>
<p>Po skonwertowaniu listy obrazów (pustej), możemy zacząć dodawać nasze zasoby. Dla ułatwienia możemy skorzystać z tej procedury:</p>
<pre class="brush: delphi">procedure AddIconTo32BitImageList(ImageList: TImageList; const FileName: String);
var
  icon: TIcon;
  stream: TFileStream;
begin
  icon := TIcon.Create;
  stream := TFileStream.Create(FileName, fmOpenRead);
  icon.LoadFromStream(stream);
  ImageList.AddIcon(icon);
  icon.Free;
  stream.Free;
end;</pre>
<p>Jak widać, powyższa procedura przyjmuje 2 parametry, komponent <em>TImageList</em> oraz ścieżkę do ikony którą chcemy dodać. Należy pamiętać o tym aby skonfigurować odpowiednio listę obrazów do naszych potrzeb &#8211; ustawić wymiar ikon.</p>
<p>Przykładowe użycie powyższej metody:</p>
<pre class="brush: delphi">procedure TForm1.FormCreate(Sender: TObject);
begin
  ImageList1.Clear;
  ConvertTo32BitImageList(ImageList1);
  AddIconTo32BitImageList(ImageList1, 'data\open.ico');
  AddIconTo32BitImageList(ImageList1, 'data\save.ico');
  AddIconTo32BitImageList(ImageList1, 'data\exit.ico');
end;</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.bbproject.net/2010/05/32-bitowe-ikony-w-delphi/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Operator trójargumentowy w Delphi</title>
		<link>http://www.bbproject.net/2010/04/operator-trojargumentowy-w-delphi/</link>
		<comments>http://www.bbproject.net/2010/04/operator-trojargumentowy-w-delphi/#comments</comments>
		<pubDate>Thu, 22 Apr 2010 12:46:35 +0000</pubDate>
		<dc:creator>M@ster</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[instrukcja warunkowa]]></category>
		<category><![CDATA[operator]]></category>
		<category><![CDATA[overload]]></category>
		<category><![CDATA[przeciążenie]]></category>

		<guid isPermaLink="false">http://www.bbproject.net/?p=212</guid>
		<description><![CDATA[W PHP funkcjonuje coś takiego jak operator trójargumentowy. Jest to składnia języka, pozwalająca na zastąpienie pojedynczego bloku if&#8230;else w bardziej przejrzysty sposób: warunek ? jeśli_prawda : jeśli_fałsz Przykładowo: $zmienna = $k &#62;= 0 ? 'dodatnie' : 'ujemne'; &#8230;odpowiada konstrukcji: if ($k &#62;= 0) {   $zmienna = 'dodatnie'; } else {   $zmienna = 'ujemne'; [...]]]></description>
			<content:encoded><![CDATA[<p>W PHP funkcjonuje coś takiego jak operator trójargumentowy. Jest to składnia języka, pozwalająca na zastąpienie pojedynczego bloku <em>if&#8230;else</em> w bardziej przejrzysty sposób:</p>
<pre>warunek ? jeśli_prawda : jeśli_fałsz</pre>
<p>Przykładowo:</p>
<pre class="brush: php">$zmienna = $k &gt;= 0 ? 'dodatnie' : 'ujemne';</pre>
<p>&#8230;odpowiada konstrukcji:</p>
<pre class="brush: php">if ($k &gt;= 0)
{
  $zmienna = 'dodatnie';
}
else
{
  $zmienna = 'ujemne';
}</pre>
<p>Jak widać uproszczenie jest znaczne. Object Pascal (Delphi) nie posiada niestety operatora trójargumentowego. W tym wpisie pokażę jak zastąpić tą funkcjonalność przy pomocy prostej funkcji i jej <a href="http://pl.wikipedia.org/wiki/Przeci%C4%85%C5%BCanie_funkcji">przeciążenia</a>.</p>
<p><span id="more-212"></span>Zasadniczo, naszym zadaniem będzie stworzenie funkcji o 3 argumentach, która będzie odpowiednikiem operatora trójargumentowego. Jako iż nie jest to skomplikowane zadanie, przystąpmy do działania:</p>
<pre class="brush: delphi">function IfThen(Condition: Boolean; const TrueValue: String; const FalseValue: String): String;
begin
  if Condition then Result := TrueValue else Result := FalseValue;
end;</pre>
<p>Funkcję tę nazwałem <em>IfThen</em>, gdyż jest to w zasadzie skrót konstrukcji <em>if&#8230;then&#8230;else</em>. Pierwszym parametrem jest warunek, kolejnym zwracana wartość w przypadku spełnienia owego warunku i ostatnim, wartość w przypadku fałszu.</p>
<p>Jak możemy zauważyć, funkcja dedykowana jest jedynie dla argumentów będących ciągiem znaków. Korzystając z dyrektywy <em>overload</em>, stwórzmy przeciążone funkcje dostosowane do wielu różnych typów zmiennych. Całość, umieściłem od razu w osobnym module w celu łatwiejszego, późniejszego wykorzystania napisanych funkcji.</p>
<pre class="brush: delphi">unit TripleOperator;

interface

function IfThen(Condition: Boolean; TrueValue, FalseValue: Byte): Byte; overload;
function IfThen(Condition: Boolean; TrueValue, FalseValue: Integer): Integer; overload;
function IfThen(Condition: Boolean; TrueValue, FalseValue: Single): Single; overload;
function IfThen(Condition: Boolean; TrueValue, FalseValue: Double): Double; overload;
function IfThen(Condition: Boolean; const TrueValue: String; const FalseValue: String): String; overload;

implementation

function IfThen(Condition: Boolean; TrueValue, FalseValue: Byte): Byte;
begin
  if Condition then Result := TrueValue else Result := FalseValue;
end;

function IfThen(Condition: Boolean; TrueValue, FalseValue: Integer): Integer;
begin
  if Condition then Result := TrueValue else Result := FalseValue;
end;

function IfThen(Condition: Boolean; TrueValue, FalseValue: Single): Single;
begin
  if Condition then Result := TrueValue else Result := FalseValue;
end;

function IfThen(Condition: Boolean; TrueValue, FalseValue: Double): Double;
begin
  if Condition then Result := TrueValue else Result := FalseValue;
end;

function IfThen(Condition: Boolean; const TrueValue: String; const FalseValue: String): String;
begin
  if Condition then Result := TrueValue else Result := FalseValue;
end;

end.
</pre>
<p style="text-align: right;">Pobierz <a href="http://www.bbproject.net/wp-content/uploads/2010/01/triple_operator.zip">TripleOperator.pas</a>.</p>
<p>Tym sposobem, zrealizowaliśmy operator trójargumentowy w Delphi dla kilku typów zmiennych. Jak widać, bardzo łatwo można dodać kolejne. Przykładowe użycie funkcji <em>IfThen</em>:</p>
<pre class="brush: delphi">procedure TForm1.Button1Click(Sender: TObject);
begin
  Caption := IfThen(Top &lt;= 200, 'okno jest nisko', 'okno jest wysoko');
end;</pre>
<p>Niestety są pewne kruczki w stosunku do wersji w PHP. Po pierwsze, jest to funkcja a nie składnia języka &#8211; ciut mniejsza wydajność. Po drugie, w przypadku spełnienia warunku, oba argumenty muszą zostać przekazane do funkcji, a nie tylko ten odpowiedzialny za prawdę. Innymi słowy, jeśli argumentami są wyniki działań innych funkcji, to bez względu na wynik parametru <em>Condition</em>, i tak obie zostaną wykonane, mimo że zwrócona zostanie tylko jedna z nich. Nie posiada tego mankamentu konstrukcja <em>if&#8230;then&#8230;else</em>, gdzie po wykonaniu pierwszej instrukcji, blok <em>else</em> w ogóle nie jest analizowany. W zależności od wykorzystania, może to nie mieć znaczenia lub mieć bardzo duże. Przykładowo:</p>
<pre class="brush: delphi">Count := IfThen(i = 0, 8, 8 div i);</pre>
<p>Taki przypadek, w sytuacji gdy zmienna <em>i</em> przyjmuje wartość 0, spowoduje niestety błąd.</p>
<p>Wszystko więc zależy od zastosowania, nie mniej, w większości przypadków skraca nam to ilość kodu jaki musielibyśmy napisać tradycyjnie.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bbproject.net/2010/04/operator-trojargumentowy-w-delphi/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Instalacja komponentów w Turbo Delphi Explorer</title>
		<link>http://www.bbproject.net/2010/03/instalacja-komponentow-w-turbo-delphi-explorer/</link>
		<comments>http://www.bbproject.net/2010/03/instalacja-komponentow-w-turbo-delphi-explorer/#comments</comments>
		<pubDate>Fri, 19 Mar 2010 08:54:57 +0000</pubDate>
		<dc:creator>M@ster</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[explorer]]></category>
		<category><![CDATA[komponent]]></category>
		<category><![CDATA[thttpget]]></category>

		<guid isPermaLink="false">http://www.bbproject.net/?p=249</guid>
		<description><![CDATA[Turbo Delphi Explorer to świetne środowisko dla obiektowego Pascala, niestety jako darmowa edycja ma zablokowaną możliwość instalowania dodatkowych komponentów. Postaram się pokazać jak mimo tego ograniczenia skorzystać z zewnętrznego kawałka kodu. Metoda opiera się na dynamicznym tworzeniu instancji komponentu, zatem jest ona zgodna z licencją i nie narusza jej w żaden sposób. Oczywiście niesie to [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-250" title="Delphi" src="http://www.bbproject.net/wp-content/uploads/2010/02/delphi.png" alt="" width="123" height="123" /><a href="http://pl.wikipedia.org/wiki/Turbo_Delphi">Turbo Delphi</a> Explorer to świetne środowisko dla obiektowego Pascala, niestety jako darmowa edycja ma zablokowaną możliwość instalowania dodatkowych komponentów. Postaram się pokazać jak mimo tego ograniczenia skorzystać z zewnętrznego kawałka kodu.</p>
<p>Metoda opiera się na dynamicznym tworzeniu instancji komponentu, zatem jest ona zgodna z licencją i nie narusza jej w żaden sposób. Oczywiście niesie to za sobą pewne niedogodności i nie zawsze może być stosowane, jednak w znakomitej większości przypadków tak.</p>
<p><span id="more-249"></span>Jako przykład, wykorzystam komponentem <em>THTTPGet</em>, służący do pobierania plików z internetu. Nie jest to komponent wizualny, tzn. udostępnia pewną funkcjonalność a nie element widoczny dla użytkownika końcowego.</p>
<p>W pierwszej kolejności, po umiejscowieniu plików na dysku, musimy dodać wybraną lokalizację do ścieżki przeszukiwania bibliotek. Robimy to w menu <em>Tools</em> &gt; <em>Options</em> &gt; <em>Library &#8211; Win32</em> &gt; <em>Library path</em>. Jeśli ten krok mamy już za sobą, dodajemy do sekcji <em>uses</em> nazwę komponentu:</p>
<pre class="brush: delphi">uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, HTTPGet;
</pre>
<p>Kolejno musimy stworzyć nową instancję komponentu, w zależności od tego czy wykorzystujemy go tylko w określonym fragmencie kodu, czy też globalnie, funkcje tworzenia i zwalnianie umieszczamy w stosownym miejscu. Ja postanowiłem utworzyć komponent zaraz po załadowaniu aplikacji oraz zwolnić go przy jej zamykaniu:</p>
<pre class="brush: delphi">procedure TForm1.FormCreate(Sender: TObject);
begin
  HTTPGet := THTTPGet.Create(Self);
end;
</pre>
<pre class="brush: delphi">procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  HTTPGet.Free;
end;
</pre>
<p><em>HTTPGet</em> to nazwa zmiennej zadeklarowanej w sekcji <em>private</em> klasy <em>TForm1</em>. W tym momencie możemy już korzystać z komponentu, odnosząc się do zmiennej <em>HTTPGet</em>.</p>
<p>To rozwiązanie pozwala nam na swobodę w doborze komponentów w Turbo Delphi Explorer, jednak niesie ze sobą pewne ograniczenia. W przypadku komponentów wizualnych, nie możemy w wygodny sposób umieścić ich na formie oraz manipulować ich wyglądem. Musimy tego dokonać po przez odnoszenie się do odpowiednich właściwości w samym kodzie, najlepiej tuż po jego stworzeniu.</p>
<p>Na koniec zamieszczam całościowy listing kodu wykorzystanego w tym wpisie, wraz z przykładowym zastosowaniem <em>THTTPGet</em>:</p>
<pre class="brush: delphi">unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, HTTPGet, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button1Click(Sender: TObject);
  private
    HTTPGet: THTTPGet;
    procedure FileDone(Sender: TObject; FileName: String; FileSize: Integer);
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  HTTPGet := THTTPGet.Create(Self);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  HTTPGet.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Button1.Enabled := False;
  with HTTPGet do
    begin
    BinaryData := True;
    URL := 'http://downloads.sourceforge.net/sevenzip/7z465.exe';
    FileName := '7z465.exe';
    OnDoneFile := FileDone;
    GetFile;
  end;
end;

procedure TForm1.FileDone(Sender: TObject; FileName: String; FileSize: Integer);
begin
  Button1.Enabled := True;
end;

end.</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.bbproject.net/2010/03/instalacja-komponentow-w-turbo-delphi-explorer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Obliczanie sumy kontrolnej MD5 w Delphi</title>
		<link>http://www.bbproject.net/2010/01/obliczanie-sumy-kontrolnej-md5-w-delphi/</link>
		<comments>http://www.bbproject.net/2010/01/obliczanie-sumy-kontrolnej-md5-w-delphi/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 08:43:39 +0000</pubDate>
		<dc:creator>M@ster</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[dcpcrypt]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[md5]]></category>
		<category><![CDATA[suma kontrolna]]></category>

		<guid isPermaLink="false">http://www.bbproject.net/?p=40</guid>
		<description><![CDATA[MD5 (z ang. Message-Digest algorithm 5 &#8211; Skrót wiadomości wersja 5) &#8211; algorytm z dziedziny kryptografii. Jest to popularna kryptograficzna funkcja skrótu, która z dowolnego ciągu danych generuje 128-bitowy skrót. Źródło: http://pl.wikipedia.org/wiki/MD5 Język programowania jakim jest Delphi, mimo swojej potęgi nie posiada wbudowanych funkcji do obliczania sum kontrolnych, nawet tak popularnych jak MD5. Nie będę [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>MD5 (z ang. Message-Digest algorithm 5 &#8211; Skrót wiadomości wersja 5) &#8211; algorytm z dziedziny kryptografii. Jest to popularna kryptograficzna funkcja skrótu, która z dowolnego ciągu danych generuje 128-bitowy skrót.</p>
<p>Źródło: <a href="http://pl.wikipedia.org/wiki/MD5">http://pl.wikipedia.org/wiki/MD5</a></p></blockquote>
<p>Język programowania jakim jest Delphi, mimo swojej potęgi nie posiada wbudowanych funkcji do obliczania sum kontrolnych, nawet tak popularnych jak MD5. Nie będę pokazywał jak stworzyć implementację algorytmu MD5 w object pascalu, chociaż jest to możliwe, a zademonstruję jak policzyć sumę kontrolną dowolnego łańcucha z wykorzystaniem pakietu <a href="http://www.cityinthesky.co.uk/cryptography.html">DCPcrypt</a>.</p>
<p><span id="more-40"></span>Pakiet DCPcrypt posiada implementację dla bardzo dużej ilości algorytmów mieszających jak i szyfrujących. W tym wpisie zajmiemy się jego niewielką cząstką w postaci sumy MD5. Pierwsze co musimy zrobić to pobrać ów pakiet, można to zrobić na <a href="http://www.cityinthesky.co.uk/cryptography.html">stronie autora</a> kodu, bądź bezpośrednio <a href="http://www.bbproject.net/wp-content/uploads/2009/11/dcpcrypt2-2009.zip">tutaj</a>. DCPcrypt można zainstalować jako komponent w środowisku Delphi, nie mniej, my ograniczymy się do wypakowania plików i dodania w konfiguracji środowiska ścieżki przeszukiwania bibliotek (<em>Tools</em> &gt; <em>Options</em> &gt; <em>Library &#8211; Win32</em> &gt; <em>Library path</em>). Operację tę przeprowadzamy dla głównego folderu pakietu oraz podfolderu <em>Hashes</em>.</p>
<p style="text-align: center;"><a href="http://www.bbproject.net/wp-content/uploads/2009/11/delphi_directories.png"><img class="alignnone size-large wp-image-42" title="Turbo Delphi - Directories" src="http://www.bbproject.net/wp-content/uploads/2009/11/delphi_directories-512x341.png" alt="Turbo Delphi - Directories" width="512" height="341" /></a></p>
<p style="text-align: left;">Po wstępnej konfiguracji możemy przejść do napisania pożądanej funkcji. W pierwszej kolejności dodajemy do listy używanych bibliotek (<em>uses</em>) moduł <em>DCPmd5</em>.</p>
<pre class="brush: delphi">uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, DCPmd5;</pre>
<p>Kolejno deklarujemy funkcję o nazwie <em>MD5</em>, która przyjmuje 1 parametr wejściowy w postaci ciągu znaków, oraz takowy zwraca &#8211; jego sumę kontrolną.</p>
<pre class="brush: delphi">function MD5(const S: String): String;
var
  i: Byte;
  digest: array[0..15] of Byte;
begin

  with TDCP_md5.Create(nil) do
  begin
    Init;
    Update(S[1], Length(S));
    Final(digest);
    Free;
  end;

  Result := '';
  for i := 0 to Length(digest)-1 do
    Result := Result + IntToHex(digest[i], 2);
  Result := LowerCase(Result);

end;</pre>
<p>Na koniec kilka słów objaśnienia powyższego kodu. Po stworzeniu instancji klasy <em>TDCP_md5</em>, następuje jej inicjacja metodą <em>Init</em>. Metoda <em>Update</em> może być wywoływana dowolną ilość razy i przyjmuje jako parametry bufor ciągu bajtów z którego generowana jest funkcja skrótu, oraz jego długość. W naszym przypadku, podajemy początek ciągu znaków (<em>[1]</em> jest wymagane gdyż zerowym elementem tablicy jakim jest String jest jego długość, co powodowało by błędne obliczenia). Jeśli obliczalibyśmy sumę kontrolną pliku, dobrym zwyczajem jest, aby nie obciążać pamięci, odczytywać fragmentami badany plik oraz obliczać część sumy przy pomocy metody <em>Update</em>. Całościowe odczytanie pliku wymagało by zadeklarowania tyle pamięci RAM ile zajmuje dany plik.</p>
<p>Metoda <em>Final</em> kończy obliczenia i zrzuca sumę w postaci tablicy bajtów. Końcowa pętla przekształca ją do postaci w jakiej jest zwykle używana (np: 0cc1099409f2effa3e09912cda637023 dla ciągu wejściowego bbproject.net).</p>
<p>Jeśli zajedzie potrzeba, powyższy kod bardzo łatwo możemy zmodyfikować na potrzeby choćby sumy SHA-1, lub dowolnej innej obsługiwanej przez DCPcrypt. Dlaczego użyłem akurat tego pakietu, podczas gdy w internecie łatwo znaleźć dziesiątki innych, gotowych implementacji? Powodów jest kilka, po pierwsze szybkość obliczeń, z moich testów wynika iż implementacja wykonana w pakiecie DCPcrypt najszybciej oblicza sumy kontrolne. Drugim powodem jest możliwość cząstkowego obliczania sumy kontrolnej (przydatne przy bardzo dużych plikach). Ilość obsługiwanych algorytmów też nie pozostała bez znaczenia.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bbproject.net/2010/01/obliczanie-sumy-kontrolnej-md5-w-delphi/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
