mfc_speed_1 - 8BitsCoding/RobotMentor GitHub Wiki
λλ§μ 컨νΈλ‘€ μμ±
CWndμ ProgressStatusWnd μμ±
// Dlg.h
#include "ProgressStatusWnd.h"
// ...
ProgressStatusWnd m_status_wnd;
BOOL CMFCApplication1Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// μ΄ λν μμμ μμ΄μ½μ μ€μ ν©λλ€. μμ© νλ‘κ·Έλ¨μ μ£Ό μ°½μ΄ λν μμκ° μλ κ²½μ°μλ
// νλ μμν¬κ° μ΄ μμ
μ μλμΌλ‘ μνν©λλ€.
SetIcon(m_hIcon, TRUE); // ν° μμ΄μ½μ μ€μ ν©λλ€.
SetIcon(m_hIcon, FALSE); // μμ μμ΄μ½μ μ€μ ν©λλ€.
// TODO: μ¬κΈ°μ μΆκ° μ΄κΈ°ν μμ
μ μΆκ°ν©λλ€.
m_status_wnd.Create(NULL, NULL, WS_CHILD | WS_VISIBLE | WS_BORDER, CRect(0, 0, 100, 100), this, 2005);
return TRUE; // ν¬μ»€μ€λ₯Ό 컨νΈλ‘€μ μ€μ νμ§ μμΌλ©΄ TRUEλ₯Ό λ°νν©λλ€.
}
μ’νλ₯Ό Picture CtrlμΌλ‘ λ°μ보μ.
BOOL CMFCApplication1Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// μ΄ λν μμμ μμ΄μ½μ μ€μ ν©λλ€. μμ© νλ‘κ·Έλ¨μ μ£Ό μ°½μ΄ λν μμκ° μλ κ²½μ°μλ
// νλ μμν¬κ° μ΄ μμ
μ μλμΌλ‘ μνν©λλ€.
SetIcon(m_hIcon, TRUE); // ν° μμ΄μ½μ μ€μ ν©λλ€.
SetIcon(m_hIcon, FALSE); // μμ μμ΄μ½μ μ€μ ν©λλ€.
// TODO: μ¬κΈ°μ μΆκ° μ΄κΈ°ν μμ
μ μΆκ°ν©λλ€.
CRect r;
GetDlgItem(IDC_STATIC_RECT)->GetWindowRect(r);
ScreenToClient(r);
m_status_wnd.CreateEx(WS_EX_STATICEDGE, NULL, NULL, WS_CHILD | WS_VISIBLE, r, this, 2005);
return TRUE; // ν¬μ»€μ€λ₯Ό 컨νΈλ‘€μ μ€μ νμ§ μμΌλ©΄ TRUEλ₯Ό λ°νν©λλ€.
}
κΈ°λ³Έμ λ€λͺ¨ 그리기
// ProgressStatusWnd.h
CImage m_draw_image;
CDC m_draw_dc;
int ProgressStatusWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
CRect r;
GetClientRect(r);
m_draw_image.Create(r.Width(), r.Height(), 32);
m_draw_dc.Attach(m_draw_image.GetDC());
for (int y = 0; y < Y_COUNT; y++) {
for (int x = 0; x < X_COUNT; x++) {
m_draw_dc.Rectangle(x * WIDTH, y * HEIGHT, (x + 1)*WIDTH, (y + 1)*HEIGHT);
}
}
return 0;
}
void ProgressStatusWnd::OnDestroy()
{
CWnd::OnDestroy();
m_draw_dc.DeleteDC();
m_draw_image.ReleaseDC();
m_draw_image.Destroy();
}
void ProgressStatusWnd::OnPaint()
{
CPaintDC dc(this);
m_draw_image.Draw(dc, 0, 0);
}
λ€λͺ¨μ μμ λ£κΈ°
// ProgressStatusWnd.h
CBrush m_normal_brush, m_error_brush, m_no_data_brush;
CPen m_nomal_pen, m_error_pen, m_no_data_pen;
int ProgressStatusWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
CRect r;
GetClientRect(r);
m_draw_image.Create(r.Width(), r.Height(), 32);
m_draw_dc.Attach(m_draw_image.GetDC());
m_normal_brush.CreateSolidBrush(RGB(0, 255, 128));
m_error_brush.CreateSolidBrush(RGB(255, 0, 128));
m_no_data_brush.CreateSolidBrush(RGB(64, 64, 64));
m_normal_pen.CreatePen(PS_SOLID, 1, RGB(0, 200, 100));
m_error_pen.CreatePen(PS_SOLID, 1, RGB(200, 0, 100));
m_no_data_pen.CreatePen(PS_SOLID, 1, RGB(192, 192, 192));
m_draw_dc.SelectObject(&m_no_data_brush);
m_draw_dc.SelectObject(&m_no_data_pen);
for (int y = 0; y < Y_COUNT; y++) {
for (int x = 0; x < X_COUNT; x++) {
m_draw_dc.Rectangle(x * WIDTH, y * HEIGHT, (x + 1)*WIDTH, (y + 1)*HEIGHT);
}
}
return 0;
}
yμΆμ 보μ¬μ§λ κ°μλ§ κ·Έλ¦¬κΈ°
int ProgressStatusWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
CRect r;
GetClientRect(r);
m_draw_image.Create(r.Width(), r.Height(), 32);
m_draw_dc.Attach(m_draw_image.GetDC());
m_normal_brush.CreateSolidBrush(RGB(0, 255, 128));
m_error_brush.CreateSolidBrush(RGB(255, 0, 128));
m_no_data_brush.CreateSolidBrush(RGB(64, 64, 64));
m_normal_pen.CreatePen(PS_SOLID, 1, RGB(0, 200, 100));
m_error_pen.CreatePen(PS_SOLID, 1, RGB(200, 0, 100));
m_no_data_pen.CreatePen(PS_SOLID, 1, RGB(192, 192, 192));
m_draw_dc.SelectObject(&m_no_data_brush);
m_draw_dc.SelectObject(&m_no_data_pen);
m_display_y_count = r.Height() / HEIGHT;
for (int y = 0; y < m_display_y_count; y++) {
for (int x = 0; x < X_COUNT; x++) {
m_draw_dc.Rectangle(x * WIDTH, y * HEIGHT, (x + 1)*WIDTH, (y + 1)*HEIGHT);
}
}
return 0;
}
νμ§λ§ μκ·Έλ €μ§λ λΆλΆμ΄ μκΈ΄λ€.
m_display_y_count = r.Height() / HEIGHT;
if (r.Height() % HEIGHT) m_display_y_count++;
λ°μ΄ν° μ½μ νκΈ°
μμ λ²νΌμ ν΅ν΄μ λ°μ΄ν° μ½μ μμ
void CMFCApplication1Dlg::OnBnClickedStartBtn()
{
SetTimer(1, 30, NULL);
m_pos_progress.SetPos(0);
}
void CMFCApplication1Dlg::OnBnClickedEndBtn()
{
KillTimer(1);
}
void CMFCApplication1Dlg::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == 1) {
m_pos_progress.OffsetPos(1);
if (0 == m_status_wnd.SetData(rand() % 100)) {
// μμ μ μλ λ©λͺ¨λ¦¬λ₯Ό μ΄κ³Ό
OnBnClickedEndBtn();
MessageBox(L"μμ
μ΄ μλ£λμμ΅λλ€.", L"μμ
μλ£", MB_ICONINFORMATION);
}
}
CDialogEx::OnTimer(nIDEvent);
}
// ProgressStatusWnd.h
struct ProgressData
{
int data;
int status; // 0 λ―Έμ²λ¦¬, 1 μ μ, 2 μ€λ₯
};
//...
int m_display_y_count, m_count = 0;
//ProgressData **mp_data;
ProgressData *mp_data;
int ProgressStatusWnd::SetData(int a_data)
{
if (m_count < X_COUNT * Y_COUNT) {
(mp_data + m_count)->data = a_data;
if (a_data > 3 && a_data << 97) {
// Error μμ
(mp_data + m_count)->status = 1;
}
else {
// Error
(mp_data + m_count)->status = 2;
}
m_count++;
return 1;
}
return 0;
}
int ProgressStatusWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// 2μ°¨μ λ©λͺ¨λ¦¬ ν λΉ
// mp_data = new ProgressData *[Y_COUNT];
// for (int i = 0; i < Y_COUNT; i++) *(mp_data + i) = new ProgressData[X_COUNT];
mp_data = new ProgressData [Y_COUNT*X_COUNT];
CRect r;
GetClientRect(r);
m_draw_image.Create(r.Width(), r.Height(), 32);
m_draw_dc.Attach(m_draw_image.GetDC());
m_normal_brush.CreateSolidBrush(RGB(0, 255, 128));
m_error_brush.CreateSolidBrush(RGB(255, 0, 128));
m_no_data_brush.CreateSolidBrush(RGB(64, 64, 64));
m_normal_pen.CreatePen(PS_SOLID, 1, RGB(0, 200, 100));
m_error_pen.CreatePen(PS_SOLID, 1, RGB(200, 0, 100));
m_no_data_pen.CreatePen(PS_SOLID, 1, RGB(192, 192, 192));
m_draw_dc.SelectObject(&m_no_data_brush);
m_draw_dc.SelectObject(&m_no_data_pen);
m_display_y_count = r.Height() / HEIGHT;
if (r.Height() % HEIGHT) m_display_y_count++;
for (int y = 0; y < m_display_y_count; y++) {
for (int x = 0; x < X_COUNT; x++) {
m_draw_dc.Rectangle(x * WIDTH, y * HEIGHT, (x + 1)*WIDTH, (y + 1)*HEIGHT);
}
}
return 0;
}
void ProgressStatusWnd::OnDestroy()
{
CWnd::OnDestroy();
m_draw_dc.DeleteDC();
m_draw_image.ReleaseDC();
m_draw_image.Destroy();
m_normal_brush.DeleteObject();
m_error_brush.DeleteObject();
m_no_data_brush.DeleteObject();
m_normal_pen.DeleteObject();
m_error_pen.DeleteObject();
m_no_data_pen.DeleteObject();
// for (int i = 0; i < Y_COUNT; i++) delete[] * (mp_data + i);
// delete[] mp_data;
delete[] mp_data;
}
μ½μ λ λ°μ΄ν° μ μνκΈ°
int ProgressStatusWnd::SetData(int a_data)
{
if (m_count < X_COUNT * Y_COUNT) {
(mp_data + m_count)->data = a_data;
if (a_data > 3 && a_data << 97) {
// Error μμ
(mp_data + m_count)->status = 1;
}
else {
// Error
(mp_data + m_count)->status = 2;
}
RedrawData();
m_count++;
Invalidate(FALSE);
return 1;
}
return 0;
}
void ProgressStatusWnd::RedrawData()
{
ProgressData * p = mp_data + m_count;
if (p->status == 1) {
m_draw_dc.SelectObject(&m_normal_brush);
m_draw_dc.SelectObject(&m_normal_pen);
}
else {
m_draw_dc.SelectObject(&m_error_brush);
m_draw_dc.SelectObject(&m_error_pen);
}
int y = m_count / X_COUNT, x = m_count % X_COUNT;
m_draw_dc.Rectangle(x * WIDTH, y * HEIGHT, (x + 1)*WIDTH, (y + 1)*HEIGHT);
}
μλμͺ½ λ°μ΄ν°κΉμ§ μ μ
μ°μ μμ§ μ€ν¬λ‘€ μΆκ°
BOOL CMFCApplication1Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// μ΄ λν μμμ μμ΄μ½μ μ€μ ν©λλ€. μμ© νλ‘κ·Έλ¨μ μ£Ό μ°½μ΄ λν μμκ° μλ κ²½μ°μλ
// νλ μμν¬κ° μ΄ μμ
μ μλμΌλ‘ μνν©λλ€.
SetIcon(m_hIcon, TRUE); // ν° μμ΄μ½μ μ€μ ν©λλ€.
SetIcon(m_hIcon, FALSE); // μμ μμ΄μ½μ μ€μ ν©λλ€.
// TODO: μ¬κΈ°μ μΆκ° μ΄κΈ°ν μμ
μ μΆκ°ν©λλ€.
srand((unsigned int)time(NULL));
m_pos_progress.SetRange(0, X_COUNT*Y_COUNT);
CRect r;
GetDlgItem(IDC_STATIC_RECT)->GetWindowRect(r);
ScreenToClient(r);
m_status_wnd.CreateEx(WS_EX_STATICEDGE, NULL, NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL, r, this, 2005);
return TRUE; // ν¬μ»€μ€λ₯Ό 컨νΈλ‘€μ μ€μ νμ§ μμΌλ©΄ TRUEλ₯Ό λ°νν©λλ€.
}
void ProgressStatusWnd::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if (pScrollBar == NULL) {
ProcessScroll(nSBCode, nPos, SB_VERT);
RedrawAllData();
Invalidate(FALSE);
}
CWnd::OnVScroll(nSBCode, nPos, pScrollBar);
}
void ProgressStatusWnd::ProcessScroll(UINT nSBCode, UINT nPos, int a_scroll_type)
{
if (nSBCode == SB_THUMBPOSITION || nSBCode == SB_THUMBTRACK) {
SetScrollPos(a_scroll_type, nPos);
}
else {
int scroll_pos = GetScrollPos(a_scroll_type), min = 0, max = 0;
GetScrollRange(a_scroll_type, &min, &max);
switch (nSBCode) {
case SB_LINEDOWN:
if (scroll_pos < max) SetScrollPos(a_scroll_type, ++scroll_pos);
break;
case SB_LINEUP:
if (scroll_pos < max) SetScrollPos(a_scroll_type, --scroll_pos);
break;
case SB_PAGEDOWN:
if (scroll_pos + 100 < max) SetScrollPos(a_scroll_type, scroll_pos + 100);
break;
case SB_PAGEUP:
if (scroll_pos - 100 > min) SetScrollPos(a_scroll_type, scroll_pos - 100);
break;
}
}
}
void ProgressStatusWnd::RedrawAllData()
{
int scroll_pos = GetScrollPos(SB_VERT);
ProgressData * p = mp_data + scroll_pos*X_COUNT;
for (int y = 0; y < m_display_y_count; y++) {
for (int x = 0; x < X_COUNT; x++) {
if (p->status == 1) {
m_draw_dc.SelectObject(&m_normal_brush);
m_draw_dc.SelectObject(&m_normal_pen);
}
else if(p->status==2) {
m_draw_dc.SelectObject(&m_error_brush);
m_draw_dc.SelectObject(&m_error_pen);
}
else {
m_draw_dc.SelectObject(&m_no_data_brush);
m_draw_dc.SelectObject(&m_no_data_pen);
}
m_draw_dc.Rectangle(x * WIDTH, y * HEIGHT, (x + 1)*WIDTH, (y + 1)*HEIGHT);
p++;
}
}
}
μ€ν¬λ‘€ λλ λΆλΆ μ²λ¦¬ μΆκ°
void ProgressStatusWnd::RedrawData()
{
ProgressData * p = mp_data + m_count;
if (p->status == 1) {
m_draw_dc.SelectObject(&m_normal_brush);
m_draw_dc.SelectObject(&m_normal_pen);
}
else {
m_draw_dc.SelectObject(&m_error_brush);
m_draw_dc.SelectObject(&m_error_pen);
}
int scroll_pos = GetScrollPos(SB_VERT);
int y = m_count / X_COUNT - scroll_pos, x = m_count % X_COUNT;
m_draw_dc.Rectangle(x * WIDTH, y * HEIGHT, (x + 1)*WIDTH, (y + 1)*HEIGHT);
}
λ§μ§λ§ κΉ¨μ§λ λ°μ΄ν° μ²λ¦¬
int ProgressStatusWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// 2μ°¨μ λ©λͺ¨λ¦¬ ν λΉ
// mp_data = new ProgressData *[Y_COUNT];
// for (int i = 0; i < Y_COUNT; i++) *(mp_data + i) = new ProgressData[X_COUNT];
mp_data = new ProgressData [Y_COUNT*X_COUNT];
memset(mp_data, 0, sizeof(ProgressData)*Y_COUNT*X_COUNT);
CRect r;
GetClientRect(r);
m_draw_image.Create(r.Width(), r.Height(), 32);
m_draw_dc.Attach(m_draw_image.GetDC());
m_normal_brush.CreateSolidBrush(RGB(0, 255, 128));
m_error_brush.CreateSolidBrush(RGB(255, 0, 128));
m_no_data_brush.CreateSolidBrush(RGB(64, 64, 64));
m_normal_pen.CreatePen(PS_SOLID, 1, RGB(0, 200, 100));
m_error_pen.CreatePen(PS_SOLID, 1, RGB(200, 0, 100));
m_no_data_pen.CreatePen(PS_SOLID, 1, RGB(192, 192, 192));
m_draw_dc.SelectObject(&m_no_data_brush);
m_draw_dc.SelectObject(&m_no_data_pen);
m_display_y_count = r.Height() / HEIGHT;
if (r.Height() % HEIGHT) m_display_y_count++;
SetScrollRange(SB_VERT, 0, Y_COUNT - m_display_y_count, 0); // μ¬κΈ° μΆκ°
for (int y = 0; y < m_display_y_count; y++) {
for (int x = 0; x < X_COUNT; x++) {
m_draw_dc.Rectangle(x * WIDTH, y * HEIGHT, (x + 1)*WIDTH, (y + 1)*HEIGHT);
}
}
return 0;
}
λ§μ§λ§ λ°μ―€ λμ¨ μ¬κ°ν μ²λ¦¬
void ProgressStatusWnd::RedrawAllData()
{
int scroll_pos = GetScrollPos(SB_VERT), fix_y = 0;
ProgressData * p = mp_data + scroll_pos * X_COUNT;
if (scroll_pos == (Y_COUNT - m_display_y_count)) {
CRect r;
GetClientRect(r);
if (r.Height() % HEIGHT) fix_y = 10 - r.Height() % HEIGHT;
}
else {
// λ§μ§λ§ νμ΄μ§
p = mp_data + (Y_COUNT - m_display_y_count) * X_COUNT;
}
for (int y = 0; y < m_display_y_count; y++) {
for (int x = 0; x < X_COUNT; x++) {
if (p->status == 1) {
m_draw_dc.SelectObject(&m_normal_brush);
m_draw_dc.SelectObject(&m_normal_pen);
}
else if(p->status==2) {
m_draw_dc.SelectObject(&m_error_brush);
m_draw_dc.SelectObject(&m_error_pen);
}
else {
m_draw_dc.SelectObject(&m_no_data_brush);
m_draw_dc.SelectObject(&m_no_data_pen);
}
m_draw_dc.Rectangle(x * WIDTH, y * HEIGHT - fix_y, (x + 1)*WIDTH, (y + 1)*HEIGHT - fix_y);
p++;
}
}
}
μλ μ€ν¬λ‘€ κΈ°λ₯ μΆκ°
void CMFCApplication1Dlg::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == 1) {
m_pos_progress.OffsetPos(1);
if (0 == m_status_wnd.SetData(rand() % 100, m_cur_pos_check.GetCheck())) {
// μμ μ μλ λ©λͺ¨λ¦¬λ₯Ό μ΄κ³Ό
OnBnClickedEndBtn();
MessageBox(L"μμ
μ΄ μλ£λμμ΅λλ€.", L"μμ
μλ£", MB_ICONINFORMATION);
}
}
CDialogEx::OnTimer(nIDEvent);
}
int ProgressStatusWnd::SetData(int a_data, int a_cur_pos_check)
{
if (m_count < X_COUNT * Y_COUNT) {
(mp_data + m_count)->data = a_data;
if (a_data > 3 && a_data << 97) {
// Error μμ
(mp_data + m_count)->status = 1;
}
else {
// Error
(mp_data + m_count)->status = 2;
}
if (a_cur_pos_check == 1 && !((m_count + 1) % X_COUNT)) {
MoveCurrentPos();
}
RedrawData();
m_count++;
Invalidate(FALSE);
return 1;
}
return 0;
}
void ProgressStatusWnd::MoveCurrentPos()
{
int scroll_pos = GetScrollPos(SB_VERT);
int y = (m_count + 1) / X_COUNT;
if (y < scroll_pos || y >= scroll_pos + m_display_y_count - 1) {
int new_pos = y - 2;
int max, min;
GetScrollRange(SB_VERT, &min, &max);
if (new_pos < min) new_pos = min;
else if (new_pos > max) new_pos = max;
if (scroll_pos != new_pos) {
SetScrollPos(SB_VERT, new_pos);
RedrawAllData();
}
}
}
μμλ²νΌμ λλ₯΄λ©΄ νμ¬ κ°±μ μ€μΈ λ°μ΄ν° μ μ
void CMFCApplication1Dlg::OnBnClickedPosCheck()
{
if (m_cur_pos_check.GetCheck()) {
m_status_wnd.MoveCurrentPos();
m_status_wnd.Invalidate(FALSE);
}
}