Tipy a triky v Delphi, díl 5.

Diskuze čtenářů k článku

Petr Vones  |  26. 08. 2001 12:16

Procedura Spust je dobrym prikladem kde lze najít hned několik chyb. Za prvé parametry typu string by se měly (s vyjímkou případů kdy je třeba obsah lokálně modifikovat) předávat zásadně jako const, dále pak nelze předat typ string do funkce ShellExecute místo parametru typu PChar a především je dobré nezapomenout na to, že API funkce vrací i nějaký výsledek který říká jestli nedošlo k chybě. Na toto se velmi často zapomíná a může to pak být zdrojem nevysvětlitelných chování aplikace. Takže po úpravě by to mohlo vypadat třeba takto:

procedure Spust(const Soubor, Param, Defaultdir: string);
var
  Res: DWORD;
begin
  Res := ShellExecute(0, nil, PChar(Soubor), PChar(Param), PChar(Defaultdir), SW_SHOWNORMAL);
  if Res <= 32 then
    ShowMessageFmt('Doslo k chybe %d: %s', [Res, SysErrorMessage(Res)]);
end;

Souhlasím  |  Nesouhlasím  |  Odpovědět
David Mensik  |  22. 08. 2001 15:22

Coze? Jake prochazeni procesu???? Jak jste na to proboha prisel.

O co jde je snad jasne z nazvu fci - potrebuju vypnout (restartovat) pocitac => potrebuju na to pravo SeShutdownPrivilege => potrebuju ho povolit pro proces, ktery bude volat ExitWindowsEx => privileges jsou v security tokenech (potrebuju ho ziskat => potrebuju handle na process). Tot vse. Zadne prochazeni procesu!

Ozon

P.S. Staci se jen podivat do MSDN a tam se o tom vsem pise. To je prave problem Delphi - hodne komponent, rychle se programuje, ale az dojde na veci pro povrchem, tak je treba stejne pouzit Win32 API . Chci jen podotknout, ze nejsem odpurcem Delphi, naopak, delam v nich hodne casto.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Radek Chalupa  |  22. 08. 2001 20:20

Samozřejmě souhlasím s Vámi, jen bych k Vaší poznámce "Stačí se podívat do MSDN" podotkl, že pro ty nešťastníky, kteří mají třeba pouze Delphi, to není možné. Já pracuji ve Visual C++ a v C++ Builderu, takže díky vlastnictví Visual C++ mám MSDN a mohu srovnávat úroveň dokumentace. Pánové od Borlandu zdá se nějak nezaregistrovali, že "Windows SDK" se vyvíjí a když v "dokumentaci" k verzi 5 C++ Builderu není ani zmínka o mnoha nových API funkcích Windows 2000, tak člověk ví své. On i rozsah dokumentace k VCL je také kapitolou samou pro sebe. Najdete tam třeba zmínku o zprávách CN_xxxxxx s vysvětlením, jak jsou v systému VCL posílány.
Pro ty co vědí o čem je řeč příklad: takto help C++ Builderu 5 popisuje TApplication::Handle:
"Provides access to the window handle of the main form (window) of the application.". Znalí věci vědí, že handle okna hlavního formu je úplně něco jiného než Application->Handle. A ti zmínění nešťastníci se pak ptají, jak skrýt ikonu aplikace z pruhu úloh, protože samozřejmě nemohou vědět že je zásadní rozdíl mezi:
ShowWindow(Form1->Handle, SW_HIDE)
a
ShowWindow(Application->Handle, SW_HIDE)
kde Form1 je hlavní formulář aplikace.

Radek Chalupa - www.rplusj.cz

Souhlasím  |  Nesouhlasím  |  Odpovědět
David Mensik  |  22. 08. 2001 21:22

Dovolte abych jeste reagoval .

Pokud se najdou lide, kteri ctou clanky na internetu, neni problem misto adresy www.zive.cz dat msdn.microsoft.com .

Najdou tam mnoho zajimaveho a treba taky pristup k MSDN library zdarma, takze se mohou hodne dozvedet. Navic si mohou stahnout SDK - to je take zdarma, nechat si to vypalit a CD a pouzivat. SDK je na ftp.microsoft.com/developr/platformsdk. Je toho sice trochu vice, stahnout to pres modem je asi vylouceno, ale rozhodne to stoji za to - v SDK je totiz take platform SDK documentation, coz je vysek z MSDN. Pravda, lepsi je MSDN cele, ale to je na webu, jak jsem rikal.

 

Ozon

Souhlasím  |  Nesouhlasím  |  Odpovědět
Radek Chalupa  |  22. 08. 2001 22:14

Zdravím,

Samozřejmě máte pravdu, ale obávám se, že mnozí jsou "odkojeni Borlandem" a když navíc jsou závislí na připojení přes telefon, tak to pro ně problém je. Obávám se, že existuje mnoho delphistů, kterých když se zeptáte, co je to MSDN, tak nevědí, zvláště pokud jejich postoj k Microsoftu je ovlivněn "veřejným míněním". Z vlastní praxe: do nedávna jsem byl na modemu. MSDN jsem měl aktualizovanou díky tomu že Microsoft legálním vlastníkům Visual C++ posílal 1 rok čtvrtletně (já ji dostal 5 krát, což je více než čtvrtletně za jeden rok) poslední verzi MSDN (vždy 3 CD zcela zdarma - díky ! - budete se divit, ale já mám rád Microsoft). Ale stažení aktualizované verze SDK (tedy knihovny a to co je potřeba k psaní kódu pro poslední verzi) byl přes dialup docela "zážitek".

Opravdu nekritizuji, ale spíše lituji ty kteří chtějí nějakou radu třeba na builder.cz s dodatkem "hlavně abych nemusel volat nějaké API funkce ....". To je výsledek "Borlandí školy".

Já osobně kromě Visual C++ (viz mé články na zive.cz - omluva za vlastní reklamu), také dělám a školím C++ Builder, a napadá mě výrok: "Díky Microsoftu (tedy MSDN) jsem si vydělal nějaké ty peníze také psaním komponent pro C++ Builder".

Na závěr se omlouvám pokud jsem se poněkud "rozkecal" mimo téma článku (mimochodem, na jaký článek to vlastně reagujeme?). Takže se pomalu půjdu věnovat příjemnějším stránkám života (děti jsou u babičky, takže si to s manželkou musíme ještě užít...) a předpokládám, že až mi zítra vyjde na živě další článek, tak budu terčem zasloužené kritiky zase já ......

P.S. Pro ty, kterým jsem zde sliboval seriál o tvorbě komponent pro C++ Builder - již jsem poslal redakci 3 díly, takže uvidíme, zda se zde objeví ....

Radek Chalupa - www.rplusj.cz

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petr Vones  |  26. 08. 2001 11:53

Máte bohužel pravdu v tom, že Win32 API dokumentace dodávaná s Delphi je více jak 5 let stará a nektuální. Je však nutné si uvědomit, že Borland nemůže vzít MSDN a distribuovat ji se svými nástroji, tak jako to dělá Microsoft. Pro ty kteří mají trochu slušné připojení k Internetu je MSDN Online dobrým řešením. Ohledně "Borlandí školy" a "hlavně abych nemusel volat nějaké API funkce ....", již několik let existuje Delphi konference na adrese www.delphi.cz kde se použití Win32 API probírá poměrně často. Snahou Borlandu je lidem programování ulehčit avšak na druhé straně nebránit v použití volání API pokud to je nutné. Jako vždy i VCL je jistým kompromisem. Programování s (výhradním) použitím komponent nebo tříd zapouzdřujících volání API nabývá na významu hlavně v případě aplikací určených pro více platforem (Windows a Linux) s použitím CLX v Delphi 6.

Ještě bych rád upozornil na knihovnu JEDI Code Library (která není knihovnou komponent, pouze kódu) a obsahuje mnoho "systémových" funkcí jako například zavření cizí aplikace, procházení procesů, zjištění jména funkce za běhu aplikace (obdoba __LINE__, __PROC__ z C) a mnoho dalšího. Jedná se o Open Source projekt pod licencí MPL, takže je možné ji používat i v komerčních aplikacích. Je určena pro Delphi 4 až 6, obsahuje rozsáhlou nápovědu, příklady a několik doplňků do Delphi IDE. Poslední verze 1.11 je ke stažení zde Pro ty kteří chtějí využívat API funkce jejichž konverze hlaviček které nejsou součástí Delphi je tu API Library, včetně podpory nových kernel funkcí pro Windows 2000.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Radek Chalupa  |  26. 08. 2001 12:16

Zdravím,

souhlasím s Vámi v tom, že na Internetu lze nalézt mnoho kvalitních materiálů k API v Delphi, jak o nich píšete. Já jsem své výroky založil na praktických zkušenostech. Nevím, proč tomu tak je, ale prostě je tomu tak, stačí se podívat na dotazy v rubrice "Delphi" popř, "C++ Builder", ale i dalších na serveru www.builder.cz. Možná ti programátoři neumí na Internetu najít to správné místo, nebo spíš hledají pouze hotové komponenty ke stažení, aniž by se zajímaly "jak věci fungují uvnitř". Ale ty dotazy mluví za vše. Navíc každý nemá k disposici "slušné připojení k Internetu", jak píšete.

Nevím, co máte na mysli tím, že "Borland nemůže vzít MSDN....". V té formě jako ji dostanete třeba s Visual C++ asi určitě ne (licence), ale součástí Delphi je ona zmíněná historická dokumentace "Windows SDK Reference". Proč ji nemůže aktualizovat? Je to problém licence? Opravdu by mě to zajímalo. Pokud máte informace "ze zákulisí", podělte se o ně. Můj laický názor byl, že prostě stačí tu zmíněnou dokumentaci dále aktualizovat. To vše ve mě vyvolává dojem, že Borland se snaží programátory od API co nejvíce "odtáhnout" a "znechutit jim ho", už třeba z důvodu jeho nadšené podpory Linuxu v posledních letech. Říkám, to je můj subjektivní názor, rád se seznámím s více fakty.

S pozdravem

Radek Chalupa - www.rplusj.cz

Souhlasím  |  Nesouhlasím  |  Odpovědět
Petr Vones  |  26. 08. 2001 12:38

Svět není jen www.builder.cz , podívejte se například na newsy které provozuje Borland. Samozřejmě že (především) začátečníci tíhnou k hledání řešení typu vezmi komponentu nastav vlastnost a je to hotové. Na druhé straně pokud by měli začít programovat přímo v API tak je to asi odradí již na začátku. Souhlasím s Vámi, že většina se už dnes nezajímá o to "jak fungují věci uvnitř", při dnešní složitosti některých technologií to už ale v mnoha případech ani není možné. Další problém je v tom, že dle mého názoru je zde málo literatury pro Delphi zabývající se pokročilejšími tétmaty, a to nemám namysli jen knihy vydané u nás.

Tím "Borland nemůže vzít MSDN...." jsem měl namysli přesně to co jste popsal. V té formě v jaké je dnes MSDN u MSVC++ by to asi nešlo a obávám se, že v jiném formátu to už asi neexistuje. Nic víc o tom nevím, občas se to probírá ve výše zmíněných newsech takže by tam třeba šlo najít nějakou odpověď.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Ales  |  22. 08. 2001 08:57

Nechci stourat, ale rozvecovani LEDek na NTckach nechodi.

Pouzivam:

    keybd_event(VK_NUMLOCK, 0, 0, 0);
    keybd_event(VK_NUMLOCK, 0, KEYEVENTF_KEYUP, 0);

Ales


 

Souhlasím  |  Nesouhlasím  |  Odpovědět
Radek Chalupa  |  22. 08. 2001 07:52

Zdravím,

Bohužel autor se dopustil docela zásadní nepřesnosti při popisu události OnCloseQuery. Správně napsal, že tato nastane, i když uživatel zavře okno třeba kliknutím na systémovou ikonku apod. Ale pozor ! Se zprávou WM_QUERYENDSESSION to nemá nic společného. Tato zpráva je posílána pouze když se ukončují Windows, resp, když se odhlašuje uživatel Tedy třeba v případe v tomto článku zmiňovanému použití ExitWindowsEx. Při zavření okna uživatelem tuto zprávu nedostanete. Když aplikace na tuto zprávu vrátí TRUE, je ukončena a vypínání systému pokračuje. Tuto zprávu tedy dostanou všechny spuštěné aplikace, když ukončujete Windows.

Takže když zachytíte (nejlépe v proceduře okna, tedy WndProc v případě VCL) zprávu WM_QUERYENDSESSION, víte, že aplikaci ukončuje zvnějšku systém....a máte vyřešen domácí úkol. (Doporučuji vrátit TRUE, viz výše....).

Ješte pro upřesnění, parametr lParam zprávy WM_QUERYENDSESSION určuje, zde jde o odhlášení uživatele (obsahuje hodnotu ENDSESSION_LOGOFF ) nebo ukončení celého systému.

Radek Chalupa - www.rplusj.cz

Souhlasím  |  Nesouhlasím  |  Odpovědět
autor  |  23. 08. 2001 02:20

Máte pravdu, je to přesně jak píšete, ovšem já nikdy v článku netvrdil opak. Pouze jsem podotkl, že při uzavření aplikace běžným způsobem se objeví ona hláška také (jako reakce na OncloseQuery), ale samozřejmě to nemá s WM_QUERYENDSESSION nic společného. Takže teď už jsme si to ujasnili.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Radek Chalupa  |  23. 08. 2001 07:11

Zdravím,

ano, máte pravdu, já jsem měl na mysli to, že z věty (cituji článek): " ....aplikacím zprávu WM_QUERYENDSESSION, kterou "zachytíme" událostí OnCloseQuery hlavního formuláře aplikace....." asi čtenáře jako první napadne, že OnCloseQuery je zapouzdřením handleru WM_QUERYENDSESSION. Jde o to, že OnCloseQuery prostě reaguje na různé události vedoucí k zavření okna. A to já opravdu nepovažuji za zapozdření handleru jedné zprávu. Navíc, když je ta zpráva WM_QUERYENDSESION "měkká" , já si vytvořím její handler, v něm "přesvědčím" Windows, aby ukončení bylo přerušeno, obávám se, že k události OnCloseQuery vůbec nemusí dojít. Je to podobně jako by jste napsal, že double-klik, tedu zprávu WM_LBUTTONDBLCK zachytíte v události nazvané jestli se nepletu OnMouseDown, tedy zachycením WM_LBUTTONDOWN. Double-klik samozřejmě také nejdříve vyvolá WM_LBUTTONDOWN, ale v OnMOuseDown nemůžete vědět zda bude následovat double-klik.

Radek Chalupa - www.rplusj.cz

Souhlasím  |  Nesouhlasím  |  Odpovědět
Radek Chalupa  |  22. 08. 2001 07:21

Zdravím,

k té "nefunkčnosti" ExitWindowsEx: Aby to fungovalo s použitím flagu EXW_POWEROFF, počítač musí podporovat "softwarové" vypnutí zdroje. Tedy ty "inteligentní zdroje", nebo jak se tomu říká. Dnes je to asi už běžné. Tento způsob vypnutí používají Windows při svém ukončení. V opačném případě (tedy bez použití tohotu flagu) se systém dostane do stavu, kdy na obrazovce dostanete hlášku typu "Nyní můžete počítač bezpečně vypnout", a musíte vypnout zdroj ručně.

Radek Chalupa - www.rplusj.cz

Souhlasím  |  Nesouhlasím  |  Odpovědět
autor  |  23. 08. 2001 02:13

Ano, to je samozřejmý předpoklad, ale i v případě, že toto "softwarové" vypnutí mám (tedy ATX zdroj a deska), stane se občas, že k vypnutí prostě nedojde. Tím nemyslím, že by se počítač zastavil v poloze s nápisem "Nyní můžete počítač....", ale buď se nestane vůbec nic a systém běží dál bez sebemenší reakce a nebo dojde jen k ukončení některých aplikací (i za použití onoho "násilného" řešení). Možná je to problém pouze mého systému, proto mě zajímalo, jestli někdo narazil na podobný problém.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Radek Chalupa  |  23. 08. 2001 10:44

Můžete zde uvést konkréktní příklad volání ExitWindowsEx, při kterém se Vám to takhle chová, a na jakém operačním systému, popř. ve WinNT/2000 s jakými právy jste přihlášen (tedy Admin..., PowerUser atd.)

Jinak těžko říci...

Radek Chalupa

Souhlasím  |  Nesouhlasím  |  Odpovědět
Fanda  |  22. 08. 2001 07:07

jednoduchsie je asi toto:

CanClose:=MessageDlg(`Opravdu ukočit ?`, mtConfirmation, mbYesNoCancel, 0)=mrYes;

Skutocne fasa serial.

Souhlasím  |  Nesouhlasím  |  Odpovědět
autor  |  22. 08. 2001 00:43

Vidím, že se pravděpodobně nějakým nedopatřením na serveru zdrojové kódy objevují stejným písmem jako samotný text. Nekamenujte mě za to, není to moje vina.

Souhlasím  |  Nesouhlasím  |  Odpovědět
Zasílat názory e-mailem: Zasílat názory Můj názor