1

これは簡単な質問のように思えますが、プログラムの実行中に実行される Win32 コードをどこに置くべきかわかりません。簡単な例として、標準の Win32 ウィンドウ初期化コードと思われるものと、それに続く単純な「ビープ」コマンドを含む例を示します。さまざまな場所でビープ コマンドを挿入しようとしましたが、結果は次の 3 つのいずれかになります。

  1. ビープ音が発生し、無限にループします
  2. ビープ音がまったく聞こえない
  3. ビープ音は、プログラムを閉じるときにのみ発生します

私が使用しているコードを以下に示します。これは、オンライン リソースから取り上げた単純な例であり、末尾にビープ コマンドが追加されています。コンパイル エラーはありません。この例では、プログラムを閉じるとビープ音が発生します。ご想像のとおり、これは私の最初の Win32 アプリです。

#include <windows.h>

    /*  Declare Windows procedure  */
    LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

    /*  Make the class name into a global variable  */
    char szClassName[ ] = "WindowsApp";

    int WINAPI WinMain (HINSTANCE hThisInstance,
                HINSTANCE hPrevInstance,
                LPSTR lpszArgument,
                int nFunsterStil)

{
                    HWND hwnd;               /* This is the handle for our window */
                    MSG messages;            /* Here messages to the application are saved */
                    WNDCLASSEX wincl;        /* Data structure for the windowclass */

       /* The Window structure */
       wincl.hInstance = hThisInstance;
       wincl.lpszClassName = szClassName;
       wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
       wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
       wincl.cbSize = sizeof (WNDCLASSEX);

       /* Use default icon and mouse-pointer */
       wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
       wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
       wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
       wincl.lpszMenuName = NULL;                 /* No menu */
       wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
       wincl.cbWndExtra = 0;                      /* structure or the window instance */
       /* Use Windows's default color as the background of the window */
       wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

       /* Register the window class, and if it fails quit the program */
       if (!RegisterClassEx (&wincl))
               return 0;

       /* The class is registered, let's create the program*/
       hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "Matt's Program That Beeps",       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
            );

       /* Make the window visible on the screen */
       ShowWindow (hwnd, nFunsterStil);

       /* Run the message loop. It will run until GetMessage() returns 0 */
       while (GetMessage (&messages, NULL, 0, 0))
       {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
       }

       /* The program return-value is 0 - The value that PostQuitMessage() gave */
       return messages.wParam;
}

/*  This function is called by the Windows function DispatchMessage()  */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 switch (message)                  /* handle the messages */
 {
    case WM_DESTROY:
        PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
        break;
    default:                      /* for messages that we don't deal with */
        return DefWindowProc (hwnd, message, wParam, lParam);
}
    Beep( 750, 300 );              /* This is the beep command */
    return 0;
}
4

3 に答える 3

2

一般的なWindowsアプリでは、すべてがメッセージループで受信したメッセージへの応答として発生します。ウィンドウを最初に開いたときに一度ビープ音を鳴らしたい場合は、WM_CREATEメッセージのハンドラーを追加して、そこにコードを配置できます。

メッセージに応答するときは、UIが遅くなったり応答しなくなったりしないように、できるだけ早く戻る必要があります。多くの作業を行う必要がある場合は、作業を処理するために別のスレッドを作成する必要があります。

于 2011-05-06T13:26:39.980 に答える
1

ウィンドウがメッセージを受信するたびにトリガーされるはずのウィンドウメッセージコールバックにビープコールを配置しています(たとえば、サイズ変更、NC領域へのマウスなど)。したがって、おそらくLOTが発生します。

別のスレッドでコードを実行して (操作が長くなる場合) 、回避策として GUI がフリーズするのを避けることができます。または、シングル ショット コードが必要な場合は、WM_CREATE ケース メッセージを使用してコードを一度実行することができます。ウィンドウが作成されます。

こちらもチェック

于 2011-05-06T13:23:03.320 に答える
0

簡単に言えば、すべてのウィンドウ メッセージでコードを実行したい場合 (おそらくそうではないでしょう)、ビープ呼び出しをウィンドウ プロシージャの先頭に置きます。特定のメッセージに対してのみ発生させたい場合はcase、それらのメッセージに a を追加し、その場合に入れます。

于 2011-05-06T13:24:00.213 に答える