Solved

Centering derived CFileDialog with Hook function enabled.

Posted on 2004-10-02
10
1,127 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Moving data to the cloud? Find out if you’re ready

Before moving to the cloud, it is important to carefully define your db needs, plan for the migration & understand prod. environment. This wp explains how to define what you need from a cloud provider, plan for the migration & what putting a cloud solution into practice entails.

 

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

Technology Partners: 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

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
In this post we will learn different types of Android Layout and some basics of an Android App.
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.
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.

623 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