清除重绘
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);//更新指定窗口的客户区
这两条 指令无效,没有清除原图像??
问题原因是在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函数释放设备上下文句柄。
这样就能够清除原图像并重新绘制波形图了。 问题分析:
根据你提供的代码,使用 ::InvalidateRect(hWnd, &rect, TRUE) 和 UpdateWindow(hWnd) 函数来清除并更新窗口,但是它们没有起到清除原图像的作用。
解决方案:
1. 确保 hWnd 是正确的窗口句柄,并且 rect 是要刷新的矩形区域。可以通过打印 hWnd 和 rect 的值来进行确认。
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 函数。这样就能够清除并更新窗口,正确显示波形图了。
如果回答对你有帮助,请给我一个最佳答案!{:10_254:}{:10_254:}{:10_254:}
给个最佳答案呗!求你了!!!{:10_254:}
页:
[1]