2013-05-08 8 views
7

Ho creato una semplice applicazione console Win32 che crea una finestra di solo messaggio nascosta e attende i messaggi, il codice completo è riportato di seguito.Come ricevere messaggi utilizzando una finestra di solo messaggio in un'applicazione console?

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

Tuttavia, non ricevo alcun messaggio da un'altra applicazione. GetMessage() solo blocchi e non ritorna mai. Io uso FindWindowEx() con lo stesso nome di classe nell'applicazione che invia un messaggio e trova la finestra. Solo il messaggio sembra non essere mai ricevuto.

Sto facendo qualcosa di sbagliato qui? Qual è l'applicazione più minimale in grado di ricevere i messaggi della finestra?

+0

c'è qualche ragione per cui sei Lanciare WindowProcedure lì? Sembra che sia già un WNDPROC. – HerrJoebob

+0

@HerrJoebob Hai ragione, non sembra necessario. – futlib

risposta

5

I tuoi messaggi potrebbero essere bloccati da User Interface Privilege Isolation. In tal caso è possibile utilizzare la funzione ChangeWindowMessageFilterEx() per consentire il passaggio del messaggio WM_COPYDATA.

+0

Non sembra essere il problema qui, UAC disattivato e i messaggi non riescono ancora a passare. – futlib

+0

Nevermind, non ho notato che ho dovuto riavviare. Era davvero UAC. Dopo averlo disattivato, funziona sia in console che in un'applicazione gui. Con UAC abilitato, non funziona in nessuno dei due. – futlib

+0

@futlib disabilitazione di uac non è raccomandato in quanto è una parte essenziale del concetto di sicurezza di Windows –

2

iam non sono sicuro che sia sbagliato con il programma, ma io uso sempre l'approccio opposto: Creo un'applicazione win32, spogliarlo e aggiungere la finestra della console.

La spogliata tutta la versione contenente WinApp (rimuove anche tutti i file di AFX-spazzatura):

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

qui il codice per aggiungere finestra della console possono essere trovati: http://justcheckingonall.wordpress.com/2008/08/29/console-window-win32-app/