Solved

Centering derived CFileDialog with Hook function enabled.

Posted on 2004-10-02
10
1,079 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
 

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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
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.
Hi friends,  in this video  I'll show you how new windows 10 user can learn the using of windows 10. Thank you.

911 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

Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!

Get 1:1 Help Now