鱼C论坛

 找回密码
 立即注册
查看: 291|回复: 3

[已解决]清除重绘

[复制链接]
发表于 2023-8-5 15:15:10 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x

  1. UINT func1(LPVOID pParam)   //线程函数
  2. {
  3.        
  4.         BOOL b = ::InvalidateRect(hWnd, &rect, TRUE);  //使客户区矩形区域的图形变得无效
  5.         BOOL b1 = UpdateWindow(hWnd);//更新指定窗口的客户区
  6.        

  7.         int t = 1;//第一个点不能画直线
  8.         short* g = (short*)pParam;
  9.         for (int i = 0; i < zong / sizeof(short); i++) {
  10.                 if (t == 1) {
  11.                         //移到起始点
  12.                         ::MoveToEx(hdc, i, *(g+i), NULL);
  13.                         t = 0;
  14.                 }
  15.                 else {
  16.                         LineTo(hdc, i, *(g + i));//绘制直线
  17.                 }
  18.                

  19.         }

  20.        
  21.         return 0;
  22. }


  23. afx_msg LRESULT CMFCyinpinDlg::OnMM_WIM_DATA(WPARAM wParam, LPARAM lParam)
  24. {
  25.         WAVEHDR* pWaveHdr = (WAVEHDR*)lParam;
  26.         memcpy(g_samples, pWaveHdr->lpData, pWaveHdr->dwBytesRecorded);//复制音频数据
  27.         zong = pWaveHdr->dwBytesRecorded;
  28.         CWinThread* pp = AfxBeginThread(func1, (short*)(g_samples), 0, 0, 0, NULL);//创建工作线程
  29.                
  30.         waveInAddBuffer(hWaveIn, pWaveHdr, sizeof(WAVEHDR));  // 继续录制下一段音频数据
  31.                
  32.         return 0;
  33. }
复制代码




我的问题:在OnMM_WIM_DATA消息函数中获得麦克风音频 数据 后,创建线程绘出波形图

每次需要清除重新绘制,
可是BOOL b = ::InvalidateRect(hWnd, &rect, TRUE);  //使客户区矩形区域的图形变得无效
        BOOL b1 = UpdateWindow(hWnd);//更新指定窗口的客户区
这两条 指令无效,没有清除原图像  ??







最佳答案
2023-8-5 15:15:27
问题原因是在OnMM_WIM_DATA消息函数中,调用InvalidateRect和UpdateWindow函数无法清除原图像。这是因为这两个函数是用于窗口重绘的,而不是用于清除图像的。

要清除原图像,可以使用FillRect函数填充矩形区域。以下是修改后的代码:

  1. afx_msg LRESULT CMFCyinpinDlg::OnMM_WIM_DATA(WPARAM wParam, LPARAM lParam)
  2. {
  3.     WAVEHDR* pWaveHdr = (WAVEHDR*)lParam;
  4.     memcpy(g_samples, pWaveHdr->lpData, pWaveHdr->dwBytesRecorded); //复制音频数据
  5.     zong = pWaveHdr->dwBytesRecorded;
  6.    
  7.     // 清除原图像
  8.     RECT clientRect;
  9.     GetClientRect(&clientRect);
  10.     HDC hdc = GetDC();
  11.     FillRect(hdc, &clientRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
  12.     ReleaseDC(hdc);
  13.    
  14.     CWinThread* pp = AfxBeginThread(func1, (short*)(g_samples), 0, 0, 0, NULL); //创建工作线程
  15.    
  16.     waveInAddBuffer(hWaveIn, pWaveHdr, sizeof(WAVEHDR)); // 继续录制下一段音频数据
  17.    
  18.     return 0;
  19. }
复制代码


在该代码中,首先通过GetClientRect函数获取客户区的矩形区域,然后使用GetDC函数获取设备上下文句柄,接着使用FillRect函数填充矩形区域为白色,最后使用ReleaseDC函数释放设备上下文句柄。

这样就能够清除原图像并重新绘制波形图了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-8-5 15:15:27 | 显示全部楼层    本楼为最佳答案   
问题原因是在OnMM_WIM_DATA消息函数中,调用InvalidateRect和UpdateWindow函数无法清除原图像。这是因为这两个函数是用于窗口重绘的,而不是用于清除图像的。

要清除原图像,可以使用FillRect函数填充矩形区域。以下是修改后的代码:

  1. afx_msg LRESULT CMFCyinpinDlg::OnMM_WIM_DATA(WPARAM wParam, LPARAM lParam)
  2. {
  3.     WAVEHDR* pWaveHdr = (WAVEHDR*)lParam;
  4.     memcpy(g_samples, pWaveHdr->lpData, pWaveHdr->dwBytesRecorded); //复制音频数据
  5.     zong = pWaveHdr->dwBytesRecorded;
  6.    
  7.     // 清除原图像
  8.     RECT clientRect;
  9.     GetClientRect(&clientRect);
  10.     HDC hdc = GetDC();
  11.     FillRect(hdc, &clientRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
  12.     ReleaseDC(hdc);
  13.    
  14.     CWinThread* pp = AfxBeginThread(func1, (short*)(g_samples), 0, 0, 0, NULL); //创建工作线程
  15.    
  16.     waveInAddBuffer(hWaveIn, pWaveHdr, sizeof(WAVEHDR)); // 继续录制下一段音频数据
  17.    
  18.     return 0;
  19. }
复制代码


在该代码中,首先通过GetClientRect函数获取客户区的矩形区域,然后使用GetDC函数获取设备上下文句柄,接着使用FillRect函数填充矩形区域为白色,最后使用ReleaseDC函数释放设备上下文句柄。

这样就能够清除原图像并重新绘制波形图了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-8-5 15:17:50 | 显示全部楼层
问题分析:

根据你提供的代码,使用 ::InvalidateRect(hWnd, &rect, TRUE)UpdateWindow(hWnd) 函数来清除并更新窗口,但是它们没有起到清除原图像的作用。

解决方案:
1. 确保 hWnd 是正确的窗口句柄,并且 rect 是要刷新的矩形区域。可以通过打印 hWndrect 的值来进行确认。

2. ::InvalidateRect(hWnd, &rect, TRUE) 函数会将指定的矩形区域标记为无效,并请求系统重绘该区域。但它并不会立即清除原图像,而是等待窗口重绘消息的到来。确保在正确的时机调用 InvalidateRect,比如在 OnMM_WIM_DATA 函数中。

3. UpdateWindow(hWnd) 函数用于立即发送重绘消息,但它只会触发一次重绘,而不会清除原图像。如果你想要清除原图像,可以在 OnPaint 函数中使用绘图操作覆盖之前的内容。

下面是修改后的代码示例:

  1. afx_msg void CMFCyinpinDlg::OnPaint()
  2. {
  3.     CPaintDC dc(this);

  4.     // 清除原图像的方法之一是使用背景色进行填充
  5.     CRect rect;
  6.     GetClientRect(rect);
  7.     dc.FillSolidRect(rect, RGB(255, 255, 255)); // 使用白色填充背景

  8.     // 在这里进行绘图操作,可以根据需要绘制波形图或其他图形

  9.     CDialogEx::OnPaint();
  10. }

  11. afx_msg LRESULT CMFCyinpinDlg::OnMM_WIM_DATA(WPARAM wParam, LPARAM lParam)
  12. {
  13.     WAVEHDR* pWaveHdr = (WAVEHDR*)lParam;
  14.     memcpy(g_samples, pWaveHdr->lpData, pWaveHdr->dwBytesRecorded);
  15.     zong = pWaveHdr->dwBytesRecorded;

  16.     CWinThread* pp = AfxBeginThread(func1, (short*)(g_samples), 0, 0, 0, NULL);

  17.     waveInAddBuffer(hWaveIn, pWaveHdr, sizeof(WAVEHDR));

  18.     Invalidate(); // 使整个窗口变得无效,触发重绘操作
  19.     UpdateWindow(); // 立即发送重绘消息

  20.     return 0;
  21. }
复制代码

在修改后的代码中,我们在 OnPaint 函数中使用 FillSolidRect 函数来填充背景色,实现清除原图像的效果。并且,在 OnMM_WIM_DATA 函数中调用了 Invalidate 来使整个窗口无效,并立即发送重绘消息使用 UpdateWindow 函数。这样就能够清除并更新窗口,正确显示波形图了。

如果回答对你有帮助,请给我一个最佳答案!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-8-5 15:19:42 | 显示全部楼层
给个最佳答案呗!求你了!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-27 14:53

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表