4ad17bf17dcc446549157a964eda984a684952d0
[reactos.git] / reactos / subsys / system / notepad / dialog.c
1 /*
2 * Notepad (dialog.c)
3 *
4 * Copyright 1998,99 Marcel Baur <mbaur@g26.ethz.ch>
5 * Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr>
6 * Copyright 2002 Andriy Palamarchuk
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 #define UNICODE
24
25 #include <assert.h>
26 #include <stdio.h>
27 #include <windows.h>
28 #include <commdlg.h>
29
30 #include "main.h"
31 #include "license.h"
32 #include "dialog.h"
33
34 static const WCHAR helpfileW[] = { 'n','o','t','e','p','a','d','.','h','l','p',0 };
35
36 static INT_PTR WINAPI DIALOG_PAGESETUP_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
37
38 VOID ShowLastError(void)
39 {
40 DWORD error = GetLastError();
41 if (error != NO_ERROR)
42 {
43 LPWSTR lpMsgBuf;
44 WCHAR szTitle[MAX_STRING_LEN];
45
46 LoadString(Globals.hInstance, STRING_ERROR, szTitle, SIZEOF(szTitle));
47 FormatMessage(
48 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
49 NULL, error, 0,
50 (LPTSTR) &lpMsgBuf, 0, NULL);
51 MessageBox(NULL, lpMsgBuf, szTitle, MB_OK | MB_ICONERROR);
52 LocalFree(lpMsgBuf);
53 }
54 }
55
56 /**
57 * Sets the caption of the main window according to Globals.szFileTitle:
58 * Notepad - (untitled) if no file is open
59 * Notepad - [filename] if a file is given
60 */
61 static void UpdateWindowCaption(void)
62 {
63 WCHAR szCaption[MAX_STRING_LEN];
64 WCHAR szUntitled[MAX_STRING_LEN];
65
66 LoadString(Globals.hInstance, STRING_NOTEPAD, szCaption, SIZEOF(szCaption));
67
68 if (Globals.szFileTitle[0] != '\0') {
69 static const WCHAR bracket_lW[] = { ' ','-',' ','[',0 };
70 static const WCHAR bracket_rW[] = { ']',0 };
71 lstrcat(szCaption, bracket_lW);
72 lstrcat(szCaption, Globals.szFileTitle);
73 lstrcat(szCaption, bracket_rW);
74 }
75 else
76 {
77 static const WCHAR hyphenW[] = { ' ','-',' ',0 };
78 LoadString(Globals.hInstance, STRING_UNTITLED, szUntitled, SIZEOF(szUntitled));
79 lstrcat(szCaption, hyphenW);
80 lstrcat(szCaption, szUntitled);
81 }
82
83 SetWindowText(Globals.hMainWnd, szCaption);
84 }
85
86 static void AlertFileNotFound(LPCWSTR szFileName)
87 {
88 WCHAR szMessage[MAX_STRING_LEN];
89 WCHAR szResource[MAX_STRING_LEN];
90
91 /* Load and format szMessage */
92 LoadString(Globals.hInstance, STRING_NOTFOUND, szResource, SIZEOF(szResource));
93 wsprintf(szMessage, szResource, szFileName);
94
95 /* Load szCaption */
96 LoadString(Globals.hInstance, STRING_ERROR, szResource, SIZEOF(szResource));
97
98 /* Display Modal Dialog */
99 MessageBox(Globals.hMainWnd, szMessage, szResource, MB_ICONEXCLAMATION);
100 }
101
102 static int AlertFileNotSaved(LPCWSTR szFileName)
103 {
104 WCHAR szMessage[MAX_STRING_LEN];
105 WCHAR szResource[MAX_STRING_LEN];
106 WCHAR szUntitled[MAX_STRING_LEN];
107
108 LoadString(Globals.hInstance, STRING_UNTITLED, szUntitled, SIZEOF(szUntitled));
109
110 /* Load and format Message */
111 LoadString(Globals.hInstance, STRING_NOTSAVED, szResource, SIZEOF(szResource));
112 wsprintf(szMessage, szResource, szFileName[0] ? szFileName : szUntitled);
113
114 /* Load Caption */
115 LoadString(Globals.hInstance, STRING_ERROR, szResource, SIZEOF(szResource));
116
117 /* Display modal */
118 return MessageBox(Globals.hMainWnd, szMessage, szResource, MB_ICONEXCLAMATION|MB_YESNOCANCEL);
119 }
120
121 /**
122 * Returns:
123 * TRUE - if file exists
124 * FALSE - if file does not exist
125 */
126 BOOL FileExists(LPCWSTR szFilename)
127 {
128 WIN32_FIND_DATA entry;
129 HANDLE hFile;
130
131 hFile = FindFirstFile(szFilename, &entry);
132 FindClose(hFile);
133
134 return (hFile != INVALID_HANDLE_VALUE);
135 }
136
137
138 static VOID DoSaveFile(VOID)
139 {
140 HANDLE hFile;
141 DWORD dwNumWrite;
142 LPWSTR pTemp;
143 LPVOID pConverted = NULL;
144 DWORD size;
145 BYTE bom[3];
146 int iBomSize = 0;
147 int iCodePage = -1;
148 int iNewSize;
149 int i;
150
151 hFile = CreateFile(Globals.szFileName, GENERIC_WRITE, FILE_SHARE_WRITE,
152 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
153 if(hFile == INVALID_HANDLE_VALUE)
154 {
155 ShowLastError();
156 return;
157 }
158
159 size = GetWindowTextLengthW(Globals.hEdit) + 1;
160 pTemp = HeapAlloc(GetProcessHeap(), 0, size * sizeof(*pTemp));
161 if (!pTemp)
162 {
163 CloseHandle(hFile);
164 ShowLastError();
165 return;
166 }
167 size = GetWindowTextW(Globals.hEdit, pTemp, size);
168
169 switch(Globals.iEncoding)
170 {
171 case ENCODING_ANSI:
172 iCodePage = CP_ACP;
173 break;
174
175 case ENCODING_UNICODE:
176 pConverted = pTemp;
177 iBomSize = 2;
178 bom[0] = 0xFF;
179 bom[1] = 0xFE;
180 break;
181
182 case ENCODING_UNICODE_BE:
183 pConverted = pTemp;
184 iBomSize = 2;
185 bom[0] = 0xFE;
186 bom[1] = 0xFF;
187
188 /* flip the endianness */
189 for (i = 0; i < size; i++)
190 {
191 pTemp[i] = ((pTemp[i] & 0x00FF) << 8)
192 | ((pTemp[i] & 0xFF00) >> 8);
193 }
194 break;
195
196 case ENCODING_UTF8:
197 iCodePage = CP_UTF8;
198 iBomSize = 3;
199 bom[0] = 0xEF;
200 bom[1] = 0xBB;
201 bom[2] = 0xBF;
202 break;
203 }
204
205 if (iCodePage >= 0)
206 {
207 iNewSize = WideCharToMultiByte(iCodePage, 0, pTemp, size, NULL, 0, NULL, NULL);
208 pConverted = HeapAlloc(GetProcessHeap(), 0, iNewSize);
209 if (!pConverted)
210 {
211 HeapFree(GetProcessHeap(), 0, pTemp);
212 CloseHandle(hFile);
213 ShowLastError();
214 return;
215 }
216 WideCharToMultiByte(iCodePage, 0, pTemp, size, pConverted, iNewSize, NULL, NULL);
217 }
218 else
219 {
220 iNewSize = size * sizeof(WCHAR);
221 }
222
223 if ((iBomSize > 0) && !WriteFile(hFile, bom, iBomSize, &dwNumWrite, NULL))
224 ShowLastError();
225 else if (!WriteFile(hFile, pConverted, iNewSize, &dwNumWrite, NULL))
226 ShowLastError();
227 else
228 SendMessage(Globals.hEdit, EM_SETMODIFY, FALSE, 0);
229
230 CloseHandle(hFile);
231 HeapFree(GetProcessHeap(), 0, pTemp);
232
233 if (iCodePage >= 0)
234 HeapFree(GetProcessHeap(), 0, pConverted);
235 }
236
237 /**
238 * Returns:
239 * TRUE - User agreed to close (both save/don't save)
240 * FALSE - User cancelled close by selecting "Cancel"
241 */
242 BOOL DoCloseFile(void)
243 {
244 int nResult;
245 static const WCHAR empty_strW[] = { 0 };
246
247 if (SendMessage(Globals.hEdit, EM_GETMODIFY, 0, 0))
248 {
249 /* prompt user to save changes */
250 nResult = AlertFileNotSaved(Globals.szFileName);
251 switch (nResult) {
252 case IDYES: DIALOG_FileSave();
253 break;
254
255 case IDNO: break;
256
257 case IDCANCEL: return(FALSE);
258 break;
259
260 default: return(FALSE);
261 break;
262 } /* switch */
263 } /* if */
264
265 SetFileName(empty_strW);
266
267 UpdateWindowCaption();
268 return(TRUE);
269 }
270
271
272 void DoOpenFile(LPCWSTR szFileName)
273 {
274 HANDLE hFile;
275 LPSTR pTemp;
276 LPWSTR pTemp2 = NULL;
277 DWORD size;
278 DWORD dwNumRead;
279 LPWSTR p;
280 LPBYTE p2;
281 int iCodePage;
282 int iNewSize;
283
284 /* Close any files and prompt to save changes */
285 if (!DoCloseFile())
286 return;
287
288 hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
289 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
290 if(hFile == INVALID_HANDLE_VALUE)
291 {
292 ShowLastError();
293 return;
294 }
295
296 size = GetFileSize(hFile, NULL);
297 if (size == INVALID_FILE_SIZE)
298 {
299 CloseHandle(hFile);
300 ShowLastError();
301 return;
302 }
303
304 pTemp = HeapAlloc(GetProcessHeap(), 0, size + sizeof(WCHAR));
305 if (!pTemp)
306 {
307 CloseHandle(hFile);
308 ShowLastError();
309 return;
310 }
311
312 if (!ReadFile(hFile, pTemp, size, &dwNumRead, NULL))
313 {
314 CloseHandle(hFile);
315 HeapFree(GetProcessHeap(), 0, pTemp);
316 ShowLastError();
317 return;
318 }
319
320 CloseHandle(hFile);
321 pTemp[dwNumRead] = 0;
322
323 if (IsTextUnicode(pTemp, dwNumRead, NULL))
324 {
325 p = (LPWSTR)pTemp;
326 p[dwNumRead / 2] = 0;
327
328 /* We need to strip BOM Unicode character, SetWindowTextW won't do it for us. */
329 if (*p == 0xFEFF)
330 {
331 Globals.iEncoding = ENCODING_UNICODE_BE;
332 p++;
333 }
334 else if (*p == 0xFFFE)
335 {
336 Globals.iEncoding = ENCODING_UNICODE;
337 p++;
338 }
339 }
340 else
341 {
342 p2 = (LPBYTE)pTemp;
343 if ((p2[0] == 0xEF) && (p2[1] == 0xBB) && (p2[2] == 0xBF))
344 {
345 iCodePage = CP_UTF8;
346 Globals.iEncoding = ENCODING_UTF8;
347 p2 += 3;
348 dwNumRead -= 3;
349 }
350 else
351 {
352 iCodePage = CP_ACP;
353 Globals.iEncoding = ENCODING_ANSI;
354 }
355
356 iNewSize = MultiByteToWideChar(iCodePage, 0, (LPCSTR)p2, dwNumRead, NULL, 0);
357 pTemp2 = HeapAlloc(GetProcessHeap(), 0, (iNewSize + 1) * sizeof(*pTemp2));
358 if (!pTemp2)
359 {
360 CloseHandle(hFile);
361 HeapFree(GetProcessHeap(), 0, pTemp);
362 ShowLastError();
363 return;
364 }
365 MultiByteToWideChar(iCodePage, 0, (LPCSTR)p2, dwNumRead, pTemp2, iNewSize);
366 pTemp2[iNewSize] = 0;
367 p = pTemp2;
368 }
369 SetWindowTextW(Globals.hEdit, p);
370
371 HeapFree(GetProcessHeap(), 0, pTemp);
372 if (pTemp2)
373 HeapFree(GetProcessHeap(), 0, pTemp2);
374
375 SendMessage(Globals.hEdit, EM_SETMODIFY, FALSE, 0);
376 SendMessage(Globals.hEdit, EM_EMPTYUNDOBUFFER, 0, 0);
377 SetFocus(Globals.hEdit);
378
379 SetFileName(szFileName);
380 UpdateWindowCaption();
381 }
382
383 VOID DIALOG_FileNew(VOID)
384 {
385 static const WCHAR empty_strW[] = { 0 };
386
387 /* Close any files and promt to save changes */
388 if (DoCloseFile()) {
389 SetWindowText(Globals.hEdit, empty_strW);
390 SendMessage(Globals.hEdit, EM_EMPTYUNDOBUFFER, 0, 0);
391 SetFocus(Globals.hEdit);
392 }
393 }
394
395 VOID DIALOG_FileOpen(VOID)
396 {
397 OPENFILENAME openfilename;
398 WCHAR szDir[MAX_PATH];
399 WCHAR szPath[MAX_PATH];
400 static const WCHAR szDefaultExt[] = { 't','x','t',0 };
401 static const WCHAR txt_files[] = { '*','.','t','x','t',0 };
402
403 ZeroMemory(&openfilename, sizeof(openfilename));
404
405 GetCurrentDirectory(SIZEOF(szDir), szDir);
406 if (Globals.szFileName[0] == 0)
407 lstrcpy(szPath, txt_files);
408 else
409 lstrcpy(szPath, Globals.szFileName);
410
411 openfilename.lStructSize = sizeof(openfilename);
412 openfilename.hwndOwner = Globals.hMainWnd;
413 openfilename.hInstance = Globals.hInstance;
414 openfilename.lpstrFilter = Globals.szFilter;
415 openfilename.lpstrFile = szPath;
416 openfilename.nMaxFile = SIZEOF(szPath);
417 openfilename.lpstrInitialDir = szDir;
418 openfilename.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST |
419 OFN_HIDEREADONLY;
420 openfilename.lpstrDefExt = szDefaultExt;
421
422
423 if (GetOpenFileName(&openfilename)) {
424 if (FileExists(openfilename.lpstrFile))
425 DoOpenFile(openfilename.lpstrFile);
426 else
427 AlertFileNotFound(openfilename.lpstrFile);
428 }
429 }
430
431
432 VOID DIALOG_FileSave(VOID)
433 {
434 if (Globals.szFileName[0] == '\0')
435 DIALOG_FileSaveAs();
436 else
437 DoSaveFile();
438 }
439
440 static UINT_PTR CALLBACK DIALOG_FileSaveAs_Hook(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
441 {
442 WCHAR szText[128];
443 HWND hCombo;
444 OFNOTIFY *pNotify;
445
446 switch(msg)
447 {
448 case WM_INITDIALOG:
449 hCombo = GetDlgItem(hDlg, ID_ENCODING);
450
451 LoadString(Globals.hInstance, STRING_ANSI, szText, SIZEOF(szText));
452 SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM) szText);
453
454 LoadString(Globals.hInstance, STRING_UNICODE, szText, SIZEOF(szText));
455 SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM) szText);
456
457 LoadString(Globals.hInstance, STRING_UNICODE_BE, szText, SIZEOF(szText));
458 SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM) szText);
459
460 LoadString(Globals.hInstance, STRING_UTF8, szText, SIZEOF(szText));
461 SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM) szText);
462
463 SendMessage(hCombo, CB_SETCURSEL, Globals.iEncoding, 0);
464 break;
465
466 case WM_NOTIFY:
467 if (((NMHDR *) lParam)->code == CDN_FILEOK)
468 {
469 pNotify = (OFNOTIFY *) lParam;
470 hCombo = GetDlgItem(hDlg, ID_ENCODING);
471 Globals.iEncoding = SendMessage(hCombo, CB_GETCURSEL, 0, 0);
472 }
473 break;
474 }
475 return 0;
476 }
477
478 VOID DIALOG_FileSaveAs(VOID)
479 {
480 OPENFILENAME saveas;
481 WCHAR szDir[MAX_PATH];
482 WCHAR szPath[MAX_PATH];
483 static const WCHAR szDefaultExt[] = { 't','x','t',0 };
484 static const WCHAR txt_files[] = { '*','.','t','x','t',0 };
485
486 ZeroMemory(&saveas, sizeof(saveas));
487
488 GetCurrentDirectory(SIZEOF(szDir), szDir);
489 if (Globals.szFileName[0] == 0)
490 lstrcpy(szPath, txt_files);
491 else
492 lstrcpy(szPath, Globals.szFileName);
493
494 saveas.lStructSize = sizeof(OPENFILENAME);
495 saveas.hwndOwner = Globals.hMainWnd;
496 saveas.hInstance = Globals.hInstance;
497 saveas.lpstrFilter = Globals.szFilter;
498 saveas.lpstrFile = szPath;
499 saveas.nMaxFile = SIZEOF(szPath);
500 saveas.lpstrInitialDir = szDir;
501 saveas.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT |
502 OFN_HIDEREADONLY | OFN_EXPLORER | OFN_ENABLETEMPLATE | OFN_ENABLEHOOK;
503 saveas.lpstrDefExt = szDefaultExt;
504 saveas.lpTemplateName = MAKEINTRESOURCE(DIALOG_ENCODING);
505 saveas.lpfnHook = DIALOG_FileSaveAs_Hook;
506
507 if (GetSaveFileName(&saveas)) {
508 SetFileName(szPath);
509 UpdateWindowCaption();
510 DoSaveFile();
511 }
512 }
513
514 VOID DIALOG_FilePrint(VOID)
515 {
516 DOCINFO di;
517 PRINTDLG printer;
518 SIZE szMetric;
519 int cWidthPels, cHeightPels, border;
520 int xLeft, yTop, pagecount, dopage, copycount;
521 unsigned int i;
522 LOGFONT hdrFont;
523 HFONT font, old_font=0;
524 DWORD size;
525 LPWSTR pTemp;
526 static const WCHAR times_new_romanW[] = { 'T','i','m','e','s',' ','N','e','w',' ','R','o','m','a','n',0 };
527
528 /* Get a small font and print some header info on each page */
529 hdrFont.lfHeight = 100;
530 hdrFont.lfWidth = 0;
531 hdrFont.lfEscapement = 0;
532 hdrFont.lfOrientation = 0;
533 hdrFont.lfWeight = FW_BOLD;
534 hdrFont.lfItalic = 0;
535 hdrFont.lfUnderline = 0;
536 hdrFont.lfStrikeOut = 0;
537 hdrFont.lfCharSet = ANSI_CHARSET;
538 hdrFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
539 hdrFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
540 hdrFont.lfQuality = PROOF_QUALITY;
541 hdrFont.lfPitchAndFamily = VARIABLE_PITCH | FF_ROMAN;
542 lstrcpy(hdrFont.lfFaceName, times_new_romanW);
543
544 font = CreateFontIndirect(&hdrFont);
545
546 /* Get Current Settings */
547 ZeroMemory(&printer, sizeof(printer));
548 printer.lStructSize = sizeof(printer);
549 printer.hwndOwner = Globals.hMainWnd;
550 printer.hInstance = Globals.hInstance;
551
552 /* Set some default flags */
553 printer.Flags = PD_RETURNDC;
554 printer.nFromPage = 0;
555 printer.nMinPage = 1;
556 /* we really need to calculate number of pages to set nMaxPage and nToPage */
557 printer.nToPage = 0;
558 printer.nMaxPage = -1;
559
560 /* Let commdlg manage copy settings */
561 printer.nCopies = (WORD)PD_USEDEVMODECOPIES;
562
563 if (!PrintDlg(&printer)) return;
564
565 assert(printer.hDC != 0);
566
567 /* initialize DOCINFO */
568 di.cbSize = sizeof(DOCINFO);
569 di.lpszDocName = Globals.szFileTitle;
570 di.lpszOutput = NULL;
571 di.lpszDatatype = NULL;
572 di.fwType = 0;
573
574 if (StartDoc(printer.hDC, &di) <= 0) return;
575
576 /* Get the page dimensions in pixels. */
577 cWidthPels = GetDeviceCaps(printer.hDC, HORZRES);
578 cHeightPels = GetDeviceCaps(printer.hDC, VERTRES);
579
580 /* Get the file text */
581 size = GetWindowTextLengthW(Globals.hEdit) + 1;
582 pTemp = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
583 if (!pTemp)
584 {
585 ShowLastError();
586 return;
587 }
588 size = GetWindowTextW(Globals.hEdit, pTemp, size);
589
590 border = 150;
591 for (copycount=1; copycount <= printer.nCopies; copycount++) {
592 i = 0;
593 pagecount = 1;
594 do {
595 static const WCHAR letterM[] = { 'M',0 };
596
597 if (pagecount >= printer.nFromPage &&
598 /* ((printer.Flags & PD_PAGENUMS) == 0 || pagecount <= printer.nToPage))*/
599 pagecount <= printer.nToPage)
600 dopage = 1;
601 else
602 dopage = 0;
603
604 old_font = SelectObject(printer.hDC, font);
605 GetTextExtentPoint32(printer.hDC, letterM, 1, &szMetric);
606
607 if (dopage) {
608 if (StartPage(printer.hDC) <= 0) {
609 static const WCHAR failedW[] = { 'S','t','a','r','t','P','a','g','e',' ','f','a','i','l','e','d',0 };
610 static const WCHAR errorW[] = { 'P','r','i','n','t',' ','E','r','r','o','r',0 };
611 MessageBox(Globals.hMainWnd, failedW, errorW, MB_ICONEXCLAMATION);
612 return;
613 }
614 /* Write a rectangle and header at the top of each page */
615 Rectangle(printer.hDC, border, border, cWidthPels-border, border+szMetric.cy*2);
616 /* I don't know what's up with this TextOut command. This comes out
617 kind of mangled.
618 */
619 TextOut(printer.hDC, border*2, border+szMetric.cy/2, Globals.szFileTitle, lstrlen(Globals.szFileTitle));
620 }
621
622 /* The starting point for the main text */
623 xLeft = border*2;
624 yTop = border+szMetric.cy*4;
625
626 SelectObject(printer.hDC, old_font);
627 GetTextExtentPoint32(printer.hDC, letterM, 1, &szMetric);
628
629 /* Since outputting strings is giving me problems, output the main
630 text one character at a time.
631 */
632 do {
633 if (pTemp[i] == '\n') {
634 xLeft = border*2;
635 yTop += szMetric.cy;
636 }
637 else if (pTemp[i] != '\r') {
638 if (dopage)
639 TextOut(printer.hDC, xLeft, yTop, &pTemp[i], 1);
640 xLeft += szMetric.cx;
641 }
642 } while (i++<size && yTop<(cHeightPels-border*2));
643
644 if (dopage)
645 EndPage(printer.hDC);
646 pagecount++;
647 } while (i<size);
648 }
649
650 EndDoc(printer.hDC);
651 DeleteDC(printer.hDC);
652 HeapFree(GetProcessHeap(), 0, pTemp);
653 }
654
655 VOID DIALOG_FilePrinterSetup(VOID)
656 {
657 PRINTDLG printer;
658
659 ZeroMemory(&printer, sizeof(printer));
660 printer.lStructSize = sizeof(printer);
661 printer.hwndOwner = Globals.hMainWnd;
662 printer.hInstance = Globals.hInstance;
663 printer.Flags = PD_PRINTSETUP;
664 printer.nCopies = 1;
665
666 PrintDlg(&printer);
667 }
668
669 VOID DIALOG_FileExit(VOID)
670 {
671 PostMessage(Globals.hMainWnd, WM_CLOSE, 0, 0l);
672 }
673
674 VOID DIALOG_EditUndo(VOID)
675 {
676 SendMessage(Globals.hEdit, EM_UNDO, 0, 0);
677 }
678
679 VOID DIALOG_EditCut(VOID)
680 {
681 SendMessage(Globals.hEdit, WM_CUT, 0, 0);
682 }
683
684 VOID DIALOG_EditCopy(VOID)
685 {
686 SendMessage(Globals.hEdit, WM_COPY, 0, 0);
687 }
688
689 VOID DIALOG_EditPaste(VOID)
690 {
691 SendMessage(Globals.hEdit, WM_PASTE, 0, 0);
692 }
693
694 VOID DIALOG_EditDelete(VOID)
695 {
696 SendMessage(Globals.hEdit, WM_CLEAR, 0, 0);
697 }
698
699 VOID DIALOG_EditSelectAll(VOID)
700 {
701 SendMessage(Globals.hEdit, EM_SETSEL, 0, (LPARAM)-1);
702 }
703
704 VOID DIALOG_EditTimeDate(VOID)
705 {
706 SYSTEMTIME st;
707 WCHAR szDate[MAX_STRING_LEN];
708 static const WCHAR spaceW[] = { ' ',0 };
709
710 GetLocalTime(&st);
711
712 GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, szDate, MAX_STRING_LEN);
713 SendMessage(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)szDate);
714
715 SendMessage(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)spaceW);
716
717 GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, szDate, MAX_STRING_LEN);
718 SendMessage(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)szDate);
719 }
720
721 VOID DIALOG_EditWrap(VOID)
722 {
723 static const WCHAR editW[] = { 'e','d','i','t',0 };
724 DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL |
725 ES_AUTOVSCROLL | ES_MULTILINE;
726 RECT rc;
727 DWORD size;
728 LPWSTR pTemp;
729
730 size = GetWindowTextLength(Globals.hEdit) + 1;
731 pTemp = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
732 if (!pTemp)
733 {
734 ShowLastError();
735 return;
736 }
737 GetWindowText(Globals.hEdit, pTemp, size);
738 DestroyWindow(Globals.hEdit);
739 GetClientRect(Globals.hMainWnd, &rc);
740 if( Globals.bWrapLongLines ) dwStyle |= WS_HSCROLL | ES_AUTOHSCROLL;
741 Globals.hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, editW, NULL, dwStyle,
742 0, 0, rc.right, rc.bottom, Globals.hMainWnd,
743 NULL, Globals.hInstance, NULL);
744 SendMessage(Globals.hEdit, WM_SETFONT, (WPARAM)Globals.hFont, (LPARAM)FALSE);
745 SetWindowTextW(Globals.hEdit, pTemp);
746 SetFocus(Globals.hEdit);
747 HeapFree(GetProcessHeap(), 0, pTemp);
748
749 Globals.bWrapLongLines = !Globals.bWrapLongLines;
750 CheckMenuItem(GetMenu(Globals.hMainWnd), CMD_WRAP,
751 MF_BYCOMMAND | (Globals.bWrapLongLines ? MF_CHECKED : MF_UNCHECKED));
752 }
753
754 VOID DIALOG_SelectFont(VOID)
755 {
756 CHOOSEFONT cf;
757 LOGFONT lf=Globals.lfFont;
758
759 ZeroMemory( &cf, sizeof(cf) );
760 cf.lStructSize=sizeof(cf);
761 cf.hwndOwner=Globals.hMainWnd;
762 cf.lpLogFont=&lf;
763 cf.Flags=CF_SCREENFONTS;
764
765 if( ChooseFont(&cf) )
766 {
767 HFONT currfont=Globals.hFont;
768
769 Globals.hFont=CreateFontIndirect( &lf );
770 Globals.lfFont=lf;
771 SendMessage( Globals.hEdit, WM_SETFONT, (WPARAM)Globals.hFont, (LPARAM)TRUE );
772 if( currfont!=NULL )
773 DeleteObject( currfont );
774 }
775 }
776
777 VOID DIALOG_Search(VOID)
778 {
779 ZeroMemory(&Globals.find, sizeof(Globals.find));
780 Globals.find.lStructSize = sizeof(Globals.find);
781 Globals.find.hwndOwner = Globals.hMainWnd;
782 Globals.find.hInstance = Globals.hInstance;
783 Globals.find.lpstrFindWhat = Globals.szFindText;
784 Globals.find.wFindWhatLen = SIZEOF(Globals.szFindText);
785 Globals.find.Flags = FR_DOWN;
786
787 /* We only need to create the modal FindReplace dialog which will */
788 /* notify us of incoming events using hMainWnd Window Messages */
789
790 Globals.hFindReplaceDlg = FindText(&Globals.find);
791 assert(Globals.hFindReplaceDlg !=0);
792 }
793
794 VOID DIALOG_SearchNext(VOID)
795 {
796 /* FIXME: Search Next */
797 DIALOG_Search();
798 }
799
800 VOID DIALOG_HelpContents(VOID)
801 {
802 WinHelp(Globals.hMainWnd, helpfileW, HELP_INDEX, 0);
803 }
804
805 VOID DIALOG_HelpSearch(VOID)
806 {
807 /* Search Help */
808 }
809
810 VOID DIALOG_HelpHelp(VOID)
811 {
812 WinHelp(Globals.hMainWnd, helpfileW, HELP_HELPONHELP, 0);
813 }
814
815 VOID DIALOG_HelpLicense(VOID)
816 {
817 WineLicense(Globals.hMainWnd);
818 }
819
820 VOID DIALOG_HelpNoWarranty(VOID)
821 {
822 WineWarranty(Globals.hMainWnd);
823 }
824
825 VOID DIALOG_HelpAboutWine(VOID)
826 {
827 static const WCHAR notepadW[] = { 'N','o','t','e','p','a','d','\n',0 };
828 WCHAR szNotepad[MAX_STRING_LEN];
829
830 LoadString(Globals.hInstance, STRING_NOTEPAD, szNotepad, SIZEOF(szNotepad));
831 ShellAbout(Globals.hMainWnd, szNotepad, notepadW, 0);
832 }
833
834
835 /***********************************************************************
836 *
837 * DIALOG_FilePageSetup
838 */
839 VOID DIALOG_FilePageSetup(void)
840 {
841 DialogBox(Globals.hInstance, MAKEINTRESOURCE(DIALOG_PAGESETUP),
842 Globals.hMainWnd, DIALOG_PAGESETUP_DlgProc);
843 }
844
845
846 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
847 *
848 * DIALOG_PAGESETUP_DlgProc
849 */
850
851 static INT_PTR WINAPI DIALOG_PAGESETUP_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
852 {
853
854 switch (msg)
855 {
856 case WM_COMMAND:
857 switch (wParam)
858 {
859 case IDOK:
860 /* save user input and close dialog */
861 GetDlgItemText(hDlg, 0x141, Globals.szHeader, SIZEOF(Globals.szHeader));
862 GetDlgItemText(hDlg, 0x143, Globals.szFooter, SIZEOF(Globals.szFooter));
863 GetDlgItemText(hDlg, 0x14A, Globals.szMarginTop, SIZEOF(Globals.szMarginTop));
864 GetDlgItemText(hDlg, 0x150, Globals.szMarginBottom, SIZEOF(Globals.szMarginBottom));
865 GetDlgItemText(hDlg, 0x147, Globals.szMarginLeft, SIZEOF(Globals.szMarginLeft));
866 GetDlgItemText(hDlg, 0x14D, Globals.szMarginRight, SIZEOF(Globals.szMarginRight));
867 EndDialog(hDlg, IDOK);
868 return TRUE;
869
870 case IDCANCEL:
871 /* discard user input and close dialog */
872 EndDialog(hDlg, IDCANCEL);
873 return TRUE;
874
875 case IDHELP:
876 {
877 /* FIXME: Bring this to work */
878 static const WCHAR sorryW[] = { 'S','o','r','r','y',',',' ','n','o',' ','h','e','l','p',' ','a','v','a','i','l','a','b','l','e',0 };
879 static const WCHAR helpW[] = { 'H','e','l','p',0 };
880 MessageBox(Globals.hMainWnd, sorryW, helpW, MB_ICONEXCLAMATION);
881 return TRUE;
882 }
883
884 default:
885 break;
886 }
887 break;
888
889 case WM_INITDIALOG:
890 /* fetch last user input prior to display dialog */
891 SetDlgItemText(hDlg, 0x141, Globals.szHeader);
892 SetDlgItemText(hDlg, 0x143, Globals.szFooter);
893 SetDlgItemText(hDlg, 0x14A, Globals.szMarginTop);
894 SetDlgItemText(hDlg, 0x150, Globals.szMarginBottom);
895 SetDlgItemText(hDlg, 0x147, Globals.szMarginLeft);
896 SetDlgItemText(hDlg, 0x14D, Globals.szMarginRight);
897 break;
898 }
899
900 return FALSE;
901 }