|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Win32 API - графика, нужна помощь срочно! |
|
Win32 API - графика, нужна помощь срочно!
|
Новый участник Сообщения: 5 |
Профиль | Отправить PM | Цитировать Так долго искал в сети справочную информацию по WIN Api, нашел относительно много, но все совсем не по теме.. Навыки программирования у меня небольшие и оч сложно разбираться на чужих примерах без камментов..
к сути: есть лабораторная работа по винайпи, надо сделать на 8 число.Согласен, времени осталось до ужаса мало, но уже ничо не изменишь. задание: с помощью функций винапи сделать равнобедренный треугольник и 5 угольник, реализовать функции выбора активной фигуры, перемещения, удаления, поворота по часовой стрелке и смена цвета. все это с помощью клавы чтоб работало. Если кто возьмется - буду рад и счастлив! а еще, если всем в лом делать всю работу, то у меня есть аналог такой лабы, пытаюсь ща ее переделать, но получается с трудом. Если есть возможность - подскажите, *как нарисовать 5 угольник (вот для примера 4х угольник: case F.tip of //выбираем тип фигуры 1: begin MoveToEx(dc,F.x-1,F.y+1,NIL); //квадрат LineTo(dc,F.x-1,F.y-1); LineTo(dc,F.x+1,F.y-1); LineTo(dc,F.x+1,F.y+1); LineTo(dc,F.x-1,F.y+1); ) *в общих чертах подскажите, как реализовать поворот такой фигуры по часовой стреле? даже не представляю.. Заранее спасибо!! )) |
|
Отправлено: 00:34, 07-01-2008 |
Новый участник Сообщения: 5
|
Профиль | Отправить PM | Цитировать если что - ася в личке!
|
Отправлено: 00:59, 07-01-2008 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Ветеран Сообщения: 3320
|
Профиль | Отправить PM | Цитировать filmo, WinApi - это не язык програмирования, а интерфейс. Те части кода что я вижу очень напоминают Паскаль/Делфи.
|
Отправлено: 01:14, 07-01-2008 | #3 |
Новый участник Сообщения: 5
|
Профиль | Отправить PM | Цитировать Admiral, если честно, мне не легче ))
оч нужна помощь... сижу ипусь... |
Отправлено: 01:59, 07-01-2008 | #4 |
Ветеран Сообщения: 3320
|
Профиль | Отправить PM | Цитировать |
|
Отправлено: 02:11, 07-01-2008 | #5 |
Новый участник Сообщения: 5
|
Профиль | Отправить PM | Цитировать ок, спасибо, намекни хотя бы как реализовать его поворот по часовой?
можно конечно, задавать ему другие параметры просто (заранее заготовленные), как и эти, но, кажется таакой подход замутный и есть гораздо проще выход.. тока я его не знаю ( |
Отправлено: 10:31, 07-01-2008 | #6 |
Ветеран Сообщения: 1180
|
Профиль | Отправить PM | Цитировать поворот производится операцией сдвига и умножения на матрицу. немного теории:
в 2-мерном векторном (евклидовом) пространстве все элементы можно представить как векторы от точки {0,0} до точки {a,b}. Ещё над векторами есть операции: сложение/вычитание и скалярное умножение (свёртка). Ещё есть так называемое тензорное (внешнее) умножение. Оно превращает 2 вектора в матрицу, 3 и больше векторов в более сложные объекты. Есть группа простейших преобразований: масштабирование, сдвиг и поворот. Они все описываются скалярным умножением вектора на матрицу. И ещё последовательные операции можно комбинировать в одну матрицу. Короче: {{Cos[a], Sin[a]}, {-Sin[a], Cos[a]}} . {x,y} - поворот вектора на угол a вокруг точки {0,0} {c,d} + {{Cos[a], Sin[a]}, {-Sin[a], Cos[a]}} . {x,y} - поворот вектора на угол a и сдвиг точки на {c,d} есть волшебная функция, которая задаёт это преобразование SetWorldTransform и которая накладывает 2 преобразования ModifyWorldTransform. Они использут структурку: x' = x * eM11 + y * eM21 + eDx, y' = x * eM12 + y * eM22 + eDy, typedef struct _XFORM { // xfrm FLOAT eM11; FLOAT eM12; FLOAT eM21; FLOAT eM22; FLOAT eDx; FLOAT eDy; } XFORM; используем подход с откатами при исключениях (при исключении не портим DC). Что получилось - смотрим скриншот. #include <vector> //#include <string> #include <iostream> #include <sstream> #include <iomanip> #include <stdexcept> //#include <windows.h> using namespace std; //---------------------------------------------- void _error(const char* message); //---------------------------------------------- // не то, чтобы класс, просто кучка функций для того, чтобы было на чём рисовать // и чтобы результаты трудов потом не затирались class Window { public: static void execute(); static char* ginit(); static void paint(HDC dc); private: static long __stdcall WndProc(HWND, unsigned, unsigned, long); }; //---------------------------------------------- // класс для рисования объектов // 1. сохраняет восстанавливает параметры DC // 2. вычисляет преобразование координат // 3. рисует полигоны class draw_t { HDC rest_dc; int rest_mode; XFORM rest_form; unsigned steps; XFORM adv_form; public: draw_t(HDC dc) : steps (10), rest_dc (dc), // включаем продвинутый режим драйвера рисования для устройства // нужно для 2k, не всегда нужно для NT и XP: rest_mode (SetGraphicsMode(rest_dc, GM_ADVANCED)), // по умолчанию уменьшение и небольшое смещение adv_form (draw_t::rotate_scale(0.0174533*10.0, 0.95, -3, -.5)) { if (0==rest_mode || !GetWorldTransform(rest_dc, &rest_form)) // запомнили настройки отображения. { _error("draw_t::draw_t"); } } ~draw_t() { // не проверяем на ошибки ибо пофиг уже SetWorldTransform(rest_dc, &rest_form); SetGraphicsMode(rest_dc, rest_mode); } // вычисляем поворот и масштабирование static XFORM rotate_scale(const double& angle, const double& scale, const double& x, const double& y) { double cos1 = scale*cos(angle); double sin1 = scale*sin(angle); XFORM form1 = {cos1, sin1, -sin1, cos1, x, y}; return form1; } // вычисляем поворот и масштабирование static XFORM rotate_scale2(const double& angle, const double& scaleX, const double& scaleY, const double& x, const double& y) { double cos1 = cos(angle); double sin1 = sin(angle); XFORM form1 = {scaleX*cos1, scaleX*sin1, -scaleY*sin1, scaleY*cos1, x, y}; return form1; } // настройка параметров void setSteps(unsigned n) { steps = n; } void setTransform(const XFORM& form1) { if (!SetWorldTransform(rest_dc, &form1)) _error("draw_t::setTransform"); } void setAdvance(const XFORM& form1) { adv_form = form1; } // рисование void operator()(POINT* points, unsigned count) { // собственно говоря, самая полезная функция, // ради которой все затевалось. Отрисовка на низком уровне. // остальной код - только для поддержания порядка. for(unsigned n=0; n<steps; ++n) { if (!Polygon(rest_dc, points, count)) _error("draw_t() at polygon"); if (!ModifyWorldTransform(rest_dc, &adv_form, MWT_LEFTMULTIPLY)) _error("draw_t() at modify transform"); } } }; //---------------------------------------------- void Window::paint(HDC dc) { // здесь происходит отрисовка на высоком уровне draw_t draw(dc); // параметры draw.setSteps(150); draw.setTransform(draw_t::rotate_scale(0.0174533*0.0, 5.0, 200, 400)); draw.setAdvance(draw_t::rotate_scale2(0.0174533*9.0, 0.90, 1.05, 5., -7.5)); // рисуешь в кореле фигуру и переписываешь сюда координаты её точек ;-) static POINT tryangle_points[3] = {{-20,-10}, {20, -10}, {0, 20}}; draw(tryangle_points, 3); } //---------------------------------------------- char* Window::ginit() { // это требуется для создания окна. Можно было через диалоги сделать, // но там код короче, но запутанней static char* class_name = 0; if (!class_name) { WNDCLASSEX wcla; wcla.cbSize = sizeof(WNDCLASSEX); wcla.style = 0; wcla.lpfnWndProc = WndProc; wcla.cbClsExtra = 0; wcla.cbWndExtra = 4; wcla.hInstance = GetModuleHandle(0); wcla.hIcon = LoadIcon(0, IDI_APPLICATION); wcla.hCursor = LoadCursor(0, IDC_ARROW); wcla.hbrBackground = HBRUSH(1 + COLOR_BTNFACE); wcla.lpszMenuName = 0; wcla.lpszClassName = "Window"; wcla.hIconSm = LoadIcon(0, IDI_APPLICATION); class_name = reinterpret_cast<char*>(RegisterClassEx(&wcla)); } return class_name; } // структура для обработки события WM_PAINT (вынесена отдельно) // и чистки мусора после неё, exception-safe struct safe_dc { HWND hwnd; PAINTSTRUCT ps; safe_dc(HWND hwnd1) : hwnd(hwnd1) { if (!BeginPaint(hwnd1, &ps)) _error("safe_dc::safe_dc"); } ~safe_dc() { EndPaint(hwnd, &ps); } }; long __stdcall Window::WndProc(HWND hwnd, unsigned code, unsigned wparam, long lparam) { // оконная процедура try { if (code==WM_PAINT) // рисуем { safe_dc safe_dc1(hwnd); Window::paint(safe_dc1.ps.hdc); return 0; } else if (code==WM_CLOSE) // закрываемся (выходим) { PostQuitMessage(0); } } catch(exception& e) { MessageBox(0, e.what(), 0, MB_OK|MB_ICONERROR); } return DefWindowProc(hwnd, code, wparam, lparam); } void Window::execute() { // простейшая обработка ввода/вывода приложения. MSG cmsg; while (GetMessage(&cmsg, 0, 0, 0)) { // TranslateMessage(&cmsg); DispatchMessage(&cmsg); } } //---------------------------------------------- void _error(const char* message) { // генерируем исключение с кодом ошибки ОС long last_error = GetLastError(); ostringstream ss; ss << message << " error="; ss.width(8); ss.fill('0'); ss.flags(ios::hex|ios::right); ss << last_error; throw runtime_error(ss.str()); } int main() { // создали окно, поигрались, уничтожили HWND hwnd = CreateWindowEx(0, Window::ginit(), "Draw Test", WS_OVERLAPPEDWINDOW|WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, GetDesktopWindow(), 0, GetModuleHandle(0), 0); if (hwnd) { Window::execute(); DestroyWindow(hwnd); } return 0; } |
Отправлено: 16:47, 07-01-2008 | #7 |
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
2008 - help плиз.... срочно нужна помощь по контроллерам домена..срочно очень | God-of-Chaos | Windows Server 2008/2008 R2 | 10 | 10-11-2009 16:47 | |
БП и ИБП - Срочно нужна помощь!!!! | disru | Прочее железо | 2 | 31-10-2009 13:36 | |
Срочно Срочно нужна помощь!!! Восстановил сервер с бэкапа | qraf eric | Microsoft Windows NT/2000/2003 | 9 | 13-10-2009 10:32 | |
Срочно нужна помощь | _zonder_ | Сетевые технологии | 2 | 25-04-2006 10:15 | |
Срочно нужна помощь!!! | Novikov | Microsoft Windows NT/2000/2003 | 7 | 14-08-2003 17:18 |
|