PlaySound() 在 WM_DESTROY 和 DrawText 问题之后继续播放我的 .wav

PlaySound() keeps playing my .wav after WM_DESTROY and a DrawText Issue

我正在 Windows 7 64 位 OS 和 win32 API.When 我 运行 我的程序在调试模式下我的 window 出现了,但我有2个错误。首先是我的 api 代码修改自 Charles Petzold 书第 3 章:

#include<Windows.h>
#include<mmsystem.h>





LRESULT CALLBACK HandleMyWindowsClassMessages(HWND WindowHandle, UINT Message, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreviousInstance, PSTR szCmdLine, int iCmdShow)
{

    WNDCLASSEX MyWindowsClass;
    static wchar_t szMyWindowsClassName[] = TEXT("The Name of My Window Class");
    static wchar_t szAppName[] = TEXT("AppName");
    HWND myWindowHandle;
    MSG msg;

    MyWindowsClass.hInstance = hInstance;
    MyWindowsClass.style = CS_HREDRAW | CS_VREDRAW;
    MyWindowsClass.lpfnWndProc = HandleMyWindowsClassMessages;
    MyWindowsClass.lpszClassName = szMyWindowsClassName;
    MyWindowsClass.cbSize = sizeof(WNDCLASSEX);
    MyWindowsClass.cbClsExtra = 0;
    MyWindowsClass.cbWndExtra = 0;
    MyWindowsClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    MyWindowsClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    MyWindowsClass.hIcon = LoadIcon(NULL, IDI_SHIELD);
    MyWindowsClass.hIconSm = NULL;
    MyWindowsClass.lpszMenuName = NULL;

    if (!RegisterClassEx(&MyWindowsClass))
    {
        MessageBoxEx(0, TEXT("This Programm Requires WINNT!"), szMyWindowsClassName, MB_ICONERROR, 0);
        return(0);
    }

    myWindowHandle = CreateWindowEx(
        WS_EX_OVERLAPPEDWINDOW,
        szMyWindowsClassName,
        szAppName,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL);

    ShowWindow(myWindowHandle, iCmdShow);
    UpdateWindow(myWindowHandle);

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


    return(msg.wParam);
}

LRESULT CALLBACK HandleMyWindowsClassMessages(HWND WindowHandle, UINT Message, WPARAM wParam, LPARAM lParam)
{
    //wchar_t szGreeting[] = TEXT("Heeeey");
    HDC hdc;
    PAINTSTRUCT ps;


    switch (Message)
    {

        case WM_CREATE:
        {
            PlaySound(TEXT("D:\mp3\aywy._&_EphRem_-_Adderall.wav"), NULL, SND_FILENAME | SND_ASYNC);
            return(0);
        } break;

        case  WM_PAINT:
        {
            hdc = BeginPaint(WindowHandle, &ps);
            DrawText(hdc, TEXT("Hello Win 7!!!"), -1, &ps.rcPaint, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
            //TextOut(hdc, 0, 0, szGreeting, (int)wcslen(szGreeting));
            EndPaint(WindowHandle, &ps);
            return(0);
        }break;

        case WM_DESTROY:
        {
            PostQuitMessage(0);
            return(0);
        }break;

    }

    return(DefWindowProc(WindowHandle, Message, wParam, lParam));
}

错误 1:PlaySound 继续播放 wav,即使我已经关闭 - 销毁 Window.When 我使用带有普通 WNDCLASS 的原始示例,错误消失了! 所以我一定是在使用 WNDCLASSEX 做错了什么???。 同样在这个错误中结束调试的执行我必须按 Shift+F5.

错误 2:TextOut 与 DrawText Info:I 我的笔记本电脑上只有 1 个 screen.I 程序。 当我使用 drawText 并且我的 window 中的文本超出我的桌面屏幕边框时,文本只是不更新​​ correclty。 当我使用 TextOut 时,错误消失了!!! 为什么???

下面我有一些图片来解释这个。

  1. 程序以调试模式启动
  2. 将 window 移出桌面边框(包括显示的文本)
  3. 将 window 移回我的桌面区域(文本已更改)
  4. Window 被破坏,即使 wav 结束,声音也会继续播放。

对于这 2 个错误中的任何一个的任何帮助,我们将不胜感激。

我的 WndProc 的第二个版本:

LRESULT CALLBACK HandleMyWindowsClassMessages(HWND WindowHandle, UINT Message, WPARAM wParam, LPARAM lParam)
{
    //wchar_t szGreeting[] = TEXT("Heeeey");
    HDC hdc;
    PAINTSTRUCT ps;
    RECT rc;

    rc.left = 50; rc.top = 100; rc.right = 200; rc.bottom = 200;

    switch (Message)
    {

    case WM_CREATE:
    {
        PlaySound(TEXT("D:\mp3\aywy._&_EphRem_-_Adderall.wav"), NULL, SND_FILENAME | SND_ASYNC);
        return(0);
    } break;

    case  WM_PAINT:
    {
        hdc = BeginPaint(WindowHandle, &ps);
        DrawText(hdc, TEXT("Hello Win 7!!!"), -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
        //TextOut(hdc, 0, 0, szGreeting, (int)wcslen(szGreeting));
        EndPaint(WindowHandle, &ps);
        return(0);
    }break;

    case WM_DESTROY:
    {
        PlaySound(NULL, NULL, SND_FILENAME | SND_ASYNC);
        PostQuitMessage(0);
        return(0);
    }break;

    }

    return(DefWindowProc(WindowHandle, Message, wParam, lParam));
}
  1. PostQuitMessage之前调用PlaySound( NULL, NULL, SND_FILENAME | SND_ASYNC)停止声音

  2. 关于DrawText - 请注意 BeginPaint returns 矩形 rcPaint 用于需要重绘的区域。如果您将它用于 DrawText 的起点,文本将出现在不同的位置。例如 - 首次创建时,区域将从 0,0 开始。然后您可以将另一个 window 移动到 DrawText 应用程序 window 上,它可能需要从点 80,100 重新绘制到右下角。尝试使用绝对(客户端)坐标,例如定义 RECT rc 并设置 rc.left = 50; rc.top = 100; rc.right = 200; rc.bottom = 200; (始终相同的位置)。