views:

338

answers:

4

Currently, I'm spawning a message box with a OS-library function (Windows.h), which magically keeps my program alive and responding to calls to the callback function.

What alternative approach could be used to silently let the program run forever?

Trapping 'Ctrl-c' or SIGINT and subsequently calling RemoveHook() for a clean exit would be nice to have but is not essential.

HOOK my_hook;

CALLBACK my_callback_fn()
{
  ...
}

int main()
{
  my_hook = SetHook(my_callback_fn);
  MessageBox("Press OK to stop."); // This is bad.
  RemoveHook(my_hook);
  return 0;
}
A: 

A simple solution is to call Sleep() in a loop

int main() {
   // your stuff
   while(1) {
      Sleep( 10000 );
   }
   return 0;
}

but note that if you want to do the remove hook stuff, you will need to do Ctrl-C trapping..

anon
That's what I had tried at first. It leads to a complete lock up.The problem seems closely Windows-related: "Message pumping" (see above) is the way to go.
Kay Sarraute
I'm missing the point about the "complete lockup"? The hook procedure (which is likely the WH_KEYBOARD_LL hook) will still be called, which is the only point of your program apparently. And since there's no other part to your program, that can't really stop responding.(Of course, trapping Ctrl-C would be done in your keyboard hook itself.)
MSalters
A: 

creating windows services with the command line could be a way to go

You could also create it programaticaly

Eric
A: 

This may sounds weird, but there is a global variable. The clipboard.

You can listen to clipboard modifications by trapping the:

  • WM_CHANGECBCHAIN
  • WM_DRAWCLIPBOARD

When WM_DRAWCLIPBOARD is sent, you read the clipboard text and if it starts with your "magic" word, ie "##EXIT##", you can terminate your application.

Nick D
+3  A: 

You probably want to pump messages. A typical message loop looks like something like this:

BOOl ret;
MSG msg;
while ((ret=::GetMessage(&msg, hWnd, 0, 0))!=0)
{
  ::TranslateMessage(&msg);
  ::DispatchMessage(&msg);
}

You don't seem to have an actual window to pump on, and you don't say what SetHook is actually doing - maybe that will be able to provide one for you?

Another method is to use the MsgWait functions. Maybe you have some kind of handle that you are waiting to become signalled so you can exit?:

while (::MsgWaitForMultipleObjects(1, &handle, FALSE, INFINITE, QS_ALLEVENTS)==WAIT_OBJECT_0+1+
{
  BOOl ret;
  MSG msg;
  while ((ret=::PeekMessage(&msg, hWnd, 0, 0, TRUE))!=0)
  {
    ::TranslateMessage(&msg);
    ::DispatchMessage(&msg);
  }
}
1800 INFORMATION
I want to watch for and respond to certain keyboard input, so I'm actually employing a Windows keyboard hook.Message pumping works perfectly in that case, here's a reusable example program: http://pastie.org/502621(I'm running it, slightly modified, as a Ruby extension. For the curious: I'll add a link the final code when it's release-ready.)
Kay Sarraute