Created skeleton for notepad application.
[reactos.git] / rosapps / notepad / framewnd.c
1 /*
2 * ReactOS notepad
3 *
4 * framewnd.c
5 *
6 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23 #include <windows.h>
24 #include <tchar.h>
25 #include <stdlib.h>
26 #include <commctrl.h>
27 #include <commdlg.h>
28 //#include <shellapi.h>
29
30 #include "main.h"
31 #include "framewnd.h"
32
33
34 ////////////////////////////////////////////////////////////////////////////////
35 // Global and Local Variables:
36 //
37
38 static BOOL bInMenuLoop = FALSE; // Tells us if we are in the menu loop
39
40 static HWND hChildWnd;
41
42 ////////////////////////////////////////////////////////////////////////////////
43 // Local module support methods
44 //
45
46 static void resize_frame_rect(HWND hWnd, PRECT prect)
47 {
48 RECT rt;
49 /*
50 if (IsWindowVisible(hToolBar)) {
51 SendMessage(hToolBar, WM_SIZE, 0, 0);
52 GetClientRect(hToolBar, &rt);
53 prect->top = rt.bottom+3;
54 prect->bottom -= rt.bottom+3;
55 }
56 */
57 if (IsWindowVisible(hStatusBar)) {
58 SetupStatusBar(hWnd, TRUE);
59 GetClientRect(hStatusBar, &rt);
60 prect->bottom -= rt.bottom;
61 }
62 MoveWindow(hChildWnd, prect->left, prect->top, prect->right, prect->bottom, TRUE);
63 }
64
65 void resize_frame_client(HWND hWnd)
66 {
67 RECT rect;
68
69 GetClientRect(hWnd, &rect);
70 resize_frame_rect(hWnd, &rect);
71 }
72
73 ////////////////////////////////////////////////////////////////////////////////
74
75 static void OnEnterMenuLoop(HWND hWnd)
76 {
77 int nParts;
78
79 // Update the status bar pane sizes
80 nParts = -1;
81 SendMessage(hStatusBar, SB_SETPARTS, 1, (long)&nParts);
82 bInMenuLoop = TRUE;
83 SendMessage(hStatusBar, SB_SETTEXT, (WPARAM)0, (LPARAM)_T(""));
84 }
85
86 static void OnExitMenuLoop(HWND hWnd)
87 {
88 bInMenuLoop = FALSE;
89 // Update the status bar pane sizes
90 SetupStatusBar(hWnd, TRUE);
91 UpdateStatusBar();
92 }
93
94 static void OnMenuSelect(HWND hWnd, UINT nItemID, UINT nFlags, HMENU hSysMenu)
95 {
96 TCHAR str[100];
97
98 _tcscpy(str, _T(""));
99 if (nFlags & MF_POPUP) {
100 if (hSysMenu != GetMenu(hWnd)) {
101 if (nItemID == 2) nItemID = 5;
102 }
103 }
104 if (LoadString(hInst, nItemID, str, 100)) {
105 // load appropriate string
106 LPTSTR lpsz = str;
107 // first newline terminates actual string
108 lpsz = _tcschr(lpsz, '\n');
109 if (lpsz != NULL)
110 *lpsz = '\0';
111 }
112 SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)str);
113 }
114
115 void SetupStatusBar(HWND hWnd, BOOL bResize)
116 {
117 RECT rc;
118 int nParts;
119 GetClientRect(hWnd, &rc);
120 nParts = rc.right;
121 // nParts = -1;
122 if (bResize)
123 SendMessage(hStatusBar, WM_SIZE, 0, 0);
124 SendMessage(hStatusBar, SB_SETPARTS, 1, (LPARAM)&nParts);
125 }
126
127 void UpdateStatusBar(void)
128 {
129 TCHAR text[260];
130 DWORD size;
131
132 size = sizeof(text)/sizeof(TCHAR);
133 GetComputerName(text, &size);
134 SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)text);
135 }
136
137 static void toggle_child(HWND hWnd, UINT cmd, HWND hchild)
138 {
139 BOOL vis = IsWindowVisible(hchild);
140 HMENU hMenuView = GetSubMenu(hMenuFrame, ID_VIEW_MENU);
141
142 CheckMenuItem(hMenuView, cmd, vis?MF_BYCOMMAND:MF_BYCOMMAND|MF_CHECKED);
143 ShowWindow(hchild, vis?SW_HIDE:SW_SHOW);
144 resize_frame_client(hWnd);
145 }
146
147 static BOOL CheckCommDlgError(HWND hWnd)
148 {
149 DWORD dwErrorCode = CommDlgExtendedError();
150 switch (dwErrorCode) {
151 case CDERR_DIALOGFAILURE:
152 break;
153 case CDERR_FINDRESFAILURE:
154 break;
155 case CDERR_NOHINSTANCE:
156 break;
157 case CDERR_INITIALIZATION:
158 break;
159 case CDERR_NOHOOK:
160 break;
161 case CDERR_LOCKRESFAILURE:
162 break;
163 case CDERR_NOTEMPLATE:
164 break;
165 case CDERR_LOADRESFAILURE:
166 break;
167 case CDERR_STRUCTSIZE:
168 break;
169 case CDERR_LOADSTRFAILURE:
170 break;
171 case FNERR_BUFFERTOOSMALL:
172 break;
173 case CDERR_MEMALLOCFAILURE:
174 break;
175 case FNERR_INVALIDFILENAME:
176 break;
177 case CDERR_MEMLOCKFAILURE:
178 break;
179 case FNERR_SUBCLASSFAILURE:
180 break;
181 default:
182 break;
183 }
184 return TRUE;
185 }
186
187 UINT_PTR CALLBACK File_OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
188 {
189 OPENFILENAME* pOpenFileName;
190 OFNOTIFY* pOfNotify;
191
192 switch (uiMsg) {
193 case WM_INITDIALOG:
194 pOpenFileName = (OPENFILENAME*)lParam;
195 break;
196 case WM_NOTIFY:
197 pOfNotify = (OFNOTIFY*)lParam;
198 if (pOfNotify->hdr.code == CDN_INITDONE) {
199 }
200 break;
201 default:
202 break;
203 }
204 return 0L;
205 }
206
207 #define MAX_CUSTOM_FILTER_SIZE 50
208 TCHAR CustomFilterBuffer[MAX_CUSTOM_FILTER_SIZE];
209 TCHAR FileNameBuffer[_MAX_PATH];
210 TCHAR FileTitleBuffer[_MAX_PATH];
211
212 static BOOL InitOpenFileName(HWND hWnd, OPENFILENAME* pofn)
213 {
214 memset(pofn, 0, sizeof(OPENFILENAME));
215 pofn->lStructSize = sizeof(OPENFILENAME);
216 pofn->hwndOwner = hWnd;
217 pofn->hInstance = hInst;
218
219 pofn->lpstrFilter = _T("Registration Files\0*.reg\0Win9x/NT4 Registration Files (notepad4)\0*.reg\0All Files (*.*)\0*.*\0\0");
220 pofn->lpstrCustomFilter = CustomFilterBuffer;
221 pofn->nMaxCustFilter = MAX_CUSTOM_FILTER_SIZE;
222 pofn->nFilterIndex = 0;
223 pofn->lpstrFile = FileNameBuffer;
224 pofn->nMaxFile = _MAX_PATH;
225 pofn->lpstrFileTitle = FileTitleBuffer;
226 pofn->nMaxFileTitle = _MAX_PATH;
227 // pofn->lpstrInitialDir = _T("");
228 // pofn->lpstrTitle = _T("Import Registry File");
229 // pofn->Flags = OFN_ENABLETEMPLATE + OFN_EXPLORER + OFN_ENABLESIZING;
230 pofn->Flags = OFN_HIDEREADONLY;
231 // pofn->nFileOffset = ;
232 // pofn->nFileExtension = ;
233 // pofn->lpstrDefExt = _T("");
234 // pofn->lCustData = ;
235 // pofn->lpfnHook = ImportRegistryFile_OFNHookProc;
236 // pofn->lpTemplateName = _T("ID_DLG_IMPORT_REGFILE");
237 // pofn->lpTemplateName = MAKEINTRESOURCE(IDD_DIALOG1);
238 // pofn->FlagsEx = ;
239 return TRUE;
240 }
241
242 BOOL open_file(TCHAR* file_name)
243 {
244 return TRUE;
245 }
246
247 BOOL save_file(TCHAR* file_name, TCHAR* unused)
248 {
249 return TRUE;
250 }
251
252 static BOOL OpenFileName(HWND hWnd)
253 {
254 OPENFILENAME ofn;
255
256 InitOpenFileName(hWnd, &ofn);
257 ofn.lpstrTitle = _T("Import Registry File");
258 // ofn.lCustData = ;
259 if (GetOpenFileName(&ofn)) {
260 if (!open_file(ofn.lpstrFile)) {
261 //printf("Can't open file \"%s\"\n", ofn.lpstrFile);
262 return FALSE;
263 }
264 } else {
265 CheckCommDlgError(hWnd);
266 }
267 return TRUE;
268 }
269
270 static BOOL SaveFileName(HWND hWnd)
271 {
272 OPENFILENAME ofn;
273 TCHAR ExportKeyPath[_MAX_PATH];
274
275 ExportKeyPath[0] = _T('\0');
276 InitOpenFileName(hWnd, &ofn);
277 ofn.lpstrTitle = _T("Export Registry File");
278 // ofn.lCustData = ;
279 ofn.Flags = OFN_ENABLETEMPLATE + OFN_EXPLORER;
280 ofn.lpfnHook = File_OFNHookProc;
281 ofn.lpTemplateName = MAKEINTRESOURCE(IDD_DIALOG1);
282 if (GetSaveFileName(&ofn)) {
283 BOOL result;
284 result = save_file(ofn.lpstrFile, ExportKeyPath);
285 //result = export_registry_key(ofn.lpstrFile, NULL);
286 //if (!export_registry_key(ofn.lpstrFile, NULL)) {
287 if (!result) {
288 //printf("Can't open file \"%s\"\n", ofn.lpstrFile);
289 return FALSE;
290 }
291 } else {
292 CheckCommDlgError(hWnd);
293 }
294 return TRUE;
295 }
296
297 BOOL PrintFile(HWND hWnd, LPTSTR path)
298 {
299 #if 1
300 PRINTDLG pd;
301
302 ZeroMemory(&pd, sizeof(PRINTDLG));
303 pd.lStructSize = sizeof(PRINTDLG);
304 pd.hwndOwner = hWnd;
305 pd.hDevMode = NULL; // Don't forget to free or store hDevMode
306 pd.hDevNames = NULL; // Don't forget to free or store hDevNames
307 pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC;
308 pd.nCopies = 1;
309 pd.nFromPage = 0xFFFF;
310 pd.nToPage = 0xFFFF;
311 pd.nMinPage = 1;
312 pd.nMaxPage = 0xFFFF;
313 if (PrintDlg(&pd) == TRUE) {
314 // GDI calls to render output.
315 DeleteDC(pd.hDC); // Delete DC when done.
316 }
317 #else
318 HRESULT hResult;
319 PRINTDLGEX pd;
320
321 hResult = PrintDlgEx(&pd);
322 if (hResult == S_OK) {
323 switch (pd.dwResultAction) {
324 case PD_RESULT_APPLY:
325 //The user clicked the Apply button and later clicked the Cancel button. This indicates that the user wants to apply the changes made in the property sheet, but does not yet want to print. The PRINTDLGEX structure contains the information specified by the user at the time the Apply button was clicked.
326 break;
327 case PD_RESULT_CANCEL:
328 //The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged.
329 break;
330 case PD_RESULT_PRINT:
331 //The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user.
332 break;
333 default:
334 break;
335 }
336 } else {
337 switch (hResult) {
338 case E_OUTOFMEMORY:
339 //Insufficient memory.
340 break;
341 case E_INVALIDARG:
342 // One or more arguments are invalid.
343 break;
344 case E_POINTER:
345 //Invalid pointer.
346 break;
347 case E_HANDLE:
348 //Invalid handle.
349 break;
350 case E_FAIL:
351 //Unspecified error.
352 break;
353 default:
354 break;
355 }
356 return FALSE;
357 }
358 #endif
359 return TRUE;
360 }
361
362 BOOL CopyToClipboard(HWND hWnd, LPTSTR keyName)
363 {
364 BOOL result;
365
366 result = OpenClipboard(hWnd);
367 if (result) {
368 result = EmptyClipboard();
369 if (result) {
370
371 //HANDLE hClipData;
372 //hClipData = SetClipboardData(UINT uFormat, HANDLE hMem);
373
374 } else {
375 // error emptying clipboard
376 DWORD dwError = GetLastError();
377 }
378 if (!CloseClipboard()) {
379 // error closing clipboard
380 DWORD dwError = GetLastError();
381 }
382 } else {
383 // error opening clipboard
384 DWORD dwError = GetLastError();
385 }
386 return result;
387 }
388
389 BOOL RefreshView(HWND hWnd)
390 {
391 // TODO:
392 MessageBeep(-1);
393 MessageBeep(MB_ICONASTERISK);
394 MessageBeep(MB_ICONEXCLAMATION);
395 MessageBeep(MB_ICONHAND);
396 MessageBeep(MB_ICONQUESTION);
397 MessageBeep(MB_OK);
398 return TRUE;
399 }
400
401 ////////////////////////////////////////////////////////////////////////////////
402 //
403 // FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
404 //
405 // PURPOSE: Processes WM_COMMAND messages for the main frame window.
406 //
407 //
408 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
409 {
410 switch (LOWORD(wParam)) {
411 // Parse the menu selections:
412 case ID_FILE_OPEN:
413 OpenFileName(hWnd);
414 break;
415 case ID_FILE_SAVE:
416 case ID_FILE_SAVEAS:
417 SaveFileName(hWnd);
418 break;
419 case ID_FILE_PAGESETUP:
420 case ID_FILE_PRINT:
421 PrintFile(hWnd, _T(""));
422 break;
423 //case ID_FILE_PRINTERSETUP:
424 //PRINTDLG pd;
425 //PrintDlg(&pd);
426 //PAGESETUPDLG psd;
427 //PageSetupDlg(&psd);
428 // break;
429 case ID_FILE_EXIT:
430 DestroyWindow(hWnd);
431 break;
432 case ID_EDIT_COPY:
433 CopyToClipboard(hWnd, _T(""));
434 break;
435 case ID_VIEW_REFRESH:
436 RefreshView(hWnd);
437 break;
438 // case ID_VIEW_TOOLBAR:
439 // toggle_child(hWnd, LOWORD(wParam), hToolBar);
440 // break;
441 // case ID_VIEW_STATUSBAR:
442 // toggle_child(hWnd, LOWORD(wParam), hStatusBar);
443 // break;
444 case ID_HELP_HELPTOPICS:
445 // WinHelp(hWnd, _T("notepad"), HELP_CONTENTS, 0);
446 WinHelp(hWnd, _T("notepad"), HELP_FINDER, 0);
447 break;
448 case ID_HELP_ABOUT:
449 #ifdef WINSHELLAPI
450 // ShellAbout(hWnd, szTitle, _T(""), LoadIcon(hInst, (LPCTSTR)IDI_notepad));
451 #else
452 // ShowAboutBox(hWnd);
453 #endif
454 break;
455 default:
456 return FALSE;
457 }
458 return TRUE;
459 }
460
461 ////////////////////////////////////////////////////////////////////////////////
462 //
463 // FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
464 //
465 // PURPOSE: Processes messages for the main frame window.
466 //
467
468 LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
469 {
470 switch (message) {
471 case WM_CREATE:
472 hChildWnd = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, _T("notepad edit"),
473 WS_VISIBLE | WS_CHILD,
474 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
475 hWnd, (HMENU)0, hInst, NULL);
476 break;
477 case WM_COMMAND:
478 if (!_CmdWndProc(hWnd, message, wParam, lParam)) {
479 return DefWindowProc(hWnd, message, wParam, lParam);
480 }
481 break;
482 case WM_SIZE:
483 resize_frame_client(hWnd);
484 break;
485 case WM_TIMER:
486 break;
487 case WM_ENTERMENULOOP:
488 OnEnterMenuLoop(hWnd);
489 break;
490 case WM_EXITMENULOOP:
491 OnExitMenuLoop(hWnd);
492 break;
493 case WM_MENUSELECT:
494 OnMenuSelect(hWnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
495 break;
496 case WM_DESTROY:
497 WinHelp(hWnd, _T("notepad"), HELP_QUIT, 0);
498 PostQuitMessage(0);
499 default:
500 return DefWindowProc(hWnd, message, wParam, lParam);
501 }
502 return 0;
503 }