summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Schiller <codedread@gmail.com>2008-09-11 07:39:53 +0000
committerjeff_schiller <jeff_schiller@users.sourceforge.net>2008-09-11 07:39:53 +0000
commit8719fea9bb4c58075ab1abbc654760233aef1128 (patch)
treed36f77ef37c4833cad80b9cbc7951fa889fdbf52
parentLIBNR REMOVAL. remove nartbpath test code in build.xml (diff)
downloadinkscape-8719fea9bb4c58075ab1abbc654760233aef1128.tar.gz
inkscape-8719fea9bb4c58075ab1abbc654760233aef1128.zip
First patch for Bug 209199: Update Win32 Save As dialog to include a Title edit box (and label). This edit box is sync'ed with the RDF and doc-level title and allows a user to edit the title prior to save. This patch does not update the GTK dialogs (that will be submitted in a subsequent patch).
(bzr r6791)
-rw-r--r--src/file.cpp16
-rw-r--r--src/ui/dialog/filedialog.cpp18
-rw-r--r--src/ui/dialog/filedialog.h49
-rw-r--r--src/ui/dialog/filedialogimpl-gtkmm.cpp5
-rw-r--r--src/ui/dialog/filedialogimpl-gtkmm.h25
-rw-r--r--src/ui/dialog/filedialogimpl-win32.cpp111
-rw-r--r--src/ui/dialog/filedialogimpl-win32.h26
7 files changed, 187 insertions, 63 deletions
diff --git a/src/file.cpp b/src/file.cpp
index b620e9c9e..ac8c0a40e 100644
--- a/src/file.cpp
+++ b/src/file.cpp
@@ -67,6 +67,7 @@
#include "inkscape.h"
#include "uri.h"
#include "id-clash.h"
+#include "dialogs/rdf.h"
#ifdef WITH_GNOME_VFS
# include <libgnomevfs/gnome-vfs.h>
@@ -749,13 +750,15 @@ sp_file_save_dialog(Gtk::Window &parentWindow, SPDocument *doc, bool is_copy)
} else {
dialog_title = (char const *) _("Select file to save to");
}
+ gchar* doc_title = doc->root->title();
Inkscape::UI::Dialog::FileSaveDialog *saveDialog =
Inkscape::UI::Dialog::FileSaveDialog::create(
parentWindow,
save_loc,
Inkscape::UI::Dialog::SVG_TYPES,
dialog_title,
- default_extension
+ default_extension,
+ doc_title ? doc_title : ""
);
saveDialog->setSelectionType(extension);
@@ -766,6 +769,11 @@ sp_file_save_dialog(Gtk::Window &parentWindow, SPDocument *doc, bool is_copy)
return success;
}
+ // set new title here (call RDF to ensure metadata and title element are updated)
+ rdf_set_work_entity(doc, rdf_find_entity("title"), saveDialog->getDocTitle().c_str());
+ // free up old string
+ if(doc_title) g_free(doc_title);
+
Glib::ustring fileName = saveDialog->getFilename();
Inkscape::Extension::Extension *selectionType = saveDialog->getSelectionType();
@@ -897,10 +905,10 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri,
Inkscape::XML::Document *xml_in_doc = sp_document_repr_doc(in_doc);
prevent_id_clashes(doc, in_doc);
-
+
SPObject *in_defs = SP_DOCUMENT_DEFS(in_doc);
Inkscape::XML::Node *last_def = SP_OBJECT_REPR(in_defs)->lastChild();
-
+
SPCSSAttr *style = sp_css_attr_from_object(SP_DOCUMENT_ROOT(doc));
// Count the number of top-level items in the imported document.
@@ -945,7 +953,7 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri,
if (newgroup) newgroup->appendChild(newitem);
else new_obj = place_to_insert->appendChildRepr(newitem);
}
-
+
// don't lose top-level defs or style elements
else if (SP_OBJECT_REPR(child)->type() == Inkscape::XML::ELEMENT_NODE) {
const gchar *tag = SP_OBJECT_REPR(child)->name();
diff --git a/src/ui/dialog/filedialog.cpp b/src/ui/dialog/filedialog.cpp
index 08a3230a9..b1ea5dfee 100644
--- a/src/ui/dialog/filedialog.cpp
+++ b/src/ui/dialog/filedialog.cpp
@@ -88,7 +88,7 @@ FileOpenDialog *FileOpenDialog::create(Gtk::Window &parentWindow,
#else
FileOpenDialog *dialog = new FileOpenDialogImplGtk(parentWindow, path, fileTypes, title);
#endif
-
+
return dialog;
}
@@ -104,16 +104,17 @@ Glib::ustring FileOpenDialog::getFilename()
/**
* Public factory method. Used in file.cpp
*/
-FileSaveDialog *FileSaveDialog::create(Gtk::Window& parentWindow,
+FileSaveDialog *FileSaveDialog::create(Gtk::Window& parentWindow,
const Glib::ustring &path,
FileDialogType fileTypes,
const char *title,
- const Glib::ustring &default_key)
+ const Glib::ustring &default_key,
+ const gchar *docTitle)
{
#ifdef WIN32
- FileSaveDialog *dialog = new FileSaveDialogImplWin32(parentWindow, path, fileTypes, title, default_key);
+ FileSaveDialog *dialog = new FileSaveDialogImplWin32(parentWindow, path, fileTypes, title, default_key, docTitle);
#else
- FileSaveDialog *dialog = new FileSaveDialogImplGtk(parentWindow, path, fileTypes, title, default_key);
+ FileSaveDialog *dialog = new FileSaveDialogImplGtk(parentWindow, path, fileTypes, title, default_key, docTitle);
#endif
return dialog;
}
@@ -123,6 +124,11 @@ Glib::ustring FileSaveDialog::getFilename()
return myFilename;
}
+Glib::ustring FileSaveDialog::getDocTitle()
+{
+ return myDocTitle;
+}
+
//void FileSaveDialog::change_path(const Glib::ustring& path)
//{
// myFilename = path;
@@ -162,7 +168,7 @@ void FileSaveDialog::appendExtension(Glib::ustring& path, Inkscape::Extension::O
/**
* Public factory method. Used in file.cpp
*/
- FileExportDialog *FileExportDialog::create(Gtk::Window& parentWindow,
+ FileExportDialog *FileExportDialog::create(Gtk::Window& parentWindow,
const Glib::ustring &path,
FileDialogType fileTypes,
const char *title,
diff --git a/src/ui/dialog/filedialog.h b/src/ui/dialog/filedialog.h
index b73955b46..eda8c4eb4 100644
--- a/src/ui/dialog/filedialog.h
+++ b/src/ui/dialog/filedialog.h
@@ -62,8 +62,8 @@ bool hasSuffix(const Glib::ustring &str, const Glib::ustring &ext);
/**
* Return true if the image is loadable by Gdk, else false
*/
-bool isValidImageFile(const Glib::ustring &fileName);
-
+bool isValidImageFile(const Glib::ustring &fileName);
+
/**
* This class provides an implementation-independent API for
* file "Open" dialogs. Using a standard interface obviates the need
@@ -89,7 +89,7 @@ public:
* @param fileTypes one of FileDialogTypes
* @param title the title of the dialog
*/
- static FileOpenDialog *create(Gtk::Window& parentWindow,
+ static FileOpenDialog *create(Gtk::Window& parentWindow,
const Glib::ustring &path,
FileDialogType fileTypes,
const char *title);
@@ -117,15 +117,15 @@ public:
Glib::ustring getFilename();
virtual std::vector<Glib::ustring> getFilenames() = 0;
-
+
virtual Glib::ustring getCurrentDirectory() = 0;
-
+
protected:
/**
* Filename that was given
*/
Glib::ustring myFilename;
-
+
}; //FileOpenDialog
@@ -158,11 +158,12 @@ public:
* @param title the title of the dialog
* @param key a list of file types from which the user can select
*/
- static FileSaveDialog *create(Gtk::Window& parentWindow,
+ static FileSaveDialog *create(Gtk::Window& parentWindow,
const Glib::ustring &path,
FileDialogType fileTypes,
const char *title,
- const Glib::ustring &default_key);
+ const Glib::ustring &default_key,
+ const gchar *docTitle);
/**
@@ -191,7 +192,12 @@ public:
* Get the file name chosen by the user. Valid after an [OK]
*/
Glib::ustring getFilename ();
-
+
+ /**
+ * Get the document title chosen by the user. Valid after an [OK]
+ */
+ Glib::ustring getDocTitle ();
+
virtual Glib::ustring getCurrentDirectory() = 0;
protected:
@@ -200,12 +206,17 @@ protected:
* Filename that was given
*/
Glib::ustring myFilename;
-
+
+ /**
+ * Doc Title that was given
+ */
+ Glib::ustring myDocTitle;
+
/**
* List of known file extensions.
*/
std::set<Glib::ustring> knownExtensions;
-
+
void appendExtension(Glib::ustring& path, Inkscape::Extension::Output* outputExtension);
@@ -248,7 +259,7 @@ public:
* @param title the title of the dialog
* @param key a list of file types from which the user can select
*/
- static FileExportDialog *create(Gtk::Window& parentWindow,
+ static FileExportDialog *create(Gtk::Window& parentWindow,
const Glib::ustring &path,
FileDialogType fileTypes,
const char *title,
@@ -279,28 +290,28 @@ public:
* Return the selected filename, if any. If not, return ""
*/
virtual Glib::ustring getFilename () =0;
-
+
/**
* Return the scope of the export. One of the enumerated types
- * in ScopeType
+ * in ScopeType
*/
virtual ScopeType getScope() = 0;
-
+
/**
* Return left side of the exported region
*/
virtual double getSourceX() = 0;
-
+
/**
* Return the top of the exported region
*/
virtual double getSourceY() = 0;
-
+
/**
* Return the width of the exported region
*/
virtual double getSourceWidth() = 0;
-
+
/**
* Return the height of the exported region
*/
@@ -346,7 +357,7 @@ public:
*/
virtual unsigned long getBackground() = 0;
-
+
}; //FileExportDialog
diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp
index b93e7837a..541eb388b 100644
--- a/src/ui/dialog/filedialogimpl-gtkmm.cpp
+++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp
@@ -849,9 +849,12 @@ FileSaveDialogImplGtk::FileSaveDialogImplGtk( Gtk::Window &parentWindow,
const Glib::ustring &dir,
FileDialogType fileTypes,
const Glib::ustring &title,
- const Glib::ustring &/*default_key*/ ) :
+ const Glib::ustring &/*default_key*/,
+ const gchar* docTitle) :
FileDialogBaseGtk(parentWindow, title, Gtk::FILE_CHOOSER_ACTION_SAVE, fileTypes, "dialogs.save_as")
{
+ FileSaveDialog::myDocTitle = docTitle;
+
/* One file at a time */
set_select_multiple(false);
diff --git a/src/ui/dialog/filedialogimpl-gtkmm.h b/src/ui/dialog/filedialogimpl-gtkmm.h
index 94067a921..5137b8481 100644
--- a/src/ui/dialog/filedialogimpl-gtkmm.h
+++ b/src/ui/dialog/filedialogimpl-gtkmm.h
@@ -16,9 +16,9 @@
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-
+
#include "filedialog.h"
-
+
//General includes
#include <unistd.h>
#include <sys/stat.h>
@@ -54,7 +54,7 @@
//For export dialog
#include "ui/widget/scalar-unit.h"
-
+
namespace Inkscape
{
namespace UI
@@ -250,7 +250,7 @@ public:
Glib::ustring getFilename();
std::vector<Glib::ustring> getFilenames();
-
+
Glib::ustring getCurrentDirectory();
private:
@@ -285,11 +285,12 @@ class FileSaveDialogImplGtk : public FileSaveDialog, public FileDialogBaseGtk
{
public:
- FileSaveDialogImplGtk(Gtk::Window &parentWindow,
+ FileSaveDialogImplGtk(Gtk::Window &parentWindow,
const Glib::ustring &dir,
FileDialogType fileTypes,
const Glib::ustring &title,
- const Glib::ustring &default_key);
+ const Glib::ustring &default_key,
+ const gchar* docTitle);
virtual ~FileSaveDialogImplGtk();
@@ -381,10 +382,10 @@ public:
/**
* Return the scope of the export. One of the enumerated types
- * in ScopeType
+ * in ScopeType
*/
ScopeType getScope()
- {
+ {
if (pageButton.get_active())
return SCOPE_PAGE;
else if (selectionButton.get_active())
@@ -395,25 +396,25 @@ public:
return SCOPE_DOCUMENT;
}
-
+
/**
* Return left side of the exported region
*/
double getSourceX()
{ return sourceX0Spinner.getValue(); }
-
+
/**
* Return the top of the exported region
*/
double getSourceY()
{ return sourceY1Spinner.getValue(); }
-
+
/**
* Return the width of the exported region
*/
double getSourceWidth()
{ return sourceWidthSpinner.getValue(); }
-
+
/**
* Return the height of the exported region
*/
diff --git a/src/ui/dialog/filedialogimpl-win32.cpp b/src/ui/dialog/filedialogimpl-win32.cpp
index 1f714c3db..ab0a8ec63 100644
--- a/src/ui/dialog/filedialogimpl-win32.cpp
+++ b/src/ui/dialog/filedialogimpl-win32.cpp
@@ -108,7 +108,7 @@ FileDialogBaseWin32::FileDialogBaseWin32(Gtk::Window &parent,
_filter_index = 1;
_filter_count = 0;
-
+
_title = (wchar_t*)g_utf8_to_utf16(title, -1, NULL, NULL, NULL);
g_assert(_title != NULL);
@@ -166,7 +166,7 @@ FileOpenDialogImplWin32::FileOpenDialogImplWin32(Gtk::Window &parent,
_preview_image_width = 0;
_preview_image_height = 0;
_preview_emf_image = false;
-
+
_mutex = NULL;
createFilterMenu();
@@ -274,10 +274,10 @@ void FileOpenDialogImplWin32::createFilterMenu()
all_image_files.filter_length +
all_image_files.name_length + 3 + 1;
// Add 3 for 2*2 \0s and a *, and 1 for a trailing \0
-
+
_filter = new wchar_t[filter_length];
wchar_t *filterptr = _filter;
-
+
for(list<Filter>::iterator filter_iterator = filter_list.begin();
filter_iterator != filter_list.end(); filter_iterator++)
{
@@ -303,7 +303,7 @@ void FileOpenDialogImplWin32::createFilterMenu()
_extension_map[extension_index++] = filter.mod;
}
*(filterptr++) = L'\0';
-
+
_filter_count = extension_index;
_filter_index = 2; // Select the 2nd filter in the list - 2 is NOT the 3rd
}
@@ -314,7 +314,7 @@ void FileOpenDialogImplWin32::GetOpenFileName_thread()
g_assert(this != NULL);
g_assert(_mutex != NULL);
-
+
WCHAR* current_directory_string = (WCHAR*)g_utf8_to_utf16(
_current_directory.data(), _current_directory.length(),
NULL, NULL, NULL);
@@ -1010,7 +1010,7 @@ MyGetEnhMetaFileW( const WCHAR *filename )
if (hmf) {
// Convert Windows Metafile to Enhanced Metafile
DWORD nSize = GetMetaFileBitsEx( hmf, 0, NULL );
-
+
if (nSize) {
BYTE *lpvData = new BYTE[nSize];
if (lpvData) {
@@ -1447,9 +1447,13 @@ FileSaveDialogImplWin32::FileSaveDialogImplWin32(Gtk::Window &parent,
const Glib::ustring &dir,
FileDialogType fileTypes,
const char *title,
- const Glib::ustring &/*default_key*/) :
- FileDialogBaseWin32(parent, dir, title, fileTypes, "dialogs.save_as")
+ const Glib::ustring &/*default_key*/,
+ const char *docTitle) :
+ FileDialogBaseWin32(parent, dir, title, fileTypes, "dialogs.save_as"),
+ _title_label(NULL),
+ _title_edit(NULL)
{
+ FileSaveDialog::myDocTitle = docTitle;
createFilterMenu();
}
@@ -1560,9 +1564,11 @@ void FileSaveDialogImplWin32::GetSaveFileName_thread()
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = current_directory_string;
ofn.lpstrTitle = _title;
- ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
+ ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_ENABLEHOOK;
ofn.lpstrFilter = _filter;
ofn.nFilterIndex = _filter_index;
+ ofn.lpfnHook = GetSaveFileName_hookproc;
+ ofn.lCustData = (LPARAM)this;
_result = GetSaveFileNameW(&ofn) != 0;
@@ -1590,7 +1596,7 @@ FileSaveDialogImplWin32::show()
_result = false;
_main_loop = g_main_loop_new(g_main_context_default(), FALSE);
-
+
if(_main_loop != NULL)
{
if(Glib::Thread::create(sigc::mem_fun(*this, &FileSaveDialogImplWin32::GetSaveFileName_thread), true))
@@ -1599,7 +1605,7 @@ FileSaveDialogImplWin32::show()
if(_result)
appendExtension(myFilename, (Inkscape::Extension::Output*)_extension);
}
-
+
return _result;
}
@@ -1609,6 +1615,87 @@ void FileSaveDialogImplWin32::setSelectionType( Inkscape::Extension::Extension *
}
+UINT_PTR CALLBACK FileSaveDialogImplWin32::GetSaveFileName_hookproc(
+ HWND hdlg, UINT uiMsg, WPARAM, LPARAM lParam)
+{
+ FileSaveDialogImplWin32 *pImpl = (FileSaveDialogImplWin32*)
+ GetWindowLongPtr(hdlg, GWLP_USERDATA);
+
+ switch(uiMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ HWND hParentWnd = GetParent(hdlg);
+ HINSTANCE hInstance = GetModuleHandle(NULL);
+
+ // get size/pos of typical combo box
+ RECT rEDT1, rCB1, rROOT, rST;
+ GetWindowRect(GetDlgItem(hParentWnd, cmb1), &rCB1);
+ GetWindowRect(GetDlgItem(hParentWnd, cmb13), &rEDT1);
+ GetWindowRect(GetDlgItem(hParentWnd, stc2), &rST);
+ GetWindowRect(hdlg, &rROOT);
+ int ydelta = rCB1.top - rEDT1.top;
+
+ // Make the window a bit longer
+ RECT rcRect;
+ GetWindowRect(hParentWnd, &rcRect);
+ MoveWindow(hParentWnd, rcRect.left, rcRect.top, rcRect.right - rcRect.left,
+ rcRect.bottom - rcRect.top + ydelta, FALSE);
+
+ // It is not necessary to delete stock objects by calling DeleteObject
+ HGDIOBJ dlgFont = GetStockObject(DEFAULT_GUI_FONT);
+
+ // Set the pointer to the object
+ OPENFILENAMEW *ofn = (OPENFILENAMEW*)lParam;
+ SetWindowLongPtr(hdlg, GWLP_USERDATA, ofn->lCustData);
+ SetWindowLongPtr(hParentWnd, GWLP_USERDATA, ofn->lCustData);
+ pImpl = (FileSaveDialogImplWin32*)ofn->lCustData;
+
+ // Create the Title label and edit control
+ pImpl->_title_label = CreateWindowEx(NULL, "STATIC", "Title:",
+ WS_VISIBLE|WS_CHILD,
+ CW_USEDEFAULT, CW_USEDEFAULT, rCB1.left-rST.left, rST.bottom-rST.top,
+ hParentWnd, NULL, hInstance, NULL);
+ if(pImpl->_title_label) {
+ if(dlgFont) SendMessage(pImpl->_title_label, WM_SETFONT, (WPARAM)dlgFont, MAKELPARAM(FALSE, 0));
+ SetWindowPos(pImpl->_title_label, NULL, rST.left-rROOT.left, rST.top+ydelta-rROOT.top,
+ rCB1.left-rST.left, rST.bottom-rST.top, SWP_SHOWWINDOW|SWP_NOZORDER);
+ }
+
+ pImpl->_title_edit = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "",
+ WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL,
+ CW_USEDEFAULT, CW_USEDEFAULT, rCB1.right-rCB1.left, rCB1.bottom-rCB1.top,
+ hParentWnd, NULL, hInstance, NULL);
+ if(pImpl->_title_edit) {
+ if(dlgFont) SendMessage(pImpl->_title_edit, WM_SETFONT, (WPARAM)dlgFont, MAKELPARAM(FALSE, 0));
+ SetWindowPos(pImpl->_title_edit, NULL, rCB1.left-rROOT.left, rCB1.top+ydelta-rROOT.top,
+ rCB1.right-rCB1.left, rCB1.bottom-rCB1.top, SWP_SHOWWINDOW|SWP_NOZORDER);
+ // TODO: make sure this works for Unicode
+ SetWindowText(pImpl->_title_edit, pImpl->myDocTitle.c_str());
+ }
+ }
+ break;
+ case WM_DESTROY:
+ {
+ if(pImpl->_title_edit) {
+ int length = GetWindowTextLength(pImpl->_title_edit)+1;
+ char* temp_title = new char[length];
+ GetWindowText(pImpl->_title_edit, temp_title, length);
+ pImpl->myDocTitle = temp_title;
+ delete[] temp_title;
+ DestroyWindow(pImpl->_title_label);
+ pImpl->_title_label = NULL;
+ DestroyWindow(pImpl->_title_edit);
+ pImpl->_title_edit = NULL;
+ }
+ }
+ break;
+ }
+
+ // Use default dialog behaviour
+ return 0;
+}
+
}
}
}
diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h
index 71fccca01..3a0c3775b 100644
--- a/src/ui/dialog/filedialogimpl-win32.h
+++ b/src/ui/dialog/filedialogimpl-win32.h
@@ -57,7 +57,7 @@ public:
protected:
/// The dialog type
FileDialogType dialogType;
-
+
/// A pointer to the GTK main-loop context object. This
/// is used to keep the rest of the inkscape UI running
/// while the file dialog is displayed
@@ -89,10 +89,10 @@ protected:
/// The index of the currently selected filter.
/// This value must be greater than or equal to 1,
/// and less than or equal to _filter_count.
- int _filter_index;
-
+ unsigned int _filter_index;
+
/// The number of filters registered
- int _filter_count;
+ unsigned int _filter_count;
/// An array of the extensions associated with the
/// file types of each filter. So the Nth entry of
@@ -100,7 +100,7 @@ protected:
/// filter in the list. NULL if no specific extension is
/// specified/
Inkscape::Extension::Extension **_extension_map;
-
+
/// The currently selected extension. Valid after an [OK]
Inkscape::Extension::Extension *_extension;
};
@@ -209,11 +209,11 @@ private:
/// This flag is set true if a file has been selected
bool _file_selected;
-
+
/// This flag is set true when the GetOpenFileName call
/// has returned
bool _finished;
-
+
/// This mutex is used to ensure that the worker thread
/// that calls GetOpenFileName cannot collide with the
/// main Inkscape thread
@@ -280,7 +280,7 @@ private:
/// @return Returns true if the image loaded successfully
bool set_emf_preview();
- /// This flag is set true when a meta file is previewed
+ /// This flag is set true when a meta file is previewed
bool _preview_emf_image;
/// Renders the unshrunk preview image to a windows HTBITMAP
@@ -309,7 +309,8 @@ public:
const Glib::ustring &dir,
FileDialogType fileTypes,
const char *title,
- const Glib::ustring &default_key);
+ const Glib::ustring &default_key,
+ const char *docTitle);
/// Destructor
virtual ~FileSaveDialogImplWin32();
@@ -333,6 +334,9 @@ public:
virtual void setSelectionType( Inkscape::Extension::Extension *key );
private:
+ /// A handle to the title label and edit box
+ HWND _title_label;
+ HWND _title_edit;
/// Create a filter menu for this type of dialog
void createFilterMenu();
@@ -341,6 +345,10 @@ private:
/// GetSaveFileName
void GetSaveFileName_thread();
+ /// A message proc which is called by the standard dialog
+ /// proc
+ static UINT_PTR CALLBACK GetSaveFileName_hookproc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam);
+
};