Изменение параметров механизма с помощью диалогового окна
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();
1à 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
2à #define mn 4 // множитель
#include "math.h"
3à#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();
4à 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
5à 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
5à KC[4], // 4-е точки, по которым рисуется камень С
KE[4];
int dK=13; // 2*dK - диагональ камня
double aK=PI/6; // 2*aK - угол между диагоналями камня
// **************************************************** // Functions // *** //
6à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.
// ************************************************************************ //
7à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 механизма.
// ************************************************************************ //
8à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 механизма.
// ************************************************************************ //
9à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);
}
Пояснение сносок