Изменение параметров механизма с помощью диалогового окна

 

1) Изменения параметров механизма запишем в уже созданной нами функции, которая и вызывает диалоговое окно «Parameters». Но сначала откроем CMotorView и в начале файла объявим заголовочный файл диалогового окна, чтобы нам были доступны все переменные этого класса:

à #include “DlgParameters.h”

Теперь уже в функцию запишем следующий код:

void CMotorView::OnParameters()

{

// TODO: Add your command handler code here

à DlgParameters dlg; // Объявление класса в данной функции

 

à if (dlg.DoModal()==IDOK)

à {

à AB = dlg.m_AB * mn;

à BC = dlg.m_BC * mn;

à BD = dlg.m_BD * mn;

à DE = dlg.m_DE * mn;

à CBD = dlg.m_CBD * PI/180;

 

à int N = dlg.m_N;

à double aN = 2*PI/N;

à a = 0;

à Background();

à for (int i=0; i<N; i++)

à {

à a += aN;

à LeadOutParameters();

à DRAW();

à }

à }

Здесь dlg.DoModal() вызывает диалоговое окно, а оператор if проверяет нажатие кнопки OK. Если кнопка OK нажата, то переменным присваиваются новые значения из диалогового окна. Здесь же в зависимости от числа N, с помощью цикла выводятся несколько положений механизма.

2) Усовершенствуем функцию OnParameters(), добавив к ней: а) возможность показывать текущие значения величин в полях диалогового окна, после неоднократного его вызова, б) комплекс условий для нормального отображения механизма, и автоматическое присваивание минимальных или максимальных значений, при вводе чисел вне указанного рядом с полем диапазона:

void CMotorView::OnParameters()

{

// TODO: Add your command handler code here

DlgParameters dlg; // Объявление класса в данной функции

 

à dlg.m_AB = round(AB/mn);

à dlg.m_BC = round(BC/mn);

à dlg.m_BD = round(BD/mn);

à dlg.m_DE = round(DE/mn);

à dlg.m_CBD = CBD*180/PI;

 

if (dlg.DoModal()==IDOK)

{

à if (dlg.m_AB<4) dlg.m_AB = 4;

à if (dlg.m_AB>20) dlg.m_AB = 20;

à if (dlg.m_BC<8) dlg.m_BC = 8;

à if (dlg.m_BC>60) dlg.m_BC = 60;

à if (dlg.m_BC<2*dlg.m_AB) dlg.m_BC = 2 * dlg.m_AB;

à if (dlg.m_BD<0) dlg.m_BD = 0;

à if (dlg.m_BD>15) dlg.m_BD = 15;

à if (dlg.m_DE<8) dlg.m_DE = 8;

à if (dlg.m_DE>60) dlg.m_DE = 60;

à if (dlg.m_DE<=(dlg.m_AB+dlg.m_BD))

à dlg.m_DE = dlg.m_AB + dlg.m_BD + 1;

 

AB = dlg.m_AB * mn;

BC = dlg.m_BC * mn;

BD = dlg.m_BD * mn;

DE = dlg.m_DE * mn;

CBD = dlg.m_CBD * PI/180;

 

int N = dlg.m_N;

double aN = 2*PI/N;

a = 0;

Background();

for (int i=0; i<N; i++)

{

a += aN;

LeadOutParameters();

DRAW();

}

}

 

Заключение

 

Исходный текст программы

Исходный текст программы содержится в файлахMotorView.h/ MotorView.cpp и DlgParameters.h/ DlgParameters.cpp.

 

MotorView.h

// MotorView.h : interface of the CMotorView class

//

/////////////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_MOTORVIEW_H__A8B4D01E_53BF_497B_A76C_7053B3C035FB__INCLUDED_)

#define AFX_MOTORVIEW_H__A8B4D01E_53BF_497B_A76C_7053B3C035FB__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

 

class CMotorView : public CView

{

protected: // create from serialization only

CMotorView();

DECLARE_DYNCREATE(CMotorView)

 

// Attributes

public:

CMotorDoc* GetDocument();

 

// Operations

public:

 

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CMotorView)

public:

virtual void OnDraw(CDC* pDC); // overridden to draw this view

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

protected:

//}}AFX_VIRTUAL

 

// Implementation

public:

int round(double z0);

void FindPointC();

void FindPointD();

void FindPointE();

void LeadOutParameters();

void Background();

void DRAW();

virtual ~CMotorView();

#ifdef _DEBUG

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const;

#endif

 

protected:

 

// Generated message map functions

protected:

//{{AFX_MSG(CMotorView)

afx_msg void OnInitial();

afx_msg void OnPrevious();

afx_msg void OnNext();

afx_msg void OnParameters();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

 

};

 

#ifndef _DEBUG // debug version in MotorView.cpp

inline CMotorDoc* CMotorView::GetDocument()

{ return (CMotorDoc*)m_pDocument; }

#endif

 

 

/////////////////////////////////////////////////////////////////////////////

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_MOTORVIEW_H__A8B4D01E_53BF_497B_A76C_7053B3C035FB__INCLUDED_)

 

MotorView.cpp

 

// MotorView.cpp : implementation of the CMotorView class

//

 

#include "stdafx.h"

#include "Motor.h"

 

#include "MotorDoc.h"

#include "MotorView.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

#define PI 3.1415

#define mn 4 // множитель

#include "math.h"

#include "DlgParameters.h"

 

/////////////////////////////////////////////////////////////////////////////

// CMotorView

 

IMPLEMENT_DYNCREATE(CMotorView, CView)

 

BEGIN_MESSAGE_MAP(CMotorView, CView)

//{{AFX_MSG_MAP(CMotorView)

ON_COMMAND(ID_INITIAL, OnInitial)

ON_COMMAND(ID_PREVIOUS, OnPrevious)

ON_COMMAND(ID_NEXT, OnNext)

ON_COMMAND(ID_PARAMETERS, OnParameters)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

/////////////////////////////////////////////////////////////////////////////

// CMotorView construction/destruction

 

CMotorView::CMotorView()

{

// TODO: add construction code here

 

}

 

CMotorView::~CMotorView()

{

}

 

BOOL CMotorView::PreCreateWindow(CREATESTRUCT& cs)

{

// TODO: Modify the Window class or styles here by modifying

// the CREATESTRUCT cs

 

return CView::PreCreateWindow(cs);

}

 

/////////////////////////////////////////////////////////////////////////////

// CMotorView drawing

 

void CMotorView::OnDraw(CDC* pDC)

{

CMotorDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

// TODO: add draw code for native data here

Background();

LeadOutParameters();

DRAW();

}

 

/////////////////////////////////////////////////////////////////////////////

// CMotorView diagnostics

 

#ifdef _DEBUG

void CMotorView::AssertValid() const

{

CView::AssertValid();

}

 

void CMotorView::Dump(CDumpContext& dc) const

{

CView::Dump(dc);

}

 

CMotorDoc* CMotorView::GetDocument() // non-debug version is inline

{

ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMotorDoc)));

return (CMotorDoc*)m_pDocument;

}

#endif //_DEBUG

 

/////////////////////////////////////////////////////////////////////////////

// CMotorView message handlers

 

// *************************************************** // Variables // *** //

int Ox=200, Oy=250, // Координаты точки A

Bx, By, // Координаты точки B

Cx, Cy,

Dx, Dy,

Ex, Ey,

AB = 6 * mn, // Длина звена AB

BC = 35 * mn, // Длина звена BC

BD = 3 * mn,

DE = 32 * mn,

ACx, ACy, // Координаты второй точки кулисы 1

AEx, AEy;

double

a01 = 32.5 * PI/180, // Угол наклона кулисы 1 к горизонтали

a02 = 327.5 * PI/180,

a = 0 * PI/180, // Угол наклона кривошипа

CBD = 75 * PI/180; // Угол между звеньями CB и BD

POINT

KC[4], // 4-е точки, по которым рисуется камень С

KE[4];

int dK=13; // 2*dK - диагональ камня

double aK=PI/6; // 2*aK - угол между диагоналями камня

 

// **************************************************** // Functions // *** //

int CMotorView::round(double z0)

{ //

int z;

double z1 = ceil(fabs(z0));

double r = z1 - fabs(z0);

if ((r<=0.5)&(z0>=0)) z0 = (ceil(z0));

if ((r<=0.5)&(z0<0)) z0 = (floor(z0));

return z = (int)z0;

}

// Функция round() округляет число вещественного типа до целой части,

// конвертируя, таким образом, число типа double в число типа int.

// ************************************************************************ //

void CMotorView::FindPointC()

{

double AC;

double fi;

if ((a>a01)&(a<(a01+PI)))

fi = a - a01;

else

fi = a01 - a;

AC = AB*cos(fi)+pow(BC*BC-AB*AB*sin(fi)*sin(fi),0.5);

Cx = Ox + round(cos(a01)*AC);

Cy = Oy - round(sin(a01)*AC);

}

// Функция FindPointC() находит координаты точки C механизма.

// ************************************************************************ //

void CMotorView::FindPointD()

{

double CD, b, psi, fi0 = a-a01;

b = asin(AB*sin(fi0)/BC);

CD = pow(BD*BD+BC*BC-2*BD*BC*cos(CBD),0.5);

psi = a01 - b + asin(BD*sin(CBD)/CD);

Dx = Cx - round(cos(psi)*CD);

Dy = Cy + round(sin(psi)*CD);

}

// Функция FindPointD() находит координаты точки D механизма.

// ************************************************************************ //

void CMotorView::FindPointE()

{

int Ae, AD, De, ex, ey;

AD = round(pow(pow(Dx-Ox,2)+pow(Dy-Oy,2),0.5));

for (Ae=DE-AD; De<DE; Ae++)

{

ex = Ox + round(Ae*cos(-a02));

ey = Oy + round(Ae*sin(-a02));

De = round(pow(pow(ex-Dx,2)+pow(ey-Dy,2),0.5));

}

Ex = ex;

Ey = ey;

}

// Функция FindPointE() находит координаты точки E механизма.

// ************************************************************************ //

10àvoid CMotorView::LeadOutParameters()

{

CClientDC dc(this);

CPen newpen;

CPen* oldpen;

CBrush newbrush;

CBrush* oldbrush;

newpen.CreatePen(PS_DASHDOT,3,RGB(123,123,123));

newbrush.CreateHatchBrush(PS_DASHDOTDOT,RGB(255,255,255));

oldpen = dc.SelectObject(&newpen);

oldbrush = dc.SelectObject(&newbrush);

 

dc.Rectangle(5, 5, 135, 140);

 

int ky=20, kx=15;

CString str, strout;

char length[2], angle[3];

 

gcvt(AB/mn, 2 , length); // Выводит

str = length; // значение

strout = "length AB = " + str; // длины

dc.TextOut(kx, 1*ky, strout); // звена AB

 

gcvt(BC/mn, 2 , length); // Выводит

str = length; // значение

strout = "length BC = " + str; // длины

dc.TextOut(kx, 2*ky, strout); // звена BC

 

if (BD==0) //

strout = "length BD = 0"; //

else //

{ //

gcvt(BD/mn, 2 , length); //

str = length; // Выводит

strout = "length BD = " + str; // значение

} // длины

dc.TextOut(kx, 3*ky, strout); // звена BD

 

gcvt(DE/mn, 2 , length); // Выводит

str = length; // значение

strout = "length DE = " + str; // длины

dc.TextOut(kx, 4*ky, strout); // звена DE

 

if (CBD==0) //

strout = "angle CBD = 0"; //

else //

{ //

gcvt(CBD*180/PI, 3 , angle); //

str = angle; //

strout = "angle CBD = " + str; // Выводит

} // значение

dc.TextOut(kx, 5*ky, strout); // угла CBD

}

// Функция LeadOutParameters() выводит на экран текущие значения параметров.

// ************************************************************************ //

11àvoid CMotorView::Background()

{

CClientDC dc(this);

CPen newpen;

CPen* oldpen;

CBrush newbrush;

CBrush* oldbrush;

newbrush.CreateHatchBrush(PS_DASHDOTDOT,RGB(255,255,0));

newpen.CreatePen(PS_SOLID,0,RGB(255,255,255));

oldpen = dc.SelectObject(&newpen);

oldbrush = dc.SelectObject(&newbrush);

dc.Rectangle(0, 0, 3000, 2000);

}

// Функция Background() закрашивает всю часть экрана желтым фоном

// ************************************************************************ //

void CMotorView::DRAW()

{

Bx = Ox + round(cos(a)*AB);

12à By = Oy - round(sin(a)*AB);

FindPointC();

FindPointD();

FindPointE();

 

CClientDC dc(this);

CPen newpen1, newpen2, newpen3;

CPen* oldpen;

CBrush newbrush;

13à CBrush* oldbrush;

newpen1.CreatePen(PS_SOLID,2,RGB(0,0,0));

newpen2.CreatePen(PS_SOLID,0,RGB(255,255,255));

newpen3.CreatePen(PS_SOLID,0,RGB(0,0,0));

newbrush.CreateHatchBrush(PS_DASHDOT, RGB(0,0,0));

 

oldpen = dc.SelectObject(&newpen3);

 

// Кулиса

ACx = Ox + round(cos(a01)*(AB+BC+50));

ACy = Oy - round(sin(a01)*(AB+BC+50));

AEx = Ox + round(cos(a02)*(AB+BD+DE+50));

14à AEy = Oy - round(sin(a02)*(AB+BD+DE+50));

 

dc.MoveTo(Ox, Oy);

dc.LineTo(ACx, ACy);

 

dc.MoveTo(Ox, Oy);

dc.LineTo(AEx, AEy);

 

//Стойка

oldbrush = dc.SelectObject(&newbrush);

oldpen = dc.SelectObject(&newpen2);

 

dc.Rectangle(Ox-14, Oy+12, Ox+14, Oy+23);

 

15à oldpen = dc.SelectObject(&newpen1);

 

dc.MoveTo(Ox, Oy);

dc.LineTo(Ox-7, Oy+12);

dc.MoveTo(Ox, Oy);

dc.LineTo(Ox+7, Oy+12);

dc.MoveTo(Ox-12, Oy+12);

dc.LineTo(Ox+12, Oy+12);

 

// Камень

oldpen = dc.SelectObject(&newpen1);

dc.SelectStockObject(PS_SOLID);

 

KC[0].x=Cx+round(cos(a01+aK)*dK); KC[0].y=Cy-round(sin(a01+aK)*dK);

KC[1].x=Cx+round(cos(a01+PI-aK)*dK); KC[1].y=Cy-round(sin(a01+PI-aK)*dK);

KC[2].x=Cx+round(cos(a01+PI+aK)*dK); KC[2].y=Cy-round(sin(a01+PI+aK)*dK);

16à KC[3].x=Cx+round(cos(a01-aK)*dK); KC[3].y=Cy-round(sin(a01-aK)*dK);

 

KE[0].x=Ex+round(cos(a02+aK)*dK); KE[0].y=Ey-round(sin(a02+aK)*dK);

KE[1].x=Ex+round(cos(a02+PI-aK)*dK); KE[1].y=Ey-round(sin(a02+PI-aK)*dK);

KE[2].x=Ex+round(cos(a02+PI+aK)*dK); KE[2].y=Ey-round(sin(a02+PI+aK)*dK);

KE[3].x=Ex+round(cos(a02-aK)*dK); KE[3].y=Ey-round(sin(a02-aK)*dK);

 

dc.Polygon(KC,4);

dc.Polygon(KE,4);

 

//Звенья

dc.MoveTo(Bx, By);

dc.LineTo(Ox, Oy);

dc.MoveTo(Bx, By);

dc.LineTo(Cx, Cy);

17à dc.MoveTo(Bx, By);

dc.LineTo(Dx, Dy);

dc.MoveTo(Dx, Dy);

dc.LineTo(Cx, Cy);

dc.MoveTo(Dx, Dy);

dc.LineTo(Ex, Ey);

 

//Шарниры

dc.Ellipse(Ox-3, Oy-3, Ox+3, Oy+3);

18à dc.Ellipse(Bx-3, By-3, Bx+3, By+3);

dc.Ellipse(Cx-3, Cy-3, Cx+3, Cy+3);

dc.Ellipse(Dx-3, Dy-3, Dx+3, Dy+3);

dc.Ellipse(Ex-3, Ey-3, Ex+3, Ey+3);

}

 

19àvoid CMotorView::OnInitial()

{

// TODO: Add your command handler code here

a = 0;

Background();

LeadOutParameters();

DRAW();

}

 

20àvoid CMotorView::OnPrevious()

{

// TODO: Add your command handler code here

if (a==2*PI) a = 0;

a += 15 * PI/180;

Background();

LeadOutParameters();

DRAW();

}

 

21àvoid CMotorView::OnNext()

{

// TODO: Add your command handler code here

if (a==2*PI) a = 0;

a -= 15 * PI/180;

Background();

LeadOutParameters();

DRAW();

}

 

void CMotorView::OnParameters()

{

// TODO: Add your command handler code here

DlgParameters dlg; // Объявление класса в данной функции

 

dlg.m_AB = round(AB/mn);

dlg.m_BC = round(BC/mn);

22à dlg.m_BD = round(BD/mn);

dlg.m_DE = round(DE/mn);

dlg.m_CBD = CBD*180/PI;

 

23à if (dlg.DoModal()==IDOK)

{

if (dlg.m_AB<4) dlg.m_AB = 4;

if (dlg.m_AB>20) dlg.m_AB = 20;

24à if (dlg.m_BC<8) dlg.m_BC = 8;

if (dlg.m_BC>60) dlg.m_BC = 60;

if (dlg.m_BC<2*dlg.m_AB) dlg.m_BC = 2 * dlg.m_AB;

if (dlg.m_BD<0) dlg.m_BD = 0;

if (dlg.m_BD>15) dlg.m_BD = 15;

24à if (dlg.m_DE<8) dlg.m_DE = 8;

if (dlg.m_DE>60) dlg.m_DE = 60;

if (dlg.m_DE<=(dlg.m_AB+dlg.m_BD))

dlg.m_DE = dlg.m_AB + dlg.m_BD + 1;

 

AB = dlg.m_AB * mn;

BC = dlg.m_BC * mn;

25à BD = dlg.m_BD * mn;

DE = dlg.m_DE * mn;

CBD = dlg.m_CBD * PI/180;

 

int N = dlg.m_N;

double aN = 2*PI/N;

a = 0;

Background();

26à for (int i=0; i<N; i++)

{

a += aN;

LeadOutParameters();

DRAW();

}

}

}

 

DlgParameters.h

#if !defined(AFX_DLGPARAMETERS_H__CF02508E_52A9_459C_B81B_F6A4005AC30B__INCLUDED_)

#define AFX_DLGPARAMETERS_H__CF02508E_52A9_459C_B81B_F6A4005AC30B__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

// DlgParameters.h : header file

//

 

/////////////////////////////////////////////////////////////////////////////

// DlgParameters dialog

 

class DlgParameters : public CDialog

{

// Construction

public:

DlgParameters(CWnd* pParent = NULL); // standard constructor

 

// Dialog Data

//{{AFX_DATA(DlgParameters)

enum { IDD = IDD_DLG_PARAMETERS };

int m_AB;

int m_BC;

int m_BD;

27à double m_CBD;

int m_DE;

int m_N;

//}}AFX_DATA

 

 

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(DlgParameters)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

 

// Implementation

protected:

 

// Generated message map functions

//{{AFX_MSG(DlgParameters)

afx_msg void OnButtonData();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_DLGPARAMETERS_H__CF02508E_52A9_459C_B81B_F6A4005AC30B__INCLUDED_)

 

DlgParameters.cpp

 

// DlgParameters.cpp : implementation file

//

 

#include "stdafx.h"

#include "Motor.h"

#include "DlgParameters.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

/////////////////////////////////////////////////////////////////////////////

// DlgParameters dialog

 

 

DlgParameters::DlgParameters(CWnd* pParent /*=NULL*/)

: CDialog(DlgParameters::IDD, pParent)

{

//{{AFX_DATA_INIT(DlgParameters)

m_AB = 6;

m_BC = 35;

28à m_BD = 3;

m_CBD = 75.0;

m_DE = 32;

m_N = 1;

//}}AFX_DATA_INIT

}

 

 

void DlgParameters::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(DlgParameters)

DDX_Text(pDX, IDC_EDIT_AB, m_AB);

DDX_Text(pDX, IDC_EDIT_BC, m_BC);

DDX_Text(pDX, IDC_EDIT_BD, m_BD);

DDX_Text(pDX, IDC_EDIT_CBD, m_CBD);

DDX_Text(pDX, IDC_EDIT_DE, m_DE);

DDX_Text(pDX, IDC_EDIT_N, m_N);

DDV_MinMaxInt(pDX, m_N, 1, 36);

//}}AFX_DATA_MAP

}

 

 

BEGIN_MESSAGE_MAP(DlgParameters, CDialog)

//{{AFX_MSG_MAP(DlgParameters)

ON_BN_CLICKED(IDC_BUTTON_DATA, OnButtonData)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

/////////////////////////////////////////////////////////////////////////////

// DlgParameters message handlers

 

29àvoid DlgParameters::OnButtonData()

{

// TODO: Add your control notification handler code here

UpdateData(true);

m_AB = 6;

m_BC = 35;

m_BD = 3;

m_DE = 32;

m_N = 1;

m_CBD = 75.;

UpdateData(false);

}

 


Пояснение сносок