Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 2 сентября!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

ПРОГРАММИРОВАНИЕ НА C и С++



Слушай, дружище, зачем так мучиться с этим языком С++, ты ведь не Билл Гейтс. Возьми тот же Python и программируй, он кроссплатформенный, под Windows тоже работает. Я сам давно заметил: то что на Си пишешь в страницу кода, на питоне решается в одну-две строки. При том, питон намного проще, я его сам недавно изучил по видеокурсу вот этому. Кстати, автор отлично там объясняет. Буквально день-два и уже будешь писать на нём, чего не скажешь про сложный С++.
Данный пример представляет собой небольшую программку, при запуске которой, в строке статуса (там где в Windows показывается время) появляется иконка, которая может обрабатывать различные события, такие как двойное нажатие мышкой, и нажатие правой кнопкой на иконке.   Соответственно в зависимости от события, главный модуль программы выполняет определённые действия (открытие всплывающего меню либо открытие различных диалоговых окон и т.д.)

Исходный текст был откомпилирован в Visual C++ 4.2.  Выбор данного компилятора ни чем не обоснован, просто мне удобно в нём работать, вот и всё.

А теперь по-порядку. Сразу представлю исходный код , а в конце подробно его прокомментирую.

  Листинг 1 (status_ico.cpp)
 
 #include <windows.h>
 
 #include <windowsx.h>
 
 
 
 LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
 
 BOOL WndProc_OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct);
 
 void WndProc_OnDestroy(HWND hWnd);
 
 void AddStatusIcon(HWND hWnd, DWORD dwMessage);
 
 void HandlePopupMenu (HWND hwnd, POINT point);
 
 
 
 #define WM_NOTIFYICONMSG (WM_USER + 2)
 
 
 
 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
 
 {
 
 	MSG msg;
 
 	HWND hWnd;
 
 	WNDCLASSEX wndclass;
 
 
 
 	hInst = hInstance;
 
 
 
 	wndclass.style = 0;
 
 	wndclass.lpfnWndProc = (WNDPROC)WndProc;
 
 	wndclass.cbClsExtra = 0;
 
 	wndclass.cbWndExtra = 0;
 
 	wndclass.hInstance = hInst;
 
 	wndclass.hIcon = NULL;
 
 	wndclass.hCursor = NULL;
 
 	wndclass.hbrBackground = NULL;
 
 	wndclass.lpszMenuName = NULL;
 
 	wndclass.lpszClassName = "WSCLAS";
 
 
 
 	if(!RegisterClassEx(&wndclass))
 
 		if(!RegisterClass((LPWNDCLASS)&wndclass.style))  return FALSE;
 
 
 
 	hWnd=CreateWindow("WSCLAS", "", 0, 0, 0, 1, 1, HWND_DESKTOP, NULL, hInst, NULL);
 
 
 
 	AddStatusIcon(hWnd, NIM_ADD);
 
 
 
 	while(GetMessage(&msg, NULL, 0, 0))  {
 
 		TranslateMessage(&msg);
 
 		DispatchMessage(&msg);
 
 	}
 
 
 
 	return msg.wParam;
 
 }
 
 
 
 LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 
 {
 
 	POINT pt;
 
 
 
 		case WM_NOTIFYICONMSG:
 
 			switch(lParam)  {
 
 				case WM_LBUTTONDBLCLK:
 
 					MessageBox(NULL, "Двойной щелчок по иконке", "Сообщение от иконки", MB_OK);
 
 				break;
 
 
 
 				case WM_RBUTTONDOWN:	// нажатие на иконку правой кнопкой мыши
 
 					GetCursorPos(&pt);	//вычисляем текущее положение курсора
 
 					HandlePopupMenu (hWnd, pt);  //рисуем меню от координат курсора
 
 					break;
 
 
 
 				default:
 
 					break;
 
 			}
 
 			break;
 
 
 
 		HANDLE_MSG(hWnd, WM_CREATE, WndProc_OnCreate);		//стандартный обработчик создания окна
 
 		HANDLE_MSG(hWnd, WM_DESTROY, WndProc_OnDestroy);	//стандартный обработчик уничтожения окна
 
 
 
 		default:
 
 			return(DefWindowProc(hWnd, msg, wParam, lParam));
 
 	}
 
 	return 0;
 
 }
 
 
 
 BOOL WndProc_OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct)
 
 {
 
 	return TRUE;
 
 }
 
 
 
 void WndProc_OnDestroy(HWND hWnd)
 
 {
 
 	PostQuitMessage(0);
 
 }
 
 
 
 void AddStatusIcon(HWND hWnd, DWORD dwMessage)
 
 {
 
 	HICON hStatusIcon;			// Хэндл иконки в статус-баре
 
 	LPCSTR pszIDStatusIcon;		// Указатель на Иконку в статус-баре
 
 	NOTIFYICONDATA tnd;
 
 
 
 	pszIDStatusIcon = MAKEINTRESOURCE(IDI_ICON1);
 
 
 
 	hStatusIcon = LoadIcon( hInst,pszIDStatusIcon );
 
 	tnd.cbSize = sizeof(NOTIFYICONDATA);
 
 	tnd.hWnd = hWnd;
 
 	tnd.uID = 1;
 
 	tnd.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
 
 	tnd.uCallbackMessage = WM_NOTIFYICONMSG;
 
 	tnd.hIcon = hStatusIcon;
 
 	lstrcpyn(tnd.szTip, "Пример", sizeof(tnd.szTip));
 
 	Shell_NotifyIcon( dwMessage, &tnd );
 
 }
 
 
 
 void HandlePopupMenu (HWND hWnd, POINT point)
 
 {
 
 	HMENU hMenu;
 
 	HMENU hMenuTrackPopup;
 
 	LPCSTR pszIDMenu;
 
 
 
 	pszIDMenu = MAKEINTRESOURCE(IDM_POPUPMENU1);
 
 	hMenu = LoadMenu (hInst, pszIDMenu);
 
 	if (!hMenu)  return;
 
 	hMenuTrackPopup = GetSubMenu (hMenu, 0);
 
 	TrackPopupMenu (hMenuTrackPopup, 0, point.x, point.y, 0, hWnd, NULL);
 
 	DestroyMenu (hMenu);
 
 }
 
 
Комментарии:

В самом начале идёт обязательное включение Виндузовых заголовков (как и в любой программе под Windows. Далее я объявляю используемые в программе функции. Обычно такое объявление делается в файле-заголовке (.h) , но когда функций не так много, то я обычно эти описания вставляю в главный файл. Описание главной функции  WinMain не нужно добавлять.

Далее идёт определение идентификатора сообщения (#define WM_NOTIFYICONMSG (WM_USER + 2)), которое будет поступать от иконки. Впринципе этому идентификатору можно приствоить любое число, но чтобы быть уверенным, что такое число не используется каким-нибудь другим идентификатором, обычно присваивают  WM_USER + n   , где n - любое число.

Далее идёт основная функция, с которой начинает работать данная программа. Вообще-то в разных версиях API данная функция описывается по-разному. Например в API 16 её описание начинается с дескриптора PASCAL, но в API 32 - это WINAPI.

Следующим шагом программа создаёт окно, но не простое, а невидимое. То есть запущенная программа не будет видна в панели задач. Вообще процесс создания окна в Windows состоит из двух шагов. Первый ( RegisterClassEx(&wndclass) )- это регистрация класса окна в системе, и второй ( hWnd=CreateWindow(.... )- создание непосредственно окна. Параметр wndclass.lpfnWndProc = (WNDPROC)WndProc; указывает классу окна, что все сообщения, поступающие окну будут обрабатываться функцией WndProc. Все описания данных функций и их входных параметров Вы можете найти во многих книгах по программированию в API 32, поэтому здесь я не буду отвлекаться на эти вопросы.

Далее вызывается функция AddStatusIcon(hWnd, NIM_ADD) , задача которой заключается в том, чтобы нарисовать в панели статуса нужную иконку. Параметр hWnd означает, что все сообщения (...нажатия на ней мышкой...) от иконки будут передаваться главному окну нашей программы. Параметр NIM_ADD указывает функции, что иконка будет добавлена в статус-бар. Этот параметр может принимать значение NIM_MODIFY, означающий, что уже существующая иконка будет изменена или будет изменена её информационная надпись, которая появляется при навидении на иконку мышкой.

И наконец функция WinMain завершается бесконечным циклом, задача которого обрабатывать сообщения, поступающие главному окну. Естевственно этот цикл не такой уж и бесконечный, при поступлении определённых сообщений (например WM_CLOSE ) цикл может звершиться, и соответственно завершится сама программа. Например, если послать окну сообщение WM_DESTROY , то функция обработки оконных сообщений ( WndProc ) вызовет WndProc_OnDestroy , и наша программа завершит свою работу в системе. Соответственно при создании окна окно получает сообщение WM_CREATE и оконная функция вызывает WndProc_OnCreate(). Ещё можно добавить, что все неопознанные сообщения, или те, для которых Вы не предусмотрите обработчики сообщений напрвляются DefWindowProc(hWnd, msg, wParam, lParam) , вызов каторой находится в конце WndProc.





<< ВЕРНУТЬСЯ В ПОДРАЗДЕЛ

<< ВЕРНУТЬСЯ В ОГЛАВЛЕНИЕ




Материалы находятся на сайте https://exelab.ru/pro/



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU Проект ReactOS