Windows 为什么要花这么长时间才能听到嘟嘟声,而将应用程序窗口的一侧拖得快一点?

Windows 为什么要花这么长时间才能听到嘟嘟声,而将应用程序窗口的一侧拖得快一点?,windows,winapi,Windows,Winapi,这是一个使用WindowsAPI的非常简单的代码,其中在应用程序窗口的中心部分绘制了一个子窗口。通过在主窗口客户端区域上单击鼠标左键,子窗口将假定为空高度。通过使用鼠标右键单击,子窗口的高度在每次鼠标单击时增加10个像素。由于绘制父窗口时发出的MessageBeep(-1)呼叫,每当窗口的应用程序中出现鼠标左键或右键单击时,您都可以听到嘟嘟声 奇怪的是,当你拖动父窗口的一侧,非常缓慢地改变其宽度或高度时,你可以在每一个移动中听到嘟嘟声。但是,如果您将窗口的一侧拖得快一点,您只会听到一声蜂鸣声,鼠

这是一个使用WindowsAPI的非常简单的代码,其中在应用程序窗口的中心部分绘制了一个子窗口。通过在主窗口客户端区域上单击鼠标左键,子窗口将假定为空高度。通过使用鼠标右键单击,子窗口的高度在每次鼠标单击时增加10个像素。由于绘制父窗口时发出的
MessageBeep(-1)
呼叫,每当窗口的应用程序中出现鼠标左键或右键单击时,您都可以听到嘟嘟声

奇怪的是,当你拖动父窗口的一侧,非常缓慢地改变其宽度或高度时,你可以在每一个移动中听到嘟嘟声。但是,如果您将窗口的一侧拖得快一点,您只会听到一声蜂鸣声,鼠标按钮释放后的许多秒。为什么呢

代码如下:

#include <windows.h>

LRESULT CALLBACK        WindowProc(HWND, UINT, UINT, LONG);
LRESULT CALLBACK        ChildProc(HWND, UINT, UINT, LONG);

/****************************************************************************************************************************

    WinMain()

****************************************************************************************************************************/

int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
    MSG         msg;
    WNDCLASSEX  wndclassx;

    wndclassx.cbSize        = sizeof(WNDCLASSEX);
    wndclassx.style         = 0;
    wndclassx.lpfnWndProc   = WindowProc;
    wndclassx.cbClsExtra    = 0;
    wndclassx.cbWndExtra    = 0;
    wndclassx.hInstance     = hInstance;
    wndclassx.hIcon         = 0;
    wndclassx.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wndclassx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wndclassx.lpszMenuName  = NULL;
    wndclassx.lpszClassName = L"ParentWindow";
    wndclassx.hIconSm       = NULL;

    if( !RegisterClassEx(&wndclassx) ) return 0;

    wndclassx.cbSize        = sizeof(WNDCLASSEX);
    wndclassx.style         = 0;
    wndclassx.lpfnWndProc   = ChildProc;
    wndclassx.cbClsExtra    = 0;
    wndclassx.cbWndExtra    = 0;
    wndclassx.hInstance     = hInstance;
    wndclassx.hIcon         = 0;
    wndclassx.hCursor       = 0;
    wndclassx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wndclassx.lpszMenuName  = NULL;
    wndclassx.lpszClassName = L"ChildWindow";
    wndclassx.hIconSm       = NULL;

    if( !RegisterClassEx(&wndclassx) ) return 0;

    HWND hWnd;

    if( !(hWnd = CreateWindow(L"ParentWindow", L"Parent Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
                              CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL)) ) return 0;

    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);

    while( GetMessage(&msg, NULL, 0, 0) )
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int)msg.wParam;
}

/****************************************************************************************************************************

    WindowProc()

****************************************************************************************************************************/

LRESULT CALLBACK WindowProc (HWND hwnd, UINT message, UINT wParam, LONG lParam)
{
    PAINTSTRUCT ps;

    switch ( message )
    {
        RECT rect;
        HWND    hChild;

        case WM_CREATE:

        GetClientRect(hwnd, &rect);

        if( !CreateWindow(L"ChildWindow", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER, rect.right / 3, rect.bottom / 3, rect.right / 3,
                          rect.bottom / 3, hwnd, (HMENU)0, ((LPCREATESTRUCT)lParam)->hInstance, NULL) ) return -1;
        break;

        case WM_SIZE:

        MoveWindow(GetDlgItem(hwnd, 0), LOWORD(lParam) / 3, HIWORD(lParam) / 3, LOWORD(lParam) / 3, HIWORD(lParam) / 3,
                   true);

        break;

        case WM_LBUTTONDOWN:

        hChild = GetDlgItem(hwnd, 0);

        GetWindowRect(hChild, &rect);


        ScreenToClient(hwnd, (LPPOINT)&rect);


        ScreenToClient(hwnd, (LPPOINT)&rect.right);

        MoveWindow(hChild, rect.left, rect.top, rect.right - rect.left, 0, true);
        break;

        case WM_RBUTTONDOWN:

        hChild = GetDlgItem(hwnd, 0);

        GetWindowRect(hChild, &rect);

        ScreenToClient(hwnd, (LPPOINT)&rect);

        ScreenToClient(hwnd, (LPPOINT)&rect.right);

        MoveWindow(hChild, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top + 10, true);
        break;

        case WM_PAINT:
        BeginPaint(hwnd, &ps);
        MessageBeep(-1);
        EndPaint(hwnd, &ps);
        break;

        case WM_DESTROY:

        PostQuitMessage(0);
        break;

        default:

        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;
}

/****************************************************************************************************************************

    ChildProc()

****************************************************************************************************************************/

LRESULT CALLBACK ChildProc (HWND hwnd, UINT message, UINT wParam, LONG lParam)
{
    switch( message )
    {
        default:

        return DefWindowProc(hwnd, message, wParam, lParam);
    }
}
#包括
LRESULT回调WindowProc(HWND、UINT、UINT、LONG);
LRESULT回调ChildProc(HWND、UINT、UINT、LONG);
/****************************************************************************************************************************
WinMain()
****************************************************************************************************************************/
int APICENTRY WinMain(HINSTANCE HINSTANCE、HINSTANCE hPrevInstance、LPSTR lpszCmdLine、int nCmdShow)
{
味精;
wndclassx wndclassx;
wndclassx.cbSize=sizeof(wndclassx);
wndclassx.style=0;
wndclassx.lpfnWndProc=WindowProc;
wndclassx.cbClsExtra=0;
wndclassx.cbWndExtra=0;
wndclassx.hInstance=hInstance;
wndclassx.hIcon=0;
wndclassx.hCursor=LoadCursor(空,IDC_箭头);
wndclassx.hbrBackground=(HBRUSH)(彩色窗口+1);
wndclassx.lpszMenuame=NULL;
wndclassx.lpszClassName=L“父窗口”;
wndclassx.hIconSm=NULL;
如果(!RegisterClassEx(&wndclassx))返回0;
wndclassx.cbSize=sizeof(wndclassx);
wndclassx.style=0;
wndclassx.lpfnWndProc=ChildProc;
wndclassx.cbClsExtra=0;
wndclassx.cbWndExtra=0;
wndclassx.hInstance=hInstance;
wndclassx.hIcon=0;
wndclassx.hCursor=0;
wndclassx.hbrBackground=(HBRUSH)(彩色窗口+1);
wndclassx.lpszMenuame=NULL;
wndclassx.lpszClassName=L“ChildWindow”;
wndclassx.hIconSm=NULL;
如果(!RegisterClassEx(&wndclassx))返回0;
HWND-HWND;
如果(!(hWnd=CreateWindow(L“父窗口”,L“父窗口”,WS\u重叠窗口,CW\u使用默认值,CW\u使用默认值,
CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL)))返回0;
展示窗口(hWnd、SW_展示);
更新窗口(hWnd);
while(GetMessage(&msg,NULL,0,0))
{
翻译信息(&msg);
发送消息(&msg);
}
返回(int)msg.wParam;
}
/****************************************************************************************************************************
WindowProc()
****************************************************************************************************************************/
LRESULT回调WindowProc(HWND HWND、UINT消息、UINT wParam、长LPRAM)
{
PAINTSTRUCT-ps;
开关(信息)
{
RECT-RECT;
HWND-hChild;
案例WM_创建:
GetClientRect(hwnd和rect);
如果(!CreateWindow(L“ChildWindow”,NULL,WS|u CHILD | WS|u VISIBLE | WS|u BORDER,rect.right/3,rect.bottom/3,rect.right/3,
rect.bottom/3,hwnd,(humenu)0,((LPCREATESTRUCT)lpram)->hInstance,NULL))返回-1;
打破
案例WM_大小:
MoveWindow(GetDlgItem(hwnd,0)、LOWORD(lParam)/3、HIWORD(lParam)/3、LOWORD(lParam)/3、HIWORD(lParam)/3、,
正确的);
打破
案例WM_LBUTTONDOWN:
hChild=GetDlgItem(hwnd,0);
GetWindowRect(hChild,&rect);
屏幕客户端(hwnd,(LPPOINT)和rect);
ScreenToClient(hwnd,(LPPOINT)和右下角);
移动窗口(hChild,rect.left,rect.top,rect.right-rect.left,0,true);
打破
案例WM_RBUTTONDOWN:
hChild=GetDlgItem(hwnd,0);
GetWindowRect(hChild,&rect);
屏幕客户端(hwnd,(LPPOINT)和rect);
ScreenToClient(hwnd,(LPPOINT)和右下角);
移动窗口(hChild,rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top+10,true);
打破
案例WM_油漆:
开始油漆(hwnd和ps);
MessageBeep(-1);
端漆(hwnd和ps);
打破
案例WM_销毁:
PostQuitMessage(0);
打破
违约:
返回DefWindowProc(hwnd、message、wParam、lParam);
}
返回0;
}
/****************************************************************************************************************************
ChildProc()
****************************************************************************************************************************/
LRESULT回调ChildProc(HWND HWND、UINT消息、UINT wParam、长LPRAM)
{
开关(信息)
{
违约:
返回DefWindowProc(hwnd、message、wParam、lParam);
}
}
在MSDN上引用以下内容:

正常使用
GetMessage()
(为所有参数传递零 除了
LPMSG
参数)或
PeekMessage()
,屏幕上的任何消息 在用户输入消息之前处理应用程序队列。和输入 消息在
WM_定时器
WM_绘制
消息之前处理

换句话说,因为您在
WM_PAINT
期间调用
MessageBeep
,所以只有在窗口停止处理用户输入后(例如,当用户停止移动窗口时),才会发生这种情况