Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

Artificially generated CONTROL_C_EVENT?

May
12,935
171
For quite a while I've had a GENBREAK command in my 4CONSOLE plugin. It was quite simple:

Code:
INT WINAPI GENBREAK ( WCHAR * pArgs) {
    if ( stristr(pArgs, L"/?") ) Printf(L"Generate a CTRL_C_EVENT\r\n");
    else
    {
        GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
    }
    return 0;
}
I noticed that if TCC is waiting for input (e.g., at a command or "/P" prompt) such an artificially generated signal isn't seen until there's a keystroke. [I tested this with "LATER /s=2 GENBREAK" ... LATER another plugin function.]

I'm curious why.

I can get get the signal seen immediately if I use:

Code:
INT WINAPI GENBREAK ( WCHAR * pArgs) {
    if ( stristr(pArgs, L"/?") ) Printf(L"Generate a CTRL_C_EVENT\r\n");
    else
    {
        PostMessage(g.hWndConsole, WM_CHAR, 0, 0);
        GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
        PostMessage(g.hWndConsole, WM_CHAR, 0, 0);
    }
    return 0;
}
That seems particularly inelegant. Is there a better way?

Thanks.
 
Here's a better example.

Code:
DWORD WINAPI GBThread ( LPVOID foo )
{
    Printf(L"Thread started\r\n");
    Sleep(5000);
    GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
    Printf(L"Gererated Ctrl-C\r\n");
    return 0;
}

INT WINAPI GENBREAK ( WCHAR *pargs )
{
    CreateThread(NULL, 0, GBThread, NULL, 0, NULL);
    return 0;
}
If I issue GENBREAK and wait 5 seconds, I see:

v:\> Thread started
v:\> Generated Ctrl-C

Regardless of the time passed, it is only after I press a key that I further see:

^C
c:\>

Why doesn't TCC act on the signal immediately?

If I surround GenerateConnsoleCtrlEvent with a pair of SendMessage(hWndConsole, WM_CHAR, 0, 0) (seemingly a kludge) TCC acts on the signal immediately. Is there a more elegant way?

Thanks.
 
Why do you need two WM_CHAR messages? Is that the only way it works?

-Scott

vefatica <> wrote on 04/10/2009 12:39:20 PM:


> Here's a better example.
>
>
> Code:
> ---------
> DWORD WINAPI GBThread ( LPVOID foo )
> {
> Printf(L"Thread started\r\n");
> Sleep(5000);
> GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
> Printf(L"Gererated Ctrl-C\r\n");
> return 0;
> }
>
> INT WINAPI GENBREAK ( WCHAR *pargs )
> {
> CreateThread(NULL, 0, GBThread, NULL, 0, NULL);
> return 0;
> }
> ---------
> If I issue GENBREAK and wait 5 seconds, I see:
>
> v:\> Thread started
> v:\> Generated Ctrl-C
>
> Regardless of the time passed, it is only after I press a key that I
> further see:
>
> ^C
> c:\>
>
> Why doesn't TCC act on the signal immediately?
>
> If I surround GenerateConnsoleCtrlEvent with a pair of
> SendMessage(hWndConsole, WM_CHAR, 0, 0) (seemingly a kludge) TCC
> acts on the signal immediately. Is there a more elegant way?
>
> Thanks.
>
>
>
>
 
I really don't know what's going on. The "WM_CHAR,0" is more than a kludge,
it's a shot in the dark. Only one such message, either before or after the
signal generation doesn't work. Sending WM_NULL doesn't work. And "WM_CHAR,0"
is not completely satisfactory; it causes TCC to process the next actual
keystroke rather sluggishly.

On Fri, 10 Apr 2009 11:59:55 -0500, samintz <> wrote:

|Why do you need two WM_CHAR messages? Is that the only way it works?
|
|-Scott
|
|vefatica <> wrote on 04/10/2009 12:39:20 PM:
|
|
|
|---Quote---
|> Here's a better example.
|>
|>
|> Code:
|> ---------
|> DWORD WINAPI GBThread ( LPVOID foo )
|> {
|> Printf(L"Thread started\r\n");
|> Sleep(5000);
|> GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
|> Printf(L"Gererated Ctrl-C\r\n");
|> return 0;
|> }
|>
|> INT WINAPI GENBREAK ( WCHAR *pargs )
|> {
|> CreateThread(NULL, 0, GBThread, NULL, 0, NULL);
|> return 0;
|> }
|> ---------
|> If I issue GENBREAK and wait 5 seconds, I see:
|>
|> v:\> Thread started
|> v:\> Generated Ctrl-C
|>
|> Regardless of the time passed, it is only after I press a key that I
|> further see:
|>
|> ^C
|> c:\>
|>
|> Why doesn't TCC act on the signal immediately?
|>
|> If I surround GenerateConnsoleCtrlEvent with a pair of
|> SendMessage(hWndConsole, WM_CHAR, 0, 0) (seemingly a kludge) TCC
|> acts on the signal immediately. Is there a more elegant way?
|>
|> Thanks.
|>
|>
|>
|>
|---End Quote---
|
|
|
--
- Vince
 
I said: And "WM_CHAR,0" is not completely satisfactory; it causes TCC to process the next actual keystroke rather sluggishly.

I worked around that little anomaly by sending "WM_CHAR,0,0" then "WM_CHAR,0,0x80000000" (essentially down/up).

But I still have that kludgy feeling.
 
Back
Top