-->

如何在一个控制台应用程序使用一个唯一的消息窗口接收消息?(How to receive messag

2019-09-02 07:25发布

我创建了创建一个隐藏的仅邮件窗口,并等待消息的一个简单的Win32控制台应用程序,完整的代码如下。

#include <iostream>
#include <Windows.h>

namespace {
  LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  {
    if (uMsg == WM_COPYDATA)
      std::cout << "Got a message!" << std::endl;
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
  }
}

int main()
{
  WNDCLASS windowClass = {};
  windowClass.lpfnWndProc = WindowProcedure;
  LPCWSTR windowClassName = L"FoobarMessageOnlyWindow";
  windowClass.lpszClassName = windowClassName;
  if (!RegisterClass(&windowClass)) {
    std::cout << "Failed to register window class" << std::endl;
    return 1;
  }
  HWND messageWindow = CreateWindow(windowClassName, 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, 0);
  if (!messageWindow) {
    std::cout << "Failed to create message-only window" << std::endl;
    return 1;
  }

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

但是,我没有收到来自其他应用程序的任何消息。 GetMessage()只有几个街区,永不返回。 我用FindWindowEx()具有相同的类名称在发送消息的应用,并且它找到的窗口。 恰恰是显然从未被接收的消息。

难道我做错了什么吗? 什么是可以接受窗口消息最起码的应用程序?

Answer 1:

你的消息可能被阻塞用户界面特权隔离 。 在这种情况下,你可以使用ChangeWindowMessageFilterEx()函数允许通过WM_COPYDATA消息。



Answer 2:

IAM不知道那是错了你的计划,但我永诺使用了相反的做法:我创建了一个Win32应用程序,剥离下来,并添加控制台窗口。

在去除了所有含winapp版本(也删除所有AFX-垃圾文件):

// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER                // Allow use of features specific to Windows XP or later.
#define WINVER 0x0501        // Change this to the appropriate value to target other versions of Windows.
#endif

#ifndef _WIN32_WINNT        // Allow use of features specific to Windows XP or later.                  
#define _WIN32_WINNT 0x0501    // Change this to the appropriate value to target other versions of Windows.
#endif                       

#ifndef _WIN32_WINDOWS        // Allow use of features specific to Windows 98 or later.
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
#endif

#define WIN32_LEAN_AND_MEAN        // Exclude rarely-used stuff from Windows headers



// MinWInApp.cpp : Defines the entry point for the application.
//
#include <windows.h>

// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <strsafe.h>




#define MAX_LOADSTRING 100
#define SZ_TITLE "MinWinApp"
#define SZ_WND_CLASS "MINWINAPP"


// Global Variables:
HINSTANCE g_hInst;                // current instance
HWND g_hWnd;
HWND g_hwndNextViewer;

TCHAR* szWndClass = TEXT(SZ_WND_CLASS);


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


int APIENTRY _tWinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPTSTR    lpCmdLine,
                       int       nCmdShow)
{
  UNREFERENCED_PARAMETER(hPrevInstance);
  UNREFERENCED_PARAMETER(lpCmdLine);

  // TODO: Place code here.



  MSG msg;

  WNDCLASSEX 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      = NULL;
  wcex.hCursor    = LoadCursor(NULL, IDC_ARROW);
  wcex.hbrBackground  = (HBRUSH)(COLOR_BTNFACE+1);
  wcex.lpszMenuName  = NULL;
  wcex.lpszClassName  = szWndClass;
  wcex.hIconSm    =  NULL;
  RegisterClassEx(&wcex);


  g_hInst = hInstance; // Store instance handle in our global variable
  g_hWnd = CreateWindow(szWndClass, TEXT(SZ_TITLE), WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

  if (!g_hWnd)
  {
    return FALSE;
  }

  ShowWindow(g_hWnd, SW_SHOW);

  // Main message loop:
  while (GetMessage(&msg, NULL, 0, 0))
  {

    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }

  return (int) msg.wParam;
}


LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  int wmId, wmEvent;

  switch (message)
  {
  case WM_CREATE:
    break;
  case WM_COMMAND:
    wmId    = LOWORD(wParam);
    wmEvent = HIWORD(wParam);
    // Parse the menu selections:
    switch (wmId)
    {
    case 0:
    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
    }
    break;
  case WM_DESTROY:
    PostQuitMessage(0);
    break;
  default:
    return DefWindowProc(hWnd, message, wParam, lParam);
  }
  return 0;
} 

这里的代码添加控制台窗口中,可以发现: http://justcheckingonall.wordpress.com/2008/08/29/console-window-win32-app/



文章来源: How to receive messages using a message-only window in a console application?