Saturday, September 30, 2006

Zamezení a opětovné povolení pohybu formuláře

Upřímně řečeno přesně netuším, k čemu by se dal přesně využít následující tip, ale to ponechám na vás. Potřebujete-li zkrátka z nějakého důvodu zakázat uživateli pohybovat s oknem aplikace, můžete použít následující krátký kód, který přidáte do události OnCreate příslušného formuláře:
procedure TForm1.FormCreate(Sender: TObject);
begin
DeleteMenu(GetSystemMenu(Handle, False), SC_MOVE, MF_BYCOMMAND);
end;
Tím se znemožní pohyb formulářem, a to i prostřednictvím systémového menu, neboť je z něj odstraněna položka Přesunout. Pro úplnost se však sluší uvést též kód, který vše vrátí do původního stavu, takže zde je:
procedure TForm1.Button12Click(Sender: TObject);
begin
GetSystemMenu(Handle, True);
end;

Tuesday, September 26, 2006

A zde již slíbená funkce společně s jejím použitím:

function Verze(const Filename: string):string;
var dwHandle: THandle;
dwSize: DWORD;
lpData, lpData2: Pointer;
uiSize: UINT;
begin
Result := '';
dwSize := GetFileVersionInfoSize(PChar(FileName), dwSize);
if dwSize <> 0 then
begin
GetMem(lpData, dwSize);
if GetFileVersionInfo(PChar(FileName), dwHandle, dwSize, lpData) then
begin
uiSize := Sizeof(TVSFixedFileInfo);
VerQueryValue(lpData, '\', lpData2, uiSize);
with PVSFixedFileInfo(lpData2)^ do
Result := Format('%d.%02d.%02d.%02d', [HiWord(dwProductVersionMS), LoWord(dwProductVersionMS),HiWord(dwProductVersionLS), LoWord(dwProductVersionLS)]);
end;
FreeMem(lpData, dwSize);
end;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage('Verze aplikace: '+ Verze(Application.ExeName));
end;

Monday, September 25, 2006

Funkce vrací řetězec čtyř čísel oddělených tečkami, které značí verzi aplikace. Pokud snad není někomu znám přesný význam jednotlivých čísel, zde je stručný popis tak, jak se uvádí v Delphi:
hodnota č. 1 : Major version
hodnota č. 2 : Minor version
hodnota č. 3 : Release
hodnota č. 4 : Build

Sunday, September 24, 2006

Zjištění verze aplikace

A teď trochu z jiného soudku. Ukážeme si, jak zjistit verzi aplikace. Tento údaj pak můžete použít pro titulkový pruh hlavního formuláře či do okna "O aplikaci". Když bude toto číslo zjišťováno přímo ze souboru a pokud máte u projektu nastaveno automatické zvyšování čísla sestavení (build), nemusíte se již o tento údaj starat a ten bude aktualizován automaticky pomocí naší funkce.

Friday, September 22, 2006

A když už jsme se naučili aplikace minimalizovat, proč si neukázat také jejich obnovení. Použijeme obdobný postup jako v prvním příkladu, tentokrát se bude jednat o simulaci stisku kláves "Windows" + Shift + M.
procedure Obnovit;
begin
keybd_event(VK_LWIN, MapVirtualKey(VK_LWIN, 0), 0, 0);
keybd_event(VK_SHIFT, MapVirtualKey(VK_SHIFT, 0), 0, 0);
keybd_event(Ord('M'), MapVirtualKey(Ord('M'), 0), 0, 0);
keybd_event(Ord('M'), MapVirtualKey(Ord('M'), 0), KEYEVENTF_KEYUP, 0);
keybd_event(VK_SHIFT, MapVirtualKey(VK_SHIFT, 0), KEYEVENTF_KEYUP, 0);
keybd_event(VK_LWIN, MapVirtualKey(VK_LWIN, 0), KEYEVENTF_KEYUP, 0);
end;

Thursday, September 21, 2006

Minimalizace a obnovení všech běžících aplikací

Nejprve si ukážeme, jak minimalizovat všechny běžící aplikace. K tomu slouží například známá ikona na panelu rychlého spuštění nebo kombinace kláves "Windows" + M. A této druhé možnosti právě využijeme a v našem příkladu vlastně docílíme požadovaného efektu simulováním stisku těchto kláves. Zde je tedy kód:
procedure TForm1.Button1Click(Sender: TObject);
begin
keybd_event(VK_LWIN, MapVirtualKey(VK_LWIN, 0), 0, 0);
keybd_event(Ord('M'), MapVirtualKey(Ord('M'), 0), 0, 0);
keybd_event(Ord('M'), MapVirtualKey(Ord('M'), 0), KEYEVENTF_KEYUP, 0);
keybd_event(VK_LWIN, MapVirtualKey(VK_LWIN, 0), KEYEVENTF_KEYUP, 0);
end;

Wednesday, September 20, 2006

Změna titulku u FontDialogu

A na závěr tu máme jeden kratičký tip spíše kosmetického významu. V Delphi, přesněji řečeno v Object Inspectoru, nelze nastavit u dialogu pro výběr fontu vlastní nadpis okna. Ne že by to byla nějaká velká ztráta, ale přesto si ukážeme, jak tento nadpis celkem snadno zvolit podle sebe. Můžete pak tímto nadpisem uživatele přesně informovat, pro co že to vlastně ten font právě vybírá.
Kód je jednoduchý, do události OnShow příslušného dialogu vložte tento řádek:
procedure TForm1.FontDialog1Show(Sender: TObject);
begin
SendMessage(FontDialog1.Handle, WM_SETTEXT, 0, LPARAM(PCHAR('Vyberte písmo pro použití v menu')));
end;

Tuesday, September 19, 2006

Jak vidíte, parametrů a různých kombinací je celá řada. Když půjdeme úplně do detailu, můžete snadno docílit toho, aby mělo každé tlačítko jinou velikost fontu (defaultní tlačítka například o něco větší), ale to je ze zdrojáků snad již jasné a nechám vás experimentovat.
Další zajímavý parametr, který můžete nastavit, je Hint (bublinková nápověda) pro daná tlačítka, což standardní dialogy také nemají a někdy je alespoň tímto způsobem dobré uživateli přesněji vysvětlit, co přesně se stane při stisknutí daného tlačítka. Některé otázky v dialozích bývají někdy tak nejednoznačné, že často není jisté, jak vlastně odpovědět.
Taktéž můžete změnit velikosti jednotlivých tlačítek a jejich umístění. Nastavit se zkrátka dají v podstatě všechny klasické parametry běžných tlačítek, takže se pusťte do zkoušení.

Sunday, September 17, 2006

Všimněte si také (tedy až si ukázku spustíte, protože ze zdrojáku to nemusí být na první pohled jasné), že zvolený font nemá vliv jen na samotný text, ale stejný font a velikost bude použit i na tlačítka. To nemusí být vždycky dobré, proto můžete změnit například velikost fontu tlačítek přidáním následujícího řádku do místa kódu, kde se mění nadpisy tlačítek. Jeho velikost si nastavíme třeba na 10:
.
.
.
if Btn.Caption = '&No' then Btn.Caption := '&Ne';
if Btn.Caption = 'Cancel' then Btn.Caption := '&Storno';
if Btn.Default then ActiveControl := Btn;

Btn.Font.Size:=10;
.
.
.

Saturday, September 16, 2006

begin
with CreateMessageDialog(Msg, DlgType, Buttons) do
try
Caption := Title;
HelpContext := HelpCtx;
Font.Color := clRed;
Font.Size := 7;
Font.Style := [fsBold];
Font.Color := clRed;
Font.Name := 'Verdana';
for Cnt := 0 to ComponentCount - 1 do
begin
if Components[Cnt] is TButton then
begin
Btn:= TButton(Components[Cnt]);
Btn.Default := Btn.ModalResult = DefButton;
if Btn.Caption = '&Yes' then Btn.Caption := '&Ano';
if Btn.Caption = '&No' then Btn.Caption := '&Ne';
if Btn.Caption = 'Cancel' then Btn.Caption := '&Storno';
if Btn.Default then ActiveControl := Btn;
end;
end;
Result := ShowModal;
finally
free;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if DefMessageDlg('Otázka ?', 'Chcete opravdu zformátovat disk ?', mtConfirmation, mbYesNoCancel, mrNo, 0) = mrYes then ShowMessage('Formátuji...čekejte');
end;

Wednesday, September 13, 2006

A jaké je kromě vizuálního dojmu ještě využití tohoto tipu? Napadá mě třeba využití při lokalizaci vašich aplikací do různých jazyků, pokud nebudete chtít použít resources. Nevypadá moc dobře, když lokalizujete v programu kde co, ale dialogová okna zůstanou standardně z Delphi v angličtině.
function DefMessageDlg(const Title : string; const Msg : string; DlgType : TMsgDlgType; Buttons : TMsgDlgButtons; DefButton : integer; HelpCtx : longint): integer;
var cnt : integer;
btn : TButton;

Tuesday, September 12, 2006

Vlastní parametry dialogu v naší funkci jsou zvoleny poněkud křiklavě – tučný červený text, ale to je pouze pro názornou ukázku, aby bylo na první pohled vidět, co vše se dá změnit. Červená barva ale nemusí být úplně na škodu, záleží na typu dialogu. Parametry funkce by možná stálo za to ještě rozšířit právě o onu zmiňovanou barvu či typ písma, pokud budete často používat různé druhy dialogů.

Sunday, September 10, 2006

Úprava standardního dialogového okna

Pokud se vám nelíbí standardní dialogové okno, můžeme ho snadno upravit k obrazu svému. Ukážeme si, jak změnit titulek okna, jak změnit barvu, velikost či font textu a také nápisy tlačítek.
Jak je vidět ze zdrojového kódu, změna parametrů je relativně jednoduchá, položky jsou přehledné a jasné. Takto vytvořenou funkci voláme místo klasického dialogu s patřičnými parametry, jak je vidět taktéž v naší ukázce v události stisku tlačítka. První parametr určuje titulek okna, dále je to samotný text, typ dialogu (který mimo jiné určuje zobrazenou ikonku, i tu je však možno změnit, to vám nechám za domácí úkol), dále jsou to zobrazovaná tlačítka, defaultní tlačítko a kontext nápovědy.

Saturday, September 09, 2006

Některá

z těchto položek může být závislá na verzi Windows, nebo můžete použít i jiné .cpl soubory, ovšem měli byste vždy pamatovat na to, že ne každý má nainstalováno totéž co vy, a pokud to funguje u vás doma, nemusí to běžet všude. Proto bych se asi držel spíše těch standardních ovládacích panelů. Jediný problém takto použitých dialogů bych viděl v tom, že nemáte přesně pod kontrolou, jaké parametry uživatel zvolí. Lépe řečeno: to, co si uživatel vybral, se váš program bezprostředně nedozví, a ani nepoznáte (pokud se sami v programu nepostaráte o detekci), zda je již dialog uzavřen. Proto se asi hodí spíše pro použití v tom případě, kdy odezva uživatele (či spíše jeho provedená volba) není bezprostředně nutná pro další běh vaší aplikace.

Thursday, September 07, 2006

Nejdůležitější částí parametrů je úplný konec, v naší ukázce "mmsys.cpl". Právě tento parametr určuje, který ovládací panel bude zobrazen (v našem příkladu jsou to Multimédia). V následující tabulce najdete další z možných parametrů (jedná se o běžné soubory .cpl, které se nachází v systémovém adresáři Windows) :
access.cpl - nastavení přístupových práv
appwiz.cpl - přidat nebo odebrat programy
desk.cpl - obrazovka
intl.cpl - místní nastavení
joy.cpl - možnosti her
main.cpl - myš
mmsys.cpl - multimédia
modem.cpl - modemy
sysdm.cpl - systém
timedate.cpl - datum a čas

Wednesday, September 06, 2006

Následujícím jednoduchým a krátkým kódem dosáhneme požadovaného efektu:
procedure TForm1.Button1Click(Sender: TObject);
begin
WinExec(Pchar('rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl'),SW_NORMAL);
end;
Chci jen upozornit, že zdánlivě chybějící mezera (z typografického hlediska) za čárkou mezi "shell32.dll" a "Control_RunDLL" chybí zcela úmyslně, neboť je to součást parametrů pro "rundll32.exe". Při vložení mezery vám příklad nebude fungovat a systém se ohlásí chybovou hláškou.

Tuesday, September 05, 2006

Vyvolání dialogových oken z Ovládacích panelů

Často se v našich aplikacích stává, že je třeba změnit určitá systémová nastavení a podobně. V tom případě se můžeme o všechno postarat sami (podle pokynů uživatele) a požadovaných nastavení dosáhnout například změnou registrů. Pokud však nevíme, jak některé konkrétní nastavení změnit, a nebo prostě jen nechceme uživatele plést, můžeme využít poměrně jednoduché možnosti a vyvolat příslušný systémový dialog. Ten jednak uživatel zná a ví, kde má co nastavit, a navíc jeho správná funkčnost by měla být (doufám) zaručena.

Monday, September 04, 2006

Na úplný závěr ještě jedna malá poznámka, která se týká tohoto i předchozího příkladu. Pokud jsme hovořili o rozlišení, není to docela přesný termín, jelikož součástí těchto parametrů je i počet barev. Proto by se mělo hovořit spíše o grafickém režimu. Zmiňuji se o tom z toho důvodu, že pokud třeba použijete ve svých aplikacích poslední příklad, dojde k oznámení o změně "rozlišení" i v tom případě, když rozlišení zůstane stejné a změní se pouze barevná hloubka. Tolik pro upřesnění.
A čemu se budeme věnovat příště? I nadále zůstaneme u vylepšování našich aplikací, tentokrát se trošku podíváme na úpravu standardních systémových dialogů a podobně.

Saturday, September 02, 2006

Zachycení změny rozlišení

Poslední dnešní příklad souvisí s předchozím odstavcem. Naučíme se detekovat, zda nedošlo ke změně rozlišení. Pokud ano, může na to naše aplikace eventuelně nějak zareagovat, pokud bude potřeba a pokud to povaha naší aplikace vyžaduje. Jak jinak, opět se bude jednat o zachycení zprávy systému, konkrétně o WM_DISPLAYCHANGE. Zde je tedy kód:
.
.
.
public
{ Public declarations }
procedure WMDisplayChange(var Msg : TWMDisplayChange); message WM_DISPLAYCHANGE;
end;
.
.
.

procedure TForm1.WMDisplayChange(var Msg: TWMDisplayChange);
begin
inherited;
ShowMessage('Došlo ke změně rozlišení');
end;