<?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>xion.log &#187; Aplikacje</title>
	<atom:link href="http://xion.org.pl/category/it/apps/feed/" rel="self" type="application/rss+xml" />
	<link>http://xion.org.pl</link>
	<description>Blog Xiona o programowaniu i innych ciekawych rzeczach :)</description>
	<lastBuildDate>Tue, 27 Jul 2010 16:54:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Stare pliki INI</title>
		<link>http://xion.org.pl/2010/06/24/stare-pliki-ini/</link>
		<comments>http://xion.org.pl/2010/06/24/stare-pliki-ini/#comments</comments>
		<pubDate>Thu, 24 Jun 2010 13:47:46 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Aplikacje]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[INI]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=1917</guid>
		<description><![CDATA[Jest coś takiego jak aplikacje typu portable. Charakteryzują się tym, że nie wymagają instalacji i nie zostawiają żadnych "śladów" w systemie poza swoim własnym folderem. Takie programy są praktyczne, jeśli musimy korzystać z wielu różnych, nieswoich komputerów - wtedy można je przenieść na nośniku typu pendrive i uruchamiać bezpośrednio z niego. Oczywiście nasze własne aplikacje [...]]]></description>
			<content:encoded><![CDATA[<p>Jest coś takiego jak aplikacje typu <em>portable</em>. Charakteryzują się tym, że nie wymagają instalacji i nie zostawiają żadnych "śladów" w systemie poza swoim własnym folderem. Takie programy są praktyczne, jeśli musimy korzystać z wielu różnych, nieswoich komputerów - wtedy można je przenieść na nośniku typu <em>pendrive</em> i uruchamiać bezpośrednio z niego.</p>
<p><img style="float:right;margin:5px" src="http://xion.org.pl/wp-content/uploads/2010/06/ini-file-icon.png" alt="" title="Ikonka pliku INI" />Oczywiście nasze własne aplikacje nie muszą należeć do tej kategorii. Inaczej musielibyśmy na przykład zrezygnować z możliwości zapisywania ustawień programu w Rejestrze... Hmm, ale czy akurat tutaj jest czego żałować? :)<br />
Ano niekoniecznie. Dawno, dawno temu popularnym sposobem przechowywania konfiguracji były pliki o rozszerzeniu .<em>ini</em>. Są to bardzo proste pliki tekstowe, zawierające pary klucz-wartość pogrupowane w sekcje. Składnia takiego pliku wygląda następująco:</p>
<div class="syntax_hilite">
<div id="code-3">
<div class="code"><span style="color:#006600; font-weight:bold;">&#91;</span>Sekcja1<span style="color:#006600; font-weight:bold;">&#93;</span><br />
Klucz1=<span style="color:#800000;">42</span><br />
Klucz2=<span style="color:#CC0000;">"wartość"</span></p>
<p><span style="color:#006600; font-weight:bold;">&#91;</span>Sekcja2<span style="color:#006600; font-weight:bold;">&#93;</span><br />
Klucz=<span style="color:#CC0000;">"Ala ma kota"</span></div>
</div>
</div>
<p>
W Windows API wciąż istnieje interfejs pozwalający na odczytywanie i zapisywanie danych z takich plików, chociaż jest on trzymany podobno tylko dla kompatybilności. Obejmuje on funkcje specjalizujące się w obsłudze konkretnego pliku - mianowicie <em>win.ini</em> z głównego katalogu Windows - ale także dowolnego pliku .<em>ini</em> o podanej przez nas nazwie. Tymi bardziej elastycznymi funkcjami są:</p>
<ul>
<li>do odczytywania wartości różnych typów: <code>GetPrivateProfileInt</code>, <code>GetPrivateProfileString</code>, <code>GetPrivateProfileStruct</code></li>
<li>do zapisywania wartości: <code>WritePrivateProfileString</code>, <code>WritePrivateProfileStruct</code></li>
<li>do pobierania listy sekcji w pliku .<em>ini</em> (<code>GetPrivateProfileSectionNames</code>) oraz listy kluczy w sekcji (<code>GetPrivateProfileSection</code>)</li>
</ul>
<p>Ich użycie jest dość proste. Jeśli na przykład chcielibyśmy pobrać wartość liczbową z powyższego pliku, to wystarczy poniższe wywołanie, o ile jest on zapisany w bieżącym katalogu jako <em>plik.ini</em>:</p>
<div class="syntax_hilite">
<div id="cpp-4">
<div class="cpp"><span style="color: #0000ff;">int</span> value = GetPrivateProfileInt<span style="color: #000000;">&#40;</span><span style="color: #666666;">"Sekcja1"</span>, <span style="color: #666666;">"Klucz1"</span>, <span style="color: #0000dd;">0</span>, <span style="color: #666666;">"plik.ini"</span><span style="color: #000000;">&#41;</span>;</div>
</div>
</div>
<p>
Dość podobnie wygląda korzystanie z pozostałych funkcji operujących na pojedynczych wartościach.</p>
<p>Dzisiaj pliki .<em>ini</em> są już trochę reliktem przeszłości, ale wydaje mi się, że do niektórych prostych zastosowań nadają się całkiem dobrze. A jeśli zdarzy się ten niefortunny przypadek, iż w którejś z przyszłych wersji Windows <em>support</em> dla nich zostanie porzucony, to cóż... składniowo są one na tyle proste, że ich parsowanie nie powinno być problemem ;-)</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2010/06/24/stare-pliki-ini/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Triki z PowerShellem #14 &#8211; Moja własna mała konsolka</title>
		<link>http://xion.org.pl/2010/06/16/triki-z-powershellem-14-moja-wlasna-mala-konsolka/</link>
		<comments>http://xion.org.pl/2010/06/16/triki-z-powershellem-14-moja-wlasna-mala-konsolka/#comments</comments>
		<pubDate>Wed, 16 Jun 2010 15:49:11 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Aplikacje]]></category>
		<category><![CDATA[konsola]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=1879</guid>
		<description><![CDATA[Jak zdołałem (mam nadzieję) pokazać w kilkunastu notkach na temat PowerShella, narzędzie to pozwala na (pół)automatyczne wykonywanie wielu niekiedy skomplikowanych operacji, o ile tylko potrafimy je zakodować w postaci odpowiednich skryptów. Możemy więc ułatwić sobie życie szybkim uploadem na serwer FTP, wysyłaniem maili, a nawet (ło kurczę!) uaktualnianiem statusu na Twitterze :) Kiedyś możemy jednak [...]]]></description>
			<content:encoded><![CDATA[<p>Jak zdołałem (mam nadzieję) pokazać w <a href="http://xion.org.pl/tag/powershell/">kilkunastu notkach</a> na temat <a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx">PowerShella</a>, narzędzie to pozwala na (pół)automatyczne wykonywanie wielu niekiedy skomplikowanych operacji, o ile tylko potrafimy je zakodować w postaci odpowiednich skryptów. Możemy więc ułatwić sobie życie szybkim <a href="http://xion.org.pl/2008/05/24/triki-z-powershellem-2-szybki-upload/"><em>uploadem</em> na serwer FTP</a>, <a href="http://xion.org.pl/2008/07/03/triki-z-powershellem-6-mail-z-zalacznikami/">wysyłaniem maili</a>, a nawet (ło kurczę!) <a href="http://xion.org.pl/2009/10/30/triki-z-powershellem-11-cwierkamy/">uaktualnianiem statusu</a> na <a href="http://www.twitter.com/">Twitterze</a> :) Kiedyś możemy jednak chcieć takie pojedyncze rozwiązania złożyć w jakąś większą całość - na przykład w tytułową "małą własną konsolkę".</p>
<p>O co chodzi? W skrócie: o coś w rodzaju własnego <em>shella</em>, przyjmującego ograniczony i ściśle określony zestaw poleceń, pozwalających na wykonywanie prostych czynności. Różnica względem normalnej powłoki jest taka, iż komendy te mają być w założeniu bardzo wysokopoziomowe - każda z opisywanych dotąd przeze mnie <em>powershellowych</em> "sztuczek" podpadałaby pod li tylko jedno polecenie, jeśli w ogóle. Najbliższym graficznym odpowiednikiem czegoś takiego jest pasek narzędzi lub skrótów do programów.<br />
Aby nasz mały <em>shell</em> stał się faktem, potrzebujemy tylko kilku rzeczy, wśród których są:</p>
<ul>
<li><strong>Pobieranie poleceń od użytkownika</strong>. Od tego mamy w PSh instrukcję <code>Read-Host</code>, nad którą nie ma co się rozwodzić w jakiś specjalny sposób. Ot, po prostu daje nam w wyniku linijkę tekstu wpisaną do konsoli. Jeśli użyjemy parametru <code>Prompt</code>, nasz <em>shell</em> może mieć ładny znak zachęty :)</li>
<li><strong>Wybór właściwej akcji</strong> w zależności od wpisanej komendy. Gdybyśmy pisali "normalny" program w "normalnym" języku programowania, wtedy pewnie dodalibyśmy bazowy interfejs dla komend, potem specyficzne klasy go implementujące, a potem jeszcze fabrykę tychże... No dobra, zdecydowanie przeginam ;-) W rzeczywistości zwykły <code>switch</code> jest tu niemal zbytkiem, zwłaszcza że w PowerShellu posiada on pożyteczny parametr <code>-wildcard</code>, pozwalający na dopasowanie ciągów znaków do wzorców zawierających symbole wieloznaczne (jak np. <code>*</code> lub <code>?</code>). Dzięki temu można ograniczyć konieczność wpisywania całych nazw poleceń, jeśli jednoznaczna jest już sama pierwsza litera (<code>"t*"</code> zamiast <code>"tweet"</code>, itp.).</li>
<li><strong>Uruchamianie programów</strong> z parametrami. Odpalenie aplikacji w powłoce takiej jak PowerShell jest oczywiście bardzo proste. Nie zapominajmy jednak, ze mamy tutaj dostęp również do API .NET-owego, w tym chociażby do klasy <code>System.Diagonistics.Process</code> i jej metody <code>Start</code> - czegoś w rodzaju arcyprzydatnej kiedyś funkcji Windows API o nazwie <code>ShellExecute</code>. Jeśli zaś chodzi o przekazywanie parametrów, to nie zapominajmy o metodach do obsługi <em>string</em>ów - cała klasa <code>System.String</code> jest przecież dostępna.</li>
<li><strong>Kontrola wejścia i wyjścia</strong>. Pod Windows nie jest to specjalnie powszechne, ale zdarzają się programy "w stylu uniksowym" - przyjmujące dane ze standardowego wejścia i wypisujące wyniki na standardowe wyjście. Pamiętajmy, ze przy pomocy potokowania (operator pionowej kreski <code>|</code>) możemy sobie z takimi aplikacjami radzić. PowerShell jest zresztą dobrym narzędziem do tworzenia używalnych <em>front-end</em>ów do tego rodzaju programów.</li>
<li><strong>Pobieranie kodu wyjścia programów</strong>. W starych plikach .<em>bat</em> można było (hmm... w sumie to nadal można) korzystać ze zmiennej <code>%ERRORLEVEL%</code>, zawierającej kod wyjścia ostatnio uruchomionego programu. W PSh. jej odpowiednik ma bardziej opisową nazwę: <code>$LASTEXITCODE</code>. Przypomnieć warto, że dla kodów wyjścia wartością oznaczającą poprawne wykonanie programu jest <strong>zero</strong>.</li>
</ul>
<p>Składając te elementy w całość, możemy utworzyć <em>shella</em> z wygodnym dla nas zestawem poleceń. Kto wie, może będzie on nam odpowiadał bardziej niż pełne ikonek, kolorowe paski narzędzi :)</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2010/06/16/triki-z-powershellem-14-moja-wlasna-mala-konsolka/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Zależności między projektami w Visual Studio</title>
		<link>http://xion.org.pl/2010/05/29/zaleznosci-miedzy-projektami-w-visual-studio/</link>
		<comments>http://xion.org.pl/2010/05/29/zaleznosci-miedzy-projektami-w-visual-studio/#comments</comments>
		<pubDate>Fri, 28 May 2010 22:40:34 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Aplikacje]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[biblioteka]]></category>
		<category><![CDATA[kompilacja]]></category>
		<category><![CDATA[projekty]]></category>
		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=1838</guid>
		<description><![CDATA[Zdarza się, że pracuje nad złożonym systemem, na który składa się kilka osobnych projektów. IDE znają dobrze takie przypadki i potrafią je obsługiwać - stąd chociażby pojęcie solution (dawniej workspace) w Visual Studio. Dla pojedynczych aplikacji i bibliotek wydaje się ono zbędne, jednak staje się nieodzowne wtedy, gdy nasze projekty zależą od siebie. Typowa sytuacja [...]]]></description>
			<content:encoded><![CDATA[<p>Zdarza się, że pracuje nad złożonym systemem, na który składa się kilka osobnych projektów. IDE znają dobrze takie przypadki i potrafią je obsługiwać - stąd chociażby pojęcie <em>solution</em> (dawniej <em>workspace</em>) w Visual Studio. Dla pojedynczych aplikacji i bibliotek wydaje się ono zbędne, jednak staje się nieodzowne wtedy, gdy nasze projekty zależą od siebie.</p>
<p>Typowa sytuacja to wspólna biblioteka (<em>framework</em>, <em>engine</em> czy co jeszcze kto woli) rozwijana razem z programami, które z niej korzystają. (W najprostszym przypadku to może być po prostu jakaś aplikacja testowa). Wówczas pojawiają się zależności między projektami na etapie ich budowania: wynik szeroko pojętej "kompilacji" jednego jest wejściem do procesu budowania innego. Jeśli nie poświęcimy temu faktowi należytej uwagi, to mogą nas czekać kłopoty. W najlepszym razie jest to konieczność wciskania F7 (<em>Build Solution</em>) więcej niż raz, aż do zbudowania wszystkich projektów. W gorszym - uruchamianie (i debugowanie!) aplikacji korzystającej z nieaktualnej, bo nieprzekompilowanej wersji biblioteki.</p>
<p><img style="float:right; margin:6px;" src="http://xion.org.pl/wp-content/uploads/2010/05/vs-project-build-order.png" alt="" title="Kolejność budowania projektów w VS" />Zależności między projektami w procesie budowania da się na szczęście określić. W Visual Studio służy do tego opcja <em>Project Dependencies</em> z menu - a jakże - <em>Project</em>. Możemy w niej określić dla każdego projektu, z jakimi innymi projektami z tego samego <em>solution</em> jest on powiązany, czyli które z nich powinny być już wcześniej od niego zbudowane. Na podstawie tak podanej sieci zależności da się następnie określić właściwą kolejności "kompilacji" dla wszystkich projektów w danym <em>solution</em>. VS oczywiście to czyni, używając do tego zapewne <a href="http://en.wikipedia.org/wiki/Topological_sorting">sortowania topologicznego</a> w analogiczny sposób jak dla kompilacji jednego projektu składającego się z wielu plików.</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2010/05/29/zaleznosci-miedzy-projektami-w-visual-studio/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Szpieg++</title>
		<link>http://xion.org.pl/2010/02/26/szpieg/</link>
		<comments>http://xion.org.pl/2010/02/26/szpieg/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 15:41:17 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Aplikacje]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Spy++]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=1606</guid>
		<description><![CDATA[Pakiet Visual Studio to nie tylko samo środowisko programistyczne (IDE), ale i kilka mniejszych narzędzi. Większość z nich dotyczy albo programowania na platformy mobilne, albo .NET, ale jest przynajmniej jedno, które może okazać się przydatne dla każdego programisty Windows. Chodzi o program Spy++ (spyxx.exe). Co ta aplikacja potrafi? Otóż pozwala ona na podgląd różnych obiektów [...]]]></description>
			<content:encoded><![CDATA[<p>Pakiet Visual Studio to nie tylko samo środowisko programistyczne (IDE), ale i kilka mniejszych narzędzi. Większość z nich dotyczy albo programowania na platformy mobilne, albo .NET, ale jest przynajmniej jedno, które może okazać się przydatne dla każdego programisty Windows. Chodzi o program Spy++ (<em>spyxx.exe</em>).</p>
<p>Co ta aplikacja potrafi? Otóż pozwala ona na podgląd różnych obiektów w systemie, tj. okien, wątków i procesów wraz z ich właściwościami (jak na przykład wartości uchwytów czy ilość zaalokowanych bajtów). Na pierwszy rzut oka może nie wydawać się to jakoś wybitnie zachwycające, jako że zwykły Menedżer zadań potrafi (prawie) to samo, z dokładnością do mniejszej liczby szczegółów.<br />
<img style="float:left; margin:5px" src="http://xion.org.pl/wp-content/uploads/2010/02/spyxx-find-window-e1267198798974.png" alt="" title="Okno Find Window w Spy++" />Wyróżniającym i znacznie przydatniejszym <em>feature</em>'em Spy++ jest bowiem co innego. Umożliwia on mianowicie podglądanie, filtrowanie i logowanie wszystkich lub wybranych komunikatów Windows (<code>WM_PAINT</code>, <code>WM_LBUTTONDOWN</code>, itd.) dochodzących do wskazanego okna lub grupy okien, wraz z ich parametrami (<code>wParam</code>, <code>lParam</code>) oraz wartościami zwróconymi przez okno w odpowiedzi na nie.</p>
<p>Działa to przy tym prosto i intuicyjnie. Najpierw wybieramy sobie okno do podglądania (<em>Spy > Log Messages</em> lub <em>Spy > Find Window</em>), co możemy zrobić przy pomocy przeciągnięcia celownika myszą w jego obszar. Potem możemy określić, jakiego rodzaju komunikaty potrzebujemy przechwytywać oraz jakie informacje chcemy z nich wyciągnąć. Wynikiem będzie log mniej więcej takiej postaci:</p>
<blockquote><p>&lt;00694&gt; 0002009C P WM_MOUSEMOVE fwKeys:0000 xPos:51 yPos:259<br />
&lt;00695&gt; 0002009C P WM_MOUSELEAVE<br />
&lt;00696&gt; 0002009C P WM_PAINT hdc:00000000<br />
&lt;00697&gt; 0002009C P WM_TIMER wTimerID:5 tmprc:00000000<br />
&lt;00698&gt; 0002009C P WM_TIMER wTimerID:2 tmprc:00000000</p></blockquote>
<p>która to, jak sądzę, powinna być zrozumiała dla każdego średnio zaawansowanego programisty Windows :]</p>
<p>Po co nam jednak coś takiego?... Ano odpowiedź jest prosta: do debugowania :) Można oczywiście podchodzić do tego w "tradycyjny" sposób przy pomocy pracy krokowej tudzież <em>breakpointów</em>, ale często ogranicza nas tutaj swego rodzaju zasada nieoznaczoności, gdy <strong>samo debugowanie</strong> zmienia działanie programu - chociażby ze względu na ciągłe przełączenia między nim a IDE. To oczywiście znacznie utrudnia wykrycie i poprawienie usterek.<br />
Jak nietrudno się domyślić, istnieją też inne programy oferujące podobną funkcjonalność co Spy++, jak np. <a href="http://www.softpedia.com/get/Security/Security-Related/Winspector.shtml">Winspector</a>. Z Visual Studio otrzymujemy jednak dobre narzędzie <em>out-of-the-box</em>, więc czegóż można by chcieć więcej? ;]</p>
<p>Hmm... pewnie tego, by dowiedzieć się mniej więcej, jak ono działa. O tym można przeczytać na <a href="http://blogs.msdn.com/vcblog/archive/2007/01/16/spy-internals.aspx">blogu jego autora</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2010/02/26/szpieg/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Odczytywanie tekstu z gwiazdek</title>
		<link>http://xion.org.pl/2009/12/29/odczytywanie-tekstu-z-gwiazdek/</link>
		<comments>http://xion.org.pl/2009/12/29/odczytywanie-tekstu-z-gwiazdek/#comments</comments>
		<pubDate>Tue, 29 Dec 2009 11:24:22 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Aplikacje]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[bezpieczeństwo]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=1544</guid>
		<description><![CDATA[Aplikacje wymagające podania od użytkownika jakichś haseł zwykle ukrywają ich znaki, zastępując je "gwiazdkami", czyli np. znakami asterisk (*) lub dużymi kropkami. Dzięki temu lekko zwiększa się poziom bezpieczeństwa programu, gdyż osoba niepowołana nie może tak po prostu odczytać hasła, patrząc na ekran. Niezbyt imponujące określenie 'lekko' jest tu jednak bardzo na miejscu, bo istnieje [...]]]></description>
			<content:encoded><![CDATA[<p><img style="float:left; margin:5px" src="http://xion.org.pl/wp-content/uploads/2009/12/password-editbox.png" alt="Pole tekstowe hasła" title="Pole tekstowe hasła" />Aplikacje wymagające podania od użytkownika jakichś haseł zwykle ukrywają ich znaki, zastępując je "gwiazdkami", czyli np. znakami asterisk (*) lub dużymi kropkami. Dzięki temu lekko zwiększa się poziom bezpieczeństwa programu, gdyż osoba niepowołana nie może tak po prostu odczytać hasła, patrząc na ekran.<br />
Niezbyt imponujące określenie 'lekko' jest tu jednak bardzo na miejscu, bo istnieje całe mnóstwo narzędzi, które potrafią takie "zagwiazdkowane" hasła bez trudu odczytać. W jaki sposób to robią?</p>
<p>Otóż pola tekstowe dla haseł często są po prostu zwykłymi <em>editboksami</em>. Różnicą jest to, że mają przy tym ustawioną specjalną flagę: styl <code>ES_PASSWORD</code>; sprawia ona, że zawartość pola jest wyświetlana w sposób zamaskowany. Zakładając, że znamy jego uchwyt (<code>HWND</code>) - pozyskany na przykład z pozycji myszy i funkcji <code>WindowFromPoint</code> - możemy ów styl po prostu wyłączyć:</p>
<div class="syntax_hilite">
<div id="cpp-8">
<div class="cpp">SetWindowLong <span style="color: #000000;">&#40;</span>hEditBox, GWL_STYLE,<br />
&nbsp; &nbsp; GetWindowLong<span style="color: #000000;">&#40;</span>hEditBox, GWL_STYLE<span style="color: #000000;">&#41;</span> &amp; ~ES_PASSWORD<span style="color: #000000;">&#41;</span>;</div>
</div>
</div>
<p>
a następnie ustawić jeszcze znak zastępczy ("gwiazdkę") na <code>\0</code>:</p>
<div class="syntax_hilite">
<div id="cpp-9">
<div class="cpp">SendMessage <span style="color: #000000;">&#40;</span>hEditBox, EM_SETPASSWORDCHAR, <span style="color: #0000dd;">0</span>, <span style="color: #0000dd;">0</span><span style="color: #000000;">&#41;</span>;</div>
</div>
</div>
<p>
Wtedy kontrolka powinna zacząć normalnie wyświetlać swoją zawartość bez zamaskowania, więc użytkownik będzie w stanie ją odczytać. Jeśli natomiast chcielibyśmy programowo się do niej dostać, trzeba wysłać do kontrolki komunikat <code>WM_GETTEXT</code>. (Funkcja <code>GetWindowText</code> nie zadziała, jeśli <em>editbox</em> jest w innym procesie - a w tym przypadku właśnie tak jest).</p>
<p>Czy można swój własny program zabezpieczyć przed takim "hackiem"? Oczywiście można - wystarczy nadpisać domyślny sposób obsługi wspomnianego wyżej komunikatu <code>WM_GETTEXT</code>, by nie zwracał on rzeczywistego tekstu zapisanego w polu tekstowym. Da się to zrobić przy pomocy techniki <em>subclassingu</em>, czyli podmiany procedury zdarzeniowej okna (tutaj: pola tekstowego). Trzeba tylko pamiętać, żeby zapewnić przy okazji jakiś sposób, żeby ten tekst jednak jakoś pobierać - np. poprzez zupełnie nową wiadomość:</p>
<div class="syntax_hilite">
<div id="cpp-10">
<div class="cpp"><span style="color: #0000ff;">const</span> DWORD WM_GETREALTEXT = WM_USER + 0x0177;</div>
</div>
</div>
<p>
Najpewniejszą metodą jest aczkolwiek zupełne zrezygonowanie z przechowywania sensownej zawartości w samym <em>editboksie</em> i użycie do tego jakiegoś zewnętrznego bufora w postaci zmiennej. To jednak wymaga obsługi komunikatów związanych z całym procesem edycji, aby ten zewnętrzny bufor uaktualniać.</p>
<p>Istnieją oczywiście gotowe implementacje kontrolek, które działają właśnie w ten sposób. Czy warto ich używać? Sądzę, że niekoniecznie - z dwóch powodów.<br />
Po pierwsze, pole tekstowe do wprowadzania hasła nie musi być wcale najwęższym gardłem bezpieczeństwa aplikacji. Niewiele przyjdzie z nawet najlepszego zabezpieczenia go, jeśli potem wpisane doń hasło jest np. przesyłane otwartym tekstem przez sieć lub zapisywane w pliku w postaci <em>hasha</em> MD5.<br />
Po drugie, użytkownicy są generalnie przyzwyczajeni do jednokrotnego wpisywania haseł, które są następnie zapisywane między sesjami. Tak się dzieje chociażby na stronach WWW, gdzie w tym celu korzysta się z ciasteczek (<em>cookies</em>). Hasła więc bywają zapominane, lecz w sieci nie jest to wielkim problemem ze względu na powszechne mechanizmy przypominania. Tradycyjne aplikacje ich nie posiadają, więc istnienie jakieś metody pozwalającej użytkownikowi na odzyskanie z nich haseł (czyli użycie "odgwiazdkowujących" programów) nie jest wcale rzeczą złą.</p>
<p>A że przy okazji może to zrobić ktoś niepowołany? No cóż... Jeśli posiada on już dostęp do komputera ofiary <strong>oraz</strong> prawa administratora w jej systemie (bo to jest potrzebne, by wymienione wyżej triki działały), to jest wątpliwe, żeby poprzestał tylko na zabawie z gwiazdkami w <em>editboksach</em> ;-)</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2009/12/29/odczytywanie-tekstu-z-gwiazdek/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Naprawianie IntelliSense</title>
		<link>http://xion.org.pl/2009/12/13/naprawianie-intellisense/</link>
		<comments>http://xion.org.pl/2009/12/13/naprawianie-intellisense/#comments</comments>
		<pubDate>Sun, 13 Dec 2009 19:11:01 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Aplikacje]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=1511</guid>
		<description><![CDATA[Wbudowany w Visual Studio system autouzupełniania kodu w przypadku C++ często działa całkiem dobrze, ale wiele osób pewnie stwierdziłoby, że częściej nie działa w ogóle. Każdy na pewno spotkał się z sytuacją, że po wpisaniu operatora kropki czy strzałki (-&#62;) jego oczom nie ukazywała się wcale lista składników klasy, a jedynie mało pomocny komunikat na [...]]]></description>
			<content:encoded><![CDATA[<p>Wbudowany w Visual Studio system autouzupełniania kodu w przypadku C++ często działa całkiem dobrze, ale wiele osób pewnie stwierdziłoby, że częściej nie działa w ogóle. Każdy na pewno spotkał się z sytuacją, że po wpisaniu operatora kropki czy strzałki (<code>-&gt;</code>) jego oczom nie ukazywała się wcale lista składników klasy, a jedynie mało pomocny komunikat na pasku stanu. Sugeruje on zapoznanie się z określonym artykułem w MSDN, traktującym o rozwiązywaniu problemów z IntelliSense.</p>
<p>Przyznajmy teraz: czy ktoś rzeczony rzeczywiście artykuł przeczytał? :) Mam co do tego spore wątpliwości, lecz od razu zapewniam: nic straconego. Nie ma tam bowiem nic specjalnie użytecznego ;> Nie istnieje niestety żaden specjalny trik, który sprawiłby, aby mechanizm autouzupełniania w VS dla kodu C++ działał co najmniej w połowie tak dobrze jak chociażby dla C#. Jeśli więc chcemy, by był on dla nas choć trochę użyteczny, musimy sami mu pomóc. Jak?</p>
<ul>
<li>Poprawmy błędy kompilacji. Dotyczy to zwłaszcza błędów w nagłówkach (jako że są one dołączane wielokrotnie w różnych plikach .<em>cpp</em>) oraz błędów powodujących trudności w określeniu, gdzie kończą się poszczególne fragmenty kodu (czyli wszelkiego rodzaju nieprawidłowych nawiasowań). Drobne pomyłki w rodzaju literówek w identyfikatorach wpływają zwykle tylko na tę linijkę kodu, w której występują, a po korekcie IS potrafi bardzo szybko wrócić do działania.</li>
<li>Uważajmy na preprocesor i nagłówki. MSDN jawnie specyfikuje jedną sytuację, w której IntelliSense nie musi działać. Dotyczy to wielokrotnego dołączania tego samego pliku nagłówkowego w taki sposób, że makra (<code>#define</code>'y) wpływają na sposób, w jaki jest on przetwarzany. Przykładem może być dołączenie <em>windows.h</em> raz normalnie, a drugi raz z uprzednio zdefiniowanym makrem <code>WIN32_LEAN_AND_MEAN</code>.</li>
<li>Jeśli wszystko zawodzi, wygenerujmy od początku plik .<em>ncb</em>. W tym pliku (często największym w całym projekcie) IntelliSense przechowuje informacje o strukturze kodu. Jeśli często "rozgrzebujemy" nasz projekt, czynimy w nim duże zmiany i dokonujemy refaktoringu, to plik ten może zawierać nieaktualne, nadmiarowe lub nieprawidłowe informacje albo po prostu być uszkodzony. W takim wypadku należy go po prostu usunąć, a następnie przeprowadzić ponowne kompilację całego <em>solution</em>.</li>
</ul>
<p>Nie ma oczywiście gwarancji, że powyższe kroki sprawią, że IntelliSense poradzi sobie z podpowiadaniem w każdej sytuacji. Kod C++, zwłaszcza skomplikowany i korzystający z wielu "sztuczek językowych" (jak np. bibliotek Boost) nie jest łatwy do programowej analizy. Pozostaje więc mieć nadzieję, że w przyszłych wersjach VS z autouzupełnianiem będzie już lepiej; podobno w wersji 2010 jest z tym już całkiem nieźle :)</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2009/12/13/naprawianie-intellisense/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Triki z PowerShellem #12 &#8211; Rozpakowywanie</title>
		<link>http://xion.org.pl/2009/12/07/triki-z-powershellem-12-rozpakowywanie/</link>
		<comments>http://xion.org.pl/2009/12/07/triki-z-powershellem-12-rozpakowywanie/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 22:18:05 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Aplikacje]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[kompresja]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=1500</guid>
		<description><![CDATA[Wiele programów z sieci wciąż jeszcze ściąga się w postaci archiwów do samodzielnego wypakowania, jak choćby w formacie .zip. Ma to swoje zalety i wady - do tych drugich należy fakt, że nie bardzo wiadomo, jak wygląda wewnętrzna struktura katalogów takiej paczki. Używając opcji typu Wypakuj tutaj ryzykujemy zaśmiecenie folderu Downloads plikami programu. Dlatego osobiście [...]]]></description>
			<content:encoded><![CDATA[<p><img style="float:left; margin:5px" src="http://xion.org.pl/wp-content/uploads/2009/12/redundant-path.png" alt="Powtarzające się katalogi" title="Powtarzające się katalogi" />Wiele programów z sieci wciąż jeszcze ściąga się w postaci archiwów do samodzielnego wypakowania, jak choćby w formacie .<em>zip</em>. Ma to swoje zalety i wady - do tych drugich należy fakt, że nie bardzo wiadomo, jak wygląda wewnętrzna struktura katalogów takiej paczki. Używając opcji typu <em>Wypakuj tutaj</em> ryzykujemy zaśmiecenie folderu <em>Downloads</em> plikami programu. Dlatego osobiście zawsze stosuję polecenie <em>Wypakuj do nowego katalogu</em>.<br />
I tu czasem jest mały zonk, gdy twórca archiwum zdecydował się na spakowanie całego folderu, a nie tylko zawartych w nim plików. Powstają wtedy nadmiarowe katalogi, wydłużające ścieżki do plików (co widać obok - w wersji trochę przesadzonej ;)).</p>
<p>Ponieważ podobne sytuacje zdarzają mi się dość często, postanowiłem im zaradzić przy pomocy najlepszego narzędzia na takie okazje, czyli PowerShella rzecz jasna :) Wynikiem jest poniższy skrypt do sprytniejszego rozpakowywania archiwów:</p>
<div class="syntax_hilite">
<div id="csharp-12">
<div class="csharp"><span style="color: #008080;"># unpack.ps1</span><br />
<span style="color: #008080;"># Sprytne rozpakowywanie archiwów</span><br />
param <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#91;</span><span style="color: #FF0000;">string</span><span style="color: #000000;">&#93;</span>$archive = $<span style="color: #000000;">&#40;</span><span style="color: #0600FF;">throw</span> <span style="color: #808080;">"No archive specified"</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span></p>
<p><span style="color: #008080;"># Bierzemy nazwę archiwum i tworzymy odpowiadający mu katalog</span><br />
$name = <span style="color: #000000;">&#91;</span>IO.<span style="color: #0000FF;">Path</span><span style="color: #000000;">&#93;</span>::<span style="color: #0000FF;">GetFileNameWithoutExtension</span><span style="color: #000000;">&#40;</span>$archive<span style="color: #000000;">&#41;</span><br />
Set-Location -Path <span style="color: #000000;">&#40;</span>New-<span style="color: #FF0000;">Object</span> IO.<span style="color: #0000FF;">FileInfo</span> @<span style="color: #000000;">&#40;</span>$name<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">DirectoryName</span><br />
$dir = <span style="color: #000000;">&#91;</span>IO.<span style="color: #0000FF;">Directory</span><span style="color: #000000;">&#93;</span>::<span style="color: #0000FF;">CreateDirectory</span><span style="color: #000000;">&#40;</span>$name<span style="color: #000000;">&#41;</span></p>
<p><span style="color: #008080;"># Rozpakowujemy archiwum do tego katalogu</span><br />
$shell = New-<span style="color: #FF0000;">Object</span> -ComObject Shell.<span style="color: #0000FF;">Application</span><br />
$src = $shell.<span style="color: #0600FF;">Namespace</span><span style="color: #000000;">&#40;</span>$archive<span style="color: #000000;">&#41;</span><br />
$dest = $shell.<span style="color: #0600FF;">Namespace</span><span style="color: #000000;">&#40;</span>$name<span style="color: #000000;">&#41;</span><br />
$dest.<span style="color: #0000FF;">CopyHere</span><span style="color: #000000;">&#40;</span>$src.<span style="color: #0000FF;">items</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span></p>
<p><span style="color: #008080;"># Rekurencyjnie badamy zawartość rozpakowanego archiwum</span><br />
<span style="color: #0600FF;">while</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span>$items = $dir.<span style="color: #0000FF;">GetFileSystemInfos</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span> -eq <span style="color: #FF0000;">1</span><span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #008080;"># Sprawdzamy, czy jego pierwszy i jedyny element jest katalogiem</span><br />
&nbsp; &nbsp; $fsi = $items<span style="color: #000000;">&#91;</span><span style="color: #FF0000;">0</span><span style="color: #000000;">&#93;</span><br />
&nbsp; &nbsp; <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span>$fsi.<span style="color: #0000FF;">Attributes</span> -band <span style="color: #000000;">&#91;</span>IO.<span style="color: #0000FF;">FileAttributes</span><span style="color: #000000;">&#93;</span>::<span style="color: #0000FF;">Directory</span><span style="color: #000000;">&#41;</span> -eq <span style="color: #FF0000;">0</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span> <span style="color: #0600FF;">break</span> <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #008080;"># Jest - dokonujemy skrócenia ścieżki</span><br />
&nbsp; &nbsp; $fsi.<span style="color: #0000FF;">MoveTo</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#91;</span>IO.<span style="color: #0000FF;">Path</span><span style="color: #000000;">&#93;</span>::<span style="color: #0000FF;">GetRandomFileName</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; $dir.<span style="color: #0000FF;">Delete</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; $dir = $fsi<br />
&nbsp; &nbsp; $dir.<span style="color: #0000FF;">MoveTo</span><span style="color: #000000;">&#40;</span>$name<span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#125;</span></div>
</div>
</div>
<p>
Jego działanie polega wpierw na zwykłej dekompresji archiwum. Jak można zauważyć, używa do tego obiektu COM-owskiego <code>Shell.Application</code>. To sprawia, że skrypt ma pod tym względem te same możliwości co zwykły windowsowy Eksplorator (dla większych plików pokaże nawet pasek postępu ;]).<br />
Później wypakowana zawartość jest poddawana operacji, którą nazywam tutaj 'skróceniem ścieżki'. Polega ona wyrzuceniu jednego poziomu drzewa folderów, o ile tylko pewien katalog jest jedynym elementem swojego katalogu nadrzędnego. Takie właśnie sytuacje powstają przy dekompresji do nowego folderu archiwów źle zapakowanych (przynajmniej z mojego punktu widzenia ;P). Wynikiem działania skryptu będzie więc w sumie jeden nowy podkatalog zawierający bezpośrednio całą interesującą zawartość archiwum.</p>
<p>Oczywiście używanie powyższego skryptu tylko z poziomu linii komend PowerShella nie jest specjalnie wygodne; lepiej jest dodać go do menu kontekstowego archiwów, czyli np. plików .<em.zip</em>. O tym, jak można tego dokonać, napisałem dość obszernie przy okazji prezentacji <a href="http://xion.org.pl/2008/05/24/triki-z-powershellem-2-szybki-upload/">skryptu do wysyłania przez FTP</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2009/12/07/triki-z-powershellem-12-rozpakowywanie/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Listy skoków w Windows 7</title>
		<link>http://xion.org.pl/2009/11/30/listy-skokow-w-windows-7/</link>
		<comments>http://xion.org.pl/2009/11/30/listy-skokow-w-windows-7/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 21:44:51 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Aplikacje]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[pasek zadań]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Windows 7]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=1486</guid>
		<description><![CDATA[Jednym z bardziej zauważalnych składników Windows 7, które odróżniają ten system od Visty, jest nowy wygląd paska zadań. Jest szerszy, wyświetla duże ikony i przesunięcie go z dołu na bok ekranu w końcu ma sens (hurra dla monitorów wide-screen). Ale nowy wygląd to w tym przypadku nie wszystko, bo pasek ten zyskał też trochę na [...]]]></description>
			<content:encoded><![CDATA[<p><img style="float:right; margin:5px" src="http://xion.org.pl/wp-content/uploads/2009/11/pn-jump-list.png" alt="Przykładowa lista skoków" title="Przykładowa lista skoków" />Jednym z bardziej zauważalnych składników Windows 7, które odróżniają ten system od Visty, jest nowy wygląd paska zadań. Jest szerszy, wyświetla duże ikony i przesunięcie go z dołu na bok ekranu w końcu ma sens (hurra dla monitorów <em>wide-screen</em>). Ale nowy wygląd to w tym przypadku nie wszystko, bo pasek ten zyskał też trochę na funkcjonalnościach.<br />
Wśród nich mamy tzw. listy skoków (<em>Jump Lists</em>), zastępujące tradycyjne menu sterowania. Listy te pojawiają się po kliknięciu prawym przyciskiem na ikonkę na pasku zadań.</p>
<p>Co zawierają takie listy? Jak widać z boku, ich elementami mogą być skróty do ostatnio otwartych w programie dokumentów. Żeby było zabawniej, będzie ona wygenerowana automatycznie nawet dla tych aplikacji, których twórcy w momencie ich pisania nie mieli bladego pojęcia o tym, że kiedyś będziemy mieli taki system jak Windows 7 :) W tej wersji bowiem sam Windows zarządza listami MRU (<em>Most Recenty Used</em>) dla poszczególnych programów, o ile tylko wywołują one funkcję <code>ShAddToRecentDocs</code> przy otwieraniu poszczególnych plików.<br />
A to wbrew pozorom nie jest takie duże wymaganie, gdyż jest automatycznie ono spełnione, jeśli zachodzi jedna z poniższych sytuacji:</p>
<ul>
<li>aplikacja ma zarejestrowane skojarzenie rozszerzenia plików i użytkownik otwiera przypisany jej plik przy pomocy Eksploratora Windows (np. dwukrotnie klikając)</li>
<li>program używa standardowych okienek dialogowych do otwierania plików (np. funkcji <code>GetOpenFileName</code> z WinAPI albo <code>OpenFileDialog</code> z .NET)</li>
</ul>
<p>Na listę skoków możemy też dodawać własne pozycje w postaci tak zwanych zadań (<em>tasks</em>), działających jak zwykłe systemowe skróty i tworzonych w ten sam sposób (interfejs <code>IShellLink</code>). Szczegóły i przykładowy kod można znaleźć na przykład <a href="http://www.codeproject.com/KB/vista/SevenGoodiesJumpLists.aspx">w tym artykule na CodeProject</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2009/11/30/listy-skokow-w-windows-7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bogata ikonografia</title>
		<link>http://xion.org.pl/2009/11/10/bogata-ikonografia/</link>
		<comments>http://xion.org.pl/2009/11/10/bogata-ikonografia/#comments</comments>
		<pubDate>Tue, 10 Nov 2009 12:25:25 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Aplikacje]]></category>
		<category><![CDATA[grafika 2D]]></category>
		<category><![CDATA[ikony]]></category>
		<category><![CDATA[programy graficzne]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=1428</guid>
		<description><![CDATA[Zajmę się dzisiaj pewnym rodzajem aplikacji, którą przeciętny programista wykorzystuje rzadko, ale którą mimo tego powinien mieć. Mam tu na myśli program graficzny służący do edycji ikon, czyli tych małych (a od niedawna i większych) obrazków, które w Windows (i nie tylko) pojawiają się na każdym kroku - zwłaszcza na pulpicie czy w menu Start. [...]]]></description>
			<content:encoded><![CDATA[<p>Zajmę się dzisiaj pewnym rodzajem aplikacji, którą przeciętny programista wykorzystuje rzadko, ale którą mimo tego powinien mieć. Mam tu na myśli program graficzny służący do edycji ikon, czyli tych małych (a od niedawna i większych) obrazków, które w Windows (i nie tylko) pojawiają się na każdym kroku - zwłaszcza na pulpicie czy w menu Start. Może nieczęsto zdarza się konieczność stworzenia ikonki dla własnej aplikacji, lecz kiedy już trzeba to zrobić, warto posłużyć się w tym celu odpowiednim narzędziem (a nie Paintem na przykład :]).<br />
Znalezienie dobrej i darmowej aplikacji do edycji ikon nie jest jednak takie łatwe, jako że najlepsze i najpopularniejsze z nich są licencjonowane jako <em>shareware</em>. Istnieje jednak przynajmniej jeden darmowy i wart polecenia program tego typu; sam dowiedziałem się o nim od <a href="http://regedit.gamedev.pl">Rega</a>.</p>
<p><img style="float:right; margin:5px" src="http://xion.org.pl/wp-content/uploads/2009/11/icofx-logo.png" alt="Logo programu IcoFX" title="Logo programu IcoFX" />Nazywa się on <a href="http://icofx.ro/">IcoFX</a> i ze względu na swą niepozorną wielkość (1.5 MB) ma chyba jedną z lepszych proporcji użyteczności do rozmiaru. Zawiera on bowiem zdecydowaną większość funkcji (jeśli nie wszystkie), jakie można wymagać od tego rodzaju aplikacji.<br />
Program ten obsługuje oczywiście wszystkie używane obecnie rozmiary (od 16x16 do 256x256), głębie kolorów (od 1 do 32 bitów z kanałem alfa) i formaty ikon (łącznie z PNG wykorzystywanym od Visty wzwyż). Oprócz całego wachlarza typowych narzędzi graficznych oferuje też wiele predefiniowanych filtrów (rozmycie, detekcja krawędzi itp.) wraz z możliwością definiowania własnych. Generalnie część "graficzna" programu jest bez zarzutu. Jedynym mankamentem, na jaki się zdołałem dotąd natknąć, jest brak możliwości określania tolerancji kolorów dla wypełniania typu <em>flood fill</em>.</p>
<p align="center"><a href="http://xion.org.pl/wp-content/uploads/2009/11/icofx-screen1.png"><img src="http://xion.org.pl/wp-content/uploads/2009/11/icofx-screen1-150x99.png" alt="Screen z programu IcoFX" title="Screen z programu IcoFX" /></a>&nbsp;<a href="http://xion.org.pl/wp-content/uploads/2009/11/icofx-screen2.png"><img src="http://xion.org.pl/wp-content/uploads/2009/11/icofx-screen2-150x100.png" alt="Screen z programu IcoFX" title="Screen z programu IcoFX" /></a>&nbsp;<a href="http://xion.org.pl/wp-content/uploads/2009/11/icofx-screen3.png"><img src="http://xion.org.pl/wp-content/uploads/2009/11/icofx-screen3-150x92.png" alt="Screen z programu IcoFX" title="Screen z programu IcoFX" /></a></p>
<p>Część "narzędziowa" też prezentuje się dobrze. Przy pomocy programu możemy nie tylko ekstrahować ikony z plików .<em>exe</em> i .<em>dll</em> (w razie potrzeby masowo przy pomocy <em>batch processing</em>), ale także edytować takie pliki (w zakresie ikon, rzecz jasna). Taka edycja mogłaby być wprawdzie nieco lepiej pomyślana (dodanie nowej ikony do pliku .<em>exe</em>/.<em>dll</em> jest możliwe tylko poprzez import z .<em>ico</em>), ale w sumie da się z nią wytrzymać.</p>
<p>Tak więc na te niezbyt częste okazje, gdy musimy/chcemy pobawić z ikonami, IcoFX wydaje się ogólnie całkiem dobrym rozwiązaniem. Zwłaszcza ze tę cenę :)</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2009/11/10/bogata-ikonografia/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Jak naprawić GRUB-a</title>
		<link>http://xion.org.pl/2009/10/24/jak-naprawic-grub-a/</link>
		<comments>http://xion.org.pl/2009/10/24/jak-naprawic-grub-a/#comments</comments>
		<pubDate>Sat, 24 Oct 2009 21:38:31 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Aplikacje]]></category>
		<category><![CDATA[bootloader]]></category>
		<category><![CDATA[GRUB]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[reinstalacja]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=1387</guid>
		<description><![CDATA[Jeśli oprócz systemu okienkowego rodem z Microsoftu mamy też jakiegoś *niksa, to reinstalacja Windows będzie dla nas miała jeden nieprzyjemny efekt uboczny. Otóż instalatory Okienek radośnie nadpisują sektor startowy dysku (czyli MBR - Master Boot Sector), przez co Windows staje się jedynym systemem dającym się uruchomić w zwykły sposób. Ot, zwyczajowe MS-owe praktyki monopolistyczne ;-) [...]]]></description>
			<content:encoded><![CDATA[<p><img style="float:left; margin:5px" src="http://xion.org.pl/wp-content/uploads/2009/10/grub-logo.png" alt="&quot;Logo&quot; GRUB-a" title="&quot;Logo&quot; GRUB-a" />Jeśli oprócz systemu okienkowego rodem z Microsoftu mamy też jakiegoś *niksa, to reinstalacja Windows będzie dla nas miała jeden nieprzyjemny efekt uboczny. Otóż instalatory Okienek radośnie nadpisują sektor startowy dysku (czyli MBR - <em>Master Boot Sector</em>), przez co Windows staje się jedynym systemem dającym się uruchomić w zwykły sposób. Ot, zwyczajowe MS-owe praktyki monopolistyczne ;-)</p>
<p>Jak temu zaradzić? Trzeba oczywiście przywrócić <em>boot sector</em> do właściwego stanu, co oznacza ponowne zainstalowanie używanego przez nas wcześniej <em>bootloadera</em>. W większości przypadków (jeśli mówimy o Linuksie jako drugim systemie) jest nim GRUB; w takim wypadku jego ponowne zainstalowanie wymaga:</p>
<ol>
<li>Uruchomienia Linuksa przy użyciu płytki typu LiveCD, dystrybucji uruchamianej z <em>pendrive</em>'a, itp. Graficzny interfejs jest niepotrzebny, bo jak to zwykle w Linuksie, wszystko można zrobić z konsoli.</li>
<li>Następnie należy uruchomić GRUB-a - koniecznie <strong>z prawami <em>roota</em></strong>, a więc np. poprzez <kbd>sudo grub</kbd>.</li>
<li>Z poziomu jego wiersza poleceń należy najpierw ustawić partycję, w której znajdują się pliki z danymi <em>bootloadera</em>. Jeśli nie wiemy, która to, najlepiej użyć polecenia <kbd>find /boot/grub/stage1</kbd>. Potem rezultat przekazujemy do komendy <kbd>root</kbd>, np. <kbd>root (hd0,5)</kbd>.</li>
<li>Na koniec komendą <kbd>setup</kbd> instalujemy GRUB-a na wybranym dysku fizycznym - zazwyczaj jest to <kbd>setup (hd0)</kbd>.</li>
</ol>
<p>Tyle powinno wystarczyć, by po ponownym uruchomieniu komputera z tego dysku pojawiło się nam menu <em>bootowania</em> GRUB-a. Przy odrobinie szczęścia oba systemy będą więc uruchamiały się normalnie ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2009/10/24/jak-naprawic-grub-a/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>
