-
DalÜφ aplikace ukazuje jak vytvo°it obsluhu pro zprßvu Win32. Tento p°φklad
pou₧φvß makra mapovßnφ zprßv definovanß v SYSDEFS.H k obslou₧enφ
zprßvy WM_GETMINMAXINFO. ZaΦneme v²voj novΘ aplikace. Rozm∞ry formulß°e
zm∞nφme na 350 x 350. Na formulß° umφstφme Φty°i komponenty Label
(v₧dy dv∞ vedle sebe) a zm∞nφme texty lev²ch komponent na èφ°ka
a V²Üka. Texty prav²ch komponent zm∞nφme na 350. Dßle vytvo°φme
obsluhu udßlosti OnResize formalß°e. Obsluha bude obsahovat p°φkazy:
Label2->Caption =
IntToStr(Width);
Label4->Caption =
IntToStr(Height);
Kdy₧ nynφ aplikaci spustφme a m∞nφme velikost formulß°e, pak zobrazenΘ
texty nßs informujφ o rozm∞rech formulß°e. My ale po₧adujeme, aby
rozm∞ry formulß°e bylo mo₧no m∞nit pouze v n∞jakΘm intervalu, nap°. mezi
300 a 400 body.
Zprßva WM_GETMINMAXINFO je zaslßna oknu, kdy₧ je m∞n∞na velikost nebo
pozice okna. Aplikace m∙₧e pou₧φt tuto zprßvu k p°epsßnφ minimßlnφ a maximßlnφ
implicitnφ velikosti a pozice okna. Parametrem zprßvy je ukazatel na strukturu
MINMAXINFO,
kterß obsahuje implicitnφ hodnoty okna. Tyto implicitnφ hodnoty m∙₧eme
p°epsat. Struktura MINMAXINFO je deklarovßna takto:
typedef struct tagMINMAXINFO
{
POINT ptReserved;
POINT ptMaxSize;
POINT ptMaxPosition;
POINT ptMinTrackSize;
POINT ptMaxTrackSize;
} MINMAXINFO;
Slo₧ky struktury majφ tento v²znam:
Slo₧ka |
V²znam |
ptReserved |
Rezervovßno |
ptMaxSize |
Specifikuje maximalizovanou Üφ°ku (point.x) a maximalizovanou
v²Üku (point.y) okna. |
ptMaxPosition |
Specifikuje pozici levΘho okraje maximalizovanΘho okna
(point.x) a pozici hornφho okraje maximalizovanΘho okna (point.y). |
ptMinTrackSize |
Specifikuje minimßlnφ Üφ°ku (point.x) a minimßlnφ v²Üku
(point.y) okna. |
ptMaxTrackSize |
Specifikuje maximßlnφ Üφ°ku (point.x) a maximßlnφ v²Üku
(point.y) okna. |
Vytvo°φme tedy ve°ejnou virtußlnφ metodu formulß°e nazvanou RestrictSize
s nßsledujφcφm obsahem:
void __fastcall TForm1::RestrictSize(TMessage&
Msg)
{
((POINT far *)Msg.LParam)[3].x = 300;
((POINT far *)Msg.LParam)[3].y = 300;
((POINT far *)Msg.LParam)[4].x = 400;
((POINT far *)Msg.LParam)[4].y = 400;
TForm::Dispatch(&Msg);
}
a budeme se sna₧it namapovat zprßvu WM_GETMINMAXINFO na naÜi metodu
RestrictSize,
kterß zajistφ, ₧e Üφ°ka a v²Üka formulß°e se musφ pohybovat mezi 300 a
400. Pokud formulß° p°ijme zprßvu WM_GETMINMAXINFO, pak naÜe metoda zm∞nφ
informace zprßvy o maximßlnφm a minimßlnφm rozm∞ru okna a volßnφm Dispatch
je tato upravenß zprßva p°edßna souΦasnΘ obsluze udßlosti objektu formulß°e.
Nßsleduje v²pis deklarace typu formulß°e, ve kterΘm je uvedeno po₧adovanΘ
mapovßnφ:
class TForm1 : public
TForm
{
__published: // IDE-managed
Components
TLabel *Label1;
TLabel *Label3;
TLabel *Label2;
TLabel *Label4;
void __fastcall FormResize(TObject *Sender);
private: // User
declarations
public: //
User declarations
virtual __fastcall TForm1(TComponent* Owner);
void virtual __fastcall RestrictSize(TMessage& Msg);
// Toto mapovßnφ
mapuje zprßvu WM_GETMINMAXINFO na funkci RestrictSize
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_GETMINMAXINFO,TMessage,RestrictSize)
// Zde lze p°idat
dalÜφ mapovanΘ zprßvy.
END_MESSAGE_MAP(TForm)
};
Nynφ, kdy₧ aplikaci p°elo₧φme a spustφme, vidφme, ₧e velikost okna
lze m∞nit pouze v zadan²ch mezφch. Obdobn∞ je mo₧no provΘst mapovßnφ dalÜφch
zprßv Windows. K mapovßnφ jsou pou₧ita makra BEGIN_MESSAGE_MAP,
MESSAGE_HANDLER
a END_MESSAGE_MAP.
-
DalÜφ aplikace, se kterou se nynφ seznßmφme, je aplikace zobrazujφcφ seznam
proces∙ b∞₧φcφch na naÜem poΦφtaΦi a umo₧≥ujφcφ zruÜenφ vybranΘho procesu.
Jednß se op∞t o hotovou aplikaci. Aplikaci si stßhn∞te
a vyzkouÜejte jak pracuje. Nynφ se podφvßme jak tato aplikace je vytvo°ena.
Nejprve zaΦneme jednoduÜÜφmi Φinnostmi. VoliΦe ve spodnφ Φßsti formulß°e
pouze urΦujφ barvu textu v komponent∞ ListBox. Obsluha udßlosti
OnClick
pro vÜechny Φty°i voliΦe je tvo°ena p°φkazy:
TRadioButton *rbp
=(TRadioButton*) Sender;
ListBox1->Font->Color=rbp->Font->Color;
Obsluhu udßlosti OnTimer ΦasovaΦe (pohybuje Üipkou na panelu
nßstroj∙) tvo°φ (i je globßlnφ prom∞nnß deklarovanß na zaΦßtku zdrojovΘho
souboru formulß°e):
switch(i){
case 0:{
Image1->Picture->Bitmap->LoadFromResourceName(0,
(AnsiString)"BITMAP_5");
Image1->Refresh();
i=1;
return;
}
case 1:{
Image1->Picture->Bitmap->LoadFromResourceName(0,
(AnsiString)"BITMAP_2");
Image1->Refresh();
i=2;
return;
}
case 2:{
Image1->Picture->Bitmap->LoadFromResourceName(0,
(AnsiString)"BITMAP_3");
Image1->Refresh();
i=3;
return;
}
case 3:{
Image1->Picture->Bitmap->LoadFromResourceName(0,
(AnsiString)"BITMAP_4");
Image1->Refresh();
i=4;
return;
}
case 4:{
Image1->Picture->Bitmap->LoadFromResourceName(0,
(AnsiString)"BITMAP_1");
Image1->Refresh();
i=0;
return;
}
}
Obsluha volby File | Exit je tvo°ena p°φkazem
PostQuitMessage(0);
Funkce API PostQuitMessage p°edßvß Windows po₧adavek na ukonΦenφ.
Parametr funkce urΦuje ukonΦujφcφ k≤d aplikace. Funkce zasφlß zprßvu WM_QUIT
front∞ zprßv vlßkna. Kdy₧ vlßkno zφskß zprßvu WM_QUIT ze svΘ fronty zprßv,
ukonΦφ sv∙j cyklus zprßv a vracφ °φzenφ Windows.
Volba Help | About zobrazφ okno s informacemi o programu. Obsluha
tΘto volby nepot°ebuje ₧ßdnΘ vysv∞tlenφ.
Obsluha stisku levΘho tlaΦφtka na palet∞ nßstroj∙ je tvo°ena p°φkazy
(tato obsluha je vyvolßna i p°i volb∞ File | List Pids a File
| Refresh List):
long lp=0;
ListBox1->Enabled=true;
ListBox1->Clear();
EnumWindows((WNDENUMPROC)EnumProc,lp);
SpeedButton2->Enabled=true;
SpeedButton3->Enabled=true;
V tΘto obsluze je volßna funkce EnumWindows. Popis tΘto funkce
bude uveden pozd∞ji. Obsluhu stisku druhΘho tlaΦφtka tvo°φ (ListBox
je vyprßzdn∞n a zakßzßna dv∞ tlaΦφtka):
ListBox1->Clear();
SpeedButton3->Enabled=false;
SpeedButton1->Enabled=false;
Obsluhu stisku t°etφho tlaΦφtka tvo°φ p°φkazy (je zde volßna obsluha
stisku prvnφho tlaΦφtka a poslednφ tlaΦφtko zakßzßno):
SpeedButton4Click(0);
SpeedButton1->Enabled=false;
Obsluha udßlosti OnShow formulß°e tvo°φ p°φkazy (prom∞nnß stat
je statickß prom∞nnß s poΦßteΦnφ hodnotou 1; je deklarovßna na poΦßtku
programovΘ jednotky formulß°e):
if(stat){
stat= 0;
ListBox1->Items->Add((AnsiString)"Click
on 'pid' Tool button above");
}
Tato obsluha po prvnφm zobrazenφ formulß°e zobrazφ v ListBox
text Click on 'pid' Tool button above. Nynφ se ji₧ v∞nujeme funkci
EnumWindows.
Tato funkce prochßzφ vÜechna okna nejvyÜÜφ ·rovn∞ (nezab²vß se pod°φzen²mi
okny) na obrazovce a p°edßvß madlo ka₧dΘho z nich zp∞tn∞ volanΘ funkci.
EnumWindows
pokraΦuje a₧ do poslednφho okna nebo dokud zp∞tn∞ volanß funkce vracφ false.
Funkce mß dva parametry. Prvnφm je ukazatel na zp∞tn∞ volanou funkci a
druh² urΦuje hodnotu, kterß bude p°edßna zp∞tn∞ volanΘ funkci.
V naÜem p°φklad∞ je funkcφ EnumWindows zp∞tn∞ volßna nßsledujφcφ
funkce:
bool __stdcall EnumProc(/*HWND*/void
* hWnd,/*LPARAM*/long/*lp*/)
{
unsigned
long* pPid; //LPDWORD
unsigned
long result; //DWORD
void
*hg;
//HGLOBAL
unsigned
long id;
if(hWnd==NULL)
return false;
hg =
GlobalAlloc(GMEM_SHARE,sizeof(unsigned long));
pPid
= (unsigned long *)GlobalLock(hg);
result
= GetWindowThreadProcessId(hWnd,pPid);
if(result){
char title[110];
char className[95];
char totalStr[256];
GetClassName(hWnd,className,95);
GetWindowText(hWnd,title,110);
id=*pPid;
itoa(id,totalStr,10);
strcat(totalStr,"\t");
if(title){
strcat(totalStr,title);
strcat(totalStr,"\t");
}
strcat(totalStr,className);
Form1->ListBox1->Items->Add((AnsiString)totalStr);
}
else{
GlobalUnlock(hg);
GlobalFree(hg);
return false;
}
GlobalUnlock(hg);
GlobalFree(hg);
return
true;
}
NaÜe funkce vytvß°φ seznam spuÜt∞n²ch proces∙. Pokuste se pochopit,
jak tato funkce pracuje. V naÜem programu zb²vß jeÜt∞ obsluha udßlosti
OnClick
okna seznamu, kterou tvo°φ p°φkazy:
SpeedButton1->Enabled=true;
StatusBar1->SimpleText=
"Select 'Kill
Selected PID' to terminate the process";
a obsluha stisku poslednφho tlaΦφtka (zruÜenφ vybranΘho procesu). Obsluhu
stisku poslednφho tlaΦφtka tvo°φ:
AnsiString str;
char *tmp;
int i;
i= ListBox1->ItemIndex;
if( i != -1){
AnsiString
s;
tmp = new
char[100];
s=ListBox1->Items->Strings[i];
strcpy(tmp,(char*)s.c_str());
tmp=strtok(tmp,"\t");
}
int id=atoi(tmp);
delete[] tmp;
HANDLE ps = OpenProcess(1,false,id);
if(ps){
if(!TerminateProcess(ps,-9)){
ShowMessage((AnsiString)"Could not end process specified!");
}
else{
ShowMessage((AnsiString)"Process successfully terminated!");
}
}
else{
ShowMessage((AnsiString)"Could
not open process requested!");
}
Pokuste se pochopit, jak tato obsluha pracuje.