Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Помогите изменить и доработать код. Построить функцию y=|sin(3x)|

85K
10 октября 2016 года
Eugene Pashkevich
7 / / 09.10.2016
Код:
Листинг программного кода

Листинг 1
// Подключение используемых заголовочных файлов:
#include <windows.h>        /* Содержит декларации для всех функций в Windows API, все общие макросы и все типы данных. Он определяет очень большое количество специфических функций окна */
#include <iostream>     /* Содержит классы, функции и переменные для организации ввода-вывода */
#include <cmath>        /* Выполняет простые математические операции */
#include <commdlg.h>        /* Поддерживает реализацию общих диалоговых окон (для GetSaveFileName) */
#include <shlobj.h>     /* Поддерживает работу с путём каталога к папке или файлу (для SHGetFolderPath) */

Листинг 2
// Начало функции WinMain:
/* Спецификатор WINAPI обозначает тип вызова функции; hInstance - дескриптор экземпляра выполняющейся программы (идентификатор приложения);
hPrevInstance - дескриптор предыдущего экземпляра программы, если таковой имеется, в Win32 не имеет смысла;
lpCmdLine - это указатель на строку, содержащую командную строку, запустившую программу;
nCmdShow - определяет внешний вид окна при его создании. */

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
}

Листинг 3
    WNDCLASS wc     = {0};  // Создание объекта класса окна и обнуление полей
    // Инициализация членов структуры окна
    wc.style        = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;   // Задание стиля окна
    wc.lpfnWndProc  = WindowProc;               // Задание функции обработки сообщений
    wc.hInstance    = hInstance;                // Задание дескриптора экземпляра приложения
    wc.hCursor      = LoadCursor (NULL, IDC_ARROW);     // Задание курсора окна
    wc.hIcon        = LoadIcon(NULL, IDI_APPLICATION);  // Задание пиктограммы приложения
    wc.lpszMenuName = L"hMenu";     // Инициализация указателя на имя ресурса меню
    wc.lpszClassName= L"CMyWnd";    // Инициализация указателя на имя класса (установка имени класса окна)
    wc.hbrBackground= static_cast<HBRUSH>(GetStockObject(GRAY_BRUSH)); // Задание кисти цвета фона окна
    RegisterClass (&wc);        // Регистрация класса окна в операционной системе
Листинг 4
    /* Создание экземпляра класса окна при помощи функции CreateWindow и инициализация дескриптора hWnd возвращаемым функцией значением.
    Параметры функции:
    L"CMyWnd" - имя класса окна; L"WinMain sample" - заголовок окна; WS_OVERLAPPEDWINDOW - стиль окна (перекрываемое);
    CW_USEDEFAULT - позиция левого верхнего угла на экране по умолчанию по X;
    0 - позиция левого верхнего угла на экране по умолчанию по Y;
    320 - размер окна (ширина); 240 - размер окна (высота); NULL - нет родительского окна; NULL - нет меню;
    hInstance - дескриптор экземпляра программы; NULL - никаких данных для создания окна: */

    HWND hWnd = CreateWindow (L"CMyWnd", L"WinMain sample", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 320, 240, NULL, NULL, hInstance, NULL);

Листинг 5
    // Создание Меню
    czCreateMenu(hWnd);

Листинг 6
    /* Функция получает дескриптор контекста устройства для клиентской области указанного в параметрах окна (задает область для рисования): */
    dc = GetDC (hWnd);
    /* Функция отображает окно, причем в соответствии с параметром nCmdShow: */
    ShowWindow (hWnd, nCmdShow);

Листинг 7
    /* Функция SetTimer создает таймер с указанным значением времени простоя, когда время истечет, передается сообщение */
    SetTimer (hWnd, 1, USER_TIMER_MINIMUM, NULL);

Листинг 8
    /* Структура сообщений Windows. Т.е. создание объекта типа MSG (создаем экземпляр структуры), который будет содержать информацию о сообщении из очереди потока сообщений: */
    MSG msg;
    /* Организация цикла сообщений (message loop), или так называемой подкачки сообщений (message pump).
    Функция GetMessage возвращает TRUE (1), если получено любое сообщение кроме WM_QUIT для завершения программы (в этом случае возвращается FALSE (0)).
    При возникновении ошибки возвращается значение -1.
    Цикл будет выполняться бесконечно, пока не появится сообщение завершения программы или не возникнет ошибка: */

    while (GetMessage(&msg,NULL,0,0) > 0)
    {
        TranslateMessage (&msg);    /* Преобразует сообщения от нажатой клавиатуры в символьный вид */
        DispatchMessage (&msg); /* Функция заставляет ОС Windows осуществить диспетчеризацию сообщения, т.е. вызвать функцию WindowProc() для обработки сообщения */
    }
    return msg.wParam;  // Возврат в операционную систему

Листинг 9
// Идентификатор контекста отображения (дескриптор контекста устройства вывода, в данном случае дисплея):
HDC dc;
// Логическая переменная для проверки было ли уже произведено сохранение:
static BOOL bFirstSave = TRUE;

Листинг 10
// Прототипы используемых функций
LRESULT CALLBACK WindowProc (HWND, UINT, WPARAM, LPARAM); /* Обрабатывает события окна */
void czCreateMenu(HWND hWwnd);          /* Создает меню главного окна */
void SaveScreen(HWND hWND);             /* Создает диалог для сохранения изображения (получает путь) */
bool save (HWND hWnd, OPENFILENAME openFile);   /* Непосредственно выполняет сохранение растрового изображения */

Листинг 11
// Функция создания меню:
void czCreateMenu(HWND hwnd)
{
    HMENU MainMenu = CreateMenu();          // Функция создает меню (пока пустое)
    HMENU hPopupMenu1 = CreatePopupMenu();      // Функция создает подменю - раскрывающееся меню (пока пустое)
    HMENU hPopupMenu2 = CreatePopupMenu();      // Функция создает подменю - раскрывающееся меню (пока пустое)
    HMENU hPopupMenu2_1 = CreatePopupMenu();        // Функция создает подменю - раскрывающееся меню (пока пустое)
    HMENU hPopupMenu3 = CreatePopupMenu();      // Функция создает подменю - раскрывающееся меню (пока пустое)
    AppendMenu(MainMenu, MF_STRING | MF_POPUP, (UINT)hPopupMenu1, L"&File"); // Функция добавляет "выпадающее" меню "Файл" в главную строку меню
    {
        AppendMenu(hPopupMenu1, MF_STRING | MF_CHECKED, 101, L"New");   // Функция добавляет пункт "Новый" в "выпадающее" меню "Файл"
        AppendMenu(hPopupMenu1, MF_SEPARATOR, 0, L"");          // Функция добавляет разделитель в "выпадающее" меню "Файл"
        AppendMenu(hPopupMenu1, MF_STRING, 102, L"Save");       // Функция добавляет пункт "Сохранить" в "выпадающее" меню "Файл"
        AppendMenu(hPopupMenu1, MF_STRING, 103, L"Save as..."); // Функция добавляет пункт "Сохранить как..." в "выпадающее" меню "Файл"
        AppendMenu(hPopupMenu1, MF_SEPARATOR, 0, L"");          // Функция добавляет разделитель в "выпадающее" меню "Файл"
        AppendMenu(hPopupMenu1, MF_STRING, 104, L"Exit");       // Функция добавляет пункт "Выход" в "выпадающее" меню "Файл"
    }
    AppendMenu(MainMenu, MF_STRING | MF_POPUP, (UINT)hPopupMenu2, L"&View");    // Функция добавляет "выпадающее" меню "Вид" в главную строку меню
    {
        AppendMenu(hPopupMenu2, MF_STRING | MF_POPUP, (UINT)hPopupMenu2_1, L"&Color"); // Функция добавляет "выпадающее" меню "Цвет" в "выпадающее" меню "Вид"
        {
            AppendMenu(hPopupMenu2_1, MF_STRING, 201, L"Black");    // Функция добавляет пункт "Черный" в "выпадающее" меню "Цвет"
            AppendMenu(hPopupMenu2_1, MF_STRING, 202, L"Blue"); // Функция добавляет пункт "Синий" в "выпадающее" меню "Цвет"
            AppendMenu(hPopupMenu2_1, MF_STRING, 203, L"Green");    // Функция добавляет пункт "Зеленый" в "выпадающее" меню "Цвет"
            AppendMenu(hPopupMenu2_1, MF_STRING, 204, L"Red");  // Функция добавляет пункт "Красный" в "выпадающее" меню "Цвет"
        }
    }
    AppendMenu(MainMenu, MF_STRING, 300, L"&Reset");                // Функция добавляет пункт "Сброс" в главную строку меню
    AppendMenu(MainMenu, MF_STRING | MF_POPUP, (UINT)hPopupMenu3, L"&Help");    // Функция добавляет "выпадающее" меню "Справка" в главную строку меню
    {
        AppendMenu(hPopupMenu3, MF_STRING, 401, L"&About");         // Функция добавляет пункт "О программе" в "выпадающее" меню "Справка"
    }
    SetMenu(hwnd, MainMenu);                                // Функция назначает новое меню для заданного окна
}

Листинг 12
#define WIN32_LEAN_AND_MEAN /* Ускоряет сборку за счет уменьшения размера заголовочных файлов, исключая наименее распространенные функции */
// Создание идентификаторов для событий выбора пунктов меню:
#define IDM_NEW 101 // Выбрано меню "New"
#define IDM_SAVE_AS 103 // Выбрано меню "Save as"
#define IDM_EXIT    104 // Выбрано меню "Exit"
#define IDM_BLACK   201 // Выбрано меню "Black"
#define IDM_BLUE    202 // Выбрано меню "Blue"
#define IDM_GREEN   203 // Выбрано меню "Green"
#define IDM_RED     204 // Выбрано меню "Red"
#define IDM_RESET   300 // Выбрано меню "Reset"
#define IDM_ABOUT   401 // Выбрано меню "About"

Листинг 13
// Функция обработки сообщений - Message processing function
LRESULT CALLBACK WindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;              // Создание переменных для хранения параметров сообщения
    static bool Move = true;            // Логическая глобальная переменная, которая показывает должен ли перерисовываться график с изменением положения
    static int Phase=0, Width, Height;  // Переменные для аргумента периодической функции, длины и ширины области построения графика
    HPEN hPen;                  // Объявляем кисть
    switch (message)                // Использование переключателя для обработки различных событий окна
    {
        case WM_LBUTTONDOWN:            // Сообщение - нажата левая кнопка мыши
        case WM_RBUTTONDOWN:            // Сообщение - нажата правая кнопка мыши
            Move = !Move;           // Включить/выключить перемещение графика
            // Нет break, т.е. следующая ветка выполняется
        case WM_TIMER:          // Сообщение - истекло время таймера
            if (Move)           // Если Move==TRUE (если движение разрешено), то выполняется следующий оператор
                Phase++;        // Увеличение аргумента (фазы) функции на единицу
                // Нет break, т.е. следующая ветка выполняется, если Move==TRUE
            else                // Если Move!=TRUE (если движение запрещено), то выполняется следующий оператор
                break;          // Выполнение переключателя прерывается
        case WM_PAINT:          // Сообщение – требуется окрасить (перерисовать) часть окна приложения
            Rectangle (dc, -1, -1, Width+1, Height+1);              // Прорисовка прямоугольника в клиентской области
            MoveToEx (dc, 0, Height * (0.5 + 0.3*sin(0.1*Phase)), NULL);        // Функция устанавливает текущую позицию пера, равную (x,y) для указанного контекста отображения dc
            for (int i=0; i<Width; i++)                         // Цикл для рисования графика (изменение по оси X)
                LineTo (dc, i, Height * (0.5 + 0.3*sin(0.1*(i+Phase))) );   // Функция рисует линию из текущей позиции пера в точку с координатами, перечисленными в параметрах функции
            break;                                      // Выполнение переключателя прерывается
        case WM_SIZE:                                       // Сообщение – изменился размер окна
            Width = LOWORD(lParam), Height = HIWORD(lParam);    // Изменение значений ширины и высоты окна в соответствии с параметрами сообщения
            break;                              // Выполнение переключателя прерывается
        case WM_KEYDOWN:            // Сообщение - нажата несистемная клавиша (без + Alt). Посылается окну с фокусом клавиатуры
            if (wParam != VK_ESCAPE)    // Проверка – нажата ли клавиша «Esc»
                break;          // Выполнение переключателя прерывается
            // else no break – в противном случае прерывания переключателя нет, т.е. переход к завершению работы окна
        case WM_DESTROY:            // Сообщение – окно должно быть разрушено (завершить работу приложения). После этого сообщения окно удаляется с экрана
            PostQuitMessage (0);        // Функция направляет сообщение WM_QUIT в функцию WinMain (обычно в ответ на сообщение WM_DESTROY). Указывает системе, что процесс, сделавший запрос необходимо прекратить
            break;              // Выполнение переключателя прерывается
        case WM_COMMAND:            // Сообщение – выбран пункт меню или элемент управления (кнопка); нажата «горячая» клавиша
            break;              // Выполнение переключателя прерывается
    }
    return DefWindowProc (hWnd, message, wParam, lParam);       // Смотри комментарии выше
}


Листинг 14
            wmId    = LOWORD(wParam);   // Выделение из 32-битового целочисленного значения младшего слова и запись в переменную
            wmEvent = HIWORD(wParam);   // Выделение из 32-битового целочисленного значения старшего слова и запись в переменную
            // Новый переключатель для определения какой пункт меня выбран (кнопок нет, поэтому подобные события отсутствуют):
            switch (wmId)           // Параметром переключателя служит код-идентификатор, указанный при создании пункта меню
            {
                case IDM_SAVE_AS:       // Сообщение - выбран пункт меню «Сохранить как…»
                    SaveScreen (hWnd);  // Вызов функции сохранения изображения клиентской области
                    break;          // Выполнение переключателя прерывается
                case IDM_EXIT:      // Сообщение - выбран пункт меню «Выход»
                    DestroyWindow(hWnd);    // Функция уничтожает окно. Она посылает сообщения WM_DESTROY и WM_NCDESTROY окну, чтобы разрушить его и удалить фокус клавиатуры из него. Функция также уничтожает меню, очищает очередь сообщений, разрушает таймеры и т.д.
                    break;          // Выполнение переключателя прерывается
                case IDM_BLACK:     // Сообщение - выбран пункт меню «Черный»
                    hPen=CreatePen(PS_SOLID, 1, RGB(0,0,0));    // Создание пера с определенным стилем, шириной и цветом
                    SelectObject(dc, hPen);         // Функция производит выбор объекта в контекст устройства
                    break;                      // Выполнение переключателя прерывается
                case IDM_BLUE:                  // Сообщение - выбран пункт меню «Синий»
                    hPen=CreatePen(PS_SOLID, 1, RGB(0,0,255));  // Создание пера с определенным стилем, шириной и цветом
                    SelectObject(dc, hPen);             // Функция производит выбор объекта в контекст устройства
                    break;                          // Выполнение переключателя прерывается
                case IDM_GREEN:                     // Сообщение - выбран пункт меню «Зеленый»
                    hPen=CreatePen(PS_SOLID, 1, RGB(0,255,0));  // Создание пера с определенным стилем, шириной и цветом
                    SelectObject(dc, hPen);             // Функция производит выбор объекта в контекст устройства
                    break;                          // Выполнение переключателя прерывается
                case IDM_RED:                           // Сообщение - выбран пункт меню «Красный»
                    hPen=CreatePen(PS_SOLID, 1, RGB(255,0,0));  // Создание пера с определенным стилем, шириной и цветом
                    SelectObject(dc, hPen);             // Функция производит выбор объекта в контекст устройства
                    break;                          // Выполнение переключателя прерывается
                case IDM_NEW:                           // Сообщение - выбран пункт меню «Новый»
                case IDM_RESET:                     // Сообщение - выбран пункт меню «Сброс»
                    Phase=0;                        // Сброс значения аргумента периодической функции в нуль
                    break;                          // Выполнение переключателя прерывается
                case IDM_ABOUT:                     // Сообщение - выбран пункт меню «О программе»
                    MessageBox(hWnd,L"PlotDrawer v.1.0. Copyright © M. Gorozheev Ph.D., 2015",L"About MessageBox", MB_OK | MB_ICONWARNING);    /* Функция отображает модальное диалоговое окно, которое содержит набор кнопок и краткое сообщение конкретных приложений (в данном случае – информацию о программе). Окно возвращает целое значение, указывающее, какая кнопка нажата пользователем */
                    break;          // Выполнение переключателя прерывается
                default:            // Эта «ветка» выполняется, если нет ни одного совпадения сообщения с метками case
                    return DefWindowProc(hWnd, message, wParam, lParam);    /* Функция обеспечивает стандартную обработку сообщений, которые явно не обрабатываются в функции WindowProc данного приложения. Эта функция гарантирует, что каждое сообщение обрабатывается. Она вызывается с теми же параметрами, что были получены функцией WindowProc */
            }

Листинг 15
// Функция создает диалог для сохранения изображения (получает путь)
void SaveScreen(HWND hWnd)
{
    OPENFILENAME openFile;  // Создание структуры. В нее записывается информация о выборе пользователя после закрытия диалогового окна
    TCHAR szPath[MAX_PATH]; // Символьный массив для хранения пути к файлу
    TCHAR szFile[MAX_PATH]; // Символьный массив для хранения имени файла
    // Инициализация структуры OPENFILENAME:
    ZeroMemory( &openFile, sizeof(OPENFILENAME) ); // Функция ZeroMemory заполняет блок памяти нулями
    openFile.lStructSize = sizeof(OPENFILENAME);   // lStructSize определяет длину структуры (байт); инициализируем оператором sizeof
    szFile[0] = '';                 // Делаем строку пустой, т.е. символ конца строки идет первым в массиве
    openFile.hwndOwner = hWnd;              // hwndOwner - дескриптор окна, которое владеет блоком диалога
    openFile.lpstrFile = szFile;            // Указатель на буфер с именем файла. Когда функция GetOpenFileName или GetSaveFileName возвращает значение, этот буфер содержит идентификатор диска, путь, имя и расширение выбранного файла
    openFile.nMaxFile = sizeof(szFile)/sizeof(*szFile);    // Размер буфера, в символах (TCHAR), указанного членом lpstrFile
    openFile.lpstrFilter = L"Bitmap Files (*.bmp)*.bmp"; // Указатель на буфер, содержащий пары строк фильтров с нулевым символом в конце. Последняя строка в буфере должна быть завершена двумя символами ПУСТО (NULL)
    openFile.lpstrDefExt = L"*.bmp";    // Указатель на буфер, который содержит заданное по умолчанию расширение
    // При первом сохранении документа пользователем путь по умолчанию приходится на папку «Мои рисунки»:
    if ( TRUE == bFirstSave )       // Если логическая переменная равняется истине, то использовать путь по умолчанию
    {
        /* Функция SHGetFolderPath возвращает полный путь к указанному специальному каталогу по его идентификатору. Макрос SUCCEEDED предусматривает унифицированную проверку на успешное завершение при любом значении состояния: */
        if ( SUCCEEDED( SHGetFolderPath( NULL, CSIDL_MYPICTURES, NULL, 0, szPath ) ) )
        {
        // Инициализация lpstrInitialDir значением (путем), который функция SHGetFolderPath записала в szPath.
        // Из-за этого функция GetSaveFileName представляет папку «Мои рисунки» в качестве начального каталога для диалогового окна:
            openFile.lpstrInitialDir = szPath;
        }
    }
    // Отображается окно стандартного диалога сохранения файла с путем по умолчанию в каталог «Мои рисунки» или выбранное пользователем
    // ранее местоположение. Функция GetSaveFileName создает диалоговое окно «Сохранить», а оператор if проверяет наличие ошибок:
    if ( GetSaveFileName( &openFile ) == TRUE ) // Смотри выше
    {
        // Пользователь нажал кнопку «Сохранить».
        // Происходит сохранение файла:
        UpdateWindow (hWnd);    // Перерисовка главного окна в связи с появлением диалогового (иначе изображение перекрывалось бы)
        save(hWnd, openFile);   // Вызов функции, которая непосредственно сохраняет изображение клиентской области окна в файл
        bFirstSave = FALSE;     // Логическая переменная «Первое_Сохранение» становится равной FALSE
    }
    else    // Если не нажата кнопка «Сохранить»
    {
        // Пользователь прервал диалог сохранения файла, или возникла ошибка
    }
}

Листинг 16
// Функция, непосредственно сохраняющая изображение клиентской области окна в файл
bool save (HWND hWnd, OPENFILENAME openFile)
{
    // Создание структуры с атрибутами файла:
    HDC hdcScreen;
    HDC hdcWindow;
    HDC hdcMemDC = NULL;
    HBITMAP hbmScreen = NULL;
    BITMAP bmpScreen;
    // Получить дескриптор контекста устройства дисплея для клиентской области окна:
    hdcScreen = GetDC(NULL);
    hdcWindow = GetDC(hWnd);
    // Создание совместимого DC, который используется в BitBlt из окна DC:
    hdcMemDC = CreateCompatibleDC(hdcWindow);
    if(!hdcMemDC)           // Если создать DC не получилось, выводится модальное окно с сообщением об ошибке
    {
        MessageBox(hWnd, L"CreateCompatibleDC has failed",L"Failed", MB_OK);
        goto done;      // Переход к завершающему коду (освобождению памяти)
    }
    // Получить клиентскую область для расчета размера:
    RECT rcClient;              // Создание прямоугольника для хранения координат рабочей области окна
    GetClientRect(hWnd, &rcClient);     // Получение координат рабочей области окна
   
    // Создать совместимый bitmap (точечный рисунок) из окна DC
    hbmScreen = CreateCompatibleBitmap(hdcWindow, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top);
    if(!hbmScreen)      // Если создать bitmap не получилось, выводится модальное окно с сообщением об ошибке
    {
        MessageBox(hWnd, L"CreateCompatibleBitmap Failed",L"Failed", MB_OK);
        goto done;      // Переход к завершающему коду (освобождению памяти)
    }
    // Выбор совместимого bitmap (растрового изображения) в памяти совместимого DC:
    SelectObject(hdcMemDC,hbmScreen);
    /* Копирование блока битов в память совместимого DC. Функция BitBlt используется для копирования отдельных битов из области источника изображения в область-получатель. Если копирование не удалось, выводится модальное окно с сообщением об ошибке: */
    if(!BitBlt(hdcMemDC, 0, 0, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top, hdcWindow, 0, 0, SRCCOPY))
    {
        MessageBox(hWnd, L"BitBlt has failed", L"Failed", MB_OK);
        goto done;      // Переход к завершающему коду (освобождению памяти)
    }
    // Получить BITMAP (точечный рисунок) из HBITMAP:
    GetObject(hbmScreen,sizeof(BITMAP),&bmpScreen);
    BITMAPFILEHEADER   bmfHeader;
    BITMAPINFOHEADER   bi;
    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biWidth = bmpScreen.bmWidth;
    bi.biHeight = bmpScreen.bmHeight;
    bi.biPlanes = 1;
    bi.biBitCount = 32;
    bi.biCompression = BI_RGB;
    bi.biSizeImage = 0;
    bi.biXPelsPerMeter = 0;
    bi.biYPelsPerMeter = 0;
    bi.biClrUsed = 0;
    bi.biClrImportant = 0;
    DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;
    // Начиная с 32-битной Windows, GlobalAlloc и LocalAlloc реализованы как «функции-обертки», которые вызывают HeapAlloc,
    // используя дескриптор, ссылающийся на кучу, выделяемую процессу по умолчанию. Таким образом, GlobalAlloc и LocalAlloc
    // имеют большую нагрузку, чем HeapAlloc:
    HANDLE hDIB = GlobalAlloc(GHND,dwBmpSize);
    char *lpbitmap = (char *)GlobalLock(hDIB);
    // Получаем "биты" из растрового изображения и копируем их в буфер, на который указывает lpbitmap:
    GetDIBits(hdcWindow, hbmScreen, 0, (UINT)bmpScreen.bmHeight, lpbitmap, (BITMAPINFO *)&bi, DIB_RGB_COLORS);
    // Создается файл. Именно здесь происходит сохранение захваченного изображения клиентской области:
    HANDLE hFile = CreateFile(openFile.lpstrFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    // Добавление размера заголовков к размеру растрового изображения, чтобы получить общий размер файла:
    DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    // Смещение, определяющее, где фактически начинаются биты растрового изображения:
    bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
    // Размер файла:
    bmfHeader.bfSize = dwSizeofDIB;
    // Компонент bfType всегда должен равняться BM для растровых изображений:
    bmfHeader.bfType = 0x4D42;      //Тип BM
    DWORD dwBytesWritten = 0;
    WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
    WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
    WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);
    // Разблокировка и освободить DIB (Device Independent Bitmap, растровое изображение) из кучи (памяти):
    GlobalUnlock(hDIB);
    GlobalFree(hDIB);
    CloseHandle(hFile);         // Закрыть дескриптор для файла, который был создан
    // После метки производится освобождение памяти (удаление объектов) и выход из функции:
done:
    DeleteObject(hbmScreen);
    DeleteObject(hdcMemDC);
    ReleaseDC(NULL,hdcScreen);
    ReleaseDC(hWnd,hdcWindow);
    return TRUE;
}
392
28 октября 2016 года
cronya
421 / / 03.01.2009
и стоило стока возиться с winapi и окном программы, когда решение лежит в пару строчек кода winform, зачем усложнять жизнь себе и другим.
85K
29 октября 2016 года
Eugene Pashkevich
7 / / 09.10.2016
Цитата: cronya
и стоило стока возиться с winapi и окном программы, когда решение лежит в пару строчек кода winform, зачем усложнять жизнь себе и другим.

если не сложно, напишите свое решение..........

85K
29 октября 2016 года
Eugene Pashkevich
7 / / 09.10.2016
Цитата: cronya
и стоило стока возиться с winapi и окном программы, когда решение лежит в пару строчек кода winform, зачем усложнять жизнь себе и другим.

если не сложно, напишите свое решение........

392
30 октября 2016 года
cronya
421 / / 03.01.2009
все просто решаете уравнение, получаете свой график, пишите математику для его постороения
пример на С#, от си++ сильно не отличается.
Код:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Graph
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
           
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Graphics ptr = e.Graphics;
            Pen penBl = new Pen(Color.Black);
            Pen penRed = new Pen(Color.Red);
            int ZeroX = 400;
            int ZeroY = 300;
            int piStep = 50;// шаг pi/3 от функции y=|sin(3x)|
            int yStep = 25;
            int Y = ZeroY;
            for(int idx=0; idx<5; idx++)
            {
                ptr.DrawLine(penBl, new Point(ZeroX,Y), new Point(ZeroX, Y + yStep));
                Y += yStep;
            }
            Y = ZeroY;
            for (int idx = 0; idx < 5; idx++)
            {
                Y -= yStep;
                ptr.DrawLine(penBl, new Point(ZeroX, Y), new Point(ZeroX, Y + yStep));                
            }
            ptr.DrawLine(penBl,new Point(ZeroX, ZeroY), new Point(ZeroX + piStep, ZeroY));
            int X = ZeroX;
            for(int idx=0; idx<5; idx++)
            {
                ptr.DrawArc(penRed, X, ZeroY - (2 * (yStep)), 50, 50, 180, 180);
                ptr.DrawLine(penBl, new Point(X, ZeroY), new Point(X + piStep, ZeroY));
                X += piStep;
            }
            ptr.DrawLine(penBl, new Point(X, ZeroY), new Point(X + piStep, ZeroY));
            X = ZeroX;
            for (int idx = 0; idx < 5; idx++)
            {
                X -= piStep;
                ptr.DrawArc(penRed, X, ZeroY - (2 * (yStep)), 50, 50, 180, 180);
                ptr.DrawLine(penBl, new Point(X, ZeroY), new Point(X + piStep, ZeroY));
            }
            X -= piStep;
            ptr.DrawLine(penBl, new Point(X, ZeroY), new Point(X + piStep, ZeroY));


        }
    }
}
выглядит так:

Вот ссылочка на WinApi, если вдруг не знаете куда дальше двигать в рисовании: http://www.functionx.com/win32/Lesson12.htm
ЗЫ: пример в ознакомительных целых предоставлен, если надо рисовать через точки, копайте в сторону полигонов (Polygon, PolyBezier), не надо кричать, что мне задали построить по точкам, задали Вам, я намекнул как..(так на всякий случай ;))
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог