3 /////////////////////////////////////////////////////////////////////////////
5 // Copyright (c) 2002 Iain Murray, Inference Group, Cavendish, Cambridge.
7 /////////////////////////////////////////////////////////////////////////////
10 TODO: For some reason I can't get VC++ 6 SP4 or SP5 (I upgraded just to see) on win2k SP1
11 to debug this module without raising "user breakpoints". While this can be due to
12 deliberate int3 instructions, in my experience it is normally indicative of junk code
13 being loaded due to a buffer overrun. I am concerned.
15 There seem to be a few common gotchas using the OPENFILNAME structure, but I don't see
16 what I'm doing wrong. In fact the WINUI\CMDDLG\COMDLG32 SDK sample suffers from exactly
17 the same problem on my system, I even downloaded the latest SDK to see if it has been
18 fixed. Now I really don't know what to do, short of reinstalling Windows and Devstudio,
19 which I really don't want to do.
21 I have wasted faar too much time fiddlying and Googling already. Could someone tell me
22 what the problem is? Could they also tell me if it will be just fine on other computers?
24 Update - on another computer (also win2k) with VC++ the problem isn't there.
25 I don't have time to work out the difference, I'll just try and compile any releases on
26 that computer (uist for inference group members).
31 #include "WinCommon.h"
33 #include "FilenameGUI.h"
34 #include "../resource.h"
42 // Track memory leaks on Windows to the line that new'd the memory
45 #define DEBUG_NEW new( _NORMAL_BLOCK, THIS_FILE, __LINE__ )
48 static char THIS_FILE
[] = __FILE__
;
52 const Tstring
CFilenameGUI::Empty
= TEXT("");
54 CFilenameGUI::CFilenameGUI(HWND WindowWithTitlebar
, Tstring AppName
, bool NewWithDate
)
55 :WindowWithTitlebar(WindowWithTitlebar
), AppName(AppName
), NewWithDate(NewWithDate
), Dirty(false), FileAndPath(TEXT("")) {
58 TCHAR CurrentDirectory
[_MAX_DIR
];
59 if(GetCurrentDirectory(_MAX_DIR
, CurrentDirectory
) > 0) {
60 OriginalPath
= CurrentDirectory
;
62 if(OriginalPath
[OriginalPath
.size() - 1] != TEXT('\\')) // Yuck. Can't find a call to get
63 OriginalPath
+= TEXT('\\'); // the directory separator
67 OriginalPath
= TEXT("");
76 const Tstring
& CFilenameGUI::New() {
78 FileAndPath
= TEXT("");
81 SYSTEMTIME SystemTime
;
82 GetLocalTime(&SystemTime
);
84 // I don't care that different countries write dates differently.
85 // It's not as if the following is even how I would write a date normally.
86 // The point is that this is a _filename_ - and filenames sort in the
87 // correct order iff you format the date with this ordering.
89 _stprintf(Buffer
, TEXT("%04d-%02d-%02d_%02d-%02d-%02d.txt"), SystemTime
.wYear
, SystemTime
.wMonth
, SystemTime
.wDay
, SystemTime
.wHour
, SystemTime
.wMinute
, SystemTime
.wSecond
);
91 FileAndPath
= OriginalPath
+ Buffer
;
100 const Tstring
& CFilenameGUI::Open() {
101 OPENFILENAME OpenDialogStructure
;
102 TCHAR FullOpenFilename
[_MAX_PATH
] = TEXT("");
104 // Initialize OPENFILENAME
105 ZeroMemory(&OpenDialogStructure
, sizeof(OpenDialogStructure
));
106 #ifdef OPENFILENAME_SIZE_VERSION_400
107 OpenDialogStructure
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
109 OpenDialogStructure
.lStructSize
= sizeof(OpenDialogStructure
);
111 OpenDialogStructure
.hwndOwner
= WindowWithTitlebar
;
112 OpenDialogStructure
.lpstrFile
= FullOpenFilename
;
113 OpenDialogStructure
.nMaxFile
= MAX_PATH
;
114 OpenDialogStructure
.lpstrFilter
= TEXT("All Files\0*.*\0Text Documents (*.txt)\0*.txt\0");
115 OpenDialogStructure
.nFilterIndex
= 1;
116 OpenDialogStructure
.lpstrDefExt
= TEXT("txt");
117 OpenDialogStructure
.lpstrInitialDir
= NULL
;
118 OpenDialogStructure
.Flags
= OFN_PATHMUSTEXIST
| OFN_FILEMUSTEXIST
| OFN_HIDEREADONLY
;
120 // Display the Open dialog box.
121 if(GetOpenFileName(&OpenDialogStructure
) != TRUE
)
124 // Remember file details if we have them
125 FileAndPath
= OpenDialogStructure
.lpstrFile
;
130 const Tstring
& CFilenameGUI::Save() {
131 if(FileAndPath
!= TEXT(""))
132 return FileAndPath
; // Return current filename if there is one
134 // Or as fairly standard in Windows apps, we revert to SaveAs behaviour
138 const Tstring
& CFilenameGUI::SaveAs() {
139 // Lots of this is copy and pasted from FileOpen(), which means my programing style has gone to pot
140 // TODO make this better
141 OPENFILENAME OpenDialogStructure
;
142 TCHAR FullOpenFilename
[MAX_PATH
] = TEXT("");
144 // Initialize OPENFILENAME
145 ZeroMemory(&OpenDialogStructure
, sizeof(OpenDialogStructure
));
146 #ifdef OPENFILENAME_SIZE_VERSION_400
147 OpenDialogStructure
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
149 OpenDialogStructure
.lStructSize
= sizeof(OpenDialogStructure
);
151 OpenDialogStructure
.hwndOwner
= WindowWithTitlebar
;
152 OpenDialogStructure
.lpstrFile
= FullOpenFilename
;
153 OpenDialogStructure
.nMaxFile
= MAX_PATH
;
154 OpenDialogStructure
.lpstrFilter
= TEXT("All Files\0*.*\0Text Documents (*.txt)\0*.txt\0");
155 OpenDialogStructure
.nFilterIndex
= 1;
156 OpenDialogStructure
.lpstrDefExt
= TEXT("txt");
157 OpenDialogStructure
.lpstrInitialDir
= NULL
;
158 OpenDialogStructure
.Flags
= OFN_PATHMUSTEXIST
| OFN_OVERWRITEPROMPT
;
160 // Display the SaveAs dialog box.
161 if(GetSaveFileName(&OpenDialogStructure
) != TRUE
)
164 // Remember file details if we have them
165 FileAndPath
= OpenDialogStructure
.lpstrFile
;
170 void CFilenameGUI::SetNewWithDate(bool Value
) {
174 void CFilenameGUI::SetDirty(bool Value
) {
181 void CFilenameGUI::SetWindowTitle() {
185 TCHAR PrettyName
[_MAX_FNAME
];
186 if(GetFileTitle(FileAndPath
.c_str(), PrettyName
, _MAX_FNAME
) == 0)
187 TitleText
= PrettyName
;
190 WinLocalisation::GetResourceString(IDS_UNTITLED_FILE
, &TitleText
);
193 TitleText
+= TEXT("*");
194 TitleText
+= TEXT(" - ");
195 TitleText
+= AppName
;
196 SendMessage(WindowWithTitlebar
, WM_SETTEXT
, 0, (LPARAM
) TitleText
.c_str());
199 int CFilenameGUI::QuerySaveFirst() {
201 Tstring ResourceString
;
203 WinLocalisation::GetResourceString(IDS_QUERY_SAVE_CHANGES
, &ResourceString
);
204 WinLocalisation::GetResourceString(IDS_UNSAVED_CHANGES
, &Title
);
206 return MessageBox(WindowWithTitlebar
, ResourceString
.c_str(), Title
.c_str(), MB_YESNOCANCEL
| MB_ICONWARNING
| MB_DEFBUTTON1
| MB_APPLMODAL
);
212 void CFilenameGUI::SetFilename(const Tstring
&FileName
) {
213 FileAndPath
= FileName
;