10

I've created a simple Win32 console application that creates a hidden message-only window and waits for messages, the full code is below.

#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;
}

However, I'm not receiving any messages from another application. GetMessage() just blocks and never returns. I use FindWindowEx() with the same class name in the application that sends a message, and it finds the window. Just the message is apparently never being received.

Am I doing something wrong here? What is the most minimal application that can receive window messages?

2
  • Is there some reason you're casting WindowProcedure there? It looks like it's already a WNDPROC. Commented May 8, 2013 at 19:28
  • @HerrJoebob You're right, doesn't seem to be necessary. Commented May 10, 2013 at 3:55

2 Answers 2

7

Your messages may be blocked by User Interface Privilege Isolation. In that case you can use the ChangeWindowMessageFilterEx() function to allow the WM_COPYDATA message through.

Sign up to request clarification or add additional context in comments.

4 Comments

Doesn't seem to be the issue here, deactivated UAC and the messages still don't get through.
Nevermind, didn't notice I had to reboot. It really was UAC. After I deactivated it, it works in both a console and gui application. With UAC enabled, it works in neither.
@futlib disabling uac is not recommended since it is an essential part of windows security concept
@vlad_tepesch That was just a test to see if UAC is the issue. There's no way I can make all users disable UAC if I wanted to.
2

iam not sure that is wrong with your program, but i allways use the opposite approach: I create a win32 app, strip that down and add console window.

The stripped all containing winapp version (also removes all afx-junk files):

// 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;
} 

here the code to add console window can be found: http://justcheckingonall.wordpress.com/2008/08/29/console-window-win32-app/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.