Date: | April 8, 2005 / year-entry #89 |
Tags: | code |
Orig Link: | https://blogs.msdn.microsoft.com/oldnewthing/20050408-41/?p=35943 |
Comments: | 2 |
Summary: | Along lines similar to last time, you can also add custom accelerators to your dialog box. (In a sense, this is a generalization of custom navigation, since you can make your navigation keys be accelerators.) So let's use accelerators to navigate instead of picking off the keys manually. Our accelerator table might look like this:... |
Along lines similar to last time, you can also add custom accelerators to your dialog box. (In a sense, this is a generalization of custom navigation, since you can make your navigation keys be accelerators.) So let's use accelerators to navigate instead of picking off the keys manually. Our accelerator table might look like this: IDA_PROPSHEET ACCELERATORS BEGIN VK_TAB ,IDC_NEXTPAGE ,VIRTKEY,CONTROL VK_TAB ,IDC_PREVPAGE ,VIRTKEY,CONTROL,SHIFT END Here you can see my comma placement convention for tables. I like to put commas at the far end of the field rather than jamming it up against the last word in the column. Doing this makes cut/paste a lot easier, since you can cut a column and paste it somewhere else without having to go back and twiddle all the commas. Assuming you've loaded this accelerator table into the variable "hacc", you can use that table in your custom dialog loop: while (<dialog still active> && GetMessage(&msg, NULL, 0, 0, 0)) { if (!TranslateAccelerator(hdlg, hacc, &msg) && !IsDialogMessage(hdlg, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } }
The The same as last time, if you think there might be modeless dialogs owned by this message loop, you will have to do filtering so that you don't pick off somebody else's navigation keys. while (<dialog still active> && GetMessage(&msg, NULL, 0, 0, 0)) { if (!((hdlg == msg.hwnd || IsChild(hdlg, msg.hwnd)) && !TranslateAccelerator(hdlg, hacc, &msg)) && !IsDialogMessage(hdlg, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } Okay, I think that's enough of dialog boxes for now. |
Comments (2)
Comments are closed. |
My head certainly hurts. However I have one question (I hope this is not off topic) : what should we do about APCs in modal loops ? I have sometimes wanted to do something like what follows, but I do not have enough experience to decide if this is suicide or not.
//CTor
m_hDummy = ::CreateEvent(NULL, FALSE, FALSE, NULL);
//Message loop :
while (<dialog still active>)
{
//alertable wait on dummy handle until there are messages to process
while(WAIT_IO_COMPLETION == ::MsgWaitForMultipleObjectsEx(1, &m_hDummy, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE))
{
//Process APCs and go back to sleep.
}
//Message handling.
if(GetMessage(&msg, NULL, 0, 0, 0)))
{
//Do your stuff
}
}
Fracois, you definitely can do that. Just be sure to structure your loop to pump messages while waiting on that handle.
while (-1 != (iRet = PeekMessage(..)))
{
if (iRet)
{
// translate, dispatch, etc
}
else
{
MsgWaitForMultipleObjectsEx(…)
// process here if the handle woke us up.
// otherwise fall through to the PeekMessage
}
}