【问题标题】:win32 waiting for events(synchroniztion)win32 等待事件(同步)
【发布时间】:2012-10-22 06:21:47
【问题描述】:

我有 3 个窗口必须使用事件相互交互。 窗口 1 和 2 相同;每个只有一个按钮。

基本上,我的主窗口(程序 3)直到其他两个窗口按钮中的 一个 才会显示 被点击;实验室是这样描述的:

您需要使用同步来控制进程(通过 Program1 或 2 启动 Program3,通过关闭 Program3 结束 Program1 或 2)。注意:Program1 和 Program2 必须点击按钮才能接收到死亡信号

到目前为止,我一直在四处寻找代码:

主窗口(程序 3):

#include <windows.h>
#include<string.h>

#include <stdio.h>
#include <tchar.h>
#include <conio.h>
#pragma comment(lib, "winmm.lib")


LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     static TCHAR szAppName[] = TEXT ("RACE") ;
     HWND         hwnd ;
     MSG          msg ;
     WNDCLASS     wndclass ;
     HANDLE hEvents[2];
     hEvents[0] = "btn2";
     hEvents[1] = "btn3";
     DWORD count = 2;

     HBRUSH brush;
     brush = CreateSolidBrush(RGB(255,0,0));

     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0;
     wndclass.cbWndExtra    = 0;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = brush;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;

     if (!RegisterClass (&wndclass))
     {
          MessageBox (NULL, TEXT ("This program requires Windows NT!"), 
                      szAppName, MB_ICONERROR) ;
          return 0 ;
     }
     TCHAR* name;

     //WAIT FOR SIGNAL
     DWORD result = WaitForMultipleObjects(count,hEvents,FALSE,INFINITE);//work on this
     if(result == WAIT_OBJECT_0)
     {
        name = TEXT("Program 1");       
     }
     else if(result == WAIT_OBJECT_0 + 1)
     {
        name = TEXT("Program 2");
     }

    hwnd = CreateWindow (szAppName,                  // window class name
                          name, // window caption
                          WS_OVERLAPPEDWINDOW,        // window style
                          0,              // initial x position
                          0,              // initial y position
                          600,              // initial x size
                          600,              // initial y size
                          NULL,                       // parent window handle
                          NULL,                       // window menu handle
                          hInstance,                  // program instance handle
                          NULL);                     // creation parameters



     ShowWindow (hwnd, iCmdShow) ;//DON'T SHOW UNTIL ANOTHER WINDOW'S BUTTON IS PUSHED.
     UpdateWindow (hwnd) ;

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

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     HDC         hdc ;
     PAINTSTRUCT ps ;


     TCHAR* carNames[5] = {TEXT("Red Car"), TEXT("Blue Car"), TEXT("Black Car"), TEXT("Green Car"), TEXT("Orange Car")};
     switch (message)
     {
     case WM_CREATE:
         HWND hwndButton;

         for(int i = 0; i < 5; i++)
         {
         hwndButton = CreateWindow ( TEXT("button"),//type of child window 
                                   carNames[i],//text displayed on button
                                   WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,//type of button
                                   20, (20*i*5+10),
                                   85, 25,
                                   hwnd, //parent handle i.e. main window handle
                                    (HMENU) i,//child ID – any number
                                   ((LPCREATESTRUCT) lParam)->hInstance, NULL);
         }



         break;


          return 0 ;

     case WM_PAINT:
          hdc = BeginPaint (hwnd, &ps) ;



          EndPaint (hwnd, &ps) ;
          return 0 ;

    /* case WM_CLOSE:

          c--;
          DestroyWindow(hwnd);
          return 0 ;*/

     case WM_DESTROY:

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

窗口 2(程序 2):

    #include <windows.h>
    #include<string.h>
    #pragma comment(lib, "winmm.lib")

    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                        PSTR szCmdLine, int iCmdShow)
    {
         static TCHAR szAppName[] = TEXT ("Part 2") ;
         HWND         hwnd ;
         MSG          msg ;
         WNDCLASS     wndclass ;


         wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
         wndclass.lpfnWndProc   = WndProc ;
         wndclass.cbClsExtra    = 0;
         wndclass.cbWndExtra    = 0;
         wndclass.hInstance     = hInstance ;
         wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
         wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
         wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
         wndclass.lpszMenuName  = NULL ;
         wndclass.lpszClassName = szAppName ;

         if (!RegisterClass (&wndclass))
         {
              MessageBox (NULL, TEXT ("This program requires Windows NT!"), 
                          szAppName, MB_ICONERROR) ;
              return 0 ;
         }

         hwnd = CreateWindow (szAppName,                  // window class name
                              TEXT ("Part 2"), // window caption
                              WS_OVERLAPPEDWINDOW,        // window style
                              0,              // initial x position
                              0,              // initial y position
                              300,              // initial x size
                              200,              // initial y size
                              NULL,                       // parent window handle
                              NULL,                       // window menu handle
                              hInstance,                  // program instance handle
                             NULL) ;                     // creation parameters



         ShowWindow (hwnd, iCmdShow) ;
         UpdateWindow (hwnd) ;


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

    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
         HDC         hdc ;
         PAINTSTRUCT ps ;
         HANDLE hEvent;


         switch (message)
         {
         case WM_CREATE:
             HWND hwndButton2;
               hwndButton2 = CreateWindow ( TEXT("button"),//type of child window 
                                       TEXT("PRESS ME!"),//text displayed on button
                                       WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,//type of button
                                       20, 20,
                                       200, 25,
                                       hwnd, //parent handle i.e. main window handle
                                        (HMENU) 45,//child ID – any number
                                       ((LPCREATESTRUCT) lParam)->hInstance, NULL);

               hEvent = CreateEvent(NULL, //no security attributes
                FALSE, //auto-reset event object
                FALSE, //initial state is nonsignaled
                L"btn2"); //unnamed object



              return 0 ;

         case WM_PAINT:
              hdc = BeginPaint (hwnd, &ps) ;



              EndPaint (hwnd, &ps) ;
              return 0 ;

         case WM_COMMAND:


             SetEvent("btn2");

             return 0;

         case WM_DESTROY:

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

窗口 3(程序 3): 与窗口 2 几乎相同

#include <windows.h>
#include<string.h>
#pragma comment(lib, "winmm.lib")

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     static TCHAR szAppName[] = TEXT ("Part 3") ;
     HWND         hwnd ;
     MSG          msg ;
     WNDCLASS     wndclass ;


     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0;
     wndclass.cbWndExtra    = 0;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;

     if (!RegisterClass (&wndclass))
     {
          MessageBox (NULL, TEXT ("This program requires Windows NT!"), 
                      szAppName, MB_ICONERROR) ;
          return 0 ;
     }

     hwnd = CreateWindow (szAppName,                  // window class name
                          TEXT ("Part 3"), // window caption
                          WS_OVERLAPPEDWINDOW,        // window style
                          0,              // initial x position
                          0,              // initial y position
                          300,              // initial x size
                          200,              // initial y size
                          NULL,                       // parent window handle
                          NULL,                       // window menu handle
                          hInstance,                  // program instance handle
                         NULL) ;                     // creation parameters



     ShowWindow (hwnd, iCmdShow) ;
     UpdateWindow (hwnd) ;


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

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     HDC         hdc ;
     PAINTSTRUCT ps ;
     HANDLE hEvent1;

     switch (message)
     {
     case WM_CREATE:
           HWND hwndButton3;
           hwndButton3 = CreateWindow ( TEXT("button"),//type of child window 
                                   TEXT("PRESS ME!"),//text displayed on button
                                   WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,//type of button
                                   20, 20,
                                   200, 25,
                                   hwnd, //parent handle i.e. main window handle
                                    (HMENU) 95,//child ID – any number
                                   ((LPCREATESTRUCT) lParam)->hInstance, NULL);

           hEvent1 = CreateEvent(NULL, //no security attributes
            FALSE, //auto-reset event object
            FALSE, //initial state is nonsignaled
            L"btn3"); //unnamed object


          return 0 ;

     case WM_PAINT:
          hdc = BeginPaint (hwnd, &ps) ;



          EndPaint (hwnd, &ps) ;
          return 0 ;

          case WM_COMMAND:

         SetEvent("btn3");

         return 0;


     case WM_DESTROY:

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

这些都在同一个解决方案中;但在不同的项目中(一个解决方案中的多个项目)。

现在的问题是,当我单击时,我似乎无法打开主窗口 任一按钮。我尝试了很多不同的方法,但似乎都没有奏效。

我们不胜感激。提前致谢。

【问题讨论】:

  • (1) 您的第一个 prog 没有用于处理子控件/菜单命令的 WM_COMMAND 处理程序。 (2) 您的第二个 prog 几乎是空白的,但确实包含使用字符串常量而不是有效事件句柄的无效 SetEvent() 调用。您的第三个实际上是第二个的副本,唯一的区别是使用不同的(并且不正确的)字符串常量进行了不同的无效 SetEvent() 调用。简而言之,除了向库存的 WIN32 向导生成的项目文件中添加十几行代码之外,这与您分配的任务无处接近

标签: winapi events synchronization


【解决方案1】:
 HANDLE hEvents[2];
 hEvents[0] = "btn2";
 hEvents[1] = "btn3";

这是不对的。您必须像在其他两个程序中一样调用CreateEvent 函数。

【讨论】:

  • 我正在其他两个窗口程序中创建事件。有人告诉我,我在那里制作它们,然后在单击按钮时使用 SetEvent 设置事件。并且赋予事件的名称将是在等待事件时如何识别它(WaitForMultipleObjects)。所以我认为我必须将这些特定事件放入句柄数组中。但我不知道该怎么做。创建一个新活动不会是与我需要的活动不同的活动吗?
  • 我相信您正在混淆 真实世界 事件,例如用物理鼠标在物理桌面上单击按钮和同步原语。
  • @LuciferFayte:阅读有关命名事件如何工作的文档。使用相同的名称将为现有事件创建一个新句柄。
  • 我让它工作了。谢谢你。你说的对;创建一个与现有事件同名的事件会将句柄返回给您。据我了解。
  • 您也可以使用OpenEvent,但前提是您知道其他程序已经创建了该事件。如果两者同时运行,最好使用两次CreateEvent
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-13
  • 2018-12-27
  • 2011-10-04
相关资源
最近更新 更多