Настроить Visual Studio для создания Win32 приложений на Visual C++ с использованием RCE совсем несложно. Для этого:
Функция WinMain - входная точка в приложение Win32.
Объявление функции WinMain:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow );
Windows приложение строится по принципу управляемого событиями (event-driven). Данный принцип заключается в том, что в обычном состоянии приложение просто ожидает какое-либо событие от системы и ничего не делает. Получив от системы уведомление о событии, приложение выполняет какие-то действия и возвращает управление системе.
Система уведомляет приложение о событиях в форме сообщений (message). Если рассматривать упрощённо, то сообщения помещаются системой в очередь сообщений (message queue) и для извлечения их оттуда каждое приложение должно иметь цикл обработки сообщений (message loop).
Пример цикла обработки сообщений:
MSG msg;
BOOL bRet;
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
// Обработчик ошибки
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Здесь наибольший интерес представляет функция GetMessage, которая непосредственно и занимается
извлечением сообщений из очереди. Функция GetMessage возвращает управление приложению, только когда
в очереди имеются сообщения. В остальных случаях приложение будет находиться в режиме ожидания.
Сообщения, извлекаемые из очереди сообщений, имеют четыре параметра: описатель окна, для которого
предназначается сообщение, идентификатор сообщения, и два значения, называемые параметрами сообщения.
Извлекаемые сообщения передаются для обработки в оконную процедуру, соответствующего окна.
Передачей сообщений оконной процедуре занимается функция DispatchMessage. Необходимо отметить,
что в некоторых случаях сообщения могут передаваться оконной процедуре напрямую функцией GetMessage.
Базовым элементом Windows приложения, взаимодействующего с пользователем, является окно (window). Каждое окно имеет связанную с собой оконную процедуру (window procedure). Именно оконная процедура занимается выполнением каких-либо действий в ответ на полученные события, т.е. в оконной процедуре находятся обработчики сообщений.
Пример оконной процедуры:
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
return 0;
case WM_PAINT:
return 0;
case WM_SIZE:
return 0;
case WM_DESTROY:
return 0;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
hWnd - описатель окна;
WM_CREATE, WM_PAINT, WM_SIZE, WM_DESTROY - это идентификаторы сообщений;
wParam, lParam - параметры сообщения;
Каждое окно принадлежит к какому-либо классу окна (window class). Именно класс связывает окно с оконной процедурой. Окна, принадлежащие одному классу, имеют одну и ту же оконную процедуру. Для регистрации класса окна используется функция RegisterClassEx.
Пример регистрации класса окна:
BOOL MainWinClassReg(HINSTANCE hinstance)
{
WNDCLASSEX wcx;
wcx.cbSize = sizeof(wcx);
wcx.style = CS_HREDRAW | CS_VREDRAW;
wcx.lpfnWndProc = MainWndProc;
wcx.cbClsExtra = 0;
wcx.cbWndExtra = 0;
wcx.hInstance = hinstance;
wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
wcx.hbrBackground = GetStockObject(WHITE_BRUSH);
wcx.lpszMenuName = "MainMenu";
wcx.lpszClassName = "MainWClass";
wcx.hIconSm = LoadImage(hinstance, MAKEINTRESOURCE(IDI_SMICON),
IMAGE_ICON, GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR);
return RegisterClassEx(&wcx);
}
Здесь одним из важных параметров является lpfnWndProc - оконная процедура.
Другой важный параметр - это lpszClassName, который задает имя класса окна.
Для создания окна используется функция CreateWindowEx. Одним из параметров данной функции является имя класса окна. Этот параметр и связывает окно с классом.
Более подробное описание приведённого материала можно найти в библиотеке MSDN.