Skip to content

Instantly share code, notes, and snippets.

@tkojitu
Last active October 18, 2021 04:46
Show Gist options
  • Save tkojitu/d4f96f0a13af9786e936bea489e9100e to your computer and use it in GitHub Desktop.
Save tkojitu/d4f96f0a13af9786e936bea489e9100e to your computer and use it in GitHub Desktop.
#include "pch.h"
#include "framework.h"
#include "DoubleBuffering.h"
#include "DoubleBufferingDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
BEGIN_MESSAGE_MAP(CDoubleBufferingApp, CWinApp)
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()
CDoubleBufferingApp::CDoubleBufferingApp() : m_rect(CRect(0, 0, 10, 10))
{
}
CDoubleBufferingApp theApp;
BOOL CDoubleBufferingApp::InitInstance()
{
CWinApp::InitInstance();
SetRegistryKey(_T("MyApp"));
CDoubleBufferingDlg* dlg = new CDoubleBufferingDlg(this);
m_pMainWnd = dlg;
dlg->Create(IDD_DOUBLEBUFFERING_DIALOG);
dlg->ShowWindow(SW_SHOW);
return DoLoop();
}
BOOL CDoubleBufferingApp::DoLoop()
{
MSG msg;
BOOL ret;
while ((ret = GetMessage(&msg, nullptr, 0, 0)) != 0) {
if (ret == -1)
continue;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (BOOL)msg.wParam;
}
void CDoubleBufferingApp::StartAnimation()
{
GetDlg()->StartAnimation();
}
void CDoubleBufferingApp::StopAnimation()
{
GetDlg()->StopAnimation();
}
CDoubleBufferingDlg* CDoubleBufferingApp::GetDlg()
{
return (CDoubleBufferingDlg*)m_pMainWnd;
}
void CDoubleBufferingApp::MoveRect(CRect client_rect)
{
m_rect.OffsetRect(10, 10);
if (m_rect.top > client_rect.bottom)
m_rect.MoveToY(0);
if (m_rect.left > client_rect.right)
m_rect.MoveToX(0);
GetDlg()->Invalidate();
GetDlg()->UpdateWindow();
}
CRect CDoubleBufferingApp::GetRect()
{
return m_rect;
}
#pragma once
#include "resource.h"
class CDoubleBufferingDlg;
class CDoubleBufferingApp : public CWinApp
{
public:
CDoubleBufferingApp();
virtual ~CDoubleBufferingApp() {}
virtual BOOL InitInstance();
virtual void MoveRect(CRect client_rect);
virtual CRect GetRect();
virtual void StartAnimation();
virtual void StopAnimation();
private:
virtual CDoubleBufferingDlg* GetDlg();
virtual BOOL DoLoop();
private:
CRect m_rect;
DECLARE_MESSAGE_MAP()
};
extern CDoubleBufferingApp theApp;
#include "pch.h"
#include "framework.h"
#include "DoubleBuffering.h"
#include "DoubleBufferingDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
CDoubleBufferingDlg::CDoubleBufferingDlg(CDoubleBufferingApp * app, CWnd* pParent)
: CDialogEx(IDD_DOUBLEBUFFERING_DIALOG, pParent),
m_app(app)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CDoubleBufferingDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CDoubleBufferingDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_TIMER()
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
BOOL CDoubleBufferingDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
SetIcon(m_hIcon, TRUE);
SetIcon(m_hIcon, FALSE);
return TRUE;
}
void CDoubleBufferingDlg::OnPaint()
{
if (IsIconic()) {
OnPaintIconic();
return;
}
CPaintDC dc(this);
DrawRect(&dc);
}
void CDoubleBufferingDlg::DrawRect(CDC * dc)
{
CDC bufdc;
bufdc.CreateCompatibleDC(dc);
CRect cli_rect;
GetClientRect(cli_rect);
CBitmap bufbm;
bufbm.CreateCompatibleBitmap(dc, cli_rect.Width(), cli_rect.Height());
CBitmap* saved_bm = bufdc.SelectObject(&bufbm);
{
CBrush brush_white;
brush_white.CreateSolidBrush(RGB(255, 255, 255));
bufdc.FillRect(cli_rect, &brush_white);
CBrush brush_red;
brush_red.CreateSolidBrush(RGB(255, 0, 0));
CRect rect = m_app->GetRect();
bufdc.FillRect(rect, &brush_red);
dc->BitBlt(0, 0, cli_rect.Width(), cli_rect.Height(), &bufdc, 0, 0, SRCCOPY);
}
bufdc.SelectObject(saved_bm);
}
void CDoubleBufferingDlg::OnPaintIconic()
{
CPaintDC dc(this);
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
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;
dc.DrawIcon(x, y, m_hIcon);
}
HCURSOR CDoubleBufferingDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CDoubleBufferingDlg::OnTimer(UINT_PTR id)
{
CRect rect;
GetClientRect(&rect);
m_app->MoveRect(rect);
}
void CDoubleBufferingDlg::StartAnimation()
{
SetTimer((UINT_PTR)this, 33, NULL);
}
void CDoubleBufferingDlg::StopAnimation()
{
KillTimer((UINT_PTR)this);
}
void CDoubleBufferingDlg::OnCancel()
{
PostQuitMessage(0);
}
void CDoubleBufferingDlg::OnOK()
{
m_app->StartAnimation();
}
BOOL CDoubleBufferingDlg::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
#pragma once
class CDoubleBufferingApp;
class CDoubleBufferingDlg : public CDialogEx
{
public:
CDoubleBufferingDlg(CDoubleBufferingApp* app, CWnd* pParent = nullptr);
virtual ~CDoubleBufferingDlg() {}
afx_msg void OnTimer(UINT_PTR id);
virtual void StartAnimation();
virtual void StopAnimation();
virtual void OnCancel() override;
virtual void OnOK() override;
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DOUBLEBUFFERING_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX);
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
virtual void OnPaintIconic();
virtual void DrawRect(CDC* dc);
protected:
CDoubleBufferingApp* m_app;
HICON m_hIcon;
DECLARE_MESSAGE_MAP()
public:
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment