带有 Windows API 的两个 cpp 文件的消息队列

问题描述

一个文件发送队列中的消息并在另一个文件获取消息。我阅读了微软的文档并尝试实现如下

test2.c - 发布消息 main.c - 获取消息

Testing1:如果我在单个文件中执行相同的代码并收到数据

测试:相同的代码写在两个单独的文件“如果(msg.message == WM_YOUR_MESSAGE)”这些语句不满足。

test2.h

typedef struct
{
    int SomeData1;
    int SomeData2;
    int SomeDatan;
} MessageData;

/* Unique IDs for Window messages to exchange between the worker and the 
GUI thread. */

#define WM_YOUR_MESSAGE   ( WM_USER + 3 )

void __cdecl ThreadProc(void* aArg);

test2.c

#include <windows.h>
#include <process.h>
#include "malloc.h"
#include <stdio.h>
#include <test2.h>

volatile DWORD ThreadID_GUI;

void __cdecl ThreadProc(void* aArg)
{
    MessageData* data;

    for (;; )
    {
        Sleep(500);

        /* Allocate memory for a new message data structure */
        data = (MessageData*)malloc(sizeof(*data));

        /* Initialize the message data structure with some information to transfer
           to the GUI thread. */
        data->SomeData1 = 1234;
        data->SomeData2 = 4567;
        data->SomeDatan = 7894;

       PostThreadMessage(ThreadID_GUI,WM_YOUR_MESSAGE,(LParaM)data);
    }
}

main.c

#include <windows.h>
#include <tchar.h>
#include <process.h>
#include "malloc.h"
#include "stdio.h"
#include<test2.h>

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPWSTR    lpCmdLine,_In_ int       nCmdshow)
   {
    UNREFERENCED_ParaMETER(hPrevInstance);
    UNREFERENCED_ParaMETER(lpCmdLine);

// Todo: Place code here.

ThreadID_GUI = GetCurrentThreadId();

/* Start some background thread */
_beginthread(ThreadProc,0);

// Initialize global strings
LoadStringW(hInstance,IDS_APP_TITLE,szTitle,MAX_LOADSTRING);
LoadStringW(hInstance,IDC_TESTMESSAGEQUEUE,szWindowClass,MAX_LOADSTRING);
MyRegisterClass(hInstance);

// Perform application initialization:
if (!InitInstance (hInstance,nCmdshow))
{
    return FALSE;
}

HACCEL hAccelTable = LoadAccelerators(hInstance,MAKEINTRESOURCE(IDC_TESTMESSAGEQUEUE));

MSG msg;

// Main message loop:
while (GetMessage(&msg,NULL,0))
{
        /* STEP 3: React on the message sent from the foreign thread */
        if (msg.message == WM_YOUR_MESSAGE)
        {
            MessageData* tmp = (MessageData*)msg.lParam;

                if (tmp->SomeData1 == 1234) {
                printf("someData\n");
            }
            /* Free the data structure associated to the message */
            free(tmp);
        }
        TranslateMessage(&msg);
        dispatchMessage(&msg);
}

return (int) msg.wParam;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style          = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc    = WndProc;
wcex.cbClsExtra     = 0;
wcex.cbWndExtra     = 0;
wcex.hInstance      = hInstance;
wcex.hIcon          = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_CLIENTMQ));
wcex.hCursor        = LoadCursor(nullptr,IDC_ARROW);
wcex.hbrBackground  = (HBrush)(COLOR_WINDOW+1);
wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_CLIENTMQ);
wcex.lpszClassName  = szWindowClass;
wcex.hIconSm        = LoadIcon(wcex.hInstance,MAKEINTRESOURCE(IDI_SMALL));

return RegisterClassExW(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance,int nCmdshow)
{
hInst = hInstance; // Store instance handle in our global variable

HWND hWnd = CreateWindowW(szWindowClass,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,nullptr,hInstance,nullptr);

if (!hWnd)
{
  return FALSE;
}

ShowWindow(hWnd,nCmdshow);
UpdateWindow(hWnd);

return TRUE;
}

 LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WParaM wParam,LParaM 
 lParam)
 {
 switch (message)
 {
case WM_COMMAND:
    {
        int wmId = LOWORD(wParam);
        // Parse the menu selections:
        switch (wmId)
        {
        case IDM_ABOUT:
            DialogBox(hInst,MAKEINTRESOURCE(IDD_ABOUTBox),hWnd,About);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd,message,wParam,lParam);
        }
    }
    break;
case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hWnd,&ps);
        // Todo: Add any drawing code that uses hdc here...
        EndPaint(hWnd,&ps);
    }
    break;
case WM_DESTROY:
    PostQuitMessage(0);
    break;
default:
    return DefWindowProc(hWnd,lParam);
}
return 0;
}

 // Message handler for about Box.
 INT_PTR CALLBACK About(HWND hDlg,LParaM 
 lParam)
{
 UNREFERENCED_ParaMETER(lParam);
 switch (message)
{
case WM_INITDIALOG:
    return (INT_PTR)TRUE;

case WM_COMMAND:
    if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
    {
        EndDialog(hDlg,LOWORD(wParam));
        return (INT_PTR)TRUE;
    }
    break;
}
return (INT_PTR)FALSE;
}

解决方法

在您填写源代码中所有缺失的信息并删除无用代码后,您的代码就可以正常工作了。

main.c:

C:\Users\yourUsername\PycharmProjects\yourProjectName\venv\Scripts\activate.bat

test2.c:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <process.h>
#include "test2.h"

HINSTANCE hInst;
LPCWSTR szWindowClass = L"Piu";
LPCWSTR szTitle = L"Title";

LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM
    lParam)
{
    switch (message)
    {
    case WM_COMMAND:
    {
        int wmId = LOWORD(wParam);
        // Parse the menu selections:
        switch (wmId)
        {
            /*
        case IDM_ABOUT:
            DialogBox(hInst,MAKEINTRESOURCE(IDD_ABOUTBOX),hWnd,About);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
            */
        default:
            return DefWindowProc(hWnd,message,wParam,lParam);
        }
    }
    break;
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hWnd,&ps);
        // TODO: Add any drawing code that uses hdc here...
        EndPaint(hWnd,&ps);
    }
    break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd,lParam);
    }
    return 0;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW wcex;

    ZeroMemory(&wcex,sizeof(wcex));

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    /*
    wcex.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_CLIENTMQ));
    wcex.hIconSm = LoadIcon(wcex.hInstance,MAKEINTRESOURCE(IDI_SMALL));
    wcex.hCursor = LoadCursor(nullptr,IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_CLIENTMQ);
    */
    wcex.lpszClassName = szWindowClass;

    return RegisterClassExW(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance,int nCmdShow)
{
    hInst = hInstance; // Store instance handle in our global variable

    HWND hWnd = CreateWindowW(szWindowClass,szTitle,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,hInstance,NULL);

    if (!hWnd)
    {
        return FALSE;
    }

    ShowWindow(hWnd,nCmdShow);
    UpdateWindow(hWnd);

    return TRUE;
}

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPWSTR    lpCmdLine,_In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: Place code here.

    ThreadID_GUI = GetCurrentThreadId();

    /* Start some background thread */
    _beginthread(ThreadProc,0);

    // Initialize global strings
//    LoadStringW(hInstance,IDS_APP_TITLE,MAX_LOADSTRING);
//    LoadStringW(hInstance,IDC_TESTMESSAGEQUEUE,szWindowClass,MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // Perform application initialization:
    if (!InitInstance(hInstance,nCmdShow))
    {
        return FALSE;
    }

//    HACCEL hAccelTable = LoadAccelerators(hInstance,MAKEINTRESOURCE(IDC_TESTMESSAGEQUEUE));

    MSG msg;

    // Main message loop:
    while (GetMessage(&msg,NULL,0))
    {
        /* STEP 3: React on the message sent from the foreign thread */
        if (msg.message == WM_YOUR_MESSAGE)
        {
            MessageData* tmp = (MessageData*)msg.lParam;

            if (tmp->SomeData1 == 1234) {
                printf("someData\n");
            }
            /* Free the data structure associated to the message */
            free(tmp);
        }
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int)msg.wParam;

}

test2.h

#include <Windows.h>
#include "test2.h"

volatile DWORD ThreadID_GUI;

void __cdecl ThreadProc(void* aArg)
{
    MessageData* data;

    for (;; )
    {
        Sleep(500);

        /* Allocate memory for a new message data structure */
        data = (MessageData*)malloc(sizeof(*data));

        /* Initialize the message data structure with some information to transfer
           to the GUI thread. */
        data->SomeData1 = 1234;
        data->SomeData2 = 4567;
        data->SomeDataN = 7894;

        PostThreadMessage(ThreadID_GUI,WM_YOUR_MESSAGE,(LPARAM)data);
    }
}

我删除了菜单和图标,所以没有 .rc 文件。