- •Спецификация
- •Постановка цели, задач и описание предметной области
- •Формализованное словесное описание алгоритма решения задачи
- •Варианты взаимодействия программы и оператора (Use Case)
- •Разработка дружественного интерфейса
- •Блок-схема движения данных (Data flow diagram)
- •Выбор и обоснование типов переменных, разработка структур данных
- •Вводимые и выводимые параметры и их типы
- •Диаграмма классов
- •Структура проекта, перечисление нужных файлов
- •Инструкция по использованию
- •Текст программы и файлов заголовков с комментариями.
- •Копии экрана при работе программы
- •Контрольный пример, сравнение результата с эталоном (MathCad)
- •Ведомость соответствия программы спецификации
Текст программы и файлов заголовков с комментариями.
Graphic.h
// Graphic.h : main header file for the PROJECT_NAME application
//
#pragma once
#ifndef __AFXWIN_H__
#error "include 'stdafx.h' before including this file for PCH"
#endif
#include "Resource.h" // main symbols
// CGraphicApp:
// See Graphic.cpp for the implementation of this class
//
class CGraphicApp : public CWinApp
{
public:
CGraphicApp();
// Overrides
public:
virtual BOOL InitInstance();
// Implementation
DECLARE_MESSAGE_MAP()
};
extern CGraphicApp theApp;
GraphicDlg.h
#pragma once
#include "MyPaint.h"
#include "MyCalc.h"
// CGraphicDlg dialog
class CGraphicDlg : public CDialogEx
{
// Construction
public:
CGraphicDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_GRAPHIC_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
CMyPaint m_Graph; //переменная графика
CMyCalc m_Calc; //переменная класса СMyCalc
CString SR; //переменная поля ввода R
CString Sr; //переменная поля ввода r
CString SScale; //переменная поля ввода масштаба
afx_msg void OnTimer(UINT_PTR nIDEvent);
virtual BOOL OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult);
double m_R, m_r, m_a, m_X, m_Y; // переменные структуры
CSliderCtrl m_Slider; //переменная ползунка
int m_DrawSpd; //переменная скорости отрисовки
afx_msg void OnBnClickedButton1();
CString SdX; //переменная поля ввода X
CString SdY; //переменная поля ввода Y
afx_msg void OnNMCustomdrawSlider1(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnBnClickedButton2();
afx_msg void OnBnClickedOk2();
afx_msg void OnBnClickedButton3();
};
MyCalc.h
#pragma once
#include <vector>
typedef struct
{
double xMax; // максимальная координата x
int nPoints; // точки в графике
int yCenter;//центр y
int xCenter;//центр x
int yMax;//максимальная координата y
int R;//радиус большой окружности
int r;//радиус катящейся окружности
double fi0;//начальный угол
double fiMax;//конечный угол
double a;//переменная масштаба
double dfi;//малый угол
double m;//параметр
int current;//счетчик точек
double dX;//сдвиг по Х
double dY;//сдвиг по У
}MyParams_t;
class CMyCalc
{
public:
CMyCalc();
~CMyCalc();
public:
MyParams_t m_Param;//переменная структуры
int GetPoints(std::vector<CPoint> & vecPt);
bool SetParams(MyParams_t par);
};
MyPaint.h
#pragma once
// CMyPaint
class CMyPaint : public CStatic
{
DECLARE_DYNAMIC(CMyPaint)
public:
CMyPaint();
virtual ~CMyPaint();
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnPaint();
public:
size_t m_Npt;//количество точек
bool m_click; //логическая переменная срабатывания рисовки
};
BOOL CaptureScreen(CString strPath, CWnd *pWnd);
Graphic.cpp
// Graphic.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "Graphic.h"
#include "GraphicDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CGraphicApp
BEGIN_MESSAGE_MAP(CGraphicApp, CWinApp)
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()
// CGraphicApp construction
CGraphicApp::CGraphicApp()
{
// support Restart Manager
m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
// The one and only CGraphicApp object
CGraphicApp theApp;
// CGraphicApp initialization
BOOL CGraphicApp::InitInstance()
{
// InitCommonControlsEx() is required on Windows XP if an application
// manifest specifies use of ComCtl32.dll version 6 or later to enable
// visual styles. Otherwise, any window creation will fail.
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// Set this to include all the common control classes you want to use
// in your application.
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
AfxEnableControlContainer();
// Create the shell manager, in case the dialog contains
// any shell tree view or shell list view controls.
CShellManager *pShellManager = new CShellManager;
// Activate "Windows Native" visual manager for enabling themes in MFC controls
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need
// Change the registry key under which our settings are stored
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
CGraphicDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
else if (nResponse == -1)
{
TRACE(traceAppMsg, 0, "Warning: dialog creation failed, so application is terminating unexpectedly.\n");
TRACE(traceAppMsg, 0, "Warning: if you are using MFC controls on the dialog, you cannot #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS.\n");
}
// Delete the shell manager created above.
if (pShellManager != NULL)
{
delete pShellManager;
}
#ifndef _AFXDLL
ControlBarCleanUp();
#endif
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
GraphicDlg.cpp
// GraphicDlg.cpp : implementation file
//
#include <cstdlib>
#include "stdafx.h"
#include "Graphic.h"
#include "GraphicDlg.h"
#include "afxdialogex.h"
#define _USE_MATH_DEFINES
#include "math.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// Dialog Data
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_ABOUTBOX };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CGraphicDlg dialog
CGraphicDlg::CGraphicDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(IDD_GRAPHIC_DIALOG, pParent)
, SR(_T(""))
, Sr(_T(""))
, SScale(_T(""))
, SdX(_T(""))
, SdY(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CGraphicDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT_RB, SR);
DDX_Text(pDX, IDC_EDIT_RM, Sr);
DDX_Text(pDX, IDC_EDIT_A, SScale);
DDX_Text(pDX, IDC_EDIT_X, SdX);
DDX_Text(pDX, IDC_EDIT_Y, SdY);
}
BEGIN_MESSAGE_MAP(CGraphicDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, &CGraphicDlg::OnBnClickedButton1)
ON_WM_TIMER()
ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER1, &CGraphicDlg::OnNMCustomdrawSlider1)
ON_BN_CLICKED(IDC_BUTTON2, &CGraphicDlg::OnBnClickedButton2)
ON_BN_CLICKED(IDOK2, &CGraphicDlg::OnBnClickedOk2)
ON_BN_CLICKED(IDC_BUTTON3, &CGraphicDlg::OnBnClickedButton3)
END_MESSAGE_MAP()
// CGraphicDlg message handlers
BOOL CGraphicDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
m_Graph.SubclassDlgItem(IDC_STATIC, this);
m_Slider.SubclassDlgItem(IDC_SLIDER1, this);
m_R = 3;
CString stra;
stra.Format(_T("%4.1f"), m_R);
GetDlgItem(IDC_EDIT_RB)->SetWindowTextW(stra);
m_r = 1;
stra.Format(_T("%4.1f"), m_r);
GetDlgItem(IDC_EDIT_RM)->SetWindowTextW(stra);
m_a = 1;
stra.Format(_T("%4.1f"), m_a);
GetDlgItem(IDC_EDIT_A)->SetWindowTextW(stra);
m_X = 0;
stra.Format(_T("%4.1f"), m_X);
GetDlgItem(IDC_EDIT_X)->SetWindowTextW(stra);
m_Y = 0;
stra.Format(_T("%4.1f"), m_Y);
GetDlgItem(IDC_EDIT_Y)->SetWindowTextW(stra);
m_DrawSpd = 1;
m_Slider.SetRange(1, 10);
m_Slider.SetPos(m_DrawSpd);
return TRUE; // return TRUE unless you set the focus to a control
}
void CGraphicDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CGraphicDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CGraphicDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CGraphicDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: добавьте свой код обработчика сообщений или вызов стандартного
// TODO: добавьте свой код обработчика сообщений или вызов стандартного
CMyPaint* pG = (CMyPaint*)GetDlgItem(IDC_STATIC);
if (pG)
{
pG->m_Npt++;
pG->Invalidate();
}
CDialogEx::OnTimer(nIDEvent);
}
BOOL CGraphicDlg::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
if (message == WM_USER + 1)
KillTimer(55555);
return CDialogEx::OnWndMsg(message, wParam, lParam, pResult);
}
void CGraphicDlg::OnBnClickedButton1()
{
CString mRB,mRM,mA,mX,mY; //исключения для пустых полей ввода
GetDlgItem(IDC_EDIT_RB)->GetWindowText(mRB);
GetDlgItem(IDC_EDIT_RM)->GetWindowText(mRM);
GetDlgItem(IDC_EDIT_A)->GetWindowText(mA);
GetDlgItem(IDC_EDIT_X)->GetWindowText(mX);
GetDlgItem(IDC_EDIT_Y)->GetWindowText(mY);
if (mRB !=""&& mRM != ""&& mA != ""&& mX != ""&& mY != "")
{
CString SR; //R
CWnd* pE1 = GetDlgItem(IDC_EDIT_RB);
if (pE1)
{
pE1->GetWindowText(SR);
MyParams_t par = m_Calc.m_Param;
par.R = 20 * atof(CW2A(SR));
m_Calc.SetParams(par);
CWnd* pG = GetDlgItem(IDC_STATIC);
if (pG)
{
pG->RedrawWindow();
}
}
CString Sr; // r
CWnd* pE2 = GetDlgItem(IDC_EDIT_RM);
if (pE2)
{
pE2->GetWindowText(Sr);
MyParams_t par = m_Calc.m_Param;
par.r = 20 * atof(CW2A(Sr));
m_Calc.SetParams(par);
CWnd* pG = GetDlgItem(IDC_STATIC);
if (pG)
{
pG->RedrawWindow();
}
}
CString Sa; //A
CWnd* pE4 = GetDlgItem(IDC_EDIT_A);
if (pE4)
{
pE4->GetWindowText(Sa);
MyParams_t par = m_Calc.m_Param;
par.a = atof(CW2A(Sa));
m_Calc.SetParams(par);
CWnd* pG = GetDlgItem(IDC_STATIC);
if (pG)
{
pG->RedrawWindow();
}
}
CString SX; //X
CWnd* pE5 = GetDlgItem(IDC_EDIT_X);
if (pE5)
{
pE5->GetWindowText(SX);
MyParams_t par = m_Calc.m_Param;
par.dX = atof(CW2A(SX));
m_Calc.SetParams(par);
CWnd* pG = GetDlgItem(IDC_STATIC);
if (pG)
{
pG->RedrawWindow();
}
}
CString SY; //Y
CWnd* pE6 = GetDlgItem(IDC_EDIT_Y);
if (pE6)
{
pE6->GetWindowText(SY);
MyParams_t par = m_Calc.m_Param;
par.dY = atof(CW2A(SY));
m_Calc.SetParams(par);
CWnd* pG = GetDlgItem(IDC_STATIC);
if (pG)
{
pG->RedrawWindow();
}
}
SetTimer(55555, 100 / m_DrawSpd, NULL);
CMyPaint* pG = (CMyPaint*)GetDlgItem(IDC_STATIC);
if (pG)
{
pG->m_Npt = 0;
pG->Invalidate();
}
m_Graph.m_click = true;
}
else
{
MessageBox(L"Введите значения!");
}
}
void CGraphicDlg::OnNMCustomdrawSlider1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);
// TODO: Add your control notification handler code here
m_DrawSpd = m_Slider.GetPos();
*pResult = 0;
}
void CGraphicDlg::OnBnClickedButton2()
{
// TODO: добавьте свой код обработчика уведомлений
static TCHAR szFilter[] = _T("BMP Files (*.bmp)|*.bmp|");
CFileDialog dlg(FALSE, _T(".bmp"), NULL, 6UL, szFilter);
if (IDOK == dlg.DoModal())
{
CString strPath = dlg.GetOFN().lpstrFile;
CaptureScreen(strPath, GetDlgItem(IDC_STATIC));
}
}
void CGraphicDlg::OnBnClickedOk2()
{
SR.Empty();
Sr.Empty();
SScale.Empty();
UpdateData(FALSE);
m_Graph.m_click = false; //Перерисовать первое окно по команде с кнопки
if (m_Graph.GetSafeHwnd())
m_Graph.Invalidate();
}
void CGraphicDlg::OnBnClickedButton3()
{
MessageBox(L"Для получения правильного замкнутого графика важно вводить радиусы в отношении 3:1, с нулевой дробной частью. Все параметры ввести обязательно.");
}
MyCalc.cpp
#include "stdafx.h"
#include "MyCalc.h"
#define _USE_MATH_DEFINES
#include "math.h"
CMyCalc::CMyCalc()//входные данные геометрии окна
{
m_Param.current = 0;
m_Param.nPoints = 100;
m_Param.r = 1;
m_Param.R = 1;
m_Param.fi0 = 0;
m_Param.dfi = M_PI / 360*10 ;
m_Param.m = 4;
m_Param.fiMax = 2. * (m_Param.R / m_Param.r) * M_PI;
m_Param.a = 1.;
}
CMyCalc::~CMyCalc()
{
}
int CMyCalc::GetPoints(std::vector<CPoint> & vecPt)//Расчёт точек
{
if (m_Param.r == 0 || m_Param.R == 0)
return 1;
double k = (double)m_Param.R / m_Param.r;
bool bole = false;
int n, m;
for (n = 1; n < 100; n++)
{
for (m = 1; m < 100; m++)
{
if (m_Param.R*n == m_Param.r*m)
{
bole = true;
break;
}
}
if (bole)
break;
}
double fiMax = M_PI*m + m_Param.dfi;
m_Param.current = 0;
for (double fi = m_Param.fi0; fi <= fiMax; fi = fi + m_Param.dfi)
{
CPoint pt;
pt.x = m_Param.dX * m_Param.a + (m_Param.xCenter + m_Param.a*(m_Param.r*(k + 1.)*(cos(fi) - cos((k + 1.)*fi)/(k + 1.))));
pt.y = -m_Param.dY * m_Param.a + (m_Param.yCenter - m_Param.a* (m_Param.r*(k + 1.)*(sin(fi) - sin((k + 1.)*fi)/(k + 1.))));
vecPt.push_back(pt);
++m_Param.current;
}
return 0;
}
bool CMyCalc::SetParams(MyParams_t par)
{
m_Param = par;
return true;
}
MyPaint.cpp
// CMyPaint message handlers
void CMyPaint::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: добавьте свой код обработчика сообщений
// Не вызывать CStatic::OnPaint() для
CRect rc;
GetClientRect(&rc);
CPoint pt;
CPen pG(PS_SOLID, 2, RGB(255, 255, 255));//цвет пера
HGDIOBJ old = dc.SelectObject(pG);
std::vector<CPoint> vec;//динамический массив
CGraphicDlg *pDlg = (CGraphicDlg *)AfxGetMainWnd();
MyParams_t par = pDlg->m_Calc.m_Param;
CRgn reg;
reg.CreateRectRgn(0, 0, rc.right, rc.bottom);
dc.SelectClipRgn(®);
dc.FillSolidRect(rc, RGB(255, 192, 203));//цвет
par.yCenter = rc.Height() / 2;//центр по у
par.xCenter = rc.Width() / 2;//центр по х
par.xMax = rc.Width();//ширина
par.yMax = rc.Height();//высота
dc.MoveTo(0, par.yMax / 2);
dc.LineTo(par.xMax, par.yMax / 2);
dc.MoveTo(par.xMax / 2, 0);
dc.LineTo(par.xMax / 2, par.yMax);
pDlg->m_Calc.SetParams(par);
pDlg->m_Calc.GetPoints(vec);
//деления на осях
for (int i = 0; i < par.xMax / 2; i = i + 20 * par.a) //ось x вправо
{
dc.MoveTo(par.xMax / 2 + i, (par.yMax / 2 - 2));
dc.LineTo(par.xMax / 2 + i, (par.yMax / 2 + 3));
}
for (int i = 0; i < par.xMax / 2; i = i + 20 * par.a) //ось x влево
{
dc.MoveTo(par.xMax / 2 - i, (par.yMax / 2 - 2));
dc.LineTo(par.xMax / 2 - i, (par.yMax / 2 + 3));
}
for (int i = 0; i < par.yMax / 2; i = i + 20 * par.a) //ось y влево
{
dc.MoveTo(par.xMax / 2 - 2, (par.yMax / 2 + i));
dc.LineTo(par.xMax / 2 + 3, (par.yMax / 2 + i));
}
for (int i = 0; i < par.yMax / 2; i = i + 20 * par.a) //ось y влево
{
dc.MoveTo(par.xMax / 2 - 2, (par.yMax / 2 - i));
dc.LineTo(par.xMax / 2 + 3, (par.yMax / 2 - i));
}
CFont fon;
fon.CreateFontW(30, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, _T("Times"));
HGDIOBJ pof = dc.SelectObject(&fon);
dc.SetTextColor(RGB(75, 0, 130));
dc.SetBkMode(TRANSPARENT);
dc.SetTextAlign(TA_CENTER | TA_TOP);
dc.TextOutW(par.xMax-20, par.yCenter+10, _T("X"));
dc.TextOutW(par.xCenter+20, par.yMax-420, _T("Y"));
dc.SelectObject(old);
if (m_click == true)//Посмтроить по команде с кнопки Построить
{
if (vec.size())
{
CPen penG(PS_SOLID, 2, RGB(75, 0, 130));
HGDIOBJ old = dc.SelectObject(penG);
std::vector<CPoint>::iterator it = vec.begin();
dc.MoveTo(*it);
int nc = 0;
for (it++; it != vec.end(); it++)//Цикл отрисовки графика
{
dc.LineTo(*it);
if (m_Npt < nc++)
break;
}
if (m_Npt > par.current)
{
AfxGetMainWnd()->SendMessage(WM_USER + 1, m_Npt, vec.size());//Остановить таймер
dc.SelectObject(old);
}
}
}
}
//сохранение
BOOL CaptureScreen(CString strPath, CWnd *pWnd)
{
CImage image;
CRect rect;
BOOL bStat;
ASSERT(pWnd);
if (pWnd == NULL)
return FALSE;
CWindowDC winDC(pWnd);
pWnd->GetWindowRect(&rect);
int nBPP = winDC.GetDeviceCaps(BITSPIXEL) * winDC.GetDeviceCaps(PLANES);
if (nBPP < 24) nBPP = 24;
bStat = image.Create(rect.Width(), rect.Height(), nBPP);
ASSERT(bStat);
if (!bStat)
return FALSE;
CImageDC imageDC(image);
::BitBlt(imageDC, 0, 0, rect.Width(), rect.Height(), winDC, 0, 0, SRCCOPY);
HRESULT hr;
CString strFull = strPath;
if (-1 != strFull.Find(_T(".bmp")))
hr = image.Save(strFull, ImageFormatBMP);
if (FAILED(hr))
{
TRACE(" Couldn't Save File: %s, %x ", (LPCTSTR)strFull, hr);
return FALSE;
}
return TRUE;
}