Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6160865
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 23, 20262026-05-23T21:23:43+00:00 2026-05-23T21:23:43+00:00

I am writing a .NET wrapper around Win32 hooks which buffers WM_CHAR messages and

  • 0

I am writing a .NET wrapper around Win32 hooks which buffers WM_CHAR messages and allows events such as key presses, key releases, and accelerator keystrokes to be subscribed to. Everything is in working order except apparently my call to TranslateAccelerator. It returns true when I expect it to (when it finds an accelerator in the given table which I constructed earlier) but the WM_COMMAND messages don’t seem to be showing up ever. Here is some relevant code.

[StructLayout(LayoutKind.Sequential)]
struct MSG {

    IntPtr hWnd;

    WindowsMessages message;

    IntPtr wParam;

    IntPtr lParam;

    UInt32 time;

    POINT pt;
}

delegate IntPtr HOOKPROC(HookCodes nCode, IntPtr wParam, ref MSG lParam);

[DllImport("user32.dll")] 
extern IntPtr CallNextHookEx(IntPtr hhk, HookCodes nCode, IntPtr wParam, ref MSG lParam);

IntPtr HookProcedure(HookCodes nCode, IntPtr wParam, ref MSG lParam) {
    IntPtr result = IntPtr.Zero;
    if(nCode < HookCodes.ACTION) { 
        result = CallNextHookEx(hHook, nCode, wParam, ref lParam);
    } else if(nCode == HookCodes.ACTION && (PeekMessageOptions)wParam == PeekMessageOptions.REMOVE) {

        /*
         * Under these conditions, each message will only be passed onto the switch below once.
         */

        switch(lParam.message) {
            case WindowsMessages.KEYDOWN: 
                //fire keydown events and call TranslateAccelerator/TranslateMessage
                break;
            case WindowsMessages.KEYUP: 
                //fire keyup events
                break;
            case WindowsMessages.COMMAND: 
                //fire accelerator events Ex: Ctrl+F, ALT+M, SHIFT+L
                break;
            case WindowsMessages.CHAR: 
                //place char in buffer
                break;
            default:
                break;
            }
        }
        return result; //Will be zero if action was taken on the message by this procedure.  
    }
}

In KeyPressed(MSG), messages are translated like so:

[DllImport("user32.dll")]
extern bool TranslateAccelerator(IntPtr hWnd, IntPtr hAccTable, ref MSG lpMsg);

[DllImport("user32.dll")] 
extern bool TranslateMessage(ref MSG lpMsg);

if(!TranslateAccelerator(hWnd, hAccel, ref msg)){
    TranslateMessage(ref msg);
}

The hook and accelerator table are created like this:

[StructLayout(LayoutKind.Sequential)]
struct ACCEL {

    byte fVirt;

    ushort key;

    ushort cmd;
}

[DllImport("user32.dll")] 
extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr lpdwProcessId);

[DllImport("user32.dll")] 
extern IntPtr SetWindowsHookEx(WindowsHooks hook, HookProcedure lpfn, IntPtr hMod, uint dwThreadId);

[DllImport("user32.dll")]
extern IntPtr CreateAcceleratorTable(ACCEL[] lpaccl, int cEntries);

HOOKPROC proc = HookProcedure;
uint pid = GetWindowThreadProcessId(/*IntPtr*/hWnd, IntPtr.Zero);
IntPtr hHook = SetWindowsHookEx(WindowsHooks.GETMESSAGE, proc, IntPtr.Zero, pid);
IntPtr hAccel = CreateAcceleratorTable(/*ACCEL[]*/accelerators, accelerators.Length);

Everything works fine (such as attaching events to key-downs and buffering WM_CHAR messages) except I can’t find WM_COMMAND or WM_SYSCOMMAND messages anywhere in the queue. They just don’t seem to be visible to my hook procedure, even though TranslateAccelerator returns true when I expect it to. Note that I am really pretty clueless when it comes to Win32 so I’m probably missing something fairly obvious to the trained eye. But I am at my wits end. I’ve tried attaching the hook to an XNA window and a Windows Form without success.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-23T21:23:44+00:00Added an answer on May 23, 2026 at 9:23 pm

    You won’t catch those WM_COMMAND messages with a GETMESSAGE hook.

    TranslateAccelerator “sends the WM_COMMAND or WM_SYSCOMMAND message directly to the specified window procedure” (see the documentation) and hence bypasses the message queue.

    You’ll need a CALLWNDPROC hook instead.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am writing a .NET wrapper class for an existing native class which throws
I'm writing a .NET wrapper around an old MFC-based library we have. It's based
I am writing a Java wrapper library around a ruby gem so I am
I am writing a .NET program which will run on a computer with several
I'm writing a media player that uses the Bass.Net wrapper for Un4Seen's Bass native
I'm writing a .NET wrapper for an unmanaged DLL. The original DLL is C++
I'm writing a wrapper in .NET (C++/CLI) to be able to use some native
Well, after a long time writing .net programs in C# I started to feel
Writing a .NET DLL how do I find Application.ProductName ? EDIT: Obviously, importing Windows.Forms
Im writing a .net webforms app. It has a number of classes, for example

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.