1Цели на упражнението



Дата21.07.2017
Размер48.94 Kb.

Упражнение 4, стр. от

Упражнение 4

Използване на SystemTray

1Цели на упражнението


  1. Запознаване с една полезна възможност на потребителския интерфейс на Windows - добавяне и използване на икона в SystemTray (най-дясната област на лентата със задачи)

  2. Запознаване с често използвания подход за предаване на параметри към функциите на Windows API - чрез структури

2Теоретична постановка

2.1Общи положения


Практически всяка функция, независимо от колко входни параметъра се нуждае и колко резултата трябва да върне и колко са сложни те, може да се реализира с единствен параметър - указател към структура. Всички необходими входни и изходни параметри могат да се дефинират като полета в структурата, с произволен брой и сложност. Този подход се използва много често в Windows API. Някои от полетата са входни и се попълват преди извикването на функцията. Други са изходни и носят информация след връщане от функцията. Някои полета могат да бъдат входно-изходни.

Често се използват две особени входни полета. В едното трябва да се зададе размера в байтове на структурата (това обикновено се налага от разширяването на възможностите на съответната функция с новите версии на Windows). Другото представлява битово поле (набор от флагове), показващо кои входни полета са валидни и/или кои изходни трябва да се попълнят.


2.2Нови функции, променливи и структури от API


За пример ще разгледаме API функцията, реализираща възможността за добавяне на икона към SystemTray.

Функцията е дефинирана така:



WINSHELLAPI BOOL WINAPI Shell_NotifyIcon

(

DWORD dwMessage, // идентификатор на съобщение

PNOTIFYICONDATA pnid // указател към структура

);

Функцията връща TRUE/FALSE в зависимост от това, дали е успяла.

Първият параметър може да бъде един от:


  • NIM_ADD - за добавяне на икона

  • NIM_DELETE - за премахване на икона

  • NIM_MODIFY - за промяна на икона

Останалата инфомация се предава към функцията чрез структурата NOTIFYICONDATA, дефинирана в API така:

typedef struct _NOTIFYICONDATA {

DWORD cbSize;

HWND hWnd;

UINT uID;

UINT uFlags;

UINT uCallbackMessage;

HICON hIcon;

char szTip[64];

} NOTIFYICONDATA, *PNOTIFYICONDATA;



  • cbSize Размер на структурата. Добре е да се използва sizeof(…), а не например 88 .

  • hWnd Манипулатор на прозорец, който да получава съобщения при действия с мишката върху иконата в SystemTray.

  • uID Идентификатор на иконата. Няма нищо общо с ресурсния идентификатор.

  • uFlags - Флагове, показващи кои полета в структурата са валидни. Може да е произволна комбинация от: NIF_ICON, NIF_MESSAGE и NIF_TIP, например NIF_ICON | NIF_MESSAGE | NIF_TIP

  • uCallbackMessage Съобщение, което да се изпрати на указания прозорец. Това трябва да бъде потребителско съобщение, а не някое от стандартните съобщения на Windows. За целта може да се дефинира константа:

#define WM_TRAY WM_USER+1

WM_USER е стандартна константа, указваща началото на стойностите, допустими за потребителски съобщения. При всяко действие с мишката върху иконата, Windows ще изпраща на указания прозорец това съобщение. При това wParam ще съдържа идентификатора на иконата (uID), а lParam - една от стойностите WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_RBUTTONDOWN, WM_LBUTTONDBLCLK, WM_RBUTTONDBLCLK



  • hIcon Манипулатор на икона, която ще се добави към SystemTray. Може да се получи чрез функция LoadIcon(…).

  • szTip Текст, който да се появява при задържане на мишката над иконата.

Последните три полета не са задължителни. За всяко от тях, което е валидно при дадено извикване на функцията, трябва да се посочи съответния флаг.
Друга функция, която може да се използва в настоящето упражнение, реализира възможността за показване на падащо меню (така както става в Windows при щракване на десен бутон на мишката).

Функцията е

BOOL TrackPopupMenu(

HMENU hMenu, // Манипулатор на меню, което да се изведе

UINT uFlags, // Флагове, определящи позицията на менюто и поведението на

// функцията

int x, // Екранни координати, където да се изведе менюто

int y, //

int nReserved,// Запазено, трябва да е 0

HWND hWnd, // Манипулатор на прозореца, от който се създава менюто

CONST RECT *prcRect // Указва област от екрана, в която потребителят може

// да щрака с мишката, без менюто да се скрива. Ако е

// NULL, менюто се скрива при щракване извън него.

);

Функцията показва указаното меню. Работата й завършва след като потребителят избере команда или щракне извън указаната област (най-често извън менюто). При валиден избор функцията изпраща на указания прозорец съответно съобщение WM_COMMAND.



За полето uFlags може да се погледне в Help-а. Примерна добра стойност за това поле е TPM_BOTTOMALIGN | TPM_RIGHTALIGN.

Манипулатор на меню може да се получи например така:

HMENU popmenu=GetSubMenu(GetMenu(hWnd),0);

Така popupmenu указва първото падащо меню на прозореца (обикновено File).


3Задачи


  1. Да се състави програма, която добавя икона към SystemTray. При натискане на ляв клавиш върху иконата да се скрива или показва прозореца на програмата.

  2. Иконата да променя вида си в зависимост от това дали прозорецът е видим или не.

  3. При натискане на десен бутон върху иконата да се извежда меню.

4Указания


  • Както и в досегашните упражнения може да се започне с "Typical Hello World Application".

  • ВАЖНА ЗАБЕЛЕЖКА:

След като AppWizard създаде скелета на програмата, трябва да се отвори файла stdafx.h и да се премахне от него реда:

#define WIN32_LEAN_AND_MEAN

Наличието му изключва "рядко използвани" (според Microsoft) неща от API. Към тях спада работата със SystemTray.


  • Удобно е обръщението към API функцията Shell_NotifyIcon() да се "скрие" в потребителска функция, например:

BOOL TrayMessage(HWND hwnd,DWORD dwMessage,HICON hIcon)

{

NOTIFYICONDATA tnd;

tnd.cbSize =sizeof(tnd);

tnd.hWnd =hwnd;

tnd.uID =100;

tnd.uFlags =NIF_TIP|NIF_ICON|NIF_MESSAGE;

tnd.uCallbackMessage =WM_TRAY;

tnd.hIcon =hIcon;

lstrcpy(tnd.szTip,"My tray icon");

return Shell_NotifyIcon(dwMessage,&tnd);

}

  • Функцията TrayMessage() трябва да се извика поне два пъти - веднъж за да покаже иконата в SystemTray, например в InitInstance() и втори път - за да я скрие, например при обработката на WM_DESTROY

HICON LoadIcon(HINSTANCE hInst, LPCTSTR iconName)

Първият параметър е екземпляр на процеса. Той се получава като параметър в WinMain функцията. Вторият параметър е идентификатора на иконата. Той може да бъде символен низ или 16 битово цяло число, следвано от байт 0. За получаване на такова число, което и да е съвместимо с LPTSTR се използва макросът

LPTSTR MAKEINTRESOURCE(WORD resourceid);

Правилният начин на зареждане на икона, генерирана от AppWizard или друга, създадена от вас, е например:



HICON myicon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_SMALL));

Използването на макроса MAKEINTRESOURCE се налага от факта, че IDI_SMALL всъщност е число (в това може да се убедите ако отворите файла RESOURCE.H). IDI_SMALL естествено може да се замени с идентификатор на икона, създадена от вас.



Има подобни функции - LoadMenu(...), LoadString(...), LoadCursor(...), LoadAccelerators(...) за зареждане съответно на меню, низ, курсор, горещи клавиши (функционални клавиши, Ctrl- комбинации)

  • Към видимостта на прозореца имат отношение следните API функции:

ShowWindow(hWnd,SW_SHOW)- показва прозорец

ShowWindow(hWnd,SW_HIDE)- скрива прозорец (за още възможности вж. Help-а)

IsWindowVisible(hWnd) - връща TRUE ако прозореца е видим, иначе-FALSE


База данных защищена авторским правом ©obuch.info 2016
отнасят до администрацията

    Начална страница