Jump to content
  • Advertisement
Sign in to follow this  
Subotron

capture WM_KEYDOWN/WM_CHAR in dialog window [SOLVED]

This topic is 4466 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

In the past, I've used both DirectInput and win32 message handling to capture keyboard input. Now, I'm posed with a problem though: I am creating some kind of a map editor, which basically consists of a dialog window, with some tools in it, and also a frame which I use as a rendering context for OpenGL. It all worked well, until I got to keyboard input. I don't want to use DirectInput here, but just capturing WM_KEYDOWN/WM_CHAR doesn't seem to do anything. I guess this must have something to do with my dialog window, but I can't figure out what the problem is. I tried stripping to code, this is what I end up with: Registering the window:
bool CWindow::register_window()
{
	instance = GetModuleHandle(NULL);

	wc.cbClsExtra		= 0;
	wc.cbWndExtra		= 0;
	wc.hbrBackground	= NULL;
	wc.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wc.hIcon		= LoadIcon(NULL, IDI_WINLOGO);
	wc.hInstance		= instance;
	wc.lpfnWndProc		= (WNDPROC)callbacks.callback[DLG_MAIN];
	wc.lpszClassName	= window_title;
	wc.lpszMenuName		= (LPCTSTR)IDR_MENU;
	wc.style		= CS_OWNDC | CS_HREDRAW | CS_VREDRAW;

	if (!RegisterClass(&wc))
		return false;

	return true;
}
Window initialization:
bool CWindow::init(const char* title)
{
	set_title(title); // Set the window's title

	InitCommonControls(); // We need this to use Microsoft's common controls

	LoadMenu(instance, (LPCSTR)IDR_MENU); // Load our menu

	if (!register_window())	// Try to register the window
		return false;		// We failed, so we return

	dlg[DLG_MAIN] = CreateDialog(instance, (LPCTSTR)IDD_DLG_MAIN, NULL, (DLGPROC)callbacks.callback[DLG_MAIN]);	// Create our main dialog

	SetWindowText(dlg[DLG_MAIN], window_title); // Set the title of our dialog to the global title

	ShowWindow(dlg[DLG_MAIN], SW_SHOW); // Show the main dialog
	SetFocus(dlg[DLG_MAIN]);		// Give focus to the main dialog
	SetActiveWindow(dlg[DLG_MAIN]);	// Set the main dialog as active window

	return true;
}
Handle the messages:
bool CWindow::handle_messages()
{
	MSG msg;

	ZeroMemory(&msg, sizeof(msg));

	while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) // Handle all messages on the stack
	{ 
		if (msg.message == WM_QUIT || msg.message == WM_CLOSE) // Required for ending the application
			return false;

		if (!IsDialogMessage(dlg[DLG_MAIN], &msg)) // If the message is not a dialog message, dispatch it to the callback function
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return true;
}
Windowproc:
callback (&engine.window, CALLBACK_MAIN)
{
	switch (msg)
	{
		case WM_SYSCOMMAND:
			switch (wparam)
			{
				case SC_SCREENSAVE:		// Screensaver is turned on
				case SC_MONITORPOWER:	// Monitor is turning to standby
				return 0;
			}
			break;

		case WM_KEYDOWN:
			MessageBox(NULL, "Key down", TITLE, MB_OK); // Never happens
			break;

		case WM_CHAR:
			MessageBox(NULL, "Key down", TITLE, MB_OK); // Never happens
			break;

		case WM_INITDIALOG:
			break;

		case WM_COMMAND:
			switch (LOWORD(wparam))
			{
				case IDC_FILE_QUIT:		// Menu File option Quit selected
					PostQuitMessage(0);	// Quit the program
					break;
			}

		case WM_MOUSEMOVE:
			// Some camera stuff I cut out of the code
			break;

		case WM_ACTIVATE:
			break;

		case WM_CLOSE:
			engine.window.destroy(); // Destroy the window
			break;

		case WM_QUIT:
			engine.window.destroy(); // Destroy the window
			break;

		case WM_DESTROY:
			PostQuitMessage(0); // The window is being destroyed, so we wan't to quit the program
			break;
	}

	return 0;
}
If anyone sees anything wrong, please tell me how to fix this :) Thanks a lot! Edit: stripped the code a little bit wrong, a break; was left somewhere it shouldn't. This has nothing to do with the problem though... [Edited by - Subotron on July 5, 2006 6:36:21 AM]

Share this post


Link to post
Share on other sites
Advertisement
yeah, it never gets called because a dialog never has the input focus... only child windows in dialogs can have the input focus (dialogs use the keys to navigate between controls and is also why when you hit Enter the dialog closes because the OK or Cancel button has the focus...). the solution (since your dialog is modeless) would be to hack into your message loop and peek at the WM_KEYDOWN/WM_CHAR messages of your dialog before they are dispatched to the child with input focus. since it looks like you have a little windows wrapper you could do something like how you would handle this in MFC... using the PreTranslateMessage function.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!