鱼C论坛

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

[已解决]清除重绘

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

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

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

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

        int t = 1;//第一个点不能画直线
        short* g = (short*)pParam;
        for (int i = 0; i < zong / sizeof(short); i++) {
                if (t == 1) {
                        //移到起始点
                        ::MoveToEx(hdc, i, *(g+i), NULL);
                        t = 0;
                }
                else {
                        LineTo(hdc, i, *(g + i));//绘制直线
                }
                

        }

        
        return 0;
}


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



我的问题:在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函数填充矩形区域。以下是修改后的代码:
afx_msg LRESULT CMFCyinpinDlg::OnMM_WIM_DATA(WPARAM wParam, LPARAM lParam)
{
    WAVEHDR* pWaveHdr = (WAVEHDR*)lParam;
    memcpy(g_samples, pWaveHdr->lpData, pWaveHdr->dwBytesRecorded); //复制音频数据
    zong = pWaveHdr->dwBytesRecorded;
    
    // 清除原图像
    RECT clientRect;
    GetClientRect(&clientRect);
    HDC hdc = GetDC();
    FillRect(hdc, &clientRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
    ReleaseDC(hdc);
    
    CWinThread* pp = AfxBeginThread(func1, (short*)(g_samples), 0, 0, 0, NULL); //创建工作线程
    
    waveInAddBuffer(hWaveIn, pWaveHdr, sizeof(WAVEHDR)); // 继续录制下一段音频数据
    
    return 0;
}

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

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

使用道具 举报

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

要清除原图像,可以使用FillRect函数填充矩形区域。以下是修改后的代码:
afx_msg LRESULT CMFCyinpinDlg::OnMM_WIM_DATA(WPARAM wParam, LPARAM lParam)
{
    WAVEHDR* pWaveHdr = (WAVEHDR*)lParam;
    memcpy(g_samples, pWaveHdr->lpData, pWaveHdr->dwBytesRecorded); //复制音频数据
    zong = pWaveHdr->dwBytesRecorded;
    
    // 清除原图像
    RECT clientRect;
    GetClientRect(&clientRect);
    HDC hdc = GetDC();
    FillRect(hdc, &clientRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
    ReleaseDC(hdc);
    
    CWinThread* pp = AfxBeginThread(func1, (short*)(g_samples), 0, 0, 0, NULL); //创建工作线程
    
    waveInAddBuffer(hWaveIn, pWaveHdr, sizeof(WAVEHDR)); // 继续录制下一段音频数据
    
    return 0;
}

在该代码中,首先通过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 函数中使用绘图操作覆盖之前的内容。

下面是修改后的代码示例:
afx_msg void CMFCyinpinDlg::OnPaint()
{
    CPaintDC dc(this);

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

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

    CDialogEx::OnPaint();
}

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

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

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

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

    return 0;
}
在修改后的代码中,我们在 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-9-27 06:52

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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