Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Win32 API - графика, нужна помощь срочно!

Ответить
Настройки темы
Win32 API - графика, нужна помощь срочно!

Новый участник


Сообщения: 5
Благодарности: 0

Профиль | Отправить 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
Благодарности: 0

Профиль | Отправить PM | Цитировать


если что - ася в личке!

Отправлено: 00:59, 07-01-2008 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Ветеран


Сообщения: 3320
Благодарности: 916

Профиль | Отправить PM | Цитировать


filmo, WinApi - это не язык програмирования, а интерфейс. Те части кода что я вижу очень напоминают Паскаль/Делфи.

Отправлено: 01:14, 07-01-2008 | #3


Новый участник


Сообщения: 5
Благодарности: 0

Профиль | Отправить PM | Цитировать


Admiral, если честно, мне не легче ))
оч нужна помощь...
сижу ипусь...

Отправлено: 01:59, 07-01-2008 | #4


Ветеран


Сообщения: 3320
Благодарности: 916

Профиль | Отправить PM | Цитировать


Цитата filmo:
сделать ... треугольник»
можно так
Код: Выделить весь код
Line(80,110,85,130);
Line(85,130,110,170);
Line(110,170,80,110);
Цитата filmo:
как нарисовать 5 угольник »
Код: Выделить весь код
Line(80,110,85,130);
Line(85,130,110,170);
Line(110,170,150,190);
Line(150,190,170,195);
Line(170,195,80,110);

Отправлено: 02:11, 07-01-2008 | #5


Новый участник


Сообщения: 5
Благодарности: 0

Профиль | Отправить PM | Цитировать


ок, спасибо, намекни хотя бы как реализовать его поворот по часовой?
можно конечно, задавать ему другие параметры просто (заранее заготовленные), как и эти, но, кажется таакой подход замутный и есть гораздо проще выход.. тока я его не знаю (

Отправлено: 10:31, 07-01-2008 | #6

pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


Изображения
Тип файла: jpg Безымянный.JPG
(78.8 Kb, 8 просмотров)

поворот производится операцией сдвига и умножения на матрицу. немного теории:
в 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;
теперь делаем следующим образом: пусть есть исходные координаты, описанные структурой POINT (из winapi)
используем подход с откатами при исключениях (при исключении не портим 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



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Win32 API - графика, нужна помощь срочно!

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
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




 
Переход