Solved

Centering derived CFileDialog with Hook function enabled.

Posted on 2004-10-02
10
1,099 Views
Last Modified: 2013-11-20
My problem is that if you define a hook function for a CFileDialog object, I can not figure out how to convert the HWND parameter to a CWnd parameter and call the CenterWindow function.

Here is how I create my File Dialog object…

CFileDialog cDlg(TRUE, "txt", NULL,
OFN_SHOWHELP|OFN_FILEMUSTEXIST|OFN_EXPLORER|
OFN_ENABLEHOOK,
strFilter, pFrameWnd );      // pFrameWnd is set to my MDI Frame

cDlg.m_ofn.lStructSize          = sizeof(OPENFILENAME);
cDlg.m_ofn.hInstance        = AfxGetInstanceHandle();
cDlg.m_ofn.lpstrCustomFilter= NULL;
cDlg.m_ofn.nMaxCustFilter   = 0;
cDlg.m_ofn.nFilterIndex     = 0;
cDlg.m_ofn.lpstrFile        = (LPSTR)fileName;
cDlg.m_ofn.nMaxFile         = sizeof(fileName);
cDlg.m_ofn.lpstrFileTitle   = NULL;
cDlg.m_ofn.nMaxFileTitle    = 0;
cDlg.m_ofn.lpstrInitialDir  = NULL;
cDlg.m_ofn.lpstrTitle       = NULL;
cDlg.m_ofn.nFileOffset      = 0;
cDlg.m_ofn.nFileExtension   = 0;
cDlg.m_ofn.lCustData        = 0;
cDlg.m_ofn.lpTemplateName   = NULL;
cDlg.m_ofn.lpfnHook   = FileOpenHookFunction;

cDlg.DoModal();            // I am not testing the return value yet (testing now).

Here is my hook function…

UINT CALLBACK FileOpenHookFunction( HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam )
{
      CModelXApp* pApp = (CModelXApp *) AfxGetApp();
      CWnd* pWnd = CWnd::FromHandlePermanent( hdlg );
      LPOFNOTIFY lpon;

      switch ( uiMsg )
      {
      case CDN_INITDONE:

            lpon = (LPOFNOTIFY)lParam;
            if ((pWnd != NULL) && (lpon->hdr.code == CDN_INITDONE))
            {
                  pWnd->CenterWindow();
            }
            break;

      case WM_PAINT:
      case WM_SHOWWINDOW:

            // Redraw views so that when moving the file open dialog box, there is not gray area.
            if ((pApp != NULL) && (pApp->m_pMainFrameWindow != NULL))
                  pApp->m_pMainFrameWindow->OnRender();
            break;

      default:
            break;
      }
      return false;
}

I have tested in debug mode and the function is not receiving the CDN_INITDONE message.  What do I have to do in order to receive this message.  According to the MFC documentation, all you have to specify is the OFN_EXPLORER style which I do, but I still am not receiving the CDN_INITDONE message.

Also, if you define a derived class for the CFileDialog class, you can not use a hook function because all messages will be sent to the hook function and not the message  functions you have overridden.  I kind of need to use a hook function because I want to be able to redraw the views underneath the file dialog before it is displayed (WM_PAINT and WM_SHOWWINDOW) – if I do not, they will all be dark gray.  I have tried to override the OnPaint and OnShowWindow functions with a class derived from CFileDialog and not use a hook function and redraw my views with my OnRender() function, but the views keep getting erased (dark-gray).

As it is now, the messages WM_PAINT and WM_SHOWWINDOW work fine inside the hook function (my views are updated before the file dialog window is shown).  But I can not get the file dialog window to be centered.

If you know how to fix this, I would appreciate it – I would also like to know if I am setting pWnd correctly in the hook function …CWnd* pWnd = CWnd::FromHandlePermanent( hdlg ).
0
Comment
Question by:danielvallas
  • 5
  • 2
10 Comments
 

Author Comment

by:danielvallas
ID: 12206940
I figured out how to receive the message...
case CDN_INITDONE, should be case WM_NOTIFY.
The CDN_INITDONE message comes in as a WM_NOTIFY message.

However, when CenterWindow is called it gives me an ASSERT error because m_hWnd is NULL.
I tried using a pointer to my CFileDialog object ( CFileDialog* pOpenFile = &cDlg; ) before calling cDlg.DoModal(), and then use that pointer to call CenterWindow() (pOpenFile->CenterWindow()) in the hook function under the WM_NOTIFY message, but I keep getting an ASSERT error because pOpenFile->m_hWnd == NULL.

Any Help?
0
 

Author Comment

by:danielvallas
ID: 12206953
I have noticied that the HWND hdlg parameter passed into the hook function is not NULL when the WM_NOTIFY message is passed.  How do you convert HWND hdlg that is passed into the hook function to a valid CWnd pointer, in order to call CWnd::CenterWindow() ????
0
 
LVL 15

Expert Comment

by:lakshman_ce
ID: 12207080
Try using FromHandle method

CWnd::FromHandlePermanent  
Returns a pointer to a CWnd object when given a handle to a window. If a CWnd object is not attached to the handle, NULL is returned.This function, unlike FromHandle, does not create temporary objects.
CWnd::FromHandle  
Returns a pointer to a CWnd object when given a handle to a window. If a CWnd object is not attached to the handle, a temporary CWnd object is created and attached.The pointer may be temporary and should not be stored for later use.

Also you can have a look at
http://www.codeguru.com/Cpp/controls/toolbar/miscellaneous/article.php/c5497/
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:danielvallas
ID: 12207340
What I just tried is writing my own CenterWindow function, here it is:

void CenterHWnd( HWND *pWnd, HWND *pParent )
{
     RECT m_rParentRect, m_rChildRect;
     int x, y, dx, dy;

     ::GetWindowRect( *pParent, &m_rParentRect );
     ::GetWindowRect( *pWnd,    &m_rChildRect );

     x  = (m_rParentRect.right -
          (m_rChildRect.right - m_rChildRect.left)) / 2;
     y  = (m_rParentRect.bottom -
          (m_rChildRect.bottom - m_rChildRect.top)) / 2;
     dx = (m_rChildRect.right  - m_rChildRect.left);
     dy = (m_rChildRect.bottom - m_rChildRect.top);

     ::SetWindowPos( *pWnd, NULL, x, y, dx, dy, SWP_NOSIZE|SWP_NOZORDER );
}

I then call it under the WM_NOTiFY message in my hook function...

case WM_NOTIFY:
   lpon = (LPOFNOTIFY)lParam;
   if (lpon->hdr.code == CDN_INITDONE)
      CenterHWnd( GetParent(hdlg), pFrameWnd->m_hWnd );
   break;

This does center the window, but I have the same problem (as I did without using a hook function) of my splitter pane render views underneith being erased when the open file dialog box is centered.  Even if I render my views before or after centering the window with my CenterHWnd function, the render views are still erased.  If I take out this function, the views are NOT erased, but of course, the window is not centered.

(The splitter pane views underneith the open file dialog window are actually Direct3D device views).

Is there a message for redrawing the window that I am missing, other than WM_PAINT and WM_SHOWWINDOW ???
0
 

Author Comment

by:danielvallas
ID: 12207360
Also,

FromHandle(), FromHandlePermanent(), and Attach() I have tried.  It was esier to write my own centerwindow function using HWND handles, instead of trying to figure out which function to use to build a CWnd from an HWND handle.
0
 

Author Comment

by:danielvallas
ID: 12207730
lakshman_ce,

Your link was no help - the example on that site does not use a hook function.
0
 
LVL 15

Expert Comment

by:lakshman_ce
ID: 12208238
Yes it doesn't use hooks, but it is to give an idea with the code fragments

void CFileDialogEx::OnInitDone()
{
   CWnd* wndParent = GetParent();
   ASSERT(wndParent != NULL);

   // Display File dialog in center
   wndParent->CenterWindow();

...

}

static CFileDialogEx* GetFileDlg (HWND hwdParent)
{
   CFileDialog* pDlg =
         (CFileDialog*)CWnd::FromHandle (hwdParent);
   ASSERT (pDlg != NULL);

   CFileDialogEx* pFD = (CFileDialogEx*) pDlg->GetDlgItem(0);
   ASSERT (pFD != NULL);

   return pFD;
}

0
 

Accepted Solution

by:
modulo earned 0 total points
ID: 12867792
PAQed with points refunded (500)

modulo
Community Support Moderator
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Unix / Linux grid computing 5 167
Whole sheet autoscrub still needed 19 53
lucky13 challenge 11 157
fizzArray2 challenge 1 100
Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

679 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question