paint_rect.h

  name="google_ads_frame" marginwidth="0" marginheight="0" src="http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-5572165936844014&dt=1194442938015&lmt=1194190197&format=336x280_as&output=html&correlator=1194442937843&url=file%3A%2F%2F%2FC%3A%2FDocuments%2520and%2520Settings%2Flhh1%2F%E6%A1%8C%E9%9D%A2%2FCLanguage.htm&color_bg=FFFFFF&color_text=000000&color_link=000000&color_url=FFFFFF&color_border=FFFFFF&ad_type=text&ga_vid=583001034.1194442938&ga_sid=1194442938&ga_hid=1942779085&flash=9&u_h=768&u_w=1024&u_ah=740&u_aw=1024&u_cd=32&u_tz=480&u_java=true" frameborder="0" width="336" scrolling="no" height="280" allowtransparency="allowtransparency"> #define IDM_EXIT           100
#define IDM_TEST           200
#define IDM_ABOUT          301

LRESULT CALLBACK WndProc  (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About    (HWND, UINT, WPARAM, LPARAM);

请根据我提供的滚动条控件源码,重构一个更高效的控件给我 #ifndef _SCROLL_BAR_H_ #define _SCROLL_BAR_H_ #include "BaseWnd/CBaseWnd.h" class ScrollBar : public MFC::CBaseWnd { public: ScrollBar(); ~ScrollBar(); BOOL Create(const int _iBar, const CRect& _Rect, CWnd* _pParent, const int _iArrowFlags = ESB_ENABLE_BOTH, const int _iSpace = 3, const int _iMinSlider = 10); BOOL SetScrollInfo(SCROLLINFO& _refScrollInfo, BOOL _bRedraw = TRUE); BOOL SetScrollPos(int _iPos, BOOL _bRedraw = TRUE); void SetTarget(CWnd* _pTargetWnd); private: int m_iBar; //此滚动条的风格: SB_HORZ = 水平横向滚动条, SB_VERT = 垂直纵向滚动条 int m_iSpace; //滚动条滑块通道两边的空白间隔 int m_iMinSlider; //滑块的最小宽度,不可能无限小吧,滑块过小了肉眼都难看到了 int m_iArrowFlags; //两边是否开启箭头 float m_fRatio; //比率: 如: 滚动条滚动 1pixl, 目标控件该移动多少 pix? 或者反过来,目标控件移动了10pix , 那么滚动条应该移动多少pix? CRect m_rcLTUP; //滚动条(左边/顶部)的箭头范围 3个范围组成完整的滚动条 CRect m_rcScroll; //滚动条通道的范围 3个范围组成完整的滚动条 CRect m_rcRTDN; //滚动条(右边/底部)的箭头范围 3个范围组成完整的滚动条 SCROLLINFO m_infoScroll; //滚动条的信息 这2个info是相互关联依赖 SCROLLBARINFO m_infoScrollBar; //滚动条的滑块信息 这2个info是相互关联依赖 //以下解释2个info的关联性 /* typedef struct tagSCROLLINFO { UINT cbSize; //size of(SCROLLINFO) UINT fMask; //SIF_ALL 即nMin, nMax, nPage, nPos, nTrackPos 5个变量值都得到更改 int nMin; //一般置 0 int nMax; //目标控件的最大可见内容, 比如我的目标控件宽度: 666 pix, 控件内有一行文字内容,此行文字占:977 pix, 那么此行内容就有: 977-666 pix内容是看不到了,那么最大可见内容nMax=977 UINT nPage; //目标控件的宽度: 666 pix, 一般一行文字的最前面和最后面都有一个占1pix的光标,正如我们打字那个光标一样, 666-2pix = 664, 那么nPag = 664 int nPos; //这里我预设为: 29, 最下面会给出这个29的计算方法 int nTrackPos; //这个值是以前旧nPos, 等更新完成后,也会变成29 } SCROLLINFO, FAR* LPSCROLLINFO; */ /* typedef struct tagSCROLLBARINFO { DWORD cbSize; //size of(SCROLLBARINFO) RECT rcScrollBar; //滚动条的全部范围: 我预设此滚动条是: 666*17 pix, 水平横向滚动条,两头带17 pix的箭头按钮 int dxyLineButton; //滚动条2头的箭头宽度: 17pix int xyThumbTop; //滑块左边位于滚动条的位置, 这里是36 pix 这个36 pix和上面的nPos 29pix是有关联性的 int xyThumbBottom; //滑块右边位于滚动条的位置, 这里是465 pix, 那么这个滚动条中间滑块的宽度就是: 465-36 int reserved; //windows预留位置,不用管 DWORD rgstate[CCHILDREN_SCROLLBAR + 1]; //当滚动可见,这里全部为0, 可视状态开关 } SCROLLBARINFO, * PSCROLLBARINFO, * LPSCROLLBARINFO; */ /*  * xyThumbTop = 36 计算出 nPos = 29 : * xyThumbTop-17 = 36-17 = 19pix, 先去除左边箭头的宽度得到真实: 当前滚动条已经滚动的距离 * 计算比率: 滚动条的长度/目标控件的最大可见内容 = (666-(17*2))/977 = 0.6468781 (17*2)是去掉2个箭头距离 * xyThumbTop / 比率 = 19/0.6468781 = 29.37183991 = (int)29 = nPos = 29 * nPos逆向计算xyThumbTop = 29*0.6468781 = 19 * 总结: SCROLLBARINFO信息控制滚动条内部信息,SCROLLINFO控制外部目标控件的信息 */ CRect m_rcSlider; //滚动条内滑块的范围 COLORREF m_clrSlider; //滑块的状态颜色 COLORREF m_clrSlider_Def; //滑块无操作状态下的颜色 COLORREF m_clrSlider_Hover; //鼠标悬停在滑块上面的颜色 COLORREF m_clrSlider_Click; //鼠标左键按下滑块的颜色 BOOL m_bIsTrack; //鼠标触发WM_MOUSEMOVE一次就触发一次鼠标悬停?明显太浪费了,所以这个bIsTrack控制,确保已经触发完成鼠标悬停事件再重置bIsTrack BOOL m_bIsCaptrue; //监视这个控件是不是正在 捕获焦点 中 CPoint m_ptMouseLastPoint; //鼠标移动: 从A点移动到B点, m_ptMouseLastPoint代表A点(存储), B点在WM_MOUSEMOVE事件能得到 int m_iLTUPBtn; //(左边/顶部)箭头的(宽度/长度) int m_iRTDNBtn; //(右边/底部)箭头的(宽度/长度) CRgn m_rgnLTUPBtn; //(左边/顶部)三角形箭头的绘画路径 CRgn m_rgnRTDNBtn; //(右边/底部)三角形箭头的绘画路径 COLORREF m_clrArrow; //箭头的状态颜色 COLORREF m_clrArrow_Def; //箭头无操作状态颜色 COLORREF m_clrArrow_Hover; //鼠标悬停在箭头上的颜色 COLORREF m_clrArrow_Click; //鼠标左键按下箭头的颜色 BOOL m_bIsEnd; //当前滚动条已经达到尽头 CWnd* m_pTargetWnd; //关联的目标控件 float m_fCorrectionLT; //补正(左箭头/顶部箭头)移动距离 float m_fCorrectionRD; //补正(右箭头/底部箭头)移动距离 public: DECLARE_MESSAGE_MAP() afx_msg void OnPaint(); afx_msg void OnMouseMove(UINT nFlags, CPoint point); afx_msg void OnMouseHover(UINT nFlags, CPoint point); afx_msg void OnMouseLeave(); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); afx_msg void OnLButtonUp(UINT nFlags, CPoint point); afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); virtual void OnMouseLeave(const CPoint& _point); virtual void OnDragSlider(const CPoint& _point); virtual void OnClickLTUPBtn();//点击了(左箭头/顶部箭头) virtual void OnClickRTDNBtn();//点击了(右箭头/底部箭头) }; #endif#include "ScrollBar.h" ScrollBar::ScrollBar(): m_iBar(0), m_iSpace(0), m_iMinSlider(0), m_iArrowFlags(ESB_ENABLE_BOTH), m_fRatio(0.0f), m_bIsTrack(FALSE), m_bIsCaptrue(FALSE), m_iLTUPBtn(0), m_iRTDNBtn(0), m_bIsEnd(FALSE), m_pTargetWnd(NULL), m_fCorrectionLT(0.0f), m_fCorrectionRD(0.0f) { //初始化一些基本结构 m_rcLTUP = { 0, 0, 0, 0 }; m_rcScroll = {0, 0, 0, 0}; m_rcRTDN = {0, 0, 0, 0}; memset(&m_infoScroll, 0, sizeof m_infoScroll); m_infoScroll.cbSize = sizeof m_infoScroll; memset(&m_infoScrollBar, 0, sizeof m_infoScrollBar); m_infoScrollBar.cbSize = sizeof m_infoScrollBar; m_rcSlider = { 0,0,0,0 }; m_clrSlider_Def = RGB(104, 104, 104); m_clrSlider_Hover = RGB(158, 158, 158); m_clrSlider_Click = RGB(239, 235, 239); m_clrSlider = m_clrSlider_Def; m_ptMouseLastPoint = { 0,0 }; m_clrArrow_Def = RGB(104, 104, 104); m_clrArrow_Hover = RGB(158, 158, 158); m_clrArrow_Click = RGB(239, 235, 239); m_clrArrow = m_clrArrow_Def; } ScrollBar::~ScrollBar() { //箭头路径销毁: windwos要求释放资源 m_rgnLTUPBtn.DeleteObject(); m_rgnRTDNBtn.DeleteObject(); } BOOL ScrollBar::Create(const int _iBar, const CRect& _Rect, CWnd* _pParent, const int _iArrowFlags, const int _iSpace, const int _iMinSlider) { //准备滚动条数据 m_iBar = _iBar; //存储滚动条风格: SB_HORZ=水平横向滚动条; SB_VERT=垂直纵向滚动条 m_iSpace = _iSpace; //存储滚动条滑块两边空白间隔 m_iArrowFlags = _iArrowFlags; //存储滚动条的箭头开关值: 0=两个都开启; 1=(左边/顶部)的箭头关闭; 2=(右边/底部)的箭头关闭; 3=两个都关闭 m_iMinSlider = _iMinSlider; //存储滚动条滑块的最小(宽度/长度),不可能无限短,太短肉眼都看不见了 CRect recWnd = { 0, 0, 0,0 }; if (CBaseWnd::Create("scroll bar", _Rect, _pParent, NULL, WS_CHILD | WS_VISIBLE))//创建控件 { //控件创建成功 m_infoScrollBar.rcScrollBar = {0, 0, _Rect.Width(), _Rect.Height()};//设置滚动条所占此控件的范围,一般是全部 recWnd = m_infoScrollBar.rcScrollBar; switch (_iBar) { case SB_HORZ: m_infoScrollBar.dxyLineButton = _Rect.Height();//如果是水平滚动条, 箭头按钮长度就是控件的宽度 break; case SB_VERT: m_infoScrollBar.dxyLineButton = _Rect.Width();//如果是垂直滚动条, 箭头按钮的宽度就是控件的长度 break; } switch (_iArrowFlags) { case ESB_ENABLE_BOTH://2个箭头都开启 m_iLTUPBtn = m_infoScrollBar.dxyLineButton; m_iRTDNBtn = m_infoScrollBar.dxyLineButton; break; case ESB_DISABLE_LTUP://关闭(左边/顶部)的箭头 m_iLTUPBtn = 0; m_iRTDNBtn = m_infoScrollBar.dxyLineButton; break; case ESB_DISABLE_RTDN://关闭(右边/底部)的箭头 m_iLTUPBtn = m_infoScrollBar.dxyLineButton; m_iRTDNBtn = 0; break; case ESB_DISABLE_BOTH://2个箭头都关闭 m_iLTUPBtn = 0; m_iRTDNBtn = 0; break; } switch (_iBar) { case SB_HORZ: { m_infoScroll.nMax = _Rect.Width();//初始化目标控件里面的内容最大可视范围 m_infoScroll.nPage = _Rect.Width();//初始化目标控件的最大范围 m_rcSlider = { recWnd.left + m_iLTUPBtn, recWnd.top + m_iSpace, recWnd.right - m_iRTDNBtn, recWnd.bottom - m_iSpace };//初始化滑块坐标范围 m_infoScrollBar.xyThumbTop = m_rcSlider.left;//滑块的左边坐标 m_infoScrollBar.xyThumbBottom = m_rcSlider.right;//滑块的右边坐标 CPoint vecPoint[3]; //绘画左边箭头三角形 vecPoint[0] = { m_iSpace+1, m_infoScrollBar.dxyLineButton / 2 }; vecPoint[1] = { m_infoScrollBar.dxyLineButton - m_iSpace*2, m_infoScrollBar.dxyLineButton - m_iSpace }; vecPoint[2] = { m_infoScrollBar.dxyLineButton - m_iSpace*2 , m_iSpace-1 }; m_rgnLTUPBtn.CreatePolygonRgn(vecPoint, 3, WINDING); //绘画右边箭头三角形 vecPoint[0] = {recWnd.Width()-(m_iSpace + 1), m_infoScrollBar.dxyLineButton / 2 }; vecPoint[1] = {recWnd.Width()- (m_infoScrollBar.dxyLineButton - m_iSpace * 2), m_infoScrollBar.dxyLineButton - m_iSpace }; vecPoint[2] = {recWnd.Width() - (m_infoScrollBar.dxyLineButton - m_iSpace * 2), m_iSpace-1 }; m_rgnRTDNBtn.CreatePolygonRgn(vecPoint, 3, WINDING); //分配范围 m_rcLTUP = { recWnd.left, recWnd.top, recWnd.left + m_iLTUPBtn, recWnd.bottom };//左箭头范围 m_rcRTDN = { recWnd.right - m_iRTDNBtn, recWnd.top, recWnd.right, recWnd.bottom };//右箭头范围 m_rcScroll = {recWnd.left+m_iLTUPBtn, recWnd.top, recWnd.right-m_iRTDNBtn, recWnd.bottom};//中间滚动条通道 m_rcSlider = {m_rcScroll.left, m_rcScroll.top+m_iSpace, m_rcScroll.right, m_rcScroll.bottom-m_iSpace}; break; } case SB_VERT: { m_infoScroll.nMax = recWnd.Height();//初始化目标控件里面的内容最大可视范围 m_infoScroll.nPage = recWnd.Height();//初始化目标控件的最大范围 m_rcSlider = {recWnd.left+m_iSpace, recWnd.top+m_iLTUPBtn, recWnd.right-m_iSpace, recWnd.bottom-m_iRTDNBtn};//初始化滑块坐标范围 m_infoScrollBar.xyThumbTop = m_rcSlider.top;//滑块顶部的坐标 m_infoScrollBar.xyThumbBottom = m_rcSlider.bottom;//滑块底部的坐标 CPoint vecPoint[3]; //绘画顶部箭头的三角形 vecPoint[0] = { m_infoScrollBar.dxyLineButton / 2 , m_iSpace }; vecPoint[1] = { m_iSpace-1, m_infoScrollBar.dxyLineButton - m_iSpace * 2 }; vecPoint[2] = { m_infoScrollBar.dxyLineButton - m_iSpace, m_infoScrollBar.dxyLineButton - m_iSpace*2 }; m_rgnLTUPBtn.CreatePolygonRgn(vecPoint, 3, WINDING); //绘画底部箭头的三角形 vecPoint[0] = { m_infoScrollBar.dxyLineButton / 2 , recWnd.Height() - m_iSpace - 1 }; vecPoint[1] = { m_iSpace , recWnd.Height() - m_infoScrollBar.dxyLineButton + m_iSpace * 2 }; vecPoint[2] = { m_infoScrollBar.dxyLineButton - m_iSpace, recWnd.Height() - m_infoScrollBar.dxyLineButton + m_iSpace * 2 }; m_rgnRTDNBtn.CreatePolygonRgn(vecPoint, 3, WINDING); //分配范围 m_rcLTUP = { recWnd.left, recWnd.top, recWnd.right, recWnd.top+m_iLTUPBtn };//上箭头范围 m_rcRTDN = { recWnd.left, recWnd.bottom - m_iRTDNBtn, recWnd.right, recWnd.bottom };//下箭头范围 m_rcScroll = { recWnd.left, recWnd.top + m_iLTUPBtn, recWnd.right, recWnd.bottom - m_iRTDNBtn };//中间滚动条通道 m_rcSlider = {m_rcScroll.left+m_iSpace, m_rcScroll.top, m_rcScroll.right-m_iSpace, m_rcScroll.bottom}; break; } } return TRUE; } return FALSE; } BEGIN_MESSAGE_MAP(ScrollBar, MFC::CBaseWnd) ON_WM_PAINT() ON_WM_MOUSEMOVE() ON_WM_MOUSEHOVER() ON_WM_MOUSELEAVE() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_HSCROLL() ON_WM_VSCROLL() END_MESSAGE_MAP() void ScrollBar::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: 在此处添加消息处理程序代码 // 不为绘图消息调用 CBaseWnd::OnPaint() CBrush brush; brush.CreateSolidBrush(m_clrArrow); m_MemDC.FillSolidRect(m_rcWnd, RGB(62, 62, 66));//背景色 m_MemDC.FillSolidRect(m_rcSlider, m_clrSlider);//滑块色 if(m_iLTUPBtn) m_MemDC.FillRgn(&m_rgnLTUPBtn, &brush); if(m_iRTDNBtn) m_MemDC.FillRgn(&m_rgnRTDNBtn, &brush); brush.DeleteObject(); dc.BitBlt(0, 0, m_rcWnd.Width(), m_rcWnd.Height(), &m_MemDC, 0, 0, SRCCOPY); //更新scroll bar info数据 switch (m_iBar) { case SB_HORZ: m_infoScrollBar.xyThumbTop = m_rcSlider.left; m_infoScrollBar.xyThumbBottom = m_rcSlider.right; break; case SB_VERT: m_infoScrollBar.xyThumbTop = m_rcSlider.top; m_infoScrollBar.xyThumbBottom = m_rcSlider.bottom; break; } } void ScrollBar::OnMouseMove(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 if (!m_bIsTrack && !m_bIsCaptrue) { m_bIsTrack = TRUE; TRACKMOUSEEVENT tme; tme.cbSize = sizeof(tme); tme.hwndTrack = m_hWnd; tme.dwFlags = TME_LEAVE | TME_HOVER; tme.dwHoverTime = 1;// 鼠标在按钮上停留超过 1ms ,才认为成功 _TrackMouseEvent(&tme); } if (m_bIsCaptrue) { OnDragSlider(point); m_ptMouseLastPoint = point; } CBaseWnd::OnMouseMove(nFlags, point); } void ScrollBar::OnMouseHover(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 OnMouseLeave(m_ptMouseLastPoint); if (PtInRect(m_rcLTUP, point)) { //鼠标悬停在(左边/顶部)箭头上面 m_clrArrow = m_clrArrow_Hover; InvalidateRect(m_rcLTUP); } else if (PtInRect(m_rcRTDN, point)) { //鼠标悬停在(右边/底部)箭头上面 m_clrArrow = m_clrArrow_Hover; InvalidateRect(m_rcRTDN); } else if (PtInRect(m_rcSlider, point)) { //鼠标悬停在滑块上面 m_clrSlider = m_clrSlider_Hover; InvalidateRect(m_rcSlider); } m_ptMouseLastPoint = point; m_bIsTrack = FALSE; CBaseWnd::OnMouseHover(nFlags, point); } void ScrollBar::OnMouseLeave(const CPoint& _point) { if (PtInRect(m_rcLTUP, _point)) { //鼠标离开(左边/顶部)箭头 m_clrArrow = m_clrArrow_Def; InvalidateRect(m_rcLTUP); } else if (PtInRect(m_rcRTDN, _point)) { //鼠标离开(右边/底部)箭头 m_clrArrow = m_clrArrow_Def; InvalidateRect(m_rcRTDN); } else if (PtInRect(m_rcSlider, _point)) { //鼠标离开滑块 m_clrSlider = m_clrSlider_Def; InvalidateRect(m_rcSlider); } } void ScrollBar::OnMouseLeave() { // TODO: 在此添加消息处理程序代码和/或调用默认值 //鼠标离开控件 m_bIsTrack = FALSE; m_clrSlider = m_clrSlider_Def; m_clrArrow = m_clrArrow_Def; Invalidate(); if (m_bIsCaptrue) { ReleaseCapture(); m_bIsCaptrue = FALSE; } CBaseWnd::OnMouseLeave(); } void ScrollBar::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 if (PtInRect(m_rcLTUP, point)) { //鼠标左键点击(左边/顶部)箭头 m_clrArrow = m_clrArrow_Click; InvalidateRect(m_rcLTUP); OnClickLTUPBtn(); } else if (PtInRect(m_rcRTDN, point)) { //鼠标左键点击(右边/底部)箭头 m_clrArrow = m_clrArrow_Click; InvalidateRect(m_rcRTDN); OnClickRTDNBtn(); } else if (PtInRect(m_rcSlider, point)) { //鼠标左键点击滑块 m_clrSlider = m_clrSlider_Click; InvalidateRect(m_rcSlider); SetCapture(); m_bIsCaptrue = TRUE; } CBaseWnd::OnLButtonDown(nFlags, point); } void ScrollBar::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 if (PtInRect(m_rcLTUP, point)) { //鼠标左键点击(左边/顶部)箭头 后 鼠标弹起 m_clrArrow = m_clrArrow_Hover; InvalidateRect(m_rcLTUP); } else if (PtInRect(m_rcRTDN, point)) { //鼠标左键点击(右边/底部)箭头 后 鼠标弹起 m_clrArrow = m_clrArrow_Hover; InvalidateRect(m_rcRTDN); } else if (PtInRect(m_rcSlider, point)) { //鼠标左键点击滑块 后 鼠标弹起 m_clrSlider = m_clrSlider_Hover; InvalidateRect(m_rcSlider); ReleaseCapture(); m_bIsCaptrue = FALSE; if (m_infoScroll.nTrackPos != m_infoScroll.nPos)//用nPos和nTrackPos比较是否滑块滑动过,nTrackPos在拖滑块中会更新 { switch (m_iBar) { case SB_HORZ: SendMessage(WM_HSCROLL, MAKEWPARAM(SB_THUMBPOSITION, m_rcSlider.left), NULL); break; case SB_VERT: SendMessage(WM_VSCROLL, MAKEWPARAM(SB_THUMBPOSITION, m_rcSlider.top), NULL); break; } } } if (m_bIsCaptrue) { ReleaseCapture(); m_bIsCaptrue = FALSE; if (m_infoScroll.nTrackPos != m_infoScroll.nPos)//用nPos和nTrackPos比较是否滑块滑动过,nTrackPos在拖滑块中会更新 { switch (m_iBar) { case SB_HORZ: SendMessage(WM_HSCROLL, MAKEWPARAM(SB_THUMBPOSITION, m_rcSlider.left), NULL); break; case SB_VERT: SendMessage(WM_VSCROLL, MAKEWPARAM(SB_THUMBPOSITION, m_rcSlider.top), NULL); break; } } } m_bIsEnd = FALSE; CBaseWnd::OnLButtonUp(nFlags, point); } void ScrollBar::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: 在此添加消息处理程序代码和/或调用默认值 if (pScrollBar == NULL)//NULL说明内部发送过来信息 { switch (nSBCode) { case SB_ENDSCROLL: { //结束滚动 //_output_debug_("水平滚动结束x:%d", nPos); if (m_pTargetWnd) { m_pTargetWnd->SendMessage(WM_HSCROLL, MAKEWPARAM(SB_ENDSCROLL, m_infoScroll.nPos), (LPARAM)this); } break; } case SB_THUMBTRACK: { //正在拖动滑块 m_infoScroll.nTrackPos = int((float)nPos / m_fRatio);//使用滑块的距离逆向比率得到目标的xPos if (m_pTargetWnd) { m_pTargetWnd->SendMessage(WM_HSCROLL, MAKEWPARAM(SB_THUMBTRACK, m_infoScroll.nTrackPos), (LPARAM)this); } break; } case SB_THUMBPOSITION: { //用户已拖动滚动框(拇指)并松开鼠标按钮 //_output_debug_("水平滚动条鼠标松开滑动,目标xPos:%d", m_infoScroll.nTrackPos); m_infoScroll.nPos = m_infoScroll.nTrackPos;//最终更新用户数据 SendMessage(WM_HSCROLL, MAKEWPARAM(SB_ENDSCROLL, m_rcSlider.left-m_iLTUPBtn), NULL); break; } case SB_LINELEFT: { //向左滚动一个单位 点击左箭头 //_output_debug_("水平滚动向左滚动一个单位:%d", nPos); m_fCorrectionLT += (float)nPos / m_fRatio;//计算目标控件的滚动距离 int pos = (int)m_fCorrectionLT; m_fCorrectionLT -= (float)pos; m_infoScroll.nPos -= pos; m_infoScroll.nPos = m_infoScroll.nPos < m_infoScroll.nMin ? m_infoScroll.nMin : m_infoScroll.nPos; m_infoScroll.nTrackPos = m_infoScroll.nPos; if (m_pTargetWnd) { m_pTargetWnd->SendMessage(WM_HSCROLL, MAKEWPARAM(SB_THUMBPOSITION, m_infoScroll.nPos), (LPARAM)this); } break; } case SB_LINERIGHT: { //向右滚动一个单位 点击右箭头 //_output_debug_("水平滚动向右滚动一个单位:%d", nPos); m_fCorrectionRD += (float)nPos / m_fRatio; int pos = (int)m_fCorrectionRD; m_fCorrectionRD -= (float)pos;//把小数位单独取出来留给后面的补正 m_infoScroll.nPos += pos;//使用滑块的距离逆向比率得到目标的xPos m_infoScroll.nPos = m_infoScroll.nPos > m_infoScroll.nMax ? m_infoScroll.nMax : m_infoScroll.nPos; m_infoScroll.nTrackPos = m_infoScroll.nPos; if (m_pTargetWnd) { m_pTargetWnd->SendMessage(WM_HSCROLL, MAKEWPARAM(SB_THUMBPOSITION, m_infoScroll.nPos), (LPARAM)this); } break; } case SB_LEFT: { //滚动到左边末尾 //_output_debug_("已经滚动到左边尽头."); //if (m_pTargetWnd) m_pTargetWnd->SendMessage(WM_HSCROLL, MAKEWPARAM(SB_LEFT, 0), (LPARAM)this); break; } case SB_RIGHT: { //滚动到右边末尾 //_output_debug_("已经滚动到右边尽头."); //if (m_pTargetWnd) m_pTargetWnd->SendMessage(WM_HSCROLL, MAKEWPARAM(SB_RIGHT, m_infoScroll.nMax), (LPARAM)this); break; } } } CBaseWnd::OnHScroll(nSBCode, nPos, pScrollBar); } void ScrollBar::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: 在此添加消息处理程序代码和/或调用默认值 if (pScrollBar == NULL)//NULL说明内部发送过来信息 { switch (nSBCode) { case SB_ENDSCROLL: { //结束滚动 //_output_debug_("垂直滚动结束y:%d", nPos); if (m_pTargetWnd) { m_pTargetWnd->SendMessage(WM_VSCROLL, MAKEWPARAM(SB_ENDSCROLL, m_infoScroll.nPos), (LPARAM)this); } break; } case SB_THUMBTRACK: { //正在拖动滑块 m_infoScroll.nTrackPos = int((float)nPos / m_fRatio);//使用滑块的距离逆向比率得到目标的xPos if (m_pTargetWnd) { m_pTargetWnd->SendMessage(WM_VSCROLL, MAKEWPARAM(SB_THUMBTRACK, m_infoScroll.nTrackPos), (LPARAM)this); } break; } case SB_THUMBPOSITION: { //用户已拖动滚动框(拇指)并松开鼠标按钮 //_output_debug_("垂直滚动条鼠标松开滑动,目标yPos: %d", m_infoScroll.nTrackPos); m_infoScroll.nPos = m_infoScroll.nTrackPos;//最终更新用户数据 SendMessage(WM_VSCROLL, MAKEWPARAM(SB_ENDSCROLL, m_rcSlider.top-m_iLTUPBtn), NULL); break; } case SB_LINEUP: { //向上滚动了一个单位 点击顶箭头 m_fCorrectionLT += int((float)nPos / m_fRatio);//使用滑块的距离逆向比率得到目标的xPos int pos = (int)m_fCorrectionLT; m_fCorrectionLT -= (float)pos; m_infoScroll.nPos -= pos; m_infoScroll.nPos = m_infoScroll.nPos < m_infoScroll.nMin ? m_infoScroll.nMin : m_infoScroll.nPos; m_infoScroll.nTrackPos = m_infoScroll.nPos; if (m_pTargetWnd) { m_pTargetWnd->SendMessage(WM_VSCROLL, MAKEWPARAM(SB_THUMBPOSITION, m_infoScroll.nPos), (LPARAM)this); } break; } case SB_LINEDOWN: { //向下滚动了一个单位 点击底箭头 m_fCorrectionRD += (float)nPos / m_fRatio; int pos = (int)m_fCorrectionRD; m_fCorrectionRD -= (float)pos;//把小数位单独取出来留给后面的补正 m_infoScroll.nPos += pos;//使用滑块的距离逆向比率得到目标的xPos m_infoScroll.nPos = m_infoScroll.nPos > m_infoScroll.nMax ? m_infoScroll.nMax : m_infoScroll.nPos; m_infoScroll.nTrackPos = m_infoScroll.nPos; if (m_pTargetWnd) { m_pTargetWnd->SendMessage(WM_VSCROLL, MAKEWPARAM(SB_THUMBPOSITION, m_infoScroll.nPos), (LPARAM)this); } break; } case SB_TOP: { //滚动到顶部 //_output_debug_("已经滚动到顶部尽头."); //if (m_pTargetWnd) m_pTargetWnd->SendMessage(WM_VSCROLL, MAKEWPARAM(SB_TOP, 0), (LPARAM)this); break; } case SB_BOTTOM: { //滚动到底部 //_output_debug_("已经滚动到底部尽头."); //if (m_pTargetWnd) m_pTargetWnd->SendMessage(WM_VSCROLL, MAKEWPARAM(SB_BOTTOM, 0), (LPARAM)this); break; } } } CBaseWnd::OnVScroll(nSBCode, nPos, pScrollBar); } void ScrollBar::OnDragSlider(const CPoint& _point) { CPoint point = {0, 0}; CRect rect = m_rcSlider; switch (m_iBar) { case SB_HORZ: { point.x = _point.x - m_ptMouseLastPoint.x; rect.OffsetRect(point); if (rect.left >= m_rcScroll.left && rect.right <= m_rcScroll.right) { //合法拖动滑块 m_rcSlider.left = rect.left;//更新滑块左边坐标 m_rcSlider.right = rect.right;//更新滑块右边坐标 InvalidateRect(m_rcScroll);//刷新通道 SendMessage(WM_HSCROLL, MAKEWPARAM(SB_THUMBTRACK, m_rcSlider.left-m_iLTUPBtn), NULL); m_bIsEnd = FALSE; } else { //拖动滑块不合法: 超出左边 或者 右边 if (!m_bIsEnd && rect.left < m_rcScroll.left) { //超出左边 m_bIsEnd = TRUE; SendMessage(WM_HSCROLL, MAKEWPARAM(SB_LEFT, m_rcScroll.left), NULL); } else if(!m_bIsEnd && rect.right > m_rcScroll.right) { //超出右边 m_bIsEnd = TRUE; SendMessage(WM_HSCROLL, MAKEWPARAM(SB_RIGHT, m_rcScroll.right), NULL); } } break; } case SB_VERT: { point.y = _point.y - m_ptMouseLastPoint.y; rect.OffsetRect(point); if (rect.top >= m_rcScroll.top && rect.bottom <= m_rcScroll.bottom) { //合法拖动滑块 m_rcSlider.top = rect.top;//更新滑块顶部坐标 m_rcSlider.bottom = rect.bottom;//更新滑块底部坐标 InvalidateRect(m_rcScroll);//刷新通道 SendMessage(WM_VSCROLL, MAKEWPARAM(SB_THUMBTRACK, m_rcSlider.top-m_iLTUPBtn), NULL); m_bIsEnd = FALSE; } else { //拖动滑块不合法: 超出顶部 或者 底部 if (!m_bIsEnd && rect.top < m_rcScroll.top) { //超出顶部 m_bIsEnd = TRUE; SendMessage(WM_VSCROLL, MAKEWPARAM(SB_TOP, m_rcScroll.top), NULL); } else if(!m_bIsEnd && rect.bottom > m_rcScroll.bottom) { //超出底部 m_bIsEnd = TRUE; SendMessage(WM_VSCROLL, MAKEWPARAM(SB_BOTTOM, m_rcScroll.bottom), NULL); } } break; } } } void ScrollBar::OnClickLTUPBtn()//点击了(左箭头/顶部箭头) { int iSpace = 0; int iPage = 0; switch (m_iBar) { case SB_HORZ: { //_output_debug_("点击了左箭头"); iSpace = m_rcScroll.Width() - m_rcSlider.Width();//计算出滑块能滑动的最大距离 iPage = int((float)iSpace / ((float)iSpace / 10.0f));//点击一次箭头 滑块移动的距离 if (m_rcSlider.left - iPage >= m_rcScroll.left) { //合法滑动 } else { //滑动可能超出左边 iPage = m_rcSlider.left-m_rcScroll.left;//重置到尽头 } if (iPage) { m_rcSlider.OffsetRect(-iPage, 0); InvalidateRect(m_rcScroll); SendMessage(WM_HSCROLL, MAKEWPARAM(SB_LINELEFT, iPage), NULL); } break; } case SB_VERT: { //_output_debug_("点击了顶部箭头"); iSpace = m_rcScroll.Height() - m_rcSlider.Height();//计算出滑块能滑动的最大距离 iPage = int((float)iSpace / ((float)iSpace / 10.0f));//点击一次箭头 滑块移动的距离 if (m_rcSlider.top - iPage >= m_rcScroll.top) { //合法滑动 } else { //滑动可能超出顶部 iPage = m_rcSlider.top - m_rcScroll.top;//重置到尽头 } if (iPage) { m_rcSlider.OffsetRect(0, -iPage); InvalidateRect(m_rcScroll); SendMessage(WM_VSCROLL, MAKEWPARAM(SB_LINEUP, iPage), NULL); } break; } } } void ScrollBar::OnClickRTDNBtn()//点击了(右箭头/底部箭头) { int iSpace = 0; int iPage = 0; switch (m_iBar) { case SB_HORZ: { //_output_debug_("点击了右箭头"); iSpace = m_rcScroll.Width() - m_rcSlider.Width();//计算出滑块能滑动的最大距离 iPage = int((float)iSpace / ((float)iSpace / 10.0f));//点击一次箭头 滑块移动的距离 if (m_rcSlider.right + iPage <= m_rcScroll.right) { //合法滑动 } else { //滑动可能超出右边 iPage = m_rcScroll.right - m_rcSlider.right;//重置到尽头 } if (iPage) { m_rcSlider.OffsetRect(iPage, 0); InvalidateRect(m_rcScroll); SendMessage(WM_HSCROLL, MAKEWPARAM(SB_LINERIGHT, iPage), NULL); } break; } case SB_VERT: { //_output_debug_("点击了底部箭头"); iSpace = m_rcScroll.Height() - m_rcSlider.Height();//计算出滑块能滑动的最大距离 iPage = int((float)iSpace / ((float)iSpace / 10.0f));//点击一次箭头 滑块移动的距离 if (m_rcSlider.bottom + iPage <= m_rcScroll.bottom) { //合法滑动 } else { //滑动可能超出底部 iPage = m_rcScroll.bottom - m_rcSlider.bottom;//重置到尽头 } if (iPage) { m_rcSlider.OffsetRect(0, iPage); InvalidateRect(m_rcScroll); SendMessage(WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, iPage), NULL); } break; } } } void ScrollBar::SetTarget(CWnd* _pTargetWnd) { m_pTargetWnd = _pTargetWnd; } BOOL ScrollBar::SetScrollInfo(SCROLLINFO& _refScrollInfo, BOOL _bRedraw) { if (_refScrollInfo.nMax > (int)_refScrollInfo.nPage) { CRect rect = m_infoScrollBar.rcScrollBar;//取出滚动条的范围 float fRatio = 0.0f;//比率 int iSliderLen = 0;//滑块(长度/宽度) int iPos = 0; int iLTUP = 0; int iRTDN = 0; bool bIsValid = false; if ((_refScrollInfo.fMask & (SIF_RANGE | SIF_PAGE | SIF_POS)) == false)//提供的fMask权限不足 { return false; } switch (m_iBar) { case SB_HORZ: { fRatio = (float)(rect.Width() - (m_iLTUPBtn + m_iRTDNBtn)) / (float)_refScrollInfo.nMax;//计算比率: (总长度-2个箭头) / 目标控件内容最大可视范围 iSliderLen = (int)((float)rect.Width() * fRatio);//计算滑块的(长度) 水平滚动条 if (iSliderLen < m_iMinSlider)//如果滑块太短了 { iSliderLen = m_iMinSlider;//使用最小滑块长度 fRatio = (float)(rect.Width() - (m_iLTUPBtn + m_iRTDNBtn + m_iMinSlider)) / (float)_refScrollInfo.nMax;//重新计算比率: (总长度-2个箭头-最小滑块长度) / 目标控件内容最大可视范围 } iPos = (int)((float)_refScrollInfo.nPos * fRatio);//根据提供的nPos算出应该滚动的距离 iLTUP = iPos + m_iLTUPBtn;//算出滑块左边的坐标值 iRTDN = iLTUP + iSliderLen;//算出滑块右边的坐标值 if (iLTUP >= m_rcScroll.left && iRTDN <= m_rcScroll.right)//如果滑块左右两边都位于滚动条通道内,提供的nPos合法 { m_rcSlider.left = iLTUP; m_rcSlider.right = iRTDN; if (_bRedraw) InvalidateRect(m_rcScroll);//更新通道内容 bIsValid = true;//操作合法 m_fRatio = fRatio;//更新比率 } else { //提供的nPos不合法 return FALSE; } break; } case SB_VERT: { fRatio = (float)(rect.Height() - (m_iLTUPBtn + m_iRTDNBtn)) / (float)_refScrollInfo.nMax;//计算比率: (总宽度-2个箭头) / 目标控件内容最大可视范围 iSliderLen = (int)((float)rect.Height() * fRatio);//计算滑块的(宽度) 垂直滚动条 if (iSliderLen < m_iMinSlider)//如果滑块太短了 { iSliderLen = m_iMinSlider;//使用最小滑块宽度 fRatio = (float)(rect.Height() - (m_iLTUPBtn + m_iRTDNBtn + m_iMinSlider)) / (float)_refScrollInfo.nMax;//重新计算比率: (总宽度-2个箭头-最小滑块宽度) / 目标控件内容最大可视范围 } iPos = (int)((float)_refScrollInfo.nPos * fRatio);//根据提供的nPos算出应该滚动的距离 iLTUP = iPos + m_iLTUPBtn;//算出滑块顶部的坐标值 iRTDN = iLTUP + iSliderLen;//算出滑块底部的坐标值 if (iLTUP >= m_rcScroll.top && iRTDN <= m_rcScroll.bottom)//如果滑块上下两边都位于滚动条通道内,提供的nPos合法 { m_rcSlider.top = iLTUP; m_rcSlider.bottom = iRTDN; if (_bRedraw) InvalidateRect(m_rcScroll);//更新通道内容 bIsValid = true;//操作合法 m_fRatio = fRatio;//更新比率 } else { //提供的nPos不合法 return FALSE; } break; } } //更新scroll info 数据 if (bIsValid && _refScrollInfo.fMask & SIF_ALL) { m_infoScroll = _refScrollInfo;//全部数据复制给内部info m_infoScroll.cbSize = sizeof SCROLLINFO;//系统性修正数据-避免提供的数据有问题 m_infoScroll.fMask = SIF_ALL;//系统性修正数据-避免提供的数据有问题 return TRUE; } else if (bIsValid) { if (_refScrollInfo.fMask & SIF_RANGE) { m_infoScroll.nMin = _refScrollInfo.nMin; m_infoScroll.nMax = _refScrollInfo.nMax; } if (_refScrollInfo.fMask & SIF_PAGE) { m_infoScroll.nPage = _refScrollInfo.nPage; } if (_refScrollInfo.fMask & SIF_POS) { m_infoScroll.nPos = _refScrollInfo.nPos; } //SIF_DISABLENOSCROLL //不处理 //SIF_TRACKPOS //系统内部处理 return TRUE; } } return FALSE; } BOOL ScrollBar::SetScrollPos(int _iPos, BOOL _bRedraw) { int iPos = (int)roundf((float)_iPos * m_fRatio);//根据提供的nPos算出应该滚动的距离 CRect rect; if (_iPos > -1) { switch (m_iBar) { case SB_HORZ: { iPos += m_iLTUPBtn; rect = m_rcSlider; rect.OffsetRect(iPos, 0); if (rect.right <= m_rcScroll.right) { m_rcSlider = rect; if(_bRedraw)InvalidateRect(m_rcScroll); m_infoScroll.nPos = _iPos; m_infoScroll.nTrackPos = _iPos; return TRUE; } else { m_rcSlider.right = m_rcScroll.right; m_rcSlider.left = m_rcSlider.right - rect.Width(); if (_bRedraw)InvalidateRect(m_rcScroll); m_infoScroll.nPos = _iPos; m_infoScroll.nTrackPos = _iPos; } break; } case SB_VERT: { iPos += m_iLTUPBtn; rect = m_rcSlider; rect.OffsetRect(0, iPos); if (rect.bottom <= m_rcScroll.bottom) { m_rcSlider = rect; if (_bRedraw)InvalidateRect(m_rcScroll); m_infoScroll.nPos = _iPos; m_infoScroll.nTrackPos = _iPos; return TRUE; } else { m_rcSlider.bottom = m_rcScroll.bottom; m_rcSlider.top = m_rcScroll.bottom - rect.Height(); if (_bRedraw)InvalidateRect(m_rcScroll); m_infoScroll.nPos = _iPos; m_infoScroll.nTrackPos = _iPos; } break; } } } return FALSE; }
07-02
class ButtonDelegate(QStyledItemDelegate): def paint(self, painter, option, index): if index.column() == 10: button_option = QStyleOptionButton() button_option.rect = option.rect.adjusted(4, 4, -4, -4) button_option.text = "解析" button_option.state = QStyle.StateFlag.State_Enabled QApplication.style().drawControl(QStyle.ControlElement.CE_PushButton, button_option, painter) else: super().paint(painter, option, index) # new 0722 按钮添加 # """绘制按钮(仅在最后一列生效)""" # self.button_text = "解析" # if index.column() == 10: # 按钮列索引为10(数据列后) # super().paint(painter, option, index) # return # # button = QPushButton("解析", self.parent()) # # button.setGeometry(option.rect) # 按钮尺寸适配单元格 # # button.render(painter, option.rect.topLeft()) # 绘制按钮 # button_opt = QStyleOptionButton() # button_opt.initFrom(option.widget) # button_opt.text = self.button_text # QApplication.style().drawControl(QStyle.CE_PushButton, button_opt, painter) def editorEvent(self, event, model, option, index): # """处理按钮点击事件""" if event.type() == QEvent.MouseButtonRelease and index.column() == 10: # button_rect = option.rect.adjusted(2, 2, -2, -2) # if button_rect.contains(event.pos()): row_data = model._data[index.row()] # 获取当前行数据(需确保模型暴露数据) self.open_analysis_window(row_data) # 触发解析逻辑 # return True return super().editorEvent(event, model, option, index) 该函数怎么判断 def add_table_row(mainwindow, chn, trx, id, SendType, RemoteFlag, ExternFlag, length, data_hex, SID = -1, subFlag = "", time="-1", list_index = 0, CF_flag = 0): # print("CF_flag1:", CF_flag) print("list_index:", list_index) # #SID是10进制数字 #id是0X开头的16进制字符串 #获取新行的位置,table的行下标从0开始 if len(mainwindow.FilterIDList) == 0 or ( int(id, 16) in mainwindow.FilterIDList): time = get_now_time() #向data_hex后填充0,凑齐23个字符 # 将字符串分割成每两个字符一组 hex_list = data_hex.split() if len(hex_list[-1]) < 2: hex_list[-1] += "0" # 计算需要补充的组数 num_groups_to_add = 8 - len(hex_list) # 补充0到列表中 hex_list.extend(['00'] * num_groups_to_add) # 将列表重新组合成字符串,每组之间有一个空格 formatted_hex_str = ' '.join(hex_list) SID_str = hex(SID).upper()[2:] # #构造新行的内容 # items = [SID_str + " " + subFlag + CF_flag_str, time, chn, trx, id + " " + str(list_index), SendType, RemoteFlag, ExternFlag, length, formatted_hex_str] # new 0722 items = [SID_str + " " + subFlag, time, chn, trx, id + " " + str(list_index), SendType, RemoteFlag, ExternFlag, length, formatted_hex_str, ""] print("CF_flag2:", CF_flag) # CF_flag = 1 if CF_flag == 0: print("yes") print("CF_flag3:", CF_flag) mainwindow.right_layout_object.table_view.setItemDelegateForColumn(10, ButtonDelegate()) # 调用模型添加行 mainwindow.right_layout_object.model.add_row(items) mainwindow.right_layout_object.table_view.scrollToBottom() 中CF_flag的值来决定是否添加按钮
07-29
#include <windows.h> #include <stdlib.h> #include <time.h> #define BUTTON_WIDTH 100 #define BUTTON_HEIGHT 50 #define BUFFER_SIZE 50 // 新增缓冲区大小常量 // 全局变量 int score = 0; RECT g_buttonRect; void DrawButton(HDC hdc, RECT rect); void MoveButton(HWND hWnd); LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); // 绘制按钮 DrawButton(hdc, g_buttonRect); // 修复点:安全文本格式化 char scoreText[BUFFER_SIZE]; sprintf_s(scoreText, BUFFER_SIZE, "得分: %d", score); // 关键修复 TextOut(hdc, 10, 10, scoreText, (int)strlen(scoreText)); EndPaint(hWnd, &ps); } break; case WM_LBUTTONDOWN: { int xPos = LOWORD(lParam); int yPos = HIWORD(lParam); if (xPos >= g_buttonRect.left && xPos <= g_buttonRect.right && yPos >= g_buttonRect.top && yPos <= g_buttonRect.bottom) { score++; MoveButton(hWnd); InvalidateRect(hWnd, NULL, TRUE); } } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, uMsg, wParam, lParam); } return 0; } void DrawButton(HDC hdc, RECT rect) { HBRUSH brush = CreateSolidBrush(RGB(0, 255, 0)); FillRect(hdc, &rect, brush); DeleteObject(brush); Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom); } void MoveButton(HWND hWnd) { RECT clientRect; GetClientRect(hWnd, &clientRect); int maxX = clientRect.right - BUTTON_WIDTH; int maxY = clientRect.bottom - BUTTON_HEIGHT; g_buttonRect.left = rand() % maxX; g_buttonRect.top = rand() % maxY; g_buttonRect.right = g_buttonRect.left + BUTTON_WIDTH; g_buttonRect.bottom = g_buttonRect.top + BUTTON_HEIGHT; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { const char CLASS_NAME[] = "ButtonClickGame"; WNDCLASS wc = { }; wc.lpfnWndProc = WindowProc; wc.hInstance = hInstance; wc.lpszClassName = CLASS_NAME; wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); if (!RegisterClass(&wc)) { MessageBox(NULL, "窗口注册失败!", "错误", MB_ICONEXCLAMATION | MB_OK); return 0; } HWND hWnd = CreateWindowEx( 0, CLASS_NAME, "按钮点击游戏", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInstance, NULL ); if (hWnd == NULL) { MessageBox(NULL, "窗口创建失败!", "错误", MB_ICONEXCLAMATION | MB_OK); return 0; } srand((unsigned int)time(NULL)); MoveButton(hWnd); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); MSG msg = { }; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } sprintf_s(scoreText, BUFFER_SIZE, "得分: %d", score);还是错的 给我重新全部用dev c++ 5.11版本的代码进行修改
最新发布
10-22
// GradientProgressCtrl.cpp : implementation file // #include "stdafx.h" #include "VProgressCtrl.h" //#include "MemDC.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif class CMemDC : public CDC { public: CMemDC(CDC* pDC); CMemDC* operator->(){return this;} operator CMemDC*(){return this;} virtual ~CMemDC(); private: CBitmap m_bitmap; CBitmap* m_pOldBitmap; CDC* m_pDC; CRect m_rect; BOOL m_bMemDC; }; CMemDC::CMemDC(CDC* pDC):CDC() { ASSERT(pDC!=NULL); m_pDC=pDC; m_pOldBitmap=NULL; m_bMemDC=!pDC->IsPrinting(); // if(m_bMemDC) { pDC->GetClipBox(&m_rect); CreateCompatibleDC(pDC); m_bitmap.CreateCompatibleBitmap(pDC,m_rect.Width(),m_rect.Height()); m_pOldBitmap=SelectObject(&m_bitmap); SetWindowOrg(m_rect.left,m_rect.top); } else //为相关的现有设备准备打印 { m_bPrinting=pDC->m_bPrinting; m_hDC=pDC->m_hDC; m_hAttribDC=pDC->m_hAttribDC; } } CMemDC::~CMemDC() { if(m_bMemDC) { m_pDC->BitBlt(m_rect.left,m_rect.top,m_rect.Width(),m_rect.Height(), this,m_rect.left,m_rect.top,SRCCOPY); SelectObject(m_pOldBitmap); } else { m_hDC=m_hAttribDC=NULL; } } ///////////////////////////////////////////////////////////////////////////// // CVProgressCtrl CVProgressCtrl::CVProgressCtrl() : m_nTextType(TextCustom) , m_strFormat(_T("%s")) , m_nLower(0) , m_nUpper(100) , m_nCurrentPosition(0) , m_nStep(1) , m_clrStart(RGB(255,0,0)) , m_clrEnd(RGB(0,0,255)) , m_clrBkGround(GetSysColor(COLOR_3DFACE)) , m_clrText(RGB(255,255,255)) { m_nLower=0; m_nUpper=100; m_nCurrentPosition=0; m_nStep=10; } CVProgressCtrl::~CVProgressCtrl() { } BEGIN_MESSAGE_MAP(CVProgressCtrl, CProgressCtrl) //{{AFX_MSG_MAP(CVProgressCtrl) ON_WM_ERASEBKGND() ON_WM_PAINT() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CVProgressCtrl message handlers void CVProgressCtrl::SetRange(int nLower,int nUpper) { //This Function is to Set Range of the progress m_nLower=nLower; m_nUpper=nUpper; m_nCurrentPosition=nLower; CProgressCtrl::SetRange(nLower,nUpper); } int CVProgressCtrl::SetStep(int nStep) { m_nStep=nStep; return (CProgressCtrl::SetStep(nStep)); } BOOL CVProgressCtrl::OnEraseBkgnd(CDC* pDC) { // TODO: Add your message handler code here and/or call default return TRUE;//CProgressCtrl::OnEraseBkgnd(pDC); } void CVProgressCtrl::DrawGradient(CPaintDC *pDC, const RECT &rectClient, const int &nMaxWidth) { RECT rectFill; //显示区域 float fStep; //每一步的幅宽 CBrush brush; //显示的颜色画刷 CMemDC memDC(pDC); int r,g,b; float rStep,gStep,bStep; //得到不同颜色并相减,返回颜色之间的最大差值 r=(GetRValue(m_clrEnd)-GetRValue(m_clrStart)); g=(GetGValue(m_clrEnd)-GetGValue(m_clrStart)); b=(GetBValue(m_clrEnd)-GetBValue(m_clrStart)); //使进程条显示的总数 等于最大的颜色差值 int nSteps=max(abs(r),max(abs(g),abs(b))); //确定每一颜色填充多大的矩形区域 fStep=(float)rectClient.right/(float)nSteps; //设置每一颜色填充的步数 rStep=r/(float)nSteps; gStep=g/(float)nSteps; bStep=b/(float)nSteps; r=GetRValue(m_clrStart); g=GetGValue(m_clrStart); b=GetBValue(m_clrStart); //绘制颜色渐变的进程条 for(int iOnBand=0;iOnBand<nSteps;iOnBand++) { ::SetRect(&rectFill, //以下为填充矩形区域的左上角x,y和右下角x,y (int)(iOnBand*fStep), 0, (int)((iOnBand+1)*fStep), rectClient.bottom+1); VERIFY(brush.CreateSolidBrush(RGB(r+rStep*iOnBand,g+gStep*iOnBand,b+bStep*iOnBand))); memDC.FillRect(&rectFill,&brush); VERIFY(brush.DeleteObject()); //在结束绘制之前,使用背景色填充乘下的的客户区域 if(rectFill.right>nMaxWidth) { ::SetRect(&rectFill,rectFill.right,0,rectClient.right,rectClient.bottom); VERIFY(brush.CreateSolidBrush(m_clrBkGround)); memDC.FillRect(&rectFill,&brush); VERIFY(brush.DeleteObject()); return; } } } void CVProgressCtrl::DrawProgressText(CPaintDC& dc,RECT& rectClient) { //根据文本类型,设置显示的文本 switch(m_nTextType) { case TextPercent: m_strText.Format(m_strFormat,(int)(100*(float)m_nCurrentPosition/m_nUpper)); break; case TextPos: m_strText.Format(m_strFormat,m_nCurrentPosition); break; default://TextCustom break; } //设置文本颜色 dc.SetTextColor(m_clrText); dc.SetBkMode(TRANSPARENT); //绘制文本 dc.DrawText(m_strText,&rectClient,DT_VCENTER|DT_CENTER|DT_SINGLELINE); } void CVProgressCtrl::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: Add your message handler code here if(m_nCurrentPosition<=m_nLower||m_nCurrentPosition>=m_nUpper) { CRect rect; GetClientRect(rect); CBrush brush; brush.CreateSolidBrush(::GetSysColor(COLOR_3DFACE)); dc.FillRect(&rect,&brush); VERIFY(brush.DeleteObject()); return; } CRect rectClient; GetClientRect(rectClient); float maxWidth((float)m_nCurrentPosition/(float)m_nUpper*(float)rectClient.right); //绘制进度条 DrawGradient(&dc,rectClient,(int)maxWidth); //绘制进度条文本 DrawProgressText(dc,rectClient); // Do not call CProgressCtrl::OnPaint() for painting messages } int CVProgressCtrl::SetPos(int nPos) { //Set the Position of the Progress m_nCurrentPosition = nPos; return (CProgressCtrl::SetPos(nPos)); } void CVProgressCtrl::SetText(LPCTSTR lpcszText) { m_strText.Format(m_strFormat,lpcszText); this->Invalidate(); } void CVProgressCtrl::SetTextType(int nTextType,LPCTSTR lpszFormat) { m_nTextType = nTextType;//文本类型 m_strFormat = lpszFormat;//文本格式化 int nIndex;//内容在格式化中的位置 if (m_strFormat.GetLength() == 0) { nIndex = 0; } else { int nTemp = m_strFormat.Find(_T("%s")); if (nTemp == -1) { nIndex = m_strFormat.GetLength(); } else { nIndex = nTemp; m_strFormat.Delete(nTemp,2); while ((nTemp = m_strFormat.Find(_T("%"),nTemp)) > -1) { m_strFormat.Insert(nTemp,_T("%")); nTemp += 2; } } } //根据文本类型不同,设置格式化字符串 switch(m_nTextType) { case TextPercent: m_strFormat.Insert(nIndex,_T("%d%%")); break; case TextPos: m_strFormat.Insert(nIndex,_T("%d")); break; default: m_strFormat.Insert(nIndex,_T("%s")); break; } } 这个代码中为什么进度条到达100%后会重置为0
06-04
#define UNICODE #define _UNICODE #include <windows.h> #include <math.h> #include <wchar.h> #include “aip_common.h” // Constants for window dimensions, gravity, and animation #define U4_SIM_WINDOW_WIDTH 600U #define U4_SIM_WINDOW_HEIGHT 500U #define U1_SIM_BALL_RADIUS 10U #define S8_SIM_GRAVITY 0.0008 #define S8_SIM_REBOUND_FACTOR 0.5 #define U4_SIM_GROUND_Y (U4_SIM_WINDOW_HEIGHT - 150U) // UI control IDs and Timer ID #define U2_CTRL_HEIGHT_INPUT 201U #define U2_CTRL_REBOUNDS_INPUT 202U #define U2_CTRL_SUBMIT_BUTTON 203U #define U4_SIM_TIMER_ID 101U // Ball structure typedef struct { S8 S8_X_POSITION; S8 S8_Y_POSITION; S8 S8_VERTICAL_VELOCITY; S8 S8_CURRENT_HEIGHT; U2 U2_REBOUNDS_COUNT; U2 U2_MAX_REBOUNDS; U1 U1_SIM_ACTIVE; U1 U1_IS_FALLING; S8 S8_INITIAL_WAIT_TIME_MS; S8 S8_TOTAL_DISTANCE; } ST_SIM_BALL; // Global variables ST_SIM_BALL ST_SIM_BALL_INSTANCE = {0}; HWND HWND_CTRL_HEIGHT_INPUT; HWND HWND_CTRL_REBOUNDS_INPUT; HWND HWND_CTRL_SUBMIT_BUTTON; HWND HWND_SIM_MAIN_WINDOW = NULL; HWND HWND_RESULT_WINDOW = NULL; U4 U4_LAST_SIM_TICK_TIME = 0; S8 S8_SIM_REBOUND_HEIGHTS[100] = {0}; S8 S8_SIM_CUMULATIVE_DISTANCES[100] = {0}; // Function prototypes void FP_SIM_INITIALIZE_BALL(S8 S8_INITIAL_HEIGHT_METERS, U2 U2_MAX_REBOUNDS); void FP_SIM_UPDATE_BALL(U4 U4_DELTA_TIME_MS); void FP_SIM_RENDER_SCENE(HDC hdc); LRESULT CALLBACK FP_RESULTS_WINDOW_PROC(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); void FP_DISPLAY_SIMULATION_RESULTS(HINSTANCE HINSTANCE_CURRENT); LRESULT CALLBACK FP_MAIN_WINDOW_PROC(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); /* ------------------------------------------------------------------ Initialize ball properties ------------------------------------------------------------------ */ void FP_SIM_INITIALIZE_BALL(S8 S8_INITIAL_HEIGHT_METERS, U2 U2_MAX_REBOUNDS) { if (S8_INITIAL_HEIGHT_METERS <= 0 || U2_MAX_REBOUNDS <= 0) return; S8 S8_INITIAL_HEIGHT_PIXELS = S8_INITIAL_HEIGHT_METERS * 2.0; ST_SIM_BALL_INSTANCE.S8_X_POSITION = U4_SIM_WINDOW_WIDTH / 2.0; ST_SIM_BALL_INSTANCE.S8_Y_POSITION = U4_SIM_GROUND_Y - S8_INITIAL_HEIGHT_PIXELS; ST_SIM_BALL_INSTANCE.S8_VERTICAL_VELOCITY = 0; ST_SIM_BALL_INSTANCE.S8_CURRENT_HEIGHT = S8_INITIAL_HEIGHT_PIXELS; ST_SIM_BALL_INSTANCE.U2_REBOUNDS_COUNT = 0; ST_SIM_BALL_INSTANCE.U2_MAX_REBOUNDS = U2_MAX_REBOUNDS; ST_SIM_BALL_INSTANCE.U1_SIM_ACTIVE = TRUE; ST_SIM_BALL_INSTANCE.U1_IS_FALLING = FALSE; ST_SIM_BALL_INSTANCE.S8_INITIAL_WAIT_TIME_MS = 2000.0; ST_SIM_BALL_INSTANCE.S8_TOTAL_DISTANCE = 0.0; for (U2 U2_I = 0; U2_I < 100; U2_I++) { S8_SIM_REBOUND_HEIGHTS[U2_I] = 0; S8_SIM_CUMULATIVE_DISTANCES[U2_I] = 0; } } /* ------------------------------------------------------------------ Update ball physics ------------------------------------------------------------------ */ void FP_SIM_UPDATE_BALL(U4 U4_DELTA_TIME_MS) { if (!ST_SIM_BALL_INSTANCE.U1_SIM_ACTIVE) return; if (ST_SIM_BALL_INSTANCE.S8_INITIAL_WAIT_TIME_MS > 0) { ST_SIM_BALL_INSTANCE.S8_INITIAL_WAIT_TIME_MS -= U4_DELTA_TIME_MS; if (ST_SIM_BALL_INSTANCE.S8_INITIAL_WAIT_TIME_MS <= 0) { ST_SIM_BALL_INSTANCE.S8_INITIAL_WAIT_TIME_MS = 0; ST_SIM_BALL_INSTANCE.U1_IS_FALLING = TRUE; } return; } if (ST_SIM_BALL_INSTANCE.U1_IS_FALLING) { ST_SIM_BALL_INSTANCE.S8_VERTICAL_VELOCITY += S8_SIM_GRAVITY * U4_DELTA_TIME_MS; ST_SIM_BALL_INSTANCE.S8_Y_POSITION += ST_SIM_BALL_INSTANCE.S8_VERTICAL_VELOCITY * U4_DELTA_TIME_MS; if (ST_SIM_BALL_INSTANCE.S8_Y_POSITION >= U4_SIM_GROUND_Y - U1_SIM_BALL_RADIUS) { ST_SIM_BALL_INSTANCE.S8_Y_POSITION = U4_SIM_GROUND_Y - U1_SIM_BALL_RADIUS; ST_SIM_BALL_INSTANCE.U1_IS_FALLING = FALSE; S8_SIM_CUMULATIVE_DISTANCES[ST_SIM_BALL_INSTANCE.U2_REBOUNDS_COUNT] = ST_SIM_BALL_INSTANCE.S8_TOTAL_DISTANCE + ST_SIM_BALL_INSTANCE.S8_CURRENT_HEIGHT; S8_SIM_REBOUND_HEIGHTS[ST_SIM_BALL_INSTANCE.U2_REBOUNDS_COUNT] = ST_SIM_BALL_INSTANCE.S8_CURRENT_HEIGHT * S8_SIM_REBOUND_FACTOR; ST_SIM_BALL_INSTANCE.S8_TOTAL_DISTANCE += ST_SIM_BALL_INSTANCE.S8_CURRENT_HEIGHT; ST_SIM_BALL_INSTANCE.U2_REBOUNDS_COUNT++; if (ST_SIM_BALL_INSTANCE.U2_REBOUNDS_COUNT < ST_SIM_BALL_INSTANCE.U2_MAX_REBOUNDS) { ST_SIM_BALL_INSTANCE.S8_CURRENT_HEIGHT *= S8_SIM_REBOUND_FACTOR; ST_SIM_BALL_INSTANCE.S8_VERTICAL_VELOCITY = -sqrt(2.0 * S8_SIM_GRAVITY * ST_SIM_BALL_INSTANCE.S8_CURRENT_HEIGHT); } else { ST_SIM_BALL_INSTANCE.U1_SIM_ACTIVE = FALSE; } } } else { ST_SIM_BALL_INSTANCE.S8_Y_POSITION += ST_SIM_BALL_INSTANCE.S8_VERTICAL_VELOCITY * U4_DELTA_TIME_MS; ST_SIM_BALL_INSTANCE.S8_VERTICAL_VELOCITY += S8_SIM_GRAVITY * U4_DELTA_TIME_MS; if (ST_SIM_BALL_INSTANCE.S8_VERTICAL_VELOCITY >= 0) { ST_SIM_BALL_INSTANCE.U1_IS_FALLING = TRUE; } } } /* ------------------------------------------------------------------ Render simulation scene ------------------------------------------------------------------ */ void FP_SIM_RENDER_SCENE(HDC hdc) { // Draw ground HPEN HPEN_GROUND = CreatePen(PS_SOLID, 2, RGB(0, 128, 0)); HPEN HPEN_OLD = (HPEN)SelectObject(hdc, HPEN_GROUND); MoveToEx(hdc, 0, U4_SIM_GROUND_Y, NULL); LineTo(hdc, U4_SIM_WINDOW_WIDTH, U4_SIM_GROUND_Y); SelectObject(hdc, HPEN_OLD); DeleteObject(HPEN_GROUND); // Draw ball HBRUSH HBRUSH_BALL = CreateSolidBrush(RGB(139, 69, 19)); HBRUSH HBRUSH_OLD = (HBRUSH)SelectObject(hdc, HBRUSH_BALL); Ellipse(hdc, (int)(ST_SIM_BALL_INSTANCE.S8_X_POSITION - U1_SIM_BALL_RADIUS), (int)(ST_SIM_BALL_INSTANCE.S8_Y_POSITION - U1_SIM_BALL_RADIUS), (int)(ST_SIM_BALL_INSTANCE.S8_X_POSITION + U1_SIM_BALL_RADIUS), (int)(ST_SIM_BALL_INSTANCE.S8_Y_POSITION + U1_SIM_BALL_RADIUS)); SelectObject(hdc, HBRUSH_OLD); DeleteObject(HBRUSH_BALL); } /* ------------------------------------------------------------------ Result window procedure ------------------------------------------------------------------ */ LRESULT CALLBACK FP_RESULTS_WINDOW_PROC(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); wchar_t WSTRING_BUFFER[256]; U2 U2_OFFSET = 10; HFONT HFONT_RESULT = CreateFontW(18, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, L"Arial"); HFONT HFONT_OLD = (HFONT)SelectObject(hdc, HFONT_RESULT); swprintf(WSTRING_BUFFER, 256, L"Total Travel Distance: %.2f meters", ST_SIM_BALL_INSTANCE.S8_TOTAL_DISTANCE / 2.0); TextOutW(hdc, 10, U2_OFFSET, WSTRING_BUFFER, wcslen(WSTRING_BUFFER)); U2_OFFSET += 20; for (U2 U2_I = 0; U2_I < ST_SIM_BALL_INSTANCE.U2_REBOUNDS_COUNT; U2_I++) { swprintf(WSTRING_BUFFER, 256, L"Rebound %d Height: %.2f meters", U2_I + 1, S8_SIM_REBOUND_HEIGHTS[U2_I] / 2.0); TextOutW(hdc, 10, U2_OFFSET, WSTRING_BUFFER, wcslen(WSTRING_BUFFER)); U2_OFFSET += 20; swprintf(WSTRING_BUFFER, 256, L"Cumulative Distance: %.2f meters", S8_SIM_CUMULATIVE_DISTANCES[U2_I] / 2.0); TextOutW(hdc, 10, U2_OFFSET, WSTRING_BUFFER, wcslen(WSTRING_BUFFER)); U2_OFFSET += 20; } SelectObject(hdc, HFONT_OLD); DeleteObject(HFONT_RESULT); EndPaint(hwnd, &ps); return 0; } case WM_DESTROY: HWND_RESULT_WINDOW = NULL; return 0; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; } /* ------------------------------------------------------------------ Display simulation results ------------------------------------------------------------------ */ void FP_DISPLAY_SIMULATION_RESULTS(HINSTANCE HINSTANCE_CURRENT) { if (HWND_RESULT_WINDOW != NULL) { InvalidateRect(HWND_RESULT_WINDOW, NULL, TRUE); return; } const wchar_t CLASS_NAME[] = L"ResultWindow"; WNDCLASS WNDCLASS_RESULTS = {0}; WNDCLASS_RESULTS.lpfnWndProc = FP_RESULTS_WINDOW_PROC; WNDCLASS_RESULTS.hInstance = HINSTANCE_CURRENT; WNDCLASS_RESULTS.lpszClassName = CLASS_NAME; WNDCLASS_RESULTS.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); RegisterClass(&WNDCLASS_RESULTS); HWND_RESULT_WINDOW = CreateWindow(CLASS_NAME, L"Simulation Results", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, HINSTANCE_CURRENT, NULL); ShowWindow(HWND_RESULT_WINDOW, SW_SHOW); UpdateWindow(HWND_RESULT_WINDOW); } /* ------------------------------------------------------------------ Main window procedure ------------------------------------------------------------------ */ LRESULT CALLBACK FP_MAIN_WINDOW_PROC(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_CREATE: { // Create input controls CreateWindow(L"STATIC", L"Initial Height (meters):", WS_VISIBLE | WS_CHILD, 20, U4_SIM_WINDOW_HEIGHT - 140, 170, 30, hwnd, NULL, NULL, NULL); HWND_CTRL_HEIGHT_INPUT = CreateWindow(L"EDIT", L"100", WS_VISIBLE | WS_CHILD | WS_BORDER | ES_NUMBER, 190, U4_SIM_WINDOW_HEIGHT - 140, 100, 30, hwnd, (HMENU)U2_CTRL_HEIGHT_INPUT, NULL, NULL); CreateWindow(L"STATIC", L"Max Rebounds:", WS_VISIBLE | WS_CHILD, 20, U4_SIM_WINDOW_HEIGHT - 100, 170, 30, hwnd, NULL, NULL, NULL); HWND_CTRL_REBOUNDS_INPUT = CreateWindow(L"EDIT", L"10", WS_VISIBLE | WS_CHILD | WS_BORDER | ES_NUMBER, 190, U4_SIM_WINDOW_HEIGHT - 100, 100, 30, hwnd, (HMENU)U2_CTRL_REBOUNDS_INPUT, NULL, NULL); HWND_CTRL_SUBMIT_BUTTON = CreateWindow(L"BUTTON", L"Submit", WS_VISIBLE | WS_CHILD, 310, U4_SIM_WINDOW_HEIGHT - 120, 100, 40, hwnd, (HMENU)U2_CTRL_SUBMIT_BUTTON, NULL, NULL); // Initialize default ball position ST_SIM_BALL_INSTANCE.S8_X_POSITION = U4_SIM_WINDOW_WIDTH / 2.0; ST_SIM_BALL_INSTANCE.S8_Y_POSITION = U4_SIM_GROUND_Y - 50; SetTimer(hwnd, U4_SIM_TIMER_ID, 10, NULL); return 0; } case WM_COMMAND: { if (LOWORD(wParam) == U2_CTRL_SUBMIT_BUTTON) { wchar_t HEIGHT_BUFFER[32], REBOUNDS_BUFFER[32]; // Get input values GetWindowText(HWND_CTRL_HEIGHT_INPUT, HEIGHT_BUFFER, 32); double HEIGHT_VALUE = _wtof(HEIGHT_BUFFER); GetWindowText(HWND_CTRL_REBOUNDS_INPUT, REBOUNDS_BUFFER, 32); int REBOUNDS_VALUE = _wtoi(REBOUNDS_BUFFER); // Validate inputs if (HEIGHT_VALUE <= 0 || HEIGHT_VALUE > 150) { MessageBox(hwnd, L"Height out of range! (0-150 meters)", L"Invalid Input", MB_ICONERROR); return 0; } if (REBOUNDS_VALUE <= 0 || REBOUNDS_VALUE > 100) { MessageBox(hwnd, L"Rebound count must be between 1-100", L"Invalid Input", MB_ICONERROR); return 0; } // Stop current simulation KillTimer(hwnd, U4_SIM_TIMER_ID); // Initialize new simulation FP_SIM_INITIALIZE_BALL(HEIGHT_VALUE, REBOUNDS_VALUE); // Record start time U4_LAST_SIM_TICK_TIME = GetTickCount(); // Restart timer SetTimer(hwnd, U4_SIM_TIMER_ID, 10, NULL); // Force redraw InvalidateRect(hwnd, NULL, TRUE); } return 0; } case WM_TIMER: { if (wParam == U4_SIM_TIMER_ID) { // Calculate time delta U4 CURRENT_TIME = GetTickCount(); U4 DELTA_TIME = (U4_LAST_SIM_TICK_TIME == 0) ? 0 : (CURRENT_TIME - U4_LAST_SIM_TICK_TIME); U4_LAST_SIM_TICK_TIME = CURRENT_TIME; if (ST_SIM_BALL_INSTANCE.U1_SIM_ACTIVE) { // Update ball physics FP_SIM_UPDATE_BALL(DELTA_TIME); // Redraw only the necessary area RECT UPDATE_RECT = { 0, 0, U4_SIM_WINDOW_WIDTH, U4_SIM_GROUND_Y + U1_SIM_BALL_RADIUS }; InvalidateRect(hwnd, &UPDATE_RECT, TRUE); } else { // Simulation complete - show results KillTimer(hwnd, U4_SIM_TIMER_ID); FP_DISPLAY_SIMULATION_RESULTS( (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE) ); } } return 0; } case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); // Clear background RECT rect; GetClientRect(hwnd, &rect); FillRect(hdc, &rect, (HBRUSH)(COLOR_WINDOW+1)); // Draw simulation elements FP_SIM_RENDER_SCENE(hdc); // Display initial wait state if (ST_SIM_BALL_INSTANCE.S8_INITIAL_WAIT_TIME_MS > 0) { wchar_t STATUS[100]; swprintf(STATUS, 100, L"Initial state: %.1f seconds remaining", ST_SIM_BALL_INSTANCE.S8_INITIAL_WAIT_TIME_MS / 1000.0); HFONT HFONT_STATUS = CreateFont(18, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, L"Arial"); HFONT HFONT_OLD = (HFONT)SelectObject(hdc, HFONT_STATUS); TextOut(hdc, 20, 20, STATUS, wcslen(STATUS)); SelectObject(hdc, HFONT_OLD); DeleteObject(HFONT_STATUS); } EndPaint(hwnd, &ps); return 0; } case WM_DESTROY: { KillTimer(hwnd, U4_SIM_TIMER_ID); PostQuitMessage(0); return 0; } default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; } /* ------------------------------------------------------------------ Application entry point ------------------------------------------------------------------ */ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { const wchar_t CLASS_NAME[] = L"BouncingBallSimulation"; WNDCLASS WNDCLASS_MAIN = {0}; WNDCLASS_MAIN.lpfnWndProc = FP_MAIN_WINDOW_PROC; WNDCLASS_MAIN.hInstance = hInstance; WNDCLASS_MAIN.lpszClassName = CLASS_NAME; WNDCLASS_MAIN.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); if (!RegisterClass(&WNDCLASS_MAIN)) { return 0; } // Calculate window size including non-client area RECT rect = {0, 0, U4_SIM_WINDOW_WIDTH, U4_SIM_WINDOW_HEIGHT}; AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, TRUE); int WIDTH = rect.right - rect.left; int HEIGHT = rect.bottom - rect.top; // Create main window HWND_SIM_MAIN_WINDOW = CreateWindow( CLASS_NAME, L"Bouncing Ball Simulation", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, WIDTH, HEIGHT, NULL, NULL, hInstance, NULL ); if (!HWND_SIM_MAIN_WINDOW) { return 0; } // Main message loop MSG MSG_SIM_LOOP; while (GetMessage(&MSG_SIM_LOOP, NULL, 0, 0)) { TranslateMessage(&MSG_SIM_LOOP); DispatchMessage(&MSG_SIM_LOOP); } return (int)MSG_SIM_LOOP.wParam; } 就在源代码上修改编码规范,刚刚的代码又逻辑不通了’
08-09
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值