// JP opened flex table

Click to See Complete Forum and Search --> : need code example of win32 file open dialog use


Mike Pliam
July 19th, 2002, 02:16 PM
I have searched Codeguru for Win32 use of the common dialog File Open. Several responses to similar questions dismissed the question by suggesting the 'querist' consult MSDN pages. This is liking asking your druggest where the dental floss is and being told to go get a root canal.

I need a simple code example that uses File Open, etc in a Win32 project. I know that you can #include <commdlg.h> and that this is not MFC. I also know that you must handle the ID_FILE_OPEN message in the windproc message switch, and that you probably need to define a windproc for the OnFileOpen thing, but I cant figure out how to do it, even after browsing <commdlg.h> and trying to set up the appropriate structs.

A code example would save me a painful trip (and alot of wasted time) to MSDN.

Thanks

billwilson3
July 19th, 2002, 02:36 PM
Google seach "Win32 dialog example"

http://www.relisoft.com/win32/dialog.html

JohnCz
July 19th, 2002, 02:42 PM
Use
::GetOpenFileName or ::GetSaveFileName passing pointer to a OPENFILENAME
structure.

Unfortunately discussing OPENFILENAME is beyond scope of this post and it can easly be found in MSDN library. MSDN is not that painful.

:cool:

Mike Pliam
March 20th, 2003, 02:49 PM
Great! I got GetOpenFileName to work. Only problem is that the dialog only opens in the upper left-hand corner of the screen.

How do I position the GetOpenFileName dialog to the center?

Thanks. Mike

billwilson3
March 20th, 2003, 05:02 PM
I can't imagine why I sent you the post I now see in the thread. I don't know much about your topic, and can see no meaningful relationship between my post and your question.

Somehow I must have crossed it with another post. Hmmm... I wonder what I put in that one?

Apologetically,

Bill

Paul McKenzie
March 20th, 2003, 06:14 PM
Originally posted by Mike Pliam
Great! I got GetOpenFileName to work. Only problem is that the dialog only opens in the upper left-hand corner of the screen.

How do I position the GetOpenFileName dialog to the center?

Thanks. Mike You have to define a HOOKPROC, and set the OPENFILENAME lpfnHook member to the HOOKPROC.

In your HOOKPROC procedure, intercept the WM_INITDIALOG message and position the dialog using MoveWindow.

Regards,

Paul McKenzie

Mike Pliam
March 26th, 2003, 09:35 PM
Thanks, Paul.

After reviewing much of the information from CodeGuru, MSDN (via Sam Hobbs), etc., I am still unable to define a HOOKPROC and get it to center the GetOpenFileName(&ofn) dialog. Also, I am unclear as to the difference between and HOOKPROC and a CALLBACK function. MSDN article says that a HOOKPROC can be a pointer to a CALLBACK function, but it is unclear whether their talking about system-wide hooks which apparently require DLLS, or simply a thread hook, which is what I think I need here.

For example, as I noted above, the following code works to open the File Open Dialog, but always in the upper left hand corner of the screen. If I make a rather uneducated attempt to define a HOOKPROC procedure and equate that procedure with ofn.lpfnHook, the compiler informs me that the operation requires a reinterpret_cast or some other type of cast. The same remarks apply to "ofn.lpfnHook = hprocMyHook;"


HOOKPROC hprocMyHook;

//...
HOOKPROC MyHook(HWND, UINT, WPARAM, LPARAM);
//...

HOOKPROC MyHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
// This is defined just like a CALLBACK function ???
{
MoveWindow(ofn.hwndOwner, 30, 30, 100, 100, TRUE);
}
//...

LRESULT CALLBACK OnFileOpen(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
//MessageBox(NULL,"File Open","X2 App", MB_ICONINFORMATION);

//=== Here we place the file path
TCHAR szFile[MAX_PATH] = { 0 };

//====== File extensions filter
TCHAR *szFilter =TEXT("Graphics Data Files (*.dat)\0")
TEXT("*.dat\0")
TEXT("All Files\0")
TEXT("*.*\0");

//====== Query the current folder
TCHAR szCurDir[MAX_PATH];
::GetCurrentDirectory(MAX_PATH-1,szCurDir);

//=== Struct used by the standard file dialog
OPENFILENAME ofn;
ZeroMemory(&ofn,sizeof(OPENFILENAME));

//====== Dialog parameters
ofn.lStructSize = sizeof(OPENFILENAME);


//====== Try to set the hook
//ofn.lpfnHook = MyHook(hWnd, ID_FILE_OPEN, 0, 0);
ofn.lpfnHook = hprocMyHook;


ofn.lpstrFilter = szFilter;
//====== The filters string index (begins with 1)
ofn.nFilterIndex = 1;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
//====== Dialog caption
ofn.lpstrTitle = _T("Open");
ofn.nMaxFileTitle = sizeof (ofn.lpstrTitle);
//====== Dialog style (only in Win2K)
ofn.Flags = OFN_EXPLORER;

//MoveWindow(hWnd, 100, 100, 200, 200, TRUE);

//====== Create and open the dialog (retuns 0 on failure)
if (GetOpenFileName(&ofn))
{
// Try to open the file (which must exist)
HANDLE hFile = CreateFile(ofn.lpstrFile, GENERIC_READ,
FILE_SHARE_READ, 0, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);

//=== On failure CreateFile returns -1
if (hFile == (HANDLE)-1)
{
MessageBox(NULL,"Could not open this file", "File I/O Error", MB_ICONSTOP);
return FALSE;
}

//====== Try to read the data
}

return FALSE;

}


While there are lots of coded example here and elsewhere, a simple one that doesnt involve DLLs would sure be helpful.

Thanks again. Mike

Mike Pliam
April 9th, 2003, 04:52 PM
Just cant get the HOOKPROC to work! I've really tried, honest!

Here's my idea of a HOOKPROC:

LPOFNHOOKPROC CenterDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
MoveWindow(hDlg, 100, 100, 200, 200, TRUE);
return 0;

}
return 0;

}


Here's how I try to use it:

// Mesage handler for file open
LRESULT CALLBACK OnFileOpen(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
//=== Here we place the file path
TCHAR szFile[MAX_PATH] = { 0 };

//====== File extensions filter
TCHAR *szFilter =TEXT("Graphics Data Files (*.dat)\0")
TEXT("*.dat\0")
TEXT("All Files\0")
TEXT("*.*\0");

//====== Query the current folder
TCHAR szCurDir[MAX_PATH];
::GetCurrentDirectory(MAX_PATH-1,szCurDir);

//=== Struct used by the standard file dialog
OPENFILENAME ofn;
ZeroMemory(&ofn,sizeof(OPENFILENAME));

//====== Dialog parameters
ofn.lStructSize = sizeof(OPENFILENAME);
//====== Set the hook
ofn.lpfnHook = CenterDlg(ofn.hwndOwner, ID_FILE_OPEN, 0, 0);

//...

}

The dialog opens, but in the upper left hand corner, and apparently nothing else happens.

Any further help greatly appreciated. I just know there are some accomplished hookers out there.

Mike

Paul McKenzie
April 9th, 2003, 05:13 PM
I'll dig up an example later today. I had to do this to get the File Save dialog to be centered.

I noticed that you did not set the hook flag (OFN_ENABLEHOOK). You need to set this.

Regards,

Paul McKenzie

filthy_mcnasty
April 9th, 2003, 05:18 PM
I haven't used a hookproc for the openfiledialog but i can suggest the following.....

when you open it, you can specify the window title with the
lpstrTitle portion. then you can simply call findwindow to locate it. if you dont want to change the title you can locate the one with the general title "Open" or "Save as" and then just verify that it's parent window is indeed your application. all this means you have the HWND handle to the open file dialog, then you can use this function i wrote to center the window over the desktop. hope this helps if the hookproc stuff doesn't work out for you.


hwndOpen = FindWindow("#32770", YOURTITLEHERE);
if(GetParent(hwndOpen) == YOURWINDOW)
{
CenterWin(hwndOpen);
}
Stuff();


void WINAPI CenterWin(HWND Top)
{
RECT rcP,rc;
GetWindowRect(GetDesktopWindow(), &rcP GetWindowRect(Top, &rc);
rcP.right -= rcP.left;
rcP.bottom -= rcP.top;
rc.right -= rc.left;
rc.bottom -= rc.top;
SetWindowPos(Top, NULL, (rcP.right/2)-(rc.right/2), (rcP.bottom/2)-(rc.bottom/2), 0, 0, SWP_NOSIZE);
}


-also realize if you use this sort of method the dialog will still initially pop up whereever it was going to so you'll have a sort of "flicker" while it's centered, this is something you cant really solve w/o the hookproc part.

Paul McKenzie
April 9th, 2003, 05:29 PM
Originally posted by Paul McKenzie
I'll dig up an example later today. I had to do this to get the File Save dialog to be centered.

I noticed that you did not set the hook flag (OFN_ENABLEHOOK). You need to set this.

Regards,

Paul McKenzie Also, you set lpfnHook to the function pointer -- you don't call it.

I don't have an example in front of me, but this is closer to what you should have been doing (not compiled):

// Prototype
UINT_PTR CenterDialog(HWND, UINT, WPARAM, LPARAM);
//...

void foo()
{
OPENFILENAME ofn;
//...
ofn.Flags = OFN_ENABLEHOOK | OFN_EXPLORER;
ofn.lpfnHook = (CALLBACK)CenterDialog;
//...
GetOpenFileName( &ofn );
//...
};

UINT_PTR CenterDialog(HWND h, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG:
// Center the dialog
return TRUE;
}
return DefDlgProc( h, msg, wParam, lParam);
}

Regards,

Paul McKenzie

Mike Pliam
April 12th, 2003, 08:18 PM
Thanks Paul.

I posted a reply a few days ago but it must have gotten lost.

I have been able to set up a hook and get it to execute, but the hook doesnt do what it is supposed to, in this case, center the Open File Dialog window.

This is my code (thanks to your help):

code:______________________________________________

LPOFNHOOKPROC CenterDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);

//...
LRESULT CALLBACK WndProc(...)
{
//...
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case ID_FILE_OPEN:
OnFileOpen(hWnd, ID_FILE_OPEN, 0, 0);
break;
//...
}

LPOFNHOOKPROC CenterDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
{
// center the dialog
HWND hWnd = GetParent(hDlg);
RECT r1, r2;
GetClientRect(hWnd, &r1);
GetWindowRect(hDlg, &r2);
POINT pt;
pt.x = (r1.right - r1.left)/2 - (r2.right - r2.left)/2;
pt.y = (r1.bottom - r1.top)/2 - (r2.bottom - r2.top)/2;
ClientToScreen(hWnd, &pt);
SetWindowPos(hDlg, HWND_TOP, pt.x, pt.y, 0, 0, SWP_NOSIZE);

return FALSE;
}
}

return 0;

}// CenterWindow(...)


// Message handler for file open
LRESULT CALLBACK OnFileOpen(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
//=== Here we place the file path
TCHAR szFile[MAX_PATH] = { 0 };

//====== File extensions filter
TCHAR *szFilter =TEXT("Matrix Data Files (*.mtx)\0")
TEXT("*.mtx\0")
TEXT("All Files\0")
TEXT("*.*\0");

//====== Query the current folder
TCHAR szCurDir[MAX_PATH];
::GetCurrentDirectory(MAX_PATH-1,szCurDir);

//=== Struct used by the standard file dialog
OPENFILENAME ofn;
ZeroMemory(&ofn,sizeof(OPENFILENAME));

//====== Dialog parameters
ofn.lStructSize = sizeof(OPENFILENAME);

//====== Window which owns the dialog
ofn.hwndOwner = GetParent(hWnd);

ofn.lpstrFilter = szFilter;
//====== The filters string index (begins with 1)
ofn.nFilterIndex = 1;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
//====== Dialog caption
ofn.lpstrTitle = _T("Open");
ofn.nMaxFileTitle = sizeof (ofn.lpstrTitle);

ofn.lpfnHook = CenterDialog((HWND)ofn.hwndOwner, ID_FILE_OPEN, 0,0);

//====== Dialog style
ofn.Flags = OFN_ENABLEHOOK | OFN_EXPLORER;

//====== Create and open the dialog (retuns 0 on failure)
if (GetOpenFileName(&ofn))
{
// Try to open the file (which must exist)
HANDLE hFile = CreateFile(ofn.lpstrFile, GENERIC_READ,
FILE_SHARE_READ, 0, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);

//=== On failure CreateFile returns -1
if (hFile == (HANDLE)-1)
{
MessageBox(NULL,"Could not open this file", "File I/O Error", MB_ICONSTOP);
return FALSE;
}

//====== Try to read the data

}
//...
}

code:________________________________________________

I know that this hook procedure is executed because I am able to trace the HOOKPROC function, BUT, it never apparently gets beyond the switch statement.

One further problem is that I am probably not calling CenterDialog with the proper parameters. How does one get a handle to the OnFileOpen Dialog?

Nevertheless, I am delighted with my progress so far. Any further help would be greatly appreciated.

Thanks again.

Mike

Sylkworm
February 13th, 2006, 01:23 PM
FYI,

I was trying to setup a OFNHookProc myself, and this thread is rather misleading. First, you need to look at microsoft's documentation for OFNHookProc.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/commondialogboxlibrary/commondialogboxreference/commondialogboxfunctions/ofnhookproc.asp

You'll see that the previous example was just declaration a function which returns a *pointer* too a HookProc (probably a NULL). What's even more confusing is that the function does get called, once, when you are attempting to assign its return value to lpfnHook.

This is the correct way to do it. Assuming you have a function declaration as:

UINT_PTR CALLBACK MyHookProc(
HWND hdlg,
UINT uiMsg,
WPARAM wParam,
LPARAM lParam
)
{
// do your thing
return NULL;
}

In your main code, you simply assign the OFNHookProc variable as so:

OPENFILENAME ofn;
//...
ofn.lpfnHook = &MyHookProc;

If you decide to include MyHookProc as a class, make it a static members. Refer to the following website for more information on creating callbacks.

http://www.newty.de/fpt/callback.html#static

Hopefully, this save the next person some time and energy. :-)

ovidiucucu
February 13th, 2006, 01:40 PM
[ Redirected thread ]

To Mike Pliam:
Mike, to make it easier to read, please use [CODE] tags for source code (see vB Code List (http://www.codeguru.com/forum/misc.php?do=bbcode)).

Thanks,
Ovidiu

kirants
February 13th, 2006, 04:15 PM
You'll see that the previous example was just declaration a function which returns a *pointer* too a HookProc (probably a NULL). What's even more confusing is that the function does get called, once, when you are attempting to assign its return value to lpfnHook.

If you are referring to this:

ofn.lpfnHook = CenterDialog((HWND)ofn.hwndOwner, ID_FILE_OPEN, 0,0);


then that error's already been pointed here:
Also, you set lpfnHook to the function pointer -- you don't call it.
;)

Anyways, thanks for pointing it out :wave: Your comment should alert anyone in future.

rince
January 20th, 2008, 11:55 AM
Hi! I've just centered Open file dialog and this topic was a big help. However, it doesn't give a complete working instruction. So here it is, maybe it'll help someone in the future.

1. Forward declaration of the hook procedure:
UINT_PTR CALLBACK HookProcCenterDialog( HWND, UINT, WPARAM, LPARAM );

2. OPENFILENAME flags must include OFN_EXPLORER and OFN_ENABLEHOOK:
ofn.Flags = OFN_EXPLORER | OFN_ENABLEHOOK | ...;

3. Pointer to the hook in OPENFILENAME:
ofn.lpfnHook = HookProcCenterDialog;

4. The hook procedure itself. There's one tricky moment here. Somehow the dialog window is not the one passed to the procedure, but its parent window.
UINT_PTR CALLBACK HookProcCenterDialog( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
if ( message == WM_INITDIALOG ) {
hDlg = GetParent( hDlg );
RECT rectDlg;
GetWindowRect( hDlg, &rectDlg );
int widthDlg = rectDlg.right - rectDlg.left;
int heightDlg = rectDlg.bottom - rectDlg.top;

HWND hParent = GetParent( hDlg );
RECT rectParent;
GetWindowRect( hParent, &rectParent );
int widthParent = rectParent.right - rectParent.left;
int heightParent = rectParent.bottom - rectParent.top;

int xDlg = rectParent.left + ( widthParent - widthDlg )/2;
int yDlg = rectParent.top + ( heightParent - heightDlg )/2;

SetWindowPos( hDlg, HWND_TOP, xDlg, yDlg, 0, 0, SWP_NOSIZE );
}
return FALSE;
}

//JP added flex table