Image
26.6.2016 0 Comments

C++ pod Windows / FAQ / 17. časť

Späť na úvod >> Späť na programovanie >> Späť na seriál

Ani sme sa nenazdali a rok 2001 sa končí. Pre niekoho bol úspešný, pre niekoho menej. Pre niekoho bol radostný, pre niekoho tragický. Som presvedčený, že rok 2001 sa napevno vpíše do dejín ľudstva ako nie príliš „úspešný“ – a nebude to uvedením Windows XP...

Ale poďme na inú tému. Keď som už spomenul Windows XP, ich uvedenie bude mať na nás vývojárov nemalý dosah. Okrem očakávaného súboju NET a Java, ktorého víťaza asi tak skoro nespoznáme, prináša tento operačný systém veľa nových vecí, ktoré sa my, „úbohí“ programátori musíme naučiť, ak chceme zostať „in“.

Čo sa týka náplne tejto časti seriálu, rozhodol som sa dopriať vám oddych od výkladu zložitých vecí Visual C++ a MFC. Celá časť bude venovaná vašim otázkam, ktoré ste mi poslali a ktoré majú všeobecnejší charakter, takže poslúžia, predpokladám, väčšine z vás. V odpovediach si ukážeme aj nejaké praktické veci, ktoré som vo výklade nespomenul, ale ich určite každý, kto tvorí praktické aplikácie, využije. V závere si povieme, čo nás ešte čaká a asi kedy budeme so seriálom končiť.

Ešte k vašim otázkam. Niektorí ste mi posielali vaše kompletné aplikácie s otázkami typu, ako urobiť to či ono, čo treba zmeniť, aby to nepadalo, a podobne. Žiaľ, nie je v mojej moci na všetky takto stavané otázky odpovedať. Čítať a pochopiť niekoho kód, akokoľvek dobre okomentovaný, je vždy časovo veľmi náročné.  A ešte k tomu dať odpoveď na otázky, ktoré nevie zodpovedať ani sám autor tohto programu, nie je možné. Preto sa ospravedlňujem tým, ktorí sa takejto odpovede nedočkali.

Q: Dá sa zadarmo zohnať/stiahnuť Visual C++?

A: Čo sa týka stiahnutia, nemám informácie, že by Microsoft uvoľnil Visual C++ takouto cestou (teda ak nie ste členmi niektorého z programov MSDN Subscriptions). Visual C++ sa však dá zohnať s niektorými knihami, ktoré vysvetľujú programovanie s týmto vývojovým nástrojom. Napríklad Visual C++ Introductory Edition (čo je vlastne Visual C++ Standard Edition, len má nejaké obmedzenia, ktoré sa týkajú tvorby komerčných aplikácií) sa dá zohnať s knihami Programujeme v Microsoft Visual C++ od tímu autorov (Kruglinski, Shepherd, Wingo)  alebo Programujeme v COM a COM+  od  Dalibora Kačmáře. Všetky vyšli vo vydavateľstve Computer Press. Sú však aj ďalšie knihy (bližšie informácie na http://www.cpress.cz/knihy).  Ak máte o ne záujem, pozrite sa v najbližšom kníhkupectve alebo virtuálnom obchode z knihami. (Počítajte však s tým, že ich cena sa pohybuje od 600 Sk vyššie.)

Q: Existujú na internete voľne dostupné učebnice o jazyku C/C++?

A: Áno, samozrejme. Za najlepšiu takto dostupnú učebnicu považujem publikáciu od Bruce Eckela Thinking in C++ 2nd. Edition; Volume 1Volume 2, kde nájdete skutočne vyčerpávajúci výklad všetkých čŕt C++ vrátane tých najmodernejších. Na konci každej kapitoly sú cvičenia, ktoré sa týkajú preberanej látky v konkrétnej kapitole a sú jasne formulované, jednoduché. Ich úspešné vyriešenie má určite motivujúci charakter. Všetky zdrojové kódy z knihy sa dajú zadarmo stiahnuť z webu (okrem riešení cvičení, tie sú dostupné za poplatok). Jedinou nevýhodou pre našinca môže byť, že stiahnutá kniha je v anglickom jazyku, ale v terajšej dobe to nepovažujem za veľký problém. Tento autor uspokojí aj záujemcov o Javu – dostupná je kniha Thinking in Java 2nd. edition – takisto veľmi kvalitná kniha. A konečne web, z ktorého sa dajú knihy stiahnuť a kde získate ďalšie informácie: www.bruceeckel.com.

Q: Aké knihy sú najvhodnejšie na učenie sa programovania s Visual C++?

A: Samozrejme, nemôžem hodnotiť, ktorá kniha je tá naj..., ale za veľmi kvalitné považujem Mistrovství ve Visual C++ od tragicky zosnulého Davida J. Kruglinského, jej pokračovanie: Programujeme v Microsoft Visual C++ (pozri vyššie), ktoré sú skutočné učebnicami, a nie referenčnými príručkami.

Q: Na inštalačných médiách Visual Studia 6.0 sa nenachádza help. Odkiaľ ho mám doinštalovať?

A: Inštalačky samotného Visual Studia 6.0 skutočne neobsahujú help k jednotlivým produktom (Visual Basic 6.0, Visual C++ 6.0, Visual FoxPro 6.0 a ďalšie). Help sa nachádza na samostatných médiách, ktoré sa označujú ako Microsoft Developer Network for Visual Studio 6.0 (známe MSDN) a mali by sa dodávať spolu s Visual Studiom (je možné ich zohnať aj samostatne). Sú to dve, prípadne viac CD (záleží od verzie). Najnovšie MSDN nájdete vždy na stránke www.msdn.microsoft.com, čo je on line verzia cédečkových MSDN.

Q: Existuje na Visual C++ nejaký Service Pack a nechystajú sa jeho nové verzie?

A: Na stránke http://msdn.microsoft.com/vstudio/downloads/updates.asp sa dá stiahnuť, prípadne objednať na CD najaktuálnejší Service Pack 5 (26.2.2001). Update sa týka všetkých aplikácií Visual Studia 6.0, ktorého je Visual C++ 6.0 súčasťou. Nová verzia Visual C++ bude zahrnutá v novom Visual Studiu NET (Visual Studio 7.0), ktoré sa momentálne (25. 10. 2001) nachádza vo verzii Release Candidate. V terajšej dobe sa dá zadarmo objednať Beta 2 Visual Studia NET(na CD alebo DVD), a keď čítate tieto riadky, pravdepodobne už aj spomínaný Release Candidate: (http://www.microsoft.cz/akce/vsbeta2/). A pozrite sa aj na stránku: http://www.msdn.microsoft.com/vstudio/nextgen/beta.asp.

To boli všeobecné otázky, ktoré sa priamo netýkali programovania vo Visual C++. Nasledujú otázky priamo súvisiace s vývojom aplikácií.

Q: Ako sa dajú čítať/zapisovať údaje z/do INI súborov?

A: Aj keď Microsoft tvrdí, že v 32-bitových Windows by sa mali všetky informácie z INI súborov nachádzať v registroch, v praxi sa toto pravidlo nie vždy dodržiava a ukazuje sa, že INI súbory sa budú používať ešte dosť dlho. Často napríklad potrebujeme takto čítať údaje, ktoré ovplyvňujú správanie celého programu, a hrabať sa u zákazníka v registroch Windows nie je veľmi praktické (je „používateľsky“ jednoduchšie zmeniť údaje v INI súbore ako ich meniť v registroch).

Na čítanie číselných dát z INI súboru slúži funkcia:

GetPrivateProfileInt( LPCTSTR menoSekcie, LPCTSTR menoKluca, INT nVratDefault, LPCTSTR menoINISuboru);

Na čítanie reťazcov slúži funkcia:

GetPrivateProfileString( LPCTSTR menoSekcie, LPCTSTR menoKluca, LPCTSTR strDefault, LPTSTR vratString, DWORD velkostRet, LPCTSTR menoINISuboru);

Presný opis parametrov nájdete v helpe, rovnako aj štruktúru INI súboru.

Ak máme INI súbor s názvom mojini.ini s obsahom:

[NASTAVENIA]

SpustP=1

CestaEXE=C:\MojProjekt\EXE\mojprojekt.exe

potom čítanie hodnoty SpustP by zabezpečovala funkcia:

int PrecitajIntINI(LPCTSTR  section, LPCTSTR name, LPCTSTR file)
{
      return GetPrivateProfileInt(section, name, 0, file);
}

Volali by sme ju napr. takto:

SpustP=PrecitajIntINI("NASTAVENIA ", "SpustP ", "mojini.ini ");

Čítanie hodnoty CestaEXE, čo je reťazec, bude zabezpečovať funkcia:

LPTSTR PrecitajStringINI(LPCTSTR section, LPCTSTR name, LPCTSTR file)
{
      LPTSTR docas=NULL;
     
      docas=(LPTSTR)GlobalAllocPtr(GHND, 50 * sizeof(TCHAR));
 
      GetPrivateProfileString(section, name, "", docas, 4096, file);
 
      return docas;
}

Volať ju môžeme takto:

char cesta[_MAX_PATH];
strcpy(cesta, PrecitajStringINI("NASTAVENIA", "CestaEXE", "mojini.ini"));

V premennej cesta budeme mať uložený string z INI súboru. Na úspešne skompilovanie tohto kódu musíte okrem štandardných hlavičkových súborov includovať aj string.h (pre strcpy), stdlib.h (pre _MAX_PATH ) a windowsx.h (na správne alokovanie pamäte pre reťazec vo funkcii PrecitajStringINI).

Tým sme vybavili čítanie, ostáva ešte zápis. Na zápis reťazcových aj číselných hodnôt bez rozdielu slúži funkcia:

BOOL WritePrivateProfileString(LPCTSTR menoSekcie, LPCTSTR menoKluca, LPCTSTR zapisRet, LPCTSTR menoINISuboru);  
Pokiaľ ide o bližší opis parameterov, opäť vás odkážem na help. Funkcia zapisujúca hodnotu 0 do parametra SpustP vyzerala takto:
BOOL ZapisStringINI(LPCTSTR section, LPCTSTR name, LPCTSTR str_zapisat, LPCTSTR file)
{
      return WritePrivateProfileString(section, name, str_zapisat, file);
}

Volali by sme ju takto:

BOOL bNavrat;
bNavrat=ZapisStringINI(“NASTAVENIA”, “SpustP”, “0”, “mojini.ini”);

Ak zadaný súbor INI v zadanej ceste neexistuje, vytvorí sa v systémovom adresári Windows. Takisto ak neexistuje sekcia/kľúč, kam chceme zapisovať, vytvoria sa. Ak je meno súboru INI bez akejkoľvek cesty (ako v našom príklade), defaultný adresár, kde ho program hľadá, je aj adresár Windows. Existujú aj ďalšie funkcie na prácu so súbormi INI [napr. WritePrivateProfileSection na zápis celej sekcie (Get... na čítanie), WritePrivateProfileStruct na zápis štruktúry dát (Get... na čítanie)], ktoré sme si tu nespomenuli, ich použitie je podobné ako v prípade zápisu/čítania jednoduchých dát. Pre záujemcov o detaily je k dispozícii help.  

Q: Ako získam zoznam všetkých procesov, ktoré práve bežia vo Windows?

A: V prvom rade je potrebné zohnať si súbory psapi.h, psapi.lib a psapi.dll (dostupné napríklad na www.msdn.microsoft.com – dajte si ich tam vyhľadať alebo mi napíšte, pošlem vám ich). Psapi.h a psapi.lib pridajte do svojho projektu (v menu Project->Add to Project->Files) a psapi.dll nahrajte do System32 adresára v adresári, kde máte nainštalované Windows. Sú to súbory obsahujúce deklarácie a definície funkcií, ktoré sú nevyhnutné pre náš ukážkový príklad a vo všeobecnosti zabezpečujú prácu s procesmi. Ukážeme si tvorbu celej aplikácie po krokoch (príklad je určený len pre operačné systémy NT/2000, mal by fungovať aj pod XP).

1. Vytvorte nový projekt s názvom Procesy (Win32 Console Application->An empty project a Finish).

2. Pridajte do projektu súbory psapi.h, psapi.lib a jeden nový zdrojový súbor – procesy.c (Nie cpp).

3. Tento kód pridajte do súboru procesy.c:

#include <windows.h>
#include <stdio.h>
 
#include "psapi.h"
 
// struktura vsetkych procesov
typedef struct {
      char* ProcesName;
      DWORD ProcessID;
 
} PROCESY;
 
// 200 ako max. pocet procesov
PROCESY proc[200];
 
void ZiskajProcesy(DWORD processID, int Poradie)
{
    HANDLE hProcess;
 
    char szProcessName[_MAX_PATH] = "unknown";
     
     // alokacia pamate pre pole mien procesov
     proc[Poradie].ProcesName=malloc(sizeof(char));
 
     // ziskame HANDLE procesu
     hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,          
                                               processID);
 
    // ziskame meno procesu
    if (hProcess) {
        HMODULE hMod;
        DWORD cbNeeded;
 
        if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) {
                  GetModuleBaseName(hProcess, hMod, szProcessName, sizeof(szProcessName));
        }
    }
 
     // zapiseme informacie o procese do struktury
     strcpy(proc[Poradie].ProcesName, szProcessName);
     proc[Poradie].ProcessID=processID;
 
     CloseHandle(hProcess);
}
 
void main()
{
    DWORD aProcesses[1024], cbNeeded, cProcesses;
    unsigned int i;
 
    if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
        return;
 
    // Kolko je procesov?
    cProcesses = cbNeeded / sizeof(DWORD);
 
    // ziskame mena a ID procesov
      for (i = 0; i<cProcesses; i++)
        ZiskajProcesy(aProcesses[i], i);
 
      // vypiseme vsetky procesy
      for (i = 0; i<cProcesses; i++)
            printf("%d %s\n", proc[i].ProcessID, proc[i].ProcesName);
}
 

Q: Ako pridám aplikáciu do SystemTray (TaskBaru)?

A: Pozrite si nasledujúcu funkciu:

 

void PridajNaTaskbar(HWND hWnd, UINT uID, HICON hIcon, LPSTR lpszTip)

{

     NOTIFYICONDATA tnid;

 

    tnid.cbSize = sizeof(NOTIFYICONDATA);

    tnid.hWnd = hWnd;

    tnid.uID = uID;

    tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;

    tnid.uCallbackMessage = WM_NOTIFYICON;

    tnid.hIcon = hIcon;

    if (lpszTip)

        lstrcpyn(tnid.szTip, lpszTip, sizeof(tnid.szTip));

    else

        tnid.szTip[0] = '\0';

 

    res = Shell_NotifyIcon(NIM_ADD, &tnid);

 

    if (hIcon)

        DestroyIcon(hIcon);

}

Má tieto parametre:

Parameter HWND hWnd získate pri tvorení okna aplikácie (návratová hodnota funkcie CreateWindow – pozri druhú časť seriálu).

Parameter UINT uID obsahuje ID zdroja ikony (zdroj ikony pridáte do zdrojov cez menu Visual C++

Insert -> Resource a vyberiete Icon alebo Import, ak chcete použiť existujúcu ikonu). Pre náš príklad bude meno zdroja ikony IDI_PRIKLAD. Potom parameter uID bude obsahovať práve toto meno.

Parameter HICON hIcon je handle zdroja ikony. Najprv musíte zadeklarovať tento handle ako:

HICON hIcon;

a jeho hodnotu získate ako návratovú hodnotu funkcie LoadIcon (parameter funkcie LoadIcon hInstance je tiež opísaný v druhej časti seriálu):

hIcon=LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PRIKLAD));

Parameter LPSTR lpszTip  je akýkoľvek textový reťazec, ktorý sa zobrazí, ak myšou „zájdete“ nad ikonu v TaskBare.

Volanie funkcie PridajNaTaskbar by v našom prípade vyzeralo takto:

PridajNaTaskbar(hWnd, IDI_PRIKLAD, hIcon, "Pokus s TaskBarom");

Ak sme však ikonu na TaskBar pridali, bolo by dobré ju po skončení aplikácie vymazať. Pridajte preto nasledujúci kód na miesto, kde ukončujete svoju aplikáciu (v druhej časti seriálu by to bolo vo vetve WM_DESTROY funkcie WndProc pred volanie funkcie PostQuitMessage(0)), napríklad:

case WM_DESTROY:
          // zmazeme ikonu z toolbaru
          tnid.cbSize = sizeof(NOTIFYICONDATA);
          tnid.hWnd = hWnd;
          tnid.uID = IDI_PRIKLAD;
        
          res=Shell_NotifyIcon(NIM_DELETE, &tnid);
   
          // potom ukocime aplikaciu
          PostQuitMessage(0);
          return 0;

Premenná res je deklarovaná ako BOOL. Otázkou zostáva, ako zachytávať správy pre aplikáciu umiestnenú v TaskBare (napr. kliknutie myšou na ikonu aplikácie). Vo funkcii PridajNaTaskbar sa nachádza riadok:

tnid.uCallbackMessage = WM_NOTIFYICON;

WM_NOTIFYICON je používateľom definovaná správa, ktorá bude vyslaná vždy, keď myšou „zájdete“ nad ikonu aplikácie v TaskBare. Túto správu obslúžite ako každú inú vo funkcii okna WndProc (stále uvažujeme príklad z druhej časti seriálu), kde bude predstavovať ďalšiu vetvu case. Napríklad  stlačenie pravého tlačidla myši na ikone aplikácie v TaskBare môžete obslúžiť takto:

switch (message) {
      // ak zajdeme mysou nad ikonu...
      case WM_NOTIFYICON:         
            // ...a stlacime prave tlacidlo mysi...
            if (lParam == WM_RBUTTONDOWN) {
                  MessageBox(hWnd, "Stlacili ste prave tlacidlo mysi?", "Informacia", MB_OK) 
             }
             break;

Správa WM_NOTIFYICON predstavuje používateľom definovanú správu, preto ju musíte na začiatku programu aj zadefinovať:

// pouzivatelom definovana sprava
#define WM_NOTIFYICON (WM_USER+100)

Ak by sa náhodou vyskytli problémy pri zachytení tejto správy (záleží na verzii Windows), zmeňte hlavičku funkcie WndProc z druhej časti seriálu takto:

LRESULT WINAPI WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) čo predstavuje modernejší zápis (používaný vo WIN32API) oproti tomu, ktorý je uvedený v druhej časti seriálu. 

Čo nás ešte čaká? V ďalších častiach si ešte preberieme kolekcie, serializáciu, rozdiely aplikácií SDI a MDI, povieme si niečo o registroch, písaní knižníc DLL, tlači a seriál ukončíme „čerešničkami“ v podobe využívania komponentov ActiveX, bitmáp a viacvláknového programovania. Tým ukončíme základ, spomínaný v prvej časti, po ktorého zvládnutí budete pripravení na získavanie ďalších vedomostí. Po dlhšom zvažovaní som sa rozhodol neopisovať prácu s databázami [pomocou DAO, o „jednoduchšom“ ADO (ActiveX Data Objects) si povieme aspoň základy], čo je veľmi rozsiahla téma, takmer na ďalší seriál. Takisto si nepovieme nič o komponentoch COM, COM+, DCOM, OLE a podobných, čo sú rovnako veľmi rozsiahle a zložité „technológie“, ktorých vývoj ešte stále nie je ukončený a v novom Visual Studiu bude práca s nimi značne zjednodušená, takže možno až potom... Vidím to tak, že seriál by mohol končiť 24. časťou, v ktorej uvedieme podobné FAQ, ako bolo v tejto časti, čím celú tému uzavrieme.

Nabudúce. V ďalšej časti sa vrátime opäť ku klasickému výkladu a budeme pokračovať v zdokonaľovaní aplikácie StudentList. Stretneme sa až v roku 2002, takže vám prajem krásne prežitie Vianoc, veselého Silvestra a veľa, veľa úspechov v roku 2002!


Nechajte si posielať prehľad najdôležitejších správ emailom

Mohlo by Vás zaujímať

Ako na to 1

Tipy a triky: Ako aplikácii prednastaviť spúšťanie s administrátorskými právami?

30.11.2016 00:10

Väčšina aspoň trochu skúsenejších používateľov vie, že aj keď máte na operačnom systéme Windows vytvorený administrátorský účet, aplikácie pre bezpečnosť nefungujú vždy splnými administrátorskými práv ...

Ako na to 1

Tipy a triky: Ako vypnúť uzamykaciu obrazovku vo Windows 10?

29.11.2016 00:10

Rozčuľuje vás, že pred každým prihlásením doúčtu vášho počítača musíte prejsť uzamykacou obrazovkou? Windows 10 na tejto obrazovke ukazuje čas,dátum anejakú zaujímavú fotografiu zrôznych kútov sveta. ...

Ako na to 3

Ako na to: Ochranná fólia versus tvrdené sklo? Čo je lepšie pre smartfón?

25.11.2016 00:16

Pomôže mobilu ďalšia vrstva ochrany alebo nie? Stačí klasická – plastová fólia alebo je tvrdené sklo tá lepšia voľba? Všetci dobre vieme, ako ľahko sa dokážu moderné smartphony doškriabať – či už pria ...

Žiadne komentáre

Vyhľadávanie

Kyocera - prve-zariadenia-formatu-a4-s-vykonom-a3

Najnovšie videá