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 7504933
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 29, 20262026-05-29T21:44:19+00:00 2026-05-29T21:44:19+00:00

I’m using C# and I’ve got the program successfully recording the journal messages using

  • 0

I’m using C# and I’ve got the program successfully recording the journal messages using SetWindowsHookEx with WH_JOURNALRECORD.

My problem comes when it’s time to stop. The docs show that if the user pressed CTRL-ESC or CTRL-ALT-DELETE a WM_CANCELJOURNAL message will be posted that I can watch to know when to stop. My application gets unhooked but I never seem to get a WM_CANCELJOURNAL.

I have two hooks setup. One hook to do the Journal Record and one to check for the cancel message:

IntPtr hinstance = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]);

JournalRecordProcedure = JournalRecordProc;
journalHook = SetWindowsHookEx(WH_JOURNALRECORD, JournalRecordProcedure, hinstance, 0);

GetMessageProcedure = GetMessageProc;
messageHook = SetWindowsHookEx(WH_GETMESSAGE, GetMessageProcedure, hinstance, 0); 


------

public static int JournalRecordProc(int nCode, IntPtr wParam, IntPtr lParam)
{
    if (nCode < 0) return CallNextHookEx(journalHook, nCode, wParam, lParam);

    EventMsgStruct msg = (EventMsgStruct) Marshal.PtrToStructure(lParam, typeof (EventMsgStruct));

    script.Add(msg); //just a quick way to record for now

    return CallNextHookEx(journalHook, nCode, wParam, lParam);
}

public static int GetMessageProc(int code, IntPtr wParam, IntPtr lParam)
{

    //it comes here but how do I test if it's WM_CANCELJOURNAL ??
    //code always seems to be equal to zero.. I must be missing something


    return CallNextHookEx(journalHook, code, wParam, lParam);
}
  • 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-29T21:44:20+00:00Added an answer on May 29, 2026 at 9:44 pm

    I suppose you’re referring to this section in the documentation:

    This role as a signal to stop journal recording means that a CTRL+BREAK key combination cannot itself be recorded. Since the CTRL+C key combination has no such role as a journaling signal, it can be recorded. There are two other key combinations that cannot be recorded: CTRL+ESC and CTRL+ALT+DEL. Those two key combinations cause the system to stop all journaling activities (record or playback), remove all journaling hooks, and post a WM_CANCELJOURNAL message to the journaling application.

    The problem is that the WM_CANCELJOURNAL message is not sent to the callback function you installed with SetWindowsHookEx. But unlike other WM_* messages, it is also not meant to be processed by a window procedure (WndProc in WinForms) because it is posted to the message queue of the thread and is not associated with any particular window.

    Rather, the documentation advises that one must process it within an application’s main loop or using a WH_GETMESSAGE hook:

    This message does not return a value. It is meant to be processed from within an application’s main loop or a GetMessage hook procedure, not from a window procedure.

    [ . . . ]

    The WM_CANCELJOURNAL message has a NULL window handle, therefore it cannot be dispatched to a window procedure. There are two ways for an application to see a WM_CANCELJOURNAL message: If the application is running in its own main loop, it must catch the message between its call to GetMessage or PeekMessage and its call to DispatchMessage. If the application is not running in its own main loop, it must set a GetMsgProc hook procedure (through a call to SetWindowsHookEx specifying the WH_GETMESSAGE hook type) that watches for the message.

    In managed WinForms code, you obviously don’t have any access to or control over the application’s main loop. I’m not sure if adding a message filter to your application will let you handle this message or not: I haven’t tried it. If it will, that’s probably the route you want to take, considering the alternative, which is to install a second hook, WH_GETMESSAGE, and then in that hook procedure, listen for the WM_CANCELJOURNAL message.


    Update:

    In the GetMessageProc callback function, the code parameter just tells you whether the hook procedure should process the message. Virtually all of the time, it’s going to be 0, which is equivalent to the symbolic constant HC_ACTION. If the code parameter is less than 0, the hook procedure should simply call the CallNextHookEx function without performing any further processing. That’s basically the exact same thing you did for the JournalRecordProc callback function.

    The window message is going to be found in a MSG structure, a pointer to which is passed to the callback function as the lParam parameter. But that’s Win32 stuff. Don’t mess with raw pointers in .NET, let the P/Invoke marshaler handle all of that dirty stuff for you. The native MSG structure is equivalent to the managed System.Windows.Forms.Message structure (the same thing used by the WndProc method), so if you declare your GetMessageProc callback function like this, things will be much simpler:

    public delegate int GetMessageProc(int code, IntPtr wParam, ref Message lParam);
    

    Then, the windows message is found as the Msg member of the Message structure. That’s the value you want to compare against WM_CANCELJOURNAL:

    public static int GetMessageProc(int code, IntPtr wParam, ref Message lParam)
    {
        if (code >= 0)
        {
            if (lParam.Msg == WM_CANCELJOURNAL)
            {
                // do something
            }
        }
    
        return CallNextHookEx(messageHook, code, wParam, ref lParam);
    }
    

    Note that in order for the above call to CallNextHookEx to work, you’ll also have to provide an overloaded definition of the CallNextHookEx function that matches the signature of your GetMessageProc callback function:

    [DllImport("user32.dll")]
    public static extern int CallNextHookEx(IntPtr hHook, int nCode,
                                            IntPtr wParam, ref Message lParam);
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm new to using the Perl treebuilder module for HTML parsing and can't figure
That's pretty much it. I'm using Nokogiri to scrape a web page what has
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I am reading a book about Javascript and jQuery and using one of the
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
I've got a string that has curly quotes in it. I'd like to replace
I'm using v2.0 of ClassTextile.php, with the following call: $testimonial_text = $textile->TextileRestricted($_POST['testimonial']); ... and
I am currently running into a problem where an element is coming back from
We're building an app, our first using Rails 3, and we're having to build
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this

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.