Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 305
  • Last Modified:

tabbing between edits on a modeless dialog

This should be something easy, but for reason I can't get my modeless dialog to tab between items or receive the enter key (I want to take a special action when enter is pressed while the modeless dialog is in focus).

PLEASE HELP!

I'm using Visual C++ 6.

If you need any other info, just ask and I can post code or whatever.
0
jbirk
Asked:
jbirk
  • 7
  • 7
1 Solution
 
jbirkAuthor Commented:
I was able to allow tabs by launching a thread which launched it as a modal instead of modeless.  Modals seem to have no problem tabbing and such, but there are other problems with this method.  It makes it more difficult to communicate with since it's a modal now...  I would still like to find a solution that uses a true modeless dialog.

-Josh
0
 
ShaunWildeCommented:
this is probably because you are not calling IsDialogMessage in your message processing. what window is the parent to this modeless dialog
0
 
ShaunWildeCommented:
ps - if you are launching it modeless why is it in a different thread?
0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
jbirkAuthor Commented:
No I used a different thread to launch a modal, so the modal didn't interfere with the main app (i.e. acted like a modeless even though I used DoModal()).  That was just a work around...

How do I call IsDialogMessage, and from where?  Which message handler provided by mfc will allow this, or if not how do I get around the mfc code to do it?  I don't have any message processing function or loop cause it's an mfc app.

For now the parent window is just a framework that I'm using to launch a series of modeless dialogs.  Each dialogs' code is in a dll to make the project more updateable (some of the dialogs have images making them rather large too).

Thanks,
Josh
0
 
ShaunWildeCommented:
I've just made an app myself and the tabbing worked fine with no modifications in a modeless dialog - do you want to post code - you can send to shaun_wilde@many-monkeys.com

IsDialogMessage should be already be called - the only time this cocks up is when you have anMFC app being hosted by a non MFC parent window
0
 
jbirkAuthor Commented:
Hmm... interesting.  My exe app is MFC as well as the dll which runs the dialog.  I'll put an example of the code together tomorrow at work and send it to you.  (the whole thing would be too much since it's a couple megabytes and includes some direct3d stuff as well)

Thanks for the help!
-Josh
0
 
ShaunWildeCommented:
okay - the odds are on the sample will work properly thought just to annoy us
0
 
jbirkAuthor Commented:
I've thought of that as a possibility as well:)  Guess I'll find out soon enough...
0
 
jbirkAuthor Commented:
OK, it still didn't work.  I've sent on my example.  Please take a look at it.  I included instructions on using it in the e-mail.  Hopefully it's just some silly setting I don't have set right:)

-Josh
0
 
ShaunWildeCommented:
ahhh - I see - the dialog is being hosted by a standard dll that supports MFC - this is the cause of your problems

If the host app was guaranteed to be an MFC app then I would opt for using an MFC extension DLL - this is what I did to get it working - copied over the dialog files and added the LaunchProperties function (but without the AFX_MANAGE_STATE call as it isn't needed in extension DLLs)

however if you do need to run it in an a normal DLL then...

this problem is actually documented in the MS KB

PRB: Modeless Dialog Box in a DLL Does Not Process TAB Key
ID: Q233263

(I was looking at this last night - but didn't think that it applied)

If you have to host the properties in a standalone DLL rather than an MFC extension DLL then you will need to use a message hook the obove article describes how you can do that

However - since this was a fun one I did it for you :) I modified you code to look like this (I hope you don't mind this being posted here but I couldn't see anything confidential that you wouldn't want seen)


HHOOK hHook;

LRESULT FAR PASCAL GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
   LPMSG lpMsg = (LPMSG) lParam;

   if ( nCode >= 0 && PM_REMOVE == wParam )
   {
      // Don't translate non-input events.
      if ( (lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST) )
      {
         if ( IsDialogMessage(prop->GetSafeHwnd(), lpMsg) )
         {
            // The value returned from this hookproc is ignored,
            // and it cannot be used to tell Windows the message has been handled.
            // To avoid further processing, convert the message to WM_NULL
            // before returning.
            lpMsg->message = WM_NULL;
            lpMsg->lParam  = 0;
            lpMsg->wParam  = 0;
         }
      }
   }

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

BOOL CProperties::OnInitDialog()
{
     CDialog::OnInitDialog();
     
     CFont cf;
     LOGFONT lf;
     m_quote1.GetFont()->GetLogFont(&lf);
     lf.lfWeight = 700;
     cf.CreateFontIndirect(&lf);
     m_quote1.SetFont(&cf,TRUE);
     m_quote2.SetFont(&cf,TRUE);
     m_quote3.SetFont(&cf,TRUE);
     m_quote4.SetFont(&cf,TRUE);
     m_quote5.SetFont(&cf,TRUE);

     hHook = SetWindowsHookEx( WH_GETMESSAGE, GetMsgProc,
                                   NULL, GetCurrentThreadId() );
         
     return TRUE;  // return TRUE unless you set the focus to a control
                   // EXCEPTION: OCX Property Pages should return FALSE
}


void CProperties::OnDestroy()
{
     CDialog::OnDestroy();
     
     // TODO: Add your message handler code here
     UnhookWindowsHookEx( hHook );
         
}

void CProperties::OnClose()
{
     if (m_bBlockCommands)
          return;
     CDialog::OnClose();
        // removed the call to delete prop here as that will be handled in the PostNcDestroy - you may have noticed the warning messages in the debug view :)
}
0
 
jbirkAuthor Commented:
Cool!  That works.  But I had to leave the delete in the close handler, because for some reason if you click the x it doesn't call postncdestroy so the var doesn't get nulled out and it won't launch a second time.  Also I had to add the Unhook command to close and postncdestroy or I got a stack overflow when the window is launched a second time.

OK, now I have the problem that hitting enter closes the window.  Instead I want enter to run the "Apply changes" button handler/code.  Is there something I put in the hook function to do this?

Thanks!
-Josh
0
 
ShaunWildeCommented:
have you set the appy now button to be the default button ?
0
 
jbirkAuthor Commented:
Duh *hits self on forehead" :)

Thanks a lot!
0
 
ShaunWildeCommented:
glad to help
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

The 14th Annual Expert Award Winners

The results are in! Meet the top members of our 2017 Expert Awards. Congratulations to all who qualified!

  • 7
  • 7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now