Solved

Centering derived CFileDialog with Hook function enabled.

Posted on 2004-10-02
10
1,091 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
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 

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

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
conditional code and condition difference 9 84
Doc'in system (example?) BA 7 115
pre4 challenge 19 104
Excel file not created as expected 7 79
Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
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…
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.
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

831 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