MFC 自绘按钮划过或点击会出现闪烁问题,求助精通GDI高手解决

鼠标划进按钮再划出再划进,速度快一点或慢一点各种尝试,会发现闪炼现象(即中间会一个白色底短时间内出现),请做过相关开发的大神们帮解决

如下是一个vs2010中建立的测试工程,打包在下面链接。
链接: https://pan.baidu.com/s/1jnL4f6qapbUBP3od4WoQRw 密码: 1jqk

(ps: C币是不是给多了还是不够,C友们不要担心问题难,本人因为没做过贴图这块学习和开发,把重心放在别的地方,奉行拿来主义,这工程中的按钮自绘类我就是从别的C友博客中直接拷贝来的,我想在人家博客下面问,不知道何年马月才可能被回复,人家也不一定愿意去再看这问题,这个按钮闪烁问题解决了,我就谢谢各位了,可惜CSDN没法散币给帮助的大家)

(再PS:这闪烁问题我尝试解决,但是能力不够,我觉得问题最可能在 SelfControlPublic.cpp 这个类中,大楖是没有使用到双缓冲,但是不知道怎么改,我只想问题再点解决,所以提供下我的猜测)

(再再PS:下面的zqbnqsdsmd网友,我不需要这种贴一大段代码,我要修改好的工程或者一段能解决的方法,只采纳能解决我问题的答案,你这样贴,和我百度搜索各种尝试有啥区别)

17个回答

void CPngButton::PaintParent()
{
CRect rect;
GetWindowRect(&rect);
Invalidate();
//GetParent()->ScreenToClient(&rect);
//GetParent()->InvalidateRect(&rect); //这里会导致闪烁,只能用双缓冲
}
我把这个函数改了一下,移动进去时候不会闪了,不知老兄是否还有时间看看啊,其实我这里有完整的一个很好用的图片按钮,如果老兄有兴趣,加个联系方式我发给你,你觉得满意也好结贴

evolay
老爸我爱你 解决了,非常感谢热心的前辈。
一年多之前 回复

给dialog加上 WS_CLIPCHILDREN .
这样, 父窗口重画的时候, 子窗口可以不用重画,直接把子窗口的东西clip过来.

WS_CLIPCHILDREN 属性!!!

evolay
老爸我爱你 回复phenix2009: 好的,我加你QQ了。
一年多之前 回复
phenix2009
白色一大坨 回复evolay: 之前回答的被删了,我改了你的CPngButton::PaintParent函数,目前的确不闪了,如果需要可以加个联系方式,我好帮你解决一下
一年多之前 回复
dabocaiqq
请你们大家多多姿瓷我菠菜菌 回复evolay: 除了我会回答你的问题,还有谁会呢。我是真心要帮你。你不采纳就算了。
接近 2 年之前 回复
evolay
老爸我爱你 要是你有心帮我调,代码链接都在上面。CSDN上的大家都看不中这点C币,没解决就算了不采纳任何。
接近 2 年之前 回复
dabocaiqq
请你们大家多多姿瓷我菠菜菌 回复evolay: 不然你采纳了我的回答,我帮你调试下你的程序。
接近 2 年之前 回复
evolay
老爸我爱你 我试了一下,如果按钮不用雪碧图,你这种方法没问题,用了雪碧图后,就不行了,按钮不能在多种状态下切换(颜色深浅变化)
接近 2 年之前 回复

oid CXPButton::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if (!m_bTracking)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
tme.dwFlags = TME_LEAVE | TME_HOVER;
tme.dwHoverTime = 1;
m_bTracking = _TrackMouseEvent(&tme);
}
CButton::OnMouseMove(nFlags, point);
}
接着添加WM_MOUSELEAVE和WM_MOUSEHOVER消息消息函数。在CXPButton类的声明中(即在XPButton.h文件中)找到afx_msg void OnMouseMove(UINT nFlags, CPoint point);的函数声明,紧接其下输入
afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnMouseHover(WPARAM wParam, LPARAM lParam);
然后在XPButton.cpp文件中找到ON_WM_MOUSEMOVE(),紧接其后输入
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
当然最后还有函数的实现了,详细代码可见本篇提供的源程序,这里就不再重复了。

DRAWITEMSTRUCT结构的定义如下:
typedef struct tagDRAWITEMSTRUCT {
UINT CtlType; //控件类型
UINT CtlID; //控件ID
UINT itemID; //菜单项、列表框或组合框中某一项的索引值
UINT itemAction; //控件行为
UINT itemState; //控件状态
HWND hwndItem; //父窗口句柄或菜单句柄
HDC hDC; //控件对应的绘图设备句柄
RECT rcItem; //控件所占据的矩形区域
DWORD itemData; //列表框或组合框中某一项的值
} DRAWITEMSTRUCT, *PDRAWITEMSTRUCT, *LPDRAWITEMSTRUCT;

phenix2009
白色一大坨 回复evolay: 有需要可以加我qq465617727
一年多之前 回复
evolay
老爸我爱你 兄台,感谢回复。你这回复两个不一样的答案是咋回事呀,而且你这复制一大段代码也不加文字说明,没看懂呀
接近 2 年之前 回复

1 CDC buttonDC;
2 CBitmap bitmapTrans;
3 BITMAP bmp;
4 CDC mem;
5 CRect rc;
6 buttonDC.Attach(lpDrawItemStruct->hDC);//得到用于绘制按钮的DC
7 mem.CreateCompatibleDC(&buttonDC);//准备向按钮区域传输图形

8

9 if (lpDrawItemStruct->CtlID == IDC_BUTTON1)
10 {
11 rc = lpDrawItemStruct->rcItem;//获取按钮所占的矩形大小
12 UINT state = lpDrawItemStruct->itemState;//获取按钮当前的状态,不同状态绘制不同的按钮

13 if (state & ODS_FOCUS)//如果按钮已经取得焦点,绘制选中状态下的按钮
14 {
15 bitmapTrans.LoadBitmap(IDB_BITMAP2);
16 bitmapTrans.GetBitmap(&bmp);
17 CBitmap * old = mem.SelectObject(&bitmapTrans);
18 //向按钮传输位图,使用stretcnblt可以使图片随按钮大小而改变
19 buttonDC.StretchBlt(rc.left,rc.top,rc.right,rc.bottom,&mem,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);
20 mem.SelectObject(old);
21 bitmapTrans.DeleteObject();
22 }
23 else //如果按钮已经取得焦点,绘制选中状态下的按钮
24 {
25 bitmapTrans.LoadBitmap(IDB_BITMAP3);
26 CBitmap *old2 = mem.SelectObject(&bitmapTrans);
27 bitmapTrans.GetBitmap(&bmp);
28 CBitmap *old=mem.SelectObject(&bitmapTrans);
29 buttonDC.StretchBlt(rc.left,rc.top,rc.right,rc.bottom,&mem,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);
30 mem.SelectObject(old2);
31 bitmapTrans.DeleteObject();
32 }
33 }

     void CMyDlg::OnNcLButtonDown(UINT nHitTest, CPoint point)  
{     

   // 1,查询当前系统“拖动显示窗口内容”设置  
    SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, &m_bDragFullWindow, NULL);  

   // 2,如果需要修改设置,则在每次进入CDialog::OnNcLButtonDown默认处理之前修改  
    if(m_bDragFullWindow)  
         SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, FALSE, NULL, NULL);  
   // 3,默认处理,系统会自动绘制虚框  
    CDialog::OnNcLButtonDown(nHitTest, point);  

   // 4,默认处理完毕后,还原系统设置  
    if(m_bDragFullWindow)  
         SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, NULL, NULL);  
}  

void CMyDlg::OnNcLButtonDown(UINT nHitTest, CPoint point)

{

// 1,查询当前系统“拖动显示窗口内容”设置

SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, &m_bDragFullWindow, NULL);

// 2,如果需要修改设置,则在每次进入CDialog::OnNcLButtonDown默认处理之前修改

if(m_bDragFullWindow)

SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, FALSE, NULL, NULL);

// 3,默认处理,系统会自动绘制虚框

CDialog::OnNcLButtonDown(nHitTest, point);

// 4,默认处理完毕后,还原系统设置

if(m_bDragFullWindow)

SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, NULL, NULL);

}

添加 以下代码在 .h中:
//member variable
CPoint m_oldPt;
CPoint m_offsetPt;
CRect m_wndRc;
CRect m_newRc;
CRect m_newSizeRect;
CRect m_oldSizeRect;
BOOL m_bDrawFrame;
BOOL m_needFinish;
BOOL m_bDrawSize;
BOOL m_needSize;

LRESULT OnMoving(WPARAM,LPARAM);
LRESULT OnExitSizeMove(WPARAM,LPARAM);
LRESULT OnEnterSizeMove(WPARAM, LPARAM);
LRESULT OnSizing(WPARAM,LPARAM);

DECLARE_MESSAGE_MAP()

添加 以下代码在 .CPP中:
ON_MESSAGE(WM_MOVING,OnMoving)
ON_MESSAGE(WM_EXITSIZEMOVE,OnExitSizeMove)
ON_MESSAGE(WM_ENTERSIZEMOVE,OnEnterSizeMove)
ON_MESSAGE(WM_SIZING,OnSizing)
END_MESSAGE_MAP()

下面是简单的处理函数,你可以扩展

LRESULT CPrimeNumDlg::OnEnterSizeMove(WPARAM, LPARAM){
GetWindowRect(&m_wndRc);
m_oldSizeRect = m_wndRc;
m_oldPt = CPoint(m_wndRc.left,m_wndRc.top);
m_offsetPt = CPoint(0,0);
m_bDrawFrame = FALSE;
return TRUE; //we don't process this message

}

LRESULT CPrimeNumDlg::OnExitSizeMove(WPARAM,LPARAM){
if(m_needFinish){
CRect rect;
rect.left = m_oldPt.x - m_offsetPt.x;
rect.top = m_oldPt.y - m_offsetPt.y;
rect.right = rect.left + m_wndRc.Width();
rect.bottom = rect.top + m_wndRc.Height();
DrawDashFrame(rect);
m_needFinish = FALSE;

SetWindowPos(NULL,m_oldPt.x,m_oldPt.y,m_wndRc.Width(),m_wndRc.Height(),\
            SWP_NOSENDCHANGING ); //prevent receiving more moving message
GetWindowRect(&m_wndRc);
m_oldPt = CPoint(m_wndRc.left,m_wndRc.top);
m_offsetPt = CPoint(0,0);
m_bDrawFrame = FALSE;

}
if(m_needSize){
m_bDrawSize = FALSE;
m_needSize = FALSE;
DrawDashFrame(m_oldSizeRect);
SetWindowPos(NULL,m_newSizeRect.left,m_newSizeRect.top,m_newSizeRect.Width(),m_newSizeRect.Height(),\
SWP_NOSENDCHANGING ); //prevent receiving more moving message
}
return TRUE; //we don't process this message
}

void CPrimeNumDlg::DrawDashFrame(CRect& rect){

CPen pen;
pen.CreatePen(PS_DASH,1,RGB(0,0,0));
CWnd* p_desktop = GetDesktopWindow();
CDC* p_dc_desktop = p_desktop->GetWindowDC();

p_dc_desktop->SetROP2(R2_XORPEN );
CPen* p_old_pen = p_dc_desktop->SelectObject(&pen);
p_dc_desktop->MoveTo(rect.left,rect.top);
p_dc_desktop->LineTo(rect.left,rect.bottom);

p_dc_desktop->MoveTo(rect.left,rect.bottom);
p_dc_desktop->LineTo(rect.right,rect.bottom);

p_dc_desktop->MoveTo(rect.right,rect.bottom);
p_dc_desktop->LineTo(rect.right,rect.top);

p_dc_desktop->MoveTo(rect.right,rect.top);
p_dc_desktop->LineTo(rect.left,rect.top);
p_dc_desktop->SelectObject(p_old_pen);
p_desktop->ReleaseDC(p_dc_desktop);
}

LRESULT CPrimeNumDlg::OnMoving(WPARAM wp,LPARAM lp){

RECT* p_rc = (RECT*)lp;
m_newRc = CRect(p_rc);
CPoint pt;
GetCursorPos(&pt);

if(!m_bDrawFrame){

m_bDrawFrame = TRUE;
m_offsetPt = CPoint(pt.x - m_wndRc.left,pt.y - m_wndRc.top);
m_oldPt = pt;

CRect rect;
rect.left = m_oldPt.x - m_offsetPt.x;
rect.top = m_oldPt.y - m_offsetPt.y;
rect.right = rect.left + m_wndRc.Width();
rect.bottom = rect.top + m_wndRc.Height();
DrawDashFrame(rect);
m_needFinish = TRUE;

}
else{
CRect rect;
rect.left = m_oldPt.x - m_offsetPt.x;
rect.top = m_oldPt.y - m_offsetPt.y;
rect.right = rect.left + m_wndRc.Width();
rect.bottom = rect.top + m_wndRc.Height();
DrawDashFrame(rect);

rect.left = pt.x - m_offsetPt.x;
rect.top = pt.y - m_offsetPt.y;
rect.right = rect.left + m_wndRc.Width();
rect.bottom = rect.top + m_wndRc.Height();
DrawDashFrame(rect);
m_oldPt = pt;

}

int width = p_rc->right - p_rc->left;
int height = p_rc->bottom - p_rc->top;

p_rc->left = m_wndRc.left;
p_rc->right = p_rc->left + width;
p_rc->top = m_wndRc.top;
p_rc->bottom = p_rc->top + height;
return FALSE; //we process this message

}

LRESULT CPrimeNumDlg::OnSizing(WPARAM wp,LPARAM lp){

m_needSize = TRUE;

if(!m_bDrawSize){
DrawDashFrame(m_wndRc);
m_oldSizeRect = m_wndRc;
m_bDrawSize = TRUE;

}
else{
RECT* p_rc = (RECT*)lp;
m_newSizeRect = CRect(p_rc);
DrawDashFrame(m_oldSizeRect);
DrawDashFrame(m_newSizeRect);
p_rc->left = m_wndRc.left;
p_rc->right = m_wndRc.right;
p_rc->top = m_wndRc.top;
p_rc->bottom = m_wndRc.bottom;
m_oldSizeRect = m_newSizeRect;
}
return FALSE; //we don't process this message
}

LRESULT CPrimeNumDlg::OnEnterSizeMove(WPARAM, LPARAM){
GetWindowRect(&m_wndRc);
m_oldSizeRect = m_wndRc;
m_oldPt = CPoint(m_wndRc.left,m_wndRc.top);
m_offsetPt = CPoint(0,0);
m_bDrawFrame = FALSE;
return TRUE; //we don't process this message

}

 LRESULT CPrimeNumDlg::OnEnterSizeMove(WPARAM, LPARAM){
GetWindowRect(&m_wndRc);
m_oldSizeRect = m_wndRc;
m_oldPt = CPoint(m_wndRc.left,m_wndRc.top);
m_offsetPt = CPoint(0,0);
m_bDrawFrame = FALSE;
return TRUE; //we don't process this message

}
共17条数据 1 尾页
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
【求助】GDI+ && MFC如何实现矩形内4种颜色相互过渡?
![图片说明](https://img-ask.csdn.net/upload/202001/20/1579485557_959952.png) 问一下dalao们,GDI+ && MFC里怎么实现图片中的渐变效果。查了很多资料没找到合适的函数
MFC 自绘按钮响应点击事件偏慢
void CButtonEx::DrawItem(LPDRAWITEMSTRUCT lpDS) { // TODO: Add your code to draw the specified item CRect rect = lpDS->rcItem; CDC *pDC = CDC::FromHandle(lpDS->hDC); pDC->SelectStockObject(GRAY_BRUSH); pDC->FillSolidRect(rect,GetSysColor(COLOR_BTNFACE)); if ((lpDS->itemState&ODS_SELECTED))//选中的时候 { pDC->DrawEdge(rect,BDR_SUNKENINNER|BDR_SUNKENOUTER,BF_RECT); rect.OffsetRect(1,1); } else //没有选中的时候 { pDC->DrawEdge(rect,BDR_RAISEDINNER,BF_RECT); } int n = rect.Height(); n = (n-16)/2; if ((lpDS->itemState&ODS_SELECTED))//选中的时候 n+=2; DrawIconEx(lpDS->hDC,n,n,m_hIcon,16,16,0,0,DI_NORMAL); CString strCaption; GetWindowText(strCaption);//获取按钮文本 // pDC->SetBkMode(TRANSPARENT); CRect rc(rect); rc.left = n; pDC->DrawText(strCaption, rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);//重绘按钮文本 if (lpDS->itemState&ODS_FOCUS)//获得焦点的时候 { rect.DeflateRect(2,2); pDC->DrawFocusRect(rect); } }
MFC CPropertySheet上面的默认按钮进行自绘
各位朋友好,我想要对MFC CPropertySheet上面的默认按钮进行自绘。但是网上找了各种资料都没有找到合适的。 下图红框部分就是CPropertySheet自带的按钮,但是和我界面的设计风格不一样,想要自绘。望大佬支支招。 ![图片说明](https://img-ask.csdn.net/upload/201909/06/1567755434_277402.png)
MFC CEdit自定义密码编辑框显示字符问题
MFC密码编辑框默认显示的是‘*’,如何显示为黑点,我利用SetPasswordChar(_T('●')),显示为问号,求大神解答
请问有人知道VS2019的MFC无法添加事件是为什么吗?没有消息类型
请问有人知道VS2019的MFC无法添加事件是为什么吗?没有消息类型![图片说明](https://img-ask.csdn.net/upload/202002/07/1581088297_140718.png)
VS2019 MFC可以使用TeeChart Pro V5 ActiveX控件吗?
在安装有vs2019的Windows10平台安装了TeeChart Pro V5控件,但是在使用时出现了问题,对话框可以正常拖入控件,因为VS2019 MFC去掉了MFC类向导的部分导入方式,所以不知道如何才能解决CTChart类的添加问题,使TeeChart Pro V5 ActiveX控件可以使用?
vs2010 mfc 对话框程序---------多层对话框的实现
请教各位,如何实现:点主对话框的一个按钮,弹出一个小对话框,输入正确密码后才能弹出另外一个对话框。主对话框和子对话框之间需要传递一些参数。谢谢。
不同MFC对话框之间按钮的点击的问题
MFC关于按钮自动点击的问题,请问如何点击另一个窗口上的一个按钮,调用OnCutton1前面的对象名怎么写?
vs2010 MFC /SQL server 几个问题
最近在看SQL server,想用MFC做的客户端访问远程的server,看到很多网友在问 数据库访问方式(ODBC ODBC(MFC) DAO OLEDB ADO)的区别。原理大概明白了,但是有些别的问题。 我们客户用的SQL server,但是没有告诉我需要用那种方式去连接server, 我想知道是不是不用知道什么方式,不管那种方式都可以访问server获取数据? 也也就是SQL server是不是默认支持这些协议,有没有哪位好心人能给科普下MFC和server的实施?
请大佬指点迷津,请ocx中启动另一个进程作为子窗口,在子窗口中切换中英文输入模式(CTRL + SPACE),不起作用?
1.问题描述:MFC应用程序中,嵌入一个ocx控件,在控件中启动另一个进程,并作为子窗口;在子窗口中切换中英文模式,不起作用! 2.ocx控件中的Oncreate函数中,启动进程代码: ``` if (COleControl::OnCreate(lpCreateStruct) == -1) return -1; m_hWndMain = GetSafeHwnd(); // 启动进程 ZeroMemory(&m_sei, sizeof(SHELLEXECUTEINFO));//使用前最好清空 m_sei.cbSize = sizeof(SHELLEXECUTEINFO);//管理员权限执行cmd,最基本的使用与 ShellExecute 类似 m_sei.fMask = SEE_MASK_NOCLOSEPROCESS; m_sei.lpVerb = TEXT("runas"); m_sei.lpFile = m_strAllPath; m_sei.lpDirectory = m_strAllPath; m_sei.lpParameters = GetVisitPara(); // 构造CEF需要访问的参数 m_sei.nShow = SW_HIDE; if(!ShellExecuteEx(&m_sei)) { AfxMessageBox(_T("初始化失败,启动MxvWebClient失败,请确认安装盘是否正确!")); return FALSE; } m_nPid = GetProcessId(m_sei.hProcess); GetWindowRect(&g_winRect); ``` 通过进程的名称找到句柄m_hWndFind,并设置父子关系;相关代码: ``` ::SetParent(m_hWndFind, m_hWndMain); long nNewType = GetWindowLong(m_hWndFind, GWL_STYLE) &~WS_POPUP &~WS_BORDER & ~WS_CAPTION & ~WS_THICKFRAME /*| WS_CHILD*/ ; ::SetWindowLong(m_hWndFind, GWL_STYLE, nNewType); //先改变大小,再发送消息 ::MoveWindow(m_hWndFind, 0, 0, g_winRect.Width(), g_winRect.Height(), FALSE); ::ShowWindow(m_hWndFind, SW_SHOW); ``` 3.在ocx控件中的进程的输入框中,切换中英文输入模式,按键CTRL+SPACE,不能切换
有关MFC中刷新控件的问题?
我有一个按钮,有个编辑框,在编辑框中输入数字,通过点击它会有我输入个数的编辑框出现,我希望在我换数字重新点击的时候,只出现最新的这次输入的相应结果,应该怎么做呢
mfc 按钮背景 多个按钮
mfc多个按钮中每一按钮单击显示一种颜色 点击其它按钮,之前的按钮效果失效 求大神解决,小弟是新手已经被这问题弄崩溃了 这次一定不忘结题!
MFC编程遇到问题求助大神
求助各路大神。。 我在VC 6.0上编写MFC程序,我在一个dlg对话框里面加两个按钮控件,设置点击它们会弹出不同的模态对话框(用的dlg.DoModal())。新的对话框有自己的编辑框和按钮,我在编辑框输入数据后点击按钮后会在结果编辑框中输出数据,但是我发现一个问题。 我这里想要做的是,点击两个按钮分别弹出一个模逆运算和模幂运算的对话框,我先写模逆的,编译运行,点击按钮,弹出对话框,在编辑框输入数据(运算数和模数),点击按钮,输出数据,结果没问题。接着我写模幂的,但是发现死活就不行了,也不报错,编译能运行,点击按钮,弹出模幂对话框,不管输入什么数据,输出始终都是0,我直接把用于输出结果的那个编辑框嗦绑定的变量人为赋值为一个非0的数,它输出居然还是0。开始我以为是第二个对话框编写函数的时候出了问题,但是又始终检查不出来就全部重新做,这次然后先写模幂的,发现模幂的可以运行了,然后写模逆,但是这次模逆的却出现刚才那个问题了,始终输出为0,感觉它就好像根本没有调用我给按钮写的响应函数一样。 小弟实在很困惑,MFC学得比较肤浅,实在不知道怎么回事了,求助各路大神。
vs2010 MFC +SQL server2014 如何高效查询取出大量数据。
过年变成最不受欢迎的人,自我隔离在家。 哪位高手没事帮我看看这个问题。 需要取出sql表中的三列,大概10万行,每行的中一个字段含长文本大概10kb,所以每次需要用mfc做的客户端取出约1Gb的数据,并把每行的10kb数据生成约10Kb的文本文件,即要生成10万个文本文件。 要求在2小时内取出数据并生成10万文件。 哪位能给出简单的思路甚至代码?谢谢
MFC框架下自定义类中定义多线程问题
本人尝试在MFC框架下自定义一个类,该类负责接收和解码视频数据,因此需要在该类中定义多线程来做这件事情,以防止在对话框调用该类的时候卡死。 目前本人在自定义类中使用了static的方式开启了多线程,在win10下运行也很正常。然而在测试兼容性的时候发现该程序在win7 64位下会出错,出错的原因似乎是因为我在类内使用了static函数定义了多线程,而我又声明了该类的几个实体,因此static函数出现了调用实体出错的问题。 想问问看: 1.有没有老哥遇到过这种问题? 2.有没有比较好的解决思路? 3.是不是不应该在一个类中用static函数的形式定义线程? 4.像多路接收解码的功能除了封装成一个类然后使用多个实体来做外,还有没有更好的封装方式? ``` class HWdecode { public: bool changertspurl = false;//是否改变rtsp的地址标志 bool reconnect = false;//需要断线重连标志 bool haveconnect = false;//正常连接标志位 CCriticalSection* mlock;//线程临界区 bool dodecodesave = false;//像素转换开启标志位 //参数对象 FFmpegDemuxer* demuxer = NULL;//FFMPEG对象 CUcontext cuContext;//Cuda设备 NvDecoder* dec = NULL;//Cuda解码对象 CUdeviceptr dpFrame = 0;//数据存储对象初始化 int hwinit()//显卡设备初始化 { int iGpu = 0;//选择解码播放的GPU,只有一个的话直接设置为0就行 //检测硬件GPU设备 ck(cuInit(0)); int nGpu = 0; ck(cuDeviceGetCount(&nGpu)); if (iGpu < 0 || iGpu >= nGpu) { std::cout << "没有相应的GPU" << std::endl; return 0; } //获得CUDA对象 CUdevice cuDevice = 0; ck(cuDeviceGet(&cuDevice, iGpu)); char szDeviceName[80]; ck(cuDeviceGetName(szDeviceName, sizeof(szDeviceName), cuDevice)); std::cout << "GPU in use: " << szDeviceName << std::endl; ck(cuCtxCreate(&cuContext, CU_CTX_SCHED_BLOCKING_SYNC, cuDevice)); return 1; } int ffmpeginit(char* url)//ffmpeg对象初始化 { demuxer = new FFmpegDemuxer(url); if (demuxer->fmtc == NULL) { return 0; } else { //RGBA帧存储显存初始化 return 1; } } void cudadecoderinit()//cuda解码对象初始化 { ck(cuMemAlloc(&dpFrame, demuxer->GetWidth() * demuxer->GetHeight() * 4)); //解码器初始化 dec = new NvDecoder(cuContext, (*demuxer).GetWidth(), (*demuxer).GetHeight(), true, FFmpeg2NvCodecId((*demuxer).GetVideoCodec())); } DWORD decAndshow()//解码和播放 { int nVideoBytes = 0, nFrameReturned = 0, nFrame = 0; uint8_t* pVideo = NULL, ** ppFrame; long bt = clock(); do { uint8_t* getdpframe = (uint8_t*)dpFrame; demuxer->Demux(&pVideo, &nVideoBytes);//获取一帧视频数据 dec->Decode(pVideo, nVideoBytes, &ppFrame, &nFrameReturned);//解码这一帧数据 //if (!nFrame && nFrameReturned) // LOG(INFO) << HWD.dec->GetVideoInfo(); if (dodecodesave) { for (int i = 0; i < nFrameReturned; i++) { mlock->Lock(); //对解码出来的图像数据类型做转换,转到BGRA printf("GetWidth %d\n", dec->GetWidth()); printf("GetHeight %d\n", dec->GetHeight()); if (dec->GetBitDepth() == 8) { if (dec->GetOutputFormat() == cudaVideoSurfaceFormat_YUV444) YUV444ToColor32<RGBA32>((uint8_t*)ppFrame[i], dec->GetWidth(), getdpframe, 4 * dec->GetWidth(), dec->GetWidth(), dec->GetHeight()); else // default assumed as NV12 Nv12ToColor32<RGBA32>((uint8_t*)ppFrame[i], dec->GetWidth(), getdpframe, 4 * dec->GetWidth(), dec->GetWidth(), dec->GetHeight()); } mlock->Unlock(); } } nFrame += nFrameReturned; } while (nVideoBytes && changertspurl == false); changertspurl = false;//将rtsp地址修改标志位重新设置为否 printf("退出,尝试断线连回\n"); reconnect = true; delete demuxer; std::cout << "Total frame decoded: " << nFrame << std::endl; std::cout << "花费时间:" << clock() - bt << "ms" << std::endl; std::cout << "FPS:" << nFrame / ((clock() - bt) / 1000.0) << std::endl; return 1; } HANDLE pRecvAndShowThread;//接收显示线程对象 static DWORD ThreadRtspRecvShowFun(LPVOID lpParam) { return ((HWdecode*)lpParam)->decAndshow();//调用线程的处理函数 } int Star(char* url, CCriticalSection * lock) { mlock = lock; if (!hwinit())//初始化硬件设备 { std::cout << "硬件初始化失败!" << std::endl; return 0; } if (!ffmpeginit(url))//初始化硬件设备 { std::cout << "无法连接码流!" << std::endl; return 0; } cudadecoderinit(); pRecvAndShowThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)HWdecode::ThreadRtspRecvShowFun, this, 0, NULL); return 1; } int ReStar(char* url, CCriticalSection* lock)//断线重连 { if (!ffmpeginit(url))//初始化硬件设备 { std::cout << "无法连接码流!" << std::endl; return 0; } if (!haveconnect) { cudadecoderinit(); } pRecvAndShowThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)HWdecode::ThreadRtspRecvShowFun, this, 0, NULL); return 1; } }; ```
OpenGL绘图颜色设置无效(MFC环境下)
用MFC做了一个小程序,大致功能是先显示一个读入的图形,然后在条件变化时显示另一个图形,最初的显示是正常的,然后消息处理函数也没问题,自定义了一个draw函数如下 void CReadView::Draw(){ glClearColor(1.0, 1.0,1.0, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer glEnable(GL_COLOR_MATERIAL); glLoadIdentity(); // Reset The Current Modelview Matrix glTranslatef(-1.5f, 0.0f, -6.0f);//物体左移1.5,向内移6,相当于移动镜头一样,让物体进入镜头中 glColor3f(1.0, 0.0, 0.0); glBegin(GL_TRIANGLES); // 绘制三角形(逆时针画出来的三角形才是正面朝着我们的) glVertex3f(-1.0, -1.0, 0.0); // 左下顶点(//glVertex 的第一个参数是X坐标,然后依次是Y坐标和Z坐标) glVertex3f(1.0, -1.0, 0.0); // 右下顶点 glVertex3f(0.0, 1.0, 0.0); // 上顶点 glEnd(); // 三角形绘制结束 glColor3f(0.4, 0.75, 1.0); glRectf(1.5f, 1.5f, 2.5f, 2.5f); glLineWidth(3); glBegin(GL_LINES); glColor3f(1.0, 0.0, 0.0); glVertex2f(3.0f, 0.0f); glVertex2f(3.5f, 0.0f); //在这里使用glVertex*系列函数 指定你所希望的顶点位置 glEnd(); glLineWidth(1); glColor3f(1.0f, 1.0f, 0.0f); glBegin(GL_LINES); glVertex3f(-3.0f, 2.0f, 3.0f); glVertex3f(3.0f, 1.0f, 0.0f); glEnd(); glColor3f(1.0f,0.0f,0.0f); glBegin(GL_LINES); glVertex2i(1, 1); glVertex2i(3, 3); glEnd(); glFlush(); } 把它放到的OnDraw函数里进行调用,程序可以正常执行,只是画出来的这些线段、图形都没有颜色(是默认的黑色),也就是glColor3f似乎失效了。 这些绘制的函数都是从网上找来做测试的,在正常单独的OpenGL环境里应该也都是没问题的。是MFC的问题吗?或者是OpenGL需要某些重新的预设置?求解答
有关MFC中容器的问题?
我想在MFC的对话框中摆放一个容器,将我动态创建的任意数量的控件放进去,应该怎么做,在网上没找到什么相关内容,没啥头绪,有大佬帮助一下么
有关MFC动态创建的静态文本框在最大化时内容出现错位的问题?
![图片说明](https://img-ask.csdn.net/upload/202001/09/1578558912_126265.png)![图片说明](https://img-ask.csdn.net/upload/202001/09/1578558923_944333.png) 第一张图片时对话框才出现的时候的,第二张是我点击最大化后形成的,这种情况是怎么造成的呢
MFC自绘按钮,如何在enableWindow的状态改变时,进行这个button对应图片的更改
我子绘了一个button,继承自CButton。在初始化的时候就已经传入了多张png图片的路径,对应了按下、普通、hover这几个状态。我想要做到,当我的调用button.enableWindow(true)或者button.enableWindow(false)的时候,响应某个事件,然后更改这个按钮的图片。 所以,当我调用enableWindow的时候,会有什么事件被触发,然后被我响应的呢
130 个相见恨晚的超实用网站,一次性分享出来
相见恨晚的超实用网站 持续更新中。。。
我花了一夜用数据结构给女朋友写个H5走迷宫游戏
起因 又到深夜了,我按照以往在csdn和公众号写着数据结构!这占用了我大量的时间!我的超越妹妹严重缺乏陪伴而 怨气满满! 而女朋友时常埋怨,认为数据结构这么抽象难懂的东西没啥作用,常会问道:天天写这玩意,有啥作用。而我答道:能干事情多了,比如写个迷宫小游戏啥的! 当我码完字准备睡觉时:写不好别睡觉! 分析 如果用数据结构与算法造出东西来呢? ...
对计算机专业来说学历真的重要吗?
我本科学校是渣渣二本,研究生学校是985,现在毕业五年,校招笔试、面试,社招面试参加了两年了,就我个人的经历来说下这个问题。 这篇文章很长,但绝对是精华,相信我,读完以后,你会知道学历不好的解决方案,记得帮我点赞哦。 先说结论,无论赞不赞同,它本质就是这样:对于技术类工作而言,学历五年以内非常重要,但有办法弥补。五年以后,不重要。 目录: 张雪峰讲述的事实 我看到的事实 为什么会这样 ...
字节跳动视频编解码面经
三四月份投了字节跳动的实习(图形图像岗位),然后hr打电话过来问了一下会不会opengl,c++,shador,当时只会一点c++,其他两个都不会,也就直接被拒了。 七月初内推了字节跳动的提前批,因为内推没有具体的岗位,hr又打电话问要不要考虑一下图形图像岗,我说实习投过这个岗位不合适,不会opengl和shador,然后hr就说秋招更看重基础。我当时想着能进去就不错了,管他哪个岗呢,就同意了面试...
win10系统安装教程(U盘PE+UEFI安装)
一、准备工作 u盘,电脑一台,win10原版镜像(msdn官网) 二、下载wepe工具箱 极力推荐微pe(微pe官方下载) 下载64位的win10 pe,使用工具箱制作启动U盘打开软件, 选择安装到U盘(按照操作无需更改) 三、重启进入pe系统 1、关机后,将U盘插入电脑 2、按下电源后,按住F12进入启动项选择(技嘉主板是F12) 选择需要启...
程序员必须掌握的核心算法有哪些?
由于我之前一直强调数据结构以及算法学习的重要性,所以就有一些读者经常问我,数据结构与算法应该要学习到哪个程度呢?,说实话,这个问题我不知道要怎么回答你,主要取决于你想学习到哪些程度,不过针对这个问题,我稍微总结一下我学过的算法知识点,以及我觉得值得学习的算法。这些算法与数据结构的学习大多数是零散的,并没有一本把他们全部覆盖的书籍。下面是我觉得值得学习的一些算法以及数据结构,当然,我也会整理一些看过...
Python——画一棵漂亮的樱花树(不同种樱花+玫瑰+圣诞树喔)
最近翻到一篇知乎,上面有不少用Python(大多是turtle库)绘制的树图,感觉很漂亮,我整理了一下,挑了一些我觉得不错的代码分享给大家(这些我都测试过,确实可以生成) one 樱花树 动态生成樱花 效果图(这个是动态的): 实现代码 import turtle as T import random import time # 画樱花的躯干(60,t) def Tree(branch, ...
大学四年自学走来,这些私藏的实用工具/学习网站我贡献出来了
大学四年,看课本是不可能一直看课本的了,对于学习,特别是自学,善于搜索网上的一些资源来辅助,还是非常有必要的,下面我就把这几年私藏的各种资源,网站贡献出来给你们。主要有:电子书搜索、实用工具、在线视频学习网站、非视频学习网站、软件下载、面试/求职必备网站。 注意:文中提到的所有资源,文末我都给你整理好了,你们只管拿去,如果觉得不错,转发、分享就是最大的支持了。 一、电子书搜索 对于大部分程序员...
《奇巧淫技》系列-python!!每天早上八点自动发送天气预报邮件到QQ邮箱
将代码部署服务器,每日早上定时获取到天气数据,并发送到邮箱。 也可以说是一个小人工智障。 思路可以运用在不同地方,主要介绍的是思路。
致 Python 初学者
欢迎来到“Python进阶”专栏!来到这里的每一位同学,应该大致上学习了很多 Python 的基础知识,正在努力成长的过程中。在此期间,一定遇到了很多的困惑,对未来的学习方向感到迷茫。我非常理解你们所面临的处境。我从2007年开始接触 python 这门编程语言,从2009年开始单一使用 python 应对所有的开发工作,直至今天。回顾自己的学习过程,也曾经遇到过无数的困难,也曾经迷茫过、困惑过。开办这个专栏,正是为了帮助像我当年一样困惑的 Python 初学者走出困境、快速成长。希望我的经验能真正帮到你
Ol4网格生成以及优化
概述 先描述一下大致场景:以0.05为单元格大小生成网格,并在地图上绘制,绘制的时候需要区分海陆。本文以此需求为契机,简单描述一下该需求的实现以及如何来优化。 效果 实现 优化前 var source = new ol.source.Vector({ features: [] }); var vector = new ol.layer.Vector({ source...
11月19日科技资讯|华为明日发布鸿蒙整体战略;京东宣告全面向技术转型;Kotlin 1.3.60 发布
「极客头条」—— 技术人员的新闻圈! CSDN 的读者朋友们早上好哇,「极客头条」来啦,快来看今天都有哪些值得我们技术人关注的重要新闻吧。扫描上方二维码进入 CSDN App 可以收听御姐萌妹 Style 的人工版音频哟。 一分钟速览新闻点! 6G 专家组成员:速率是 5G 的 10 至 100 倍,预计 2030 年商用 雷军:很多人多次劝我放弃WPS,能坚持下来并不是纯粹的商业决定 ...
C语言魔塔游戏
很早就很想写这个,今天终于写完了。 游戏截图: 编译环境: VS2017 游戏需要一些图片,如果有想要的或者对游戏有什么看法的可以加我的QQ 2985486630 讨论,如果暂时没有回应,可以在博客下方留言,到时候我会看到。 下面我来介绍一下游戏的主要功能和实现方式 首先是玩家的定义,使用结构体,这个名字是可以自己改变的 struct gamerole { char n...
iOS Bug 太多,苹果终于坐不住了!
开源的 Android 和闭源的 iOS,作为用户的你,更偏向哪一个呢? 整理 | 屠敏 出品 | CSDN(ID:CSDNnews) 毋庸置疑,当前移动设备操作系统市场中,Android 和 iOS 作为两大阵营,在相互竞争的同时不断演进。不过一直以来,开源的 Android 吸引了无数的手机厂商涌入其中,为其生态带来了百花齐放的盛景,但和神秘且闭源的 iOS 系统相比,不少网友...
Python语言高频重点汇总
Python语言高频重点汇总 GitHub面试宝典仓库 回到首页 目录: Python语言高频重点汇总 目录: 1. 函数-传参 2. 元类 3. @staticmethod和@classmethod两个装饰器 4. 类属性和实例属性 5. Python的自省 6. 列表、集合、字典推导式 7. Python中单下划线和双下划线 8. 格式化字符串中的%和format 9. 迭代器和生成器 10...
究竟你适不适合买Mac?
我清晰的记得,刚买的macbook pro回到家,开机后第一件事情,就是上了淘宝网,花了500元钱,找了一个上门维修电脑的师傅,上门给我装了一个windows系统。。。。。。 表砍我。。。 当时买mac的初衷,只是想要个固态硬盘的笔记本,用来运行一些复杂的扑克软件。而看了当时所有的SSD笔记本后,最终决定,还是买个好(xiong)看(da)的。 已经有好几个朋友问我mba怎么样了,所以今天尽量客观...
Python爬虫爬取淘宝,京东商品信息
小编是一个理科生,不善长说一些废话。简单介绍下原理然后直接上代码。 使用的工具(Python+pycharm2019.3+selenium+xpath+chromedriver)其中要使用pycharm也可以私聊我selenium是一个框架可以通过pip下载 pip installselenium -ihttps://pypi.tuna.tsinghua.edu.cn/simple/ ...
程序员写了一个新手都写不出的低级bug,被骂惨了。
这种新手都不会范的错,居然被一个工作好几年的小伙子写出来,差点被当场开除了。
Java工作4年来应聘要16K最后没要,细节如下。。。
前奏: 今天2B哥和大家分享一位前几天面试的一位应聘者,工作4年26岁,统招本科。 以下就是他的简历和面试情况。 基本情况: 专业技能: 1、&nbsp;熟悉Sping了解SpringMVC、SpringBoot、Mybatis等框架、了解SpringCloud微服务 2、&nbsp;熟悉常用项目管理工具:SVN、GIT、MAVEN、Jenkins 3、&nbsp;熟悉Nginx、tomca...
2020年,冯唐49岁:我给20、30岁IT职场年轻人的建议
点击“技术领导力”关注∆每天早上8:30推送 作者|Mr.K 编辑| Emma 来源|技术领导力(ID:jishulingdaoli) 前天的推文《冯唐:职场人35岁以后,方法论比经验重要》,收到了不少读者的反馈,觉得挺受启发。其实,冯唐写了不少关于职场方面的文章,都挺不错的。可惜大家只记住了“春风十里不如你”、“如何避免成为油腻腻的中年人”等不那么正经的文章。 本文整理了冯...
程序员该看的几部电影
1、骇客帝国(1999) 概念:在线/离线,递归,循环,矩阵等 剧情简介: 不久的将来,网络黑客尼奥对这个看似正常的现实世界产生了怀疑。 他结识了黑客崔妮蒂,并见到了黑客组织的首领墨菲斯。 墨菲斯告诉他,现实世界其实是由一个名叫“母体”的计算机人工智能系统控制,人们就像他们饲养的动物,没有自由和思想,而尼奥就是能够拯救人类的救世主。 可是,救赎之路从来都不会一帆风顺,到底哪里才是真实的世界?如何...
蓝桥杯知识点汇总:基础知识和常用算法
文章目录基础语法部分:算法竞赛常用API:算法部分数据结构部分 此系列包含蓝桥杯绝大部分所考察的知识点,以及真题题解~ 基础语法部分: 备战蓝桥杯java(一):一般输入输出 和 快速输入输(BufferedReader&amp;BufferedWrite) 备战蓝桥杯java(二):java编程规范和常用数据类型 备战蓝桥杯java(三):常用功能符以及循环结构和分支结构 备战蓝桥杯java(四...
作为一个程序员,CPU的这些硬核知识你必须会!
CPU对每个程序员来说,是个既熟悉又陌生的东西? 如果你只知道CPU是中央处理器的话,那可能对你并没有什么用,那么作为程序员的我们,必须要搞懂的就是CPU这家伙是如何运行的,尤其要搞懂它里面的寄存器是怎么一回事,因为这将让你从底层明白程序的运行机制。 随我一起,来好好认识下CPU这货吧 把CPU掰开来看 对于CPU来说,我们首先就要搞明白它是怎么回事,也就是它的内部构造,当然,CPU那么牛的一个东...
@程序员,如何花式构建线程?
作者 |曾建责编 | 郭芮出品 | CSDN(ID:CSDNnews)在项目和业务的开发中,我们难免要经常使用线程来进行业务处理,使用线程可以保证我们的业务在相互处理之间可以保证原子性...
破14亿,Python分析我国存在哪些人口危机!
一、背景 二、爬取数据 三、数据分析 1、总人口 2、男女人口比例 3、人口城镇化 4、人口增长率 5、人口老化(抚养比) 6、各省人口 7、世界人口 四、遇到的问题 遇到的问题 1、数据分页,需要获取从1949-2018年数据,观察到有近20年参数:LAST20,由此推测获取近70年的参数可设置为:LAST70 2、2019年数据没有放上去,可以手动添加上去 3、将数据进行 行列转换 4、列名...
实现简单的轮播图(单张图片、多张图片)
前言 刚学js没多久,这篇博客就当做记录了,以后还会完善的,希望大佬们多多指点。ps:下面出现的都是直接闪动,没有滑动效果的轮播图。 单张图片的替换 · ...
强烈推荐10本程序员在家读的书
很遗憾,这个春节注定是刻骨铭心的,新型冠状病毒让每个人的神经都是紧绷的。那些处在武汉的白衣天使们,尤其值得我们的尊敬。而我们这些窝在家里的程序员,能不外出就不外出,就是对社会做出的最大的贡献。 有些读者私下问我,窝了几天,有点颓丧,能否推荐几本书在家里看看。我花了一天的时间,挑选了 10 本我最喜欢的书,你可以挑选感兴趣的来读一读。读书不仅可以平复恐惧的压力,还可以对未来充满希望,毕竟苦难终将会...
Linux自学篇——linux命令英文全称及解释
man: Manual 意思是手册,可以用这个命令查询其他命令的用法。 pwd:Print working directory 意思是密码。 su:Swith user 切换用户,切换到root用户 cd:Change directory 切换目录 ls:List files 列出目录下的文件 ps:Process Status 进程状态 mkdir:Make directory ...
Python实战:抓肺炎疫情实时数据,画2019-nCoV疫情地图
今天,群里白垩老师问如何用python画武汉肺炎疫情地图。白垩老师是研究海洋生态与地球生物的学者,国家重点实验室成员,于不惑之年学习python,实为我等学习楷模。先前我并没有关注武汉肺炎的具体数据,也没有画过类似的数据分布图。于是就拿了两个小时,专门研究了一下,遂成此文。
疫情数据接口api
返回json示例 { "errcode":0,//0标识接口正常 "data":{ "date":"2020-01-30 07:47:23",//实时更新时间 "diagnosed":7736,//确诊人数 "suspect":12167,//疑是病例人数 "death":170,//死亡人数 "cur...
相关热词 c#导入fbx c#中屏蔽键盘某个键 c#正态概率密度 c#和数据库登陆界面设计 c# 高斯消去法 c# codedom c#读取cad文件文本 c# 控制全局鼠标移动 c# temp 目录 bytes初始化 c#
立即提问