Главная страница
Навигация по странице:

  • Контрольные вопросы

  • Цель работы


    Скачать 468.63 Kb.
    НазваниеЦель работы
    Дата07.04.2021
    Размер468.63 Kb.
    Формат файлаdocx
    Имя файлаlaboratornaya1.docx
    ТипДокументы
    #192174


    Цель работы:

    Реализовать windows-приложение, реализующее следующую реакцию на действия пользователя в главном окне: при клике на левую кнопку мыши создается дочернее окно приложения по отношению к главному, которое отображается в месте клика мыши и в рабочей области которого отображаются координаты клика мыши относительно главного окна; при клике на правую кнопку мыши дочернее окно перемещается в противоположный квадрант главного окна относительно клика мыши.
    2. Ход работы:

    1) Определить главные составляющие приложения, необходимые для его функционирования в соответствии с заданием.
    Главные составляющие:

    • Оконная функция WinMain, необходимая для регистрации класса окна, создания главного окна программы и запуска цикла обработки сообщений;

    • Функции окна WndPopup и WndProc, необходимые для обработки сообщений;

    • Функция RegClass необходимая для регистрация WNDCLASS;

    • Структура контекста устройства приложения HDC;

    • Структура PAINTSTRUCT содержащая информацию для приложения

    • Структура RECT определяющая координаты углов треугольника


    2) Определить все возникающие и требующие обработки сообщения Windows в приложении, определить идентификаторы данных сообщений.
    Для выполнения поставленной задачи необходимо обработать следующие сообщения:

    • Сообщение перемещения окна. Идентификатор WM_MOVE;

    • сообщение изменения размеров окна. Идентификатор WM_SIZE;

    • сообщение нажатия левой кнопки мыши. Идентификатор WM_LBUTTONDOWN;

    • сообщение нажатия правой кнопки мыши. Идентификатор WM_RBUTTONDOWN;

    • сообщение закрытия окна. Идентификатор WM_DESTROY;

    • сообщение окрашивания окна. Идентификатор WM_PAINT.


    3) Реализовать приложение с использованием WinAPI на языке С с учетом предыдущих этапов проектирования.
    Исходный код программы:
    #include
    BOOL RegClass(WNDPROC, LPCTSTR, UINT);

    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

    LRESULT CALLBACK WndPopup(HWND, UINT, WPARAM, LPARAM);
    HINSTANCE hInstance;

    char szMainName[] = "MainClass";

    char szPopupClass[] = "PopupClass";

    char szTitle[] = "Laboratornaya1";

    static HWND hwnds;

    char posMouse[20];

    int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance,

    LPSTR lpszCmdLine, int nCmdShow)

    {

    MSG msg;

    HWND hwnd;

    hInst = hInstance;

    if (!RegClass(WndProc, szMainName, COLOR_DESKTOP))

    return FALSE;

    if (!RegClass(WndPopup, szPopupClass, COLOR_BTNFACE))

    return FALSE;

    hwnd = CreateWindow(szMainName, szTitle,

    WS_OVERLAPPEDWINDOW|WS_VISIBLE,

    0, 0, 1400, 700,

    0, 0, hInstance, NULL);

    if (!hwnd) return FALSE;

    while (GetMessage(&msg, 0, 0, 0))

    {

    TranslateMessage(&msg);

    DispatchMessage(&msg);

    }

    return msg.wParam;

    }
    int RegClass(WNDPROC Proc, LPCTSTR szName, UINT brBackground)

    {

    WNDCLASS wc;

    wc.style = CS_HREDRAW | CS_VREDRAW;

    wc.cbClsExtra = wc.cbWndExtra = 0;

    wc.lpfnWndProc = Proc;

    wc.hInstance = hInstance;

    wc.hIcon = LoadIcon(NULL, IDI_INFORMATION);

    wc.hCursor = LoadCursor(NULL, IDC_CROSS);

    wc.hbrBackground = (HBRUSH)(brBackground);

    wc.lpszMenuName = (LPCTSTR)NULL;

    wc.lpszClassName = szName;

    return RegisterClass(&wc);

    }
    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)

    {

    static short left, top, Width, Height;

    static short cxClient, cyClient;

    RECT rc;

    switch(msg)

    {

    case WM_MOVE:

    {

    GetWindowRect(hwnd, &rc);

    if (IsWindow(hwnds))

    MoveWindow(hwnds,

    (rc.left + rc.right)/2,

    (rc.top + rc.bottom)/2,

    Width, Height, TRUE);

    return 0;

    }

    case WM_SIZE:

    {

    GetWindowRect(hwnd, &rc);

    cxClient = LOWORD(lParam);

    cyClient = HIWORD(lParam);

    Width = cxClient/2;

    Height = cyClient/2;

    if (IsWindow(hwnds))

    MoveWindow(hwnds,

    (rc.left + rc.right)/2,

    (rc.top + rc.bottom)/2,

    Width, Height, TRUE);

    return 0;

    }

    case WM_LBUTTONDOWN:

    {

    GetWindowRect(hwnd, &rc);

    cxClient = LOWORD(lParam);

    cyClient = HIWORD(lParam);

    _itoa(cxClient, posMouse, 10);

    strcat(posMouse, " ");

    char y[10];

    _itoa(cyClient, y, 10);

    strcat(posMouse, y);

    if (hwnds != NULL)

    return 0;

    hwnds = CreateWindow(szPopupClass, "ChildWindow",

    WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE,

    (rc.left + rc.right)/2,

    (rc.top + rc.bottom)/2,

    Width, Height, hwnd, 0, hInstance, NULL);

    break;

    }

    case WM_RBUTTONDOWN:

    {

    GetWindowRect(hwnd, &rc);

    cxClient = LOWORD(lParam);

    cyClient = HIWORD(lParam);

    if (cxClient < (rc.left + rc.right)/2)

    {

    if (cyClient < (rc.top + rc.bottom)/2)

    MoveWindow(hwnds,

    (rc.left + rc.right)/2, (rc.top + rc.bottom)/2,

    Width, Height, TRUE);

    else

    MoveWindow(hwnds,

    (rc.left + rc.right)/2, rc.top + 15,

    Width, Height, TRUE);

    }

    else if (cxClient >= (rc.left + rc.right)/2)

    {

    if (cyClient < (rc.top + rc.bottom)/2)

    MoveWindow(hwnds,

    rc.left + 5, (rc.top + rc.bottom)/2,

    Width, Height, TRUE);

    else

    MoveWindow(hwnds,

    rc.left + 5, rc.top + 15,

    Width, Height, TRUE);

    }

    return 0;

    }

    case WM_DESTROY: { PostQuitMessage(0); return 0; }

    }

    return DefWindowProc(hwnd, msg, wParam, lParam);

    }
    LRESULT CALLBACK WndPopup(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)

    {

    HDC hDC;

    PAINTSTRUCT ps;

    RECT rc;

    switch(msg)

    {

    case WM_PAINT :

    {

    hDC = BeginPaint(hwnds, &ps);

    GetClientRect(hwnds, &rc);

    SetTextColor(hDC, RGB(255, 0, 0));

    SetBkColor(hDC, RGB(255, 255, 255));

    SetTextColor(hDC, TA_CENTER);

    TextOut(hDC, (rc.left + rc.right)/2,

    (rc.top + rc.bottom)/2, posMouse, strlen(posMouse));

    EndPaint (hwnd, &ps);

    return 0;

    }

    case WM_DESTROY: { hwnds = NULL; break;}

    }

    return DefWindowProc(hwnd, msg, wParam, lParam);

    }
    Выполнение программы отображено на рисунках 1 и 2.


    Рисунок 1 – Главное окно программы


    Рисунок 2 – Появление окна с координатами клика мыши

    Контрольные вопросы

    1. Структура Windows-приложения: основные структурные части и их назначение.

    Структура Windows-приложения состоит из оконной функции WinMain() и функции окна WndProc().

    Функция WinMain() нужна для регистрации класса окна, создания главного окна приложения и создания цикла обработки сообщений

    Функция окна WndProc() нужна для связывания сообщений с соответствующими функциями обработки сообщений и непосредственно вызова этих функций обработки сообщения.


    1. Оконная функция Windows-приложения: синтаксис, состав, механизм взаимодействия приложения с операционной системой.

    Синтаксис:

    int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)

    Внутри функции WinMain() необходимо провести следующее:

    1. Зарегистрировать класс окна с помощью функции RegClass().

    2. Создать окно приложения с помощью функции CreateWindow().

    3. Создать цикл обработки сообщений while, получающий сообщения с помощью функции GetMessage() и проводящий обработку сообщений с помощью функций TranslateMessage() и DispatchMessage().

    Сам цикл отображен на рисунке.



    Рисунок 3 – Цикл обработки сообщений


    1. Функция окна Windows-приложения: синтаксис, параметры функции обратного вызова, механизм взаимодействия приложения с пользователем.

    Синтаксис:

    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)

    Параметры функции окна WndProc():

    1. Дескриптор окна адресата hwnd, обрабатывающее сообщениеж

    2. Передаваемое сообщение msg;

    3. Первый параметр сообщения wParam;

    4. Второй параметр сообщения lParam.

    Функция окна вызывается непосредственно самой ОС. Тип возвращаемого значения функции окна жестко заданы в отличие от имени функции окна, которое может быть выбрано произвольно. Имя функции окна должно быть зарегистрировано в Windows. Это происходит при регистрации структры окна.

    Функция окна получает сообщение и соответственно реагирует на него. Каждое окно определяет свою собственную функцию, которая принимает поступившие сообщения и проводит соответствующую обработку. Для непосредственной обработки сообщений используется оператор switch, с помощью ветвей которого устанавливается, какое сообщение было принято, и вызывается соответствующая функция обработки поступившего сообщения. Все сообщения, которые не связаны с собственными функциями обработки сообщений, должны быть переданы функции DefWindowsProc().


    1. Понятие адресного пространства Windows-приложения, структура адресного пространства, понятие процесса и потока.

    Процесс – экземпляр выполняемой программы. Процесс состоит из двух компонентов:

    • объект ядра;

    • адресного пространства.

    Каждому процессу выделяется собственное виртуальное адресное пространство. Для 32-разрядных процессов его размер составляет 4 Гб. Соответственно 32-битный указатель может быть любым числом от 0x00000000 до OxFFFFFFFF. Всего, таким образом, указатель может принимать 4 294 967 296 значений, что как раз и перекрывает четырех гигабайтовый диапазон. Для 64-разрядных процессов размер адресного пространства равен 1б экзабайтам, поскольку 64-битный указатель может быть любым числом от 0x00000000 00000000 до OxFFFFFFFF FFFFFFFF и принимать 18446 744 073 709 551 616 значений, охватывая диапазон в 16 экзабайтов.

    Виртуальное адресное пространство каждого процесса разбивается на такие разделы как:

    • раздел для выявления нулевых указателей:

    • раздел для совместимости с программами DOS и 16-разрядной Windows;

    • раздел для кода и данных пользовательского режима;

    • закрытый раздел размером 64 кб;

    • раздел для файлов проецируемых в память;

    • раздел для кода и данных режима ядра.

    Поток – базовая единица выполнения в Windows. Каждый процесс состоит из одного или нескольких потоков.


    написать администратору сайта