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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 */ 22 23 #include "notepad.h" 24 25 #include <assert.h> 26 #include <commctrl.h> 27 #include <strsafe.h> 28 29 LRESULT CALLBACK EDIT_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 30 31 static const TCHAR helpfile[] = _T("notepad.hlp"); 32 static const TCHAR empty_str[] = _T(""); 33 static const TCHAR szDefaultExt[] = _T("txt"); 34 static const TCHAR txt_files[] = _T("*.txt"); 35 36 static UINT_PTR CALLBACK DIALOG_PAGESETUP_Hook(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 LPTSTR lpMsgBuf = NULL; 44 TCHAR szTitle[MAX_STRING_LEN]; 45 46 LoadString(Globals.hInstance, STRING_ERROR, szTitle, ARRAY_SIZE(szTitle)); 47 48 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 49 NULL, 50 error, 51 0, 52 (LPTSTR) &lpMsgBuf, 53 0, 54 NULL); 55 56 MessageBox(NULL, lpMsgBuf, szTitle, MB_OK | MB_ICONERROR); 57 LocalFree(lpMsgBuf); 58 } 59 } 60 61 /** 62 * Sets the caption of the main window according to Globals.szFileTitle: 63 * (untitled) - Notepad if no file is open 64 * [filename] - Notepad if a file is given 65 */ 66 void UpdateWindowCaption(BOOL clearModifyAlert) 67 { 68 TCHAR szCaption[MAX_STRING_LEN]; 69 TCHAR szNotepad[MAX_STRING_LEN]; 70 TCHAR szFilename[MAX_STRING_LEN]; 71 BOOL isModified; 72 73 if (clearModifyAlert) 74 { 75 /* When a file is being opened or created, there is no need to have 76 * the edited flag shown when the file has not been edited yet. */ 77 isModified = FALSE; 78 } 79 else 80 { 81 /* Check whether the user has modified the file or not. If we are 82 * in the same state as before, don't change the caption. */ 83 isModified = !!SendMessage(Globals.hEdit, EM_GETMODIFY, 0, 0); 84 if (isModified == Globals.bWasModified) 85 return; 86 } 87 88 /* Remember the state for later calls */ 89 Globals.bWasModified = isModified; 90 91 /* Load the name of the application */ 92 LoadString(Globals.hInstance, STRING_NOTEPAD, szNotepad, ARRAY_SIZE(szNotepad)); 93 94 /* Determine if the file has been saved or if this is a new file */ 95 if (Globals.szFileTitle[0] != 0) 96 StringCchCopy(szFilename, ARRAY_SIZE(szFilename), Globals.szFileTitle); 97 else 98 LoadString(Globals.hInstance, STRING_UNTITLED, szFilename, ARRAY_SIZE(szFilename)); 99 100 /* Update the window caption based upon whether the user has modified the file or not */ 101 StringCbPrintf(szCaption, sizeof(szCaption), _T("%s%s - %s"), 102 (isModified ? _T("*") : _T("")), szFilename, szNotepad); 103 104 SetWindowText(Globals.hMainWnd, szCaption); 105 } 106 107 int DIALOG_StringMsgBox(HWND hParent, int formatId, LPCTSTR szString, DWORD dwFlags) 108 { 109 TCHAR szMessage[MAX_STRING_LEN]; 110 TCHAR szResource[MAX_STRING_LEN]; 111 112 /* Load and format szMessage */ 113 LoadString(Globals.hInstance, formatId, szResource, ARRAY_SIZE(szResource)); 114 _sntprintf(szMessage, ARRAY_SIZE(szMessage), szResource, szString); 115 116 /* Load szCaption */ 117 if ((dwFlags & MB_ICONMASK) == MB_ICONEXCLAMATION) 118 LoadString(Globals.hInstance, STRING_ERROR, szResource, ARRAY_SIZE(szResource)); 119 else 120 LoadString(Globals.hInstance, STRING_NOTEPAD, szResource, ARRAY_SIZE(szResource)); 121 122 /* Display Modal Dialog */ 123 // if (hParent == NULL) 124 // hParent = Globals.hMainWnd; 125 return MessageBox(hParent, szMessage, szResource, dwFlags); 126 } 127 128 static void AlertFileNotFound(LPCTSTR szFileName) 129 { 130 DIALOG_StringMsgBox(Globals.hMainWnd, STRING_NOTFOUND, szFileName, MB_ICONEXCLAMATION | MB_OK); 131 } 132 133 static int AlertFileNotSaved(LPCTSTR szFileName) 134 { 135 TCHAR szUntitled[MAX_STRING_LEN]; 136 137 LoadString(Globals.hInstance, STRING_UNTITLED, szUntitled, ARRAY_SIZE(szUntitled)); 138 139 return DIALOG_StringMsgBox(Globals.hMainWnd, STRING_NOTSAVED, 140 szFileName[0] ? szFileName : szUntitled, 141 MB_ICONQUESTION | MB_YESNOCANCEL); 142 } 143 144 static void AlertPrintError(void) 145 { 146 TCHAR szUntitled[MAX_STRING_LEN]; 147 148 LoadString(Globals.hInstance, STRING_UNTITLED, szUntitled, ARRAY_SIZE(szUntitled)); 149 150 DIALOG_StringMsgBox(Globals.hMainWnd, STRING_PRINTERROR, 151 Globals.szFileName[0] ? Globals.szFileName : szUntitled, 152 MB_ICONEXCLAMATION | MB_OK); 153 } 154 155 /** 156 * Returns: 157 * TRUE - if file exists 158 * FALSE - if file does not exist 159 */ 160 BOOL FileExists(LPCTSTR szFilename) 161 { 162 WIN32_FIND_DATA entry; 163 HANDLE hFile; 164 165 hFile = FindFirstFile(szFilename, &entry); 166 FindClose(hFile); 167 168 return (hFile != INVALID_HANDLE_VALUE); 169 } 170 171 BOOL HasFileExtension(LPCTSTR szFilename) 172 { 173 LPCTSTR s; 174 175 s = _tcsrchr(szFilename, _T('\\')); 176 if (s) 177 szFilename = s; 178 return _tcsrchr(szFilename, _T('.')) != NULL; 179 } 180 181 int GetSelectionTextLength(HWND hWnd) 182 { 183 DWORD dwStart = 0; 184 DWORD dwEnd = 0; 185 186 SendMessage(hWnd, EM_GETSEL, (WPARAM)&dwStart, (LPARAM)&dwEnd); 187 188 return dwEnd - dwStart; 189 } 190 191 int GetSelectionText(HWND hWnd, LPTSTR lpString, int nMaxCount) 192 { 193 DWORD dwStart = 0; 194 DWORD dwEnd = 0; 195 DWORD dwSize; 196 HRESULT hResult; 197 LPTSTR lpTemp; 198 199 if (!lpString) 200 { 201 return 0; 202 } 203 204 SendMessage(hWnd, EM_GETSEL, (WPARAM)&dwStart, (LPARAM)&dwEnd); 205 206 if (dwStart == dwEnd) 207 { 208 return 0; 209 } 210 211 dwSize = GetWindowTextLength(hWnd) + 1; 212 lpTemp = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(TCHAR)); 213 if (!lpTemp) 214 { 215 return 0; 216 } 217 218 dwSize = GetWindowText(hWnd, lpTemp, dwSize); 219 220 if (!dwSize) 221 { 222 HeapFree(GetProcessHeap(), 0, lpTemp); 223 return 0; 224 } 225 226 hResult = StringCchCopyN(lpString, nMaxCount, lpTemp + dwStart, dwEnd - dwStart); 227 HeapFree(GetProcessHeap(), 0, lpTemp); 228 229 switch (hResult) 230 { 231 case S_OK: 232 { 233 return dwEnd - dwStart; 234 } 235 236 case STRSAFE_E_INSUFFICIENT_BUFFER: 237 { 238 return nMaxCount - 1; 239 } 240 241 default: 242 { 243 return 0; 244 } 245 } 246 } 247 248 static RECT 249 GetPrintingRect(HDC hdc, RECT margins) 250 { 251 int iLogPixelsX, iLogPixelsY; 252 int iHorzRes, iVertRes; 253 int iPhysPageX, iPhysPageY, iPhysPageW, iPhysPageH; 254 RECT rcPrintRect; 255 256 iPhysPageX = GetDeviceCaps(hdc, PHYSICALOFFSETX); 257 iPhysPageY = GetDeviceCaps(hdc, PHYSICALOFFSETY); 258 iPhysPageW = GetDeviceCaps(hdc, PHYSICALWIDTH); 259 iPhysPageH = GetDeviceCaps(hdc, PHYSICALHEIGHT); 260 iLogPixelsX = GetDeviceCaps(hdc, LOGPIXELSX); 261 iLogPixelsY = GetDeviceCaps(hdc, LOGPIXELSY); 262 iHorzRes = GetDeviceCaps(hdc, HORZRES); 263 iVertRes = GetDeviceCaps(hdc, VERTRES); 264 265 rcPrintRect.left = (margins.left * iLogPixelsX / 2540) - iPhysPageX; 266 rcPrintRect.top = (margins.top * iLogPixelsY / 2540) - iPhysPageY; 267 rcPrintRect.right = iHorzRes - (((margins.left * iLogPixelsX / 2540) - iPhysPageX) + ((margins.right * iLogPixelsX / 2540) - (iPhysPageW - iPhysPageX - iHorzRes))); 268 rcPrintRect.bottom = iVertRes - (((margins.top * iLogPixelsY / 2540) - iPhysPageY) + ((margins.bottom * iLogPixelsY / 2540) - (iPhysPageH - iPhysPageY - iVertRes))); 269 270 return rcPrintRect; 271 } 272 273 static BOOL DoSaveFile(VOID) 274 { 275 BOOL bRet = TRUE; 276 HANDLE hFile; 277 LPTSTR pTemp; 278 DWORD size; 279 280 hFile = CreateFile(Globals.szFileName, GENERIC_WRITE, FILE_SHARE_WRITE, 281 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 282 if(hFile == INVALID_HANDLE_VALUE) 283 { 284 ShowLastError(); 285 return FALSE; 286 } 287 288 size = GetWindowTextLength(Globals.hEdit) + 1; 289 pTemp = HeapAlloc(GetProcessHeap(), 0, size * sizeof(*pTemp)); 290 if (!pTemp) 291 { 292 CloseHandle(hFile); 293 ShowLastError(); 294 return FALSE; 295 } 296 size = GetWindowText(Globals.hEdit, pTemp, size); 297 298 if (size) 299 { 300 if (!WriteText(hFile, (LPWSTR)pTemp, size, Globals.encFile, Globals.iEoln)) 301 { 302 ShowLastError(); 303 bRet = FALSE; 304 } 305 else 306 { 307 SendMessage(Globals.hEdit, EM_SETMODIFY, FALSE, 0); 308 bRet = TRUE; 309 } 310 } 311 312 CloseHandle(hFile); 313 HeapFree(GetProcessHeap(), 0, pTemp); 314 315 if (bRet) 316 { 317 SetFileName(Globals.szFileName); 318 } 319 320 return bRet; 321 } 322 323 /** 324 * Returns: 325 * TRUE - User agreed to close (both save/don't save) 326 * FALSE - User cancelled close by selecting "Cancel" 327 */ 328 BOOL DoCloseFile(VOID) 329 { 330 int nResult; 331 332 if (SendMessage(Globals.hEdit, EM_GETMODIFY, 0, 0)) 333 { 334 /* prompt user to save changes */ 335 nResult = AlertFileNotSaved(Globals.szFileName); 336 switch (nResult) 337 { 338 case IDYES: 339 if(!DIALOG_FileSave()) 340 return FALSE; 341 break; 342 343 case IDNO: 344 break; 345 346 case IDCANCEL: 347 return FALSE; 348 349 default: 350 return FALSE; 351 } 352 } 353 354 SetFileName(empty_str); 355 UpdateWindowCaption(TRUE); 356 357 return TRUE; 358 } 359 360 VOID DoOpenFile(LPCTSTR szFileName) 361 { 362 static const TCHAR dotlog[] = _T(".LOG"); 363 HANDLE hFile; 364 LPTSTR pszText = NULL; 365 DWORD dwTextLen; 366 TCHAR log[5]; 367 368 /* Close any files and prompt to save changes */ 369 if (!DoCloseFile()) 370 return; 371 372 hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 373 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 374 if (hFile == INVALID_HANDLE_VALUE) 375 { 376 ShowLastError(); 377 goto done; 378 } 379 380 if (!ReadText(hFile, (LPWSTR *)&pszText, &dwTextLen, &Globals.encFile, &Globals.iEoln)) 381 { 382 ShowLastError(); 383 goto done; 384 } 385 SetWindowText(Globals.hEdit, pszText); 386 387 SendMessage(Globals.hEdit, EM_SETMODIFY, FALSE, 0); 388 SendMessage(Globals.hEdit, EM_EMPTYUNDOBUFFER, 0, 0); 389 SetFocus(Globals.hEdit); 390 391 /* If the file starts with .LOG, add a time/date at the end and set cursor after 392 * See http://support.microsoft.com/?kbid=260563 393 */ 394 if (GetWindowText(Globals.hEdit, log, ARRAY_SIZE(log)) && !_tcscmp(log, dotlog)) 395 { 396 static const TCHAR lf[] = _T("\r\n"); 397 SendMessage(Globals.hEdit, EM_SETSEL, GetWindowTextLength(Globals.hEdit), -1); 398 SendMessage(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)lf); 399 DIALOG_EditTimeDate(); 400 SendMessage(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)lf); 401 } 402 403 SetFileName(szFileName); 404 UpdateWindowCaption(TRUE); 405 NOTEPAD_EnableSearchMenu(); 406 done: 407 if (hFile != INVALID_HANDLE_VALUE) 408 CloseHandle(hFile); 409 if (pszText) 410 HeapFree(GetProcessHeap(), 0, pszText); 411 } 412 413 VOID DIALOG_FileNew(VOID) 414 { 415 /* Close any files and prompt to save changes */ 416 if (DoCloseFile()) { 417 SetWindowText(Globals.hEdit, empty_str); 418 SendMessage(Globals.hEdit, EM_EMPTYUNDOBUFFER, 0, 0); 419 SetFocus(Globals.hEdit); 420 NOTEPAD_EnableSearchMenu(); 421 } 422 } 423 424 VOID DIALOG_FileNewWindow(VOID) 425 { 426 TCHAR pszNotepadExe[MAX_PATH]; 427 GetModuleFileName(NULL, pszNotepadExe, ARRAYSIZE(pszNotepadExe)); 428 ShellExecute(NULL, NULL, pszNotepadExe, NULL, NULL, SW_SHOWNORMAL); 429 } 430 431 VOID DIALOG_FileOpen(VOID) 432 { 433 OPENFILENAME openfilename; 434 TCHAR szPath[MAX_PATH]; 435 436 ZeroMemory(&openfilename, sizeof(openfilename)); 437 438 if (Globals.szFileName[0] == 0) 439 _tcscpy(szPath, txt_files); 440 else 441 _tcscpy(szPath, Globals.szFileName); 442 443 openfilename.lStructSize = sizeof(openfilename); 444 openfilename.hwndOwner = Globals.hMainWnd; 445 openfilename.hInstance = Globals.hInstance; 446 openfilename.lpstrFilter = Globals.szFilter; 447 openfilename.lpstrFile = szPath; 448 openfilename.nMaxFile = ARRAY_SIZE(szPath); 449 openfilename.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY; 450 openfilename.lpstrDefExt = szDefaultExt; 451 452 if (GetOpenFileName(&openfilename)) { 453 if (FileExists(openfilename.lpstrFile)) 454 DoOpenFile(openfilename.lpstrFile); 455 else 456 AlertFileNotFound(openfilename.lpstrFile); 457 } 458 } 459 460 BOOL DIALOG_FileSave(VOID) 461 { 462 if (Globals.szFileName[0] == 0) 463 { 464 return DIALOG_FileSaveAs(); 465 } 466 else if (DoSaveFile()) 467 { 468 UpdateWindowCaption(TRUE); 469 return TRUE; 470 } 471 return FALSE; 472 } 473 474 static UINT_PTR 475 CALLBACK 476 DIALOG_FileSaveAs_Hook(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) 477 { 478 TCHAR szText[128]; 479 HWND hCombo; 480 481 UNREFERENCED_PARAMETER(wParam); 482 483 switch(msg) 484 { 485 case WM_INITDIALOG: 486 hCombo = GetDlgItem(hDlg, ID_ENCODING); 487 488 LoadString(Globals.hInstance, STRING_ANSI, szText, ARRAY_SIZE(szText)); 489 SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM) szText); 490 491 LoadString(Globals.hInstance, STRING_UNICODE, szText, ARRAY_SIZE(szText)); 492 SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM) szText); 493 494 LoadString(Globals.hInstance, STRING_UNICODE_BE, szText, ARRAY_SIZE(szText)); 495 SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM) szText); 496 497 LoadString(Globals.hInstance, STRING_UTF8, szText, ARRAY_SIZE(szText)); 498 SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM) szText); 499 500 SendMessage(hCombo, CB_SETCURSEL, Globals.encFile, 0); 501 502 hCombo = GetDlgItem(hDlg, ID_EOLN); 503 504 LoadString(Globals.hInstance, STRING_CRLF, szText, ARRAY_SIZE(szText)); 505 SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM) szText); 506 507 LoadString(Globals.hInstance, STRING_LF, szText, ARRAY_SIZE(szText)); 508 SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM) szText); 509 510 LoadString(Globals.hInstance, STRING_CR, szText, ARRAY_SIZE(szText)); 511 SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM) szText); 512 513 SendMessage(hCombo, CB_SETCURSEL, Globals.iEoln, 0); 514 break; 515 516 case WM_NOTIFY: 517 if (((NMHDR *) lParam)->code == CDN_FILEOK) 518 { 519 hCombo = GetDlgItem(hDlg, ID_ENCODING); 520 if (hCombo) 521 Globals.encFile = (ENCODING) SendMessage(hCombo, CB_GETCURSEL, 0, 0); 522 523 hCombo = GetDlgItem(hDlg, ID_EOLN); 524 if (hCombo) 525 Globals.iEoln = (int) SendMessage(hCombo, CB_GETCURSEL, 0, 0); 526 } 527 break; 528 } 529 return 0; 530 } 531 532 BOOL DIALOG_FileSaveAs(VOID) 533 { 534 OPENFILENAME saveas; 535 TCHAR szPath[MAX_PATH]; 536 537 ZeroMemory(&saveas, sizeof(saveas)); 538 539 if (Globals.szFileName[0] == 0) 540 _tcscpy(szPath, txt_files); 541 else 542 _tcscpy(szPath, Globals.szFileName); 543 544 saveas.lStructSize = sizeof(OPENFILENAME); 545 saveas.hwndOwner = Globals.hMainWnd; 546 saveas.hInstance = Globals.hInstance; 547 saveas.lpstrFilter = Globals.szFilter; 548 saveas.lpstrFile = szPath; 549 saveas.nMaxFile = ARRAY_SIZE(szPath); 550 saveas.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | 551 OFN_EXPLORER | OFN_ENABLETEMPLATE | OFN_ENABLEHOOK; 552 saveas.lpstrDefExt = szDefaultExt; 553 saveas.lpTemplateName = MAKEINTRESOURCE(DIALOG_ENCODING); 554 saveas.lpfnHook = DIALOG_FileSaveAs_Hook; 555 556 if (GetSaveFileName(&saveas)) 557 { 558 /* HACK: Because in ROS, Save-As boxes don't check the validity 559 * of file names and thus, here, szPath can be invalid !! We only 560 * see its validity when we call DoSaveFile()... */ 561 SetFileName(szPath); 562 if (DoSaveFile()) 563 { 564 UpdateWindowCaption(TRUE); 565 return TRUE; 566 } 567 else 568 { 569 SetFileName(_T("")); 570 return FALSE; 571 } 572 } 573 else 574 { 575 return FALSE; 576 } 577 } 578 579 VOID DIALOG_FilePrint(VOID) 580 { 581 DOCINFO di; 582 TEXTMETRIC tm; 583 PRINTDLG printer; 584 SIZE szMetric; 585 int border; 586 int xLeft, yTop, pagecount, dopage, copycount; 587 unsigned int i; 588 LOGFONT hdrFont; 589 HFONT font, old_font=0; 590 DWORD size; 591 LPTSTR pTemp; 592 static const TCHAR times_new_roman[] = _T("Times New Roman"); 593 RECT rcPrintRect; 594 595 /* Get a small font and print some header info on each page */ 596 ZeroMemory(&hdrFont, sizeof(hdrFont)); 597 hdrFont.lfHeight = 100; 598 hdrFont.lfWeight = FW_BOLD; 599 hdrFont.lfCharSet = ANSI_CHARSET; 600 hdrFont.lfOutPrecision = OUT_DEFAULT_PRECIS; 601 hdrFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; 602 hdrFont.lfQuality = PROOF_QUALITY; 603 hdrFont.lfPitchAndFamily = VARIABLE_PITCH | FF_ROMAN; 604 _tcscpy(hdrFont.lfFaceName, times_new_roman); 605 606 font = CreateFontIndirect(&hdrFont); 607 608 /* Get Current Settings */ 609 ZeroMemory(&printer, sizeof(printer)); 610 printer.lStructSize = sizeof(printer); 611 printer.hwndOwner = Globals.hMainWnd; 612 printer.hInstance = Globals.hInstance; 613 614 /* Set some default flags */ 615 printer.Flags = PD_RETURNDC | PD_SELECTION; 616 617 /* Disable the selection radio button if there is no text selected */ 618 if (!GetSelectionTextLength(Globals.hEdit)) 619 { 620 printer.Flags = printer.Flags | PD_NOSELECTION; 621 } 622 623 printer.nFromPage = 0; 624 printer.nMinPage = 1; 625 /* we really need to calculate number of pages to set nMaxPage and nToPage */ 626 printer.nToPage = (WORD)-1; 627 printer.nMaxPage = (WORD)-1; 628 629 /* Let commdlg manage copy settings */ 630 printer.nCopies = (WORD)PD_USEDEVMODECOPIES; 631 632 printer.hDevMode = Globals.hDevMode; 633 printer.hDevNames = Globals.hDevNames; 634 635 if (!PrintDlg(&printer)) 636 { 637 DeleteObject(font); 638 return; 639 } 640 641 Globals.hDevMode = printer.hDevMode; 642 Globals.hDevNames = printer.hDevNames; 643 644 assert(printer.hDC != 0); 645 646 /* initialize DOCINFO */ 647 di.cbSize = sizeof(DOCINFO); 648 di.lpszDocName = Globals.szFileTitle; 649 di.lpszOutput = NULL; 650 di.lpszDatatype = NULL; 651 di.fwType = 0; 652 653 if (StartDoc(printer.hDC, &di) <= 0) 654 { 655 DeleteObject(font); 656 return; 657 } 658 659 660 /* Get the file text */ 661 if (printer.Flags & PD_SELECTION) 662 { 663 size = GetSelectionTextLength(Globals.hEdit) + 1; 664 } 665 else 666 { 667 size = GetWindowTextLength(Globals.hEdit) + 1; 668 } 669 670 pTemp = HeapAlloc(GetProcessHeap(), 0, size * sizeof(TCHAR)); 671 if (!pTemp) 672 { 673 EndDoc(printer.hDC); 674 DeleteObject(font); 675 ShowLastError(); 676 return; 677 } 678 679 if (printer.Flags & PD_SELECTION) 680 { 681 size = GetSelectionText(Globals.hEdit, pTemp, size); 682 } 683 else 684 { 685 size = GetWindowText(Globals.hEdit, pTemp, size); 686 } 687 688 /* Get the current printing area */ 689 rcPrintRect = GetPrintingRect(printer.hDC, Globals.lMargins); 690 691 /* Ensure that each logical unit maps to one pixel */ 692 SetMapMode(printer.hDC, MM_TEXT); 693 694 /* Needed to get the correct height of a text line */ 695 GetTextMetrics(printer.hDC, &tm); 696 697 border = 15; 698 for (copycount=1; copycount <= printer.nCopies; copycount++) { 699 i = 0; 700 pagecount = 1; 701 do { 702 /* Don't start a page if none of the conditions below are true */ 703 dopage = 0; 704 705 /* The user wants to print the current selection */ 706 if (printer.Flags & PD_SELECTION) 707 { 708 dopage = 1; 709 } 710 711 /* The user wants to print the entire document */ 712 if (!(printer.Flags & PD_PAGENUMS) && !(printer.Flags & PD_SELECTION)) 713 { 714 dopage = 1; 715 } 716 717 /* The user wants to print a specified range of pages */ 718 if ((pagecount >= printer.nFromPage && pagecount <= printer.nToPage)) 719 { 720 dopage = 1; 721 } 722 723 old_font = SelectObject(printer.hDC, font); 724 725 if (dopage) { 726 if (StartPage(printer.hDC) <= 0) { 727 SelectObject(printer.hDC, old_font); 728 EndDoc(printer.hDC); 729 DeleteDC(printer.hDC); 730 HeapFree(GetProcessHeap(), 0, pTemp); 731 DeleteObject(font); 732 AlertPrintError(); 733 return; 734 } 735 736 SetViewportOrgEx(printer.hDC, rcPrintRect.left, rcPrintRect.top, NULL); 737 738 /* Write a rectangle and header at the top of each page */ 739 Rectangle(printer.hDC, border, border, rcPrintRect.right - border, border + tm.tmHeight * 2); 740 /* I don't know what's up with this TextOut command. This comes out 741 kind of mangled. 742 */ 743 TextOut(printer.hDC, 744 border * 2, 745 border + tm.tmHeight / 2, 746 Globals.szFileTitle, 747 lstrlen(Globals.szFileTitle)); 748 } 749 750 /* The starting point for the main text */ 751 xLeft = 0; 752 yTop = border + tm.tmHeight * 4; 753 754 SelectObject(printer.hDC, old_font); 755 756 /* Since outputting strings is giving me problems, output the main 757 * text one character at a time. */ 758 do { 759 if (pTemp[i] == '\n') { 760 xLeft = 0; 761 yTop += tm.tmHeight; 762 } 763 else if (pTemp[i] != '\r') { 764 if (dopage) 765 TextOut(printer.hDC, xLeft, yTop, &pTemp[i], 1); 766 767 /* We need to get the width for each individual char, since a proportional font may be used */ 768 GetTextExtentPoint32(printer.hDC, &pTemp[i], 1, &szMetric); 769 xLeft += szMetric.cx; 770 771 /* Insert a line break if the current line does not fit into the printing area */ 772 if (xLeft > rcPrintRect.right) 773 { 774 xLeft = 0; 775 yTop = yTop + tm.tmHeight; 776 } 777 } 778 } while (i++ < size && yTop < rcPrintRect.bottom); 779 780 if (dopage) 781 EndPage(printer.hDC); 782 pagecount++; 783 } while (i < size); 784 } 785 786 if (old_font != 0) 787 SelectObject(printer.hDC, old_font); 788 EndDoc(printer.hDC); 789 DeleteDC(printer.hDC); 790 HeapFree(GetProcessHeap(), 0, pTemp); 791 DeleteObject(font); 792 } 793 794 VOID DIALOG_FileExit(VOID) 795 { 796 PostMessage(Globals.hMainWnd, WM_CLOSE, 0, 0l); 797 } 798 799 VOID DIALOG_EditUndo(VOID) 800 { 801 SendMessage(Globals.hEdit, EM_UNDO, 0, 0); 802 } 803 804 VOID DIALOG_EditCut(VOID) 805 { 806 SendMessage(Globals.hEdit, WM_CUT, 0, 0); 807 } 808 809 VOID DIALOG_EditCopy(VOID) 810 { 811 SendMessage(Globals.hEdit, WM_COPY, 0, 0); 812 } 813 814 VOID DIALOG_EditPaste(VOID) 815 { 816 SendMessage(Globals.hEdit, WM_PASTE, 0, 0); 817 } 818 819 VOID DIALOG_EditDelete(VOID) 820 { 821 SendMessage(Globals.hEdit, WM_CLEAR, 0, 0); 822 } 823 824 VOID DIALOG_EditSelectAll(VOID) 825 { 826 SendMessage(Globals.hEdit, EM_SETSEL, 0, (LPARAM)-1); 827 } 828 829 VOID DIALOG_EditTimeDate(VOID) 830 { 831 SYSTEMTIME st; 832 TCHAR szDate[MAX_STRING_LEN]; 833 TCHAR szText[MAX_STRING_LEN * 2 + 2]; 834 835 GetLocalTime(&st); 836 837 GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, szDate, MAX_STRING_LEN); 838 _tcscpy(szText, szDate); 839 _tcscat(szText, _T(" ")); 840 GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, szDate, MAX_STRING_LEN); 841 _tcscat(szText, szDate); 842 SendMessage(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)szText); 843 } 844 845 VOID DoCreateStatusBar(VOID) 846 { 847 RECT rc; 848 RECT rcstatus; 849 BOOL bStatusBarVisible; 850 851 /* Check if status bar object already exists. */ 852 if (Globals.hStatusBar == NULL) 853 { 854 /* Try to create the status bar */ 855 Globals.hStatusBar = CreateStatusWindow(WS_CHILD | WS_VISIBLE | WS_EX_STATICEDGE, 856 NULL, 857 Globals.hMainWnd, 858 CMD_STATUSBAR_WND_ID); 859 860 if (Globals.hStatusBar == NULL) 861 { 862 ShowLastError(); 863 return; 864 } 865 866 /* Load the string for formatting column/row text output */ 867 LoadString(Globals.hInstance, STRING_LINE_COLUMN, Globals.szStatusBarLineCol, MAX_PATH - 1); 868 869 /* Set the status bar for single-text output */ 870 SendMessage(Globals.hStatusBar, SB_SIMPLE, (WPARAM)TRUE, (LPARAM)0); 871 } 872 873 /* Set status bar visiblity according to the settings. */ 874 if ((Globals.bWrapLongLines != FALSE) || (Globals.bShowStatusBar == FALSE)) 875 { 876 bStatusBarVisible = FALSE; 877 ShowWindow(Globals.hStatusBar, SW_HIDE); 878 } 879 else 880 { 881 bStatusBarVisible = TRUE; 882 ShowWindow(Globals.hStatusBar, SW_SHOW); 883 SendMessage(Globals.hStatusBar, WM_SIZE, 0, 0); 884 } 885 886 /* Set check state in show status bar item. */ 887 if (bStatusBarVisible) 888 { 889 CheckMenuItem(Globals.hMenu, CMD_STATUSBAR, MF_BYCOMMAND | MF_CHECKED); 890 } 891 else 892 { 893 CheckMenuItem(Globals.hMenu, CMD_STATUSBAR, MF_BYCOMMAND | MF_UNCHECKED); 894 } 895 896 /* Update menu mar with the previous changes */ 897 DrawMenuBar(Globals.hMainWnd); 898 899 /* Sefety test is edit control exists */ 900 if (Globals.hEdit != NULL) 901 { 902 /* Retrieve the sizes of the controls */ 903 GetClientRect(Globals.hMainWnd, &rc); 904 GetClientRect(Globals.hStatusBar, &rcstatus); 905 906 /* If status bar is currently visible, update dimensions of edit control */ 907 if (bStatusBarVisible) 908 rc.bottom -= (rcstatus.bottom - rcstatus.top); 909 910 /* Resize edit control to right size. */ 911 MoveWindow(Globals.hEdit, 912 rc.left, 913 rc.top, 914 rc.right - rc.left, 915 rc.bottom - rc.top, 916 TRUE); 917 } 918 919 /* Update content with current row/column text */ 920 DIALOG_StatusBarUpdateCaretPos(); 921 } 922 923 VOID DoCreateEditWindow(VOID) 924 { 925 DWORD dwStyle; 926 int iSize; 927 LPTSTR pTemp = NULL; 928 BOOL bModified = FALSE; 929 930 iSize = 0; 931 932 /* If the edit control already exists, try to save its content */ 933 if (Globals.hEdit != NULL) 934 { 935 /* number of chars currently written into the editor. */ 936 iSize = GetWindowTextLength(Globals.hEdit); 937 if (iSize) 938 { 939 /* Allocates temporary buffer. */ 940 pTemp = HeapAlloc(GetProcessHeap(), 0, (iSize + 1) * sizeof(TCHAR)); 941 if (!pTemp) 942 { 943 ShowLastError(); 944 return; 945 } 946 947 /* Recover the text into the control. */ 948 GetWindowText(Globals.hEdit, pTemp, iSize + 1); 949 950 if (SendMessage(Globals.hEdit, EM_GETMODIFY, 0, 0)) 951 bModified = TRUE; 952 } 953 954 /* Restore original window procedure */ 955 SetWindowLongPtr(Globals.hEdit, GWLP_WNDPROC, (LONG_PTR)Globals.EditProc); 956 957 /* Destroy the edit control */ 958 DestroyWindow(Globals.hEdit); 959 } 960 961 /* Update wrap status into the main menu and recover style flags */ 962 if (Globals.bWrapLongLines) 963 { 964 dwStyle = EDIT_STYLE_WRAP; 965 EnableMenuItem(Globals.hMenu, CMD_STATUSBAR, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); 966 } else { 967 dwStyle = EDIT_STYLE; 968 EnableMenuItem(Globals.hMenu, CMD_STATUSBAR, MF_BYCOMMAND | MF_ENABLED); 969 } 970 971 /* Update previous changes */ 972 DrawMenuBar(Globals.hMainWnd); 973 974 /* Create the new edit control */ 975 Globals.hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, 976 EDIT_CLASS, 977 NULL, 978 dwStyle, 979 CW_USEDEFAULT, 980 CW_USEDEFAULT, 981 CW_USEDEFAULT, 982 CW_USEDEFAULT, 983 Globals.hMainWnd, 984 NULL, 985 Globals.hInstance, 986 NULL); 987 988 if (Globals.hEdit == NULL) 989 { 990 if (pTemp) 991 { 992 HeapFree(GetProcessHeap(), 0, pTemp); 993 } 994 995 ShowLastError(); 996 return; 997 } 998 999 SendMessage(Globals.hEdit, WM_SETFONT, (WPARAM)Globals.hFont, FALSE); 1000 SendMessage(Globals.hEdit, EM_LIMITTEXT, 0, 0); 1001 1002 /* If some text was previously saved, restore it. */ 1003 if (iSize != 0) 1004 { 1005 SetWindowText(Globals.hEdit, pTemp); 1006 HeapFree(GetProcessHeap(), 0, pTemp); 1007 1008 if (bModified) 1009 SendMessage(Globals.hEdit, EM_SETMODIFY, TRUE, 0); 1010 } 1011 1012 /* Sub-class a new window callback for row/column detection. */ 1013 Globals.EditProc = (WNDPROC)SetWindowLongPtr(Globals.hEdit, 1014 GWLP_WNDPROC, 1015 (LONG_PTR)EDIT_WndProc); 1016 1017 /* Create/update status bar */ 1018 DoCreateStatusBar(); 1019 1020 /* Finally shows new edit control and set focus into it. */ 1021 ShowWindow(Globals.hEdit, SW_SHOW); 1022 SetFocus(Globals.hEdit); 1023 } 1024 1025 VOID DIALOG_EditWrap(VOID) 1026 { 1027 Globals.bWrapLongLines = !Globals.bWrapLongLines; 1028 1029 if (Globals.bWrapLongLines) 1030 { 1031 EnableMenuItem(Globals.hMenu, CMD_GOTO, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); 1032 } 1033 else 1034 { 1035 EnableMenuItem(Globals.hMenu, CMD_GOTO, MF_BYCOMMAND | MF_ENABLED); 1036 } 1037 1038 DoCreateEditWindow(); 1039 } 1040 1041 VOID DIALOG_SelectFont(VOID) 1042 { 1043 CHOOSEFONT cf; 1044 LOGFONT lf = Globals.lfFont; 1045 1046 ZeroMemory( &cf, sizeof(cf) ); 1047 cf.lStructSize = sizeof(cf); 1048 cf.hwndOwner = Globals.hMainWnd; 1049 cf.lpLogFont = &lf; 1050 cf.Flags = CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT | CF_NOVERTFONTS; 1051 1052 if (ChooseFont(&cf)) 1053 { 1054 HFONT currfont = Globals.hFont; 1055 1056 Globals.hFont = CreateFontIndirect(&lf); 1057 Globals.lfFont = lf; 1058 SendMessage(Globals.hEdit, WM_SETFONT, (WPARAM)Globals.hFont, (LPARAM)TRUE); 1059 if (currfont != NULL) 1060 DeleteObject(currfont); 1061 } 1062 } 1063 1064 typedef HWND (WINAPI *FINDPROC)(LPFINDREPLACE lpfr); 1065 1066 static VOID DIALOG_SearchDialog(FINDPROC pfnProc) 1067 { 1068 if (Globals.hFindReplaceDlg != NULL) 1069 { 1070 SetFocus(Globals.hFindReplaceDlg); 1071 return; 1072 } 1073 1074 ZeroMemory(&Globals.find, sizeof(Globals.find)); 1075 Globals.find.lStructSize = sizeof(Globals.find); 1076 Globals.find.hwndOwner = Globals.hMainWnd; 1077 Globals.find.hInstance = Globals.hInstance; 1078 Globals.find.lpstrFindWhat = Globals.szFindText; 1079 Globals.find.wFindWhatLen = ARRAY_SIZE(Globals.szFindText); 1080 Globals.find.lpstrReplaceWith = Globals.szReplaceText; 1081 Globals.find.wReplaceWithLen = ARRAY_SIZE(Globals.szReplaceText); 1082 Globals.find.Flags = FR_DOWN; 1083 1084 /* We only need to create the modal FindReplace dialog which will */ 1085 /* notify us of incoming events using hMainWnd Window Messages */ 1086 1087 Globals.hFindReplaceDlg = pfnProc(&Globals.find); 1088 assert(Globals.hFindReplaceDlg != NULL); 1089 } 1090 1091 VOID DIALOG_Search(VOID) 1092 { 1093 DIALOG_SearchDialog(FindText); 1094 } 1095 1096 VOID DIALOG_SearchNext(VOID) 1097 { 1098 if (Globals.find.lpstrFindWhat != NULL) 1099 NOTEPAD_FindNext(&Globals.find, FALSE, TRUE); 1100 else 1101 DIALOG_Search(); 1102 } 1103 1104 VOID DIALOG_Replace(VOID) 1105 { 1106 DIALOG_SearchDialog(ReplaceText); 1107 } 1108 1109 static INT_PTR 1110 CALLBACK 1111 DIALOG_GoTo_DialogProc(HWND hwndDialog, UINT uMsg, WPARAM wParam, LPARAM lParam) 1112 { 1113 BOOL bResult = FALSE; 1114 HWND hTextBox; 1115 TCHAR szText[32]; 1116 1117 switch(uMsg) { 1118 case WM_INITDIALOG: 1119 hTextBox = GetDlgItem(hwndDialog, ID_LINENUMBER); 1120 _sntprintf(szText, ARRAY_SIZE(szText), _T("%Id"), lParam); 1121 SetWindowText(hTextBox, szText); 1122 break; 1123 case WM_COMMAND: 1124 if (HIWORD(wParam) == BN_CLICKED) 1125 { 1126 if (LOWORD(wParam) == IDOK) 1127 { 1128 hTextBox = GetDlgItem(hwndDialog, ID_LINENUMBER); 1129 GetWindowText(hTextBox, szText, ARRAY_SIZE(szText)); 1130 EndDialog(hwndDialog, _ttoi(szText)); 1131 bResult = TRUE; 1132 } 1133 else if (LOWORD(wParam) == IDCANCEL) 1134 { 1135 EndDialog(hwndDialog, 0); 1136 bResult = TRUE; 1137 } 1138 } 1139 break; 1140 } 1141 1142 return bResult; 1143 } 1144 1145 VOID DIALOG_GoTo(VOID) 1146 { 1147 INT_PTR nLine; 1148 LPTSTR pszText; 1149 int nLength, i; 1150 DWORD dwStart, dwEnd; 1151 1152 nLength = GetWindowTextLength(Globals.hEdit); 1153 pszText = (LPTSTR) HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(*pszText)); 1154 if (!pszText) 1155 return; 1156 1157 /* Retrieve current text */ 1158 GetWindowText(Globals.hEdit, pszText, nLength + 1); 1159 SendMessage(Globals.hEdit, EM_GETSEL, (WPARAM) &dwStart, (LPARAM) &dwEnd); 1160 1161 nLine = 1; 1162 for (i = 0; (i < (int) dwStart) && pszText[i]; i++) 1163 { 1164 if (pszText[i] == '\n') 1165 nLine++; 1166 } 1167 1168 nLine = DialogBoxParam(Globals.hInstance, 1169 MAKEINTRESOURCE(DIALOG_GOTO), 1170 Globals.hMainWnd, 1171 DIALOG_GoTo_DialogProc, 1172 nLine); 1173 1174 if (nLine >= 1) 1175 { 1176 for (i = 0; pszText[i] && (nLine > 1) && (i < nLength - 1); i++) 1177 { 1178 if (pszText[i] == '\n') 1179 nLine--; 1180 } 1181 SendMessage(Globals.hEdit, EM_SETSEL, i, i); 1182 SendMessage(Globals.hEdit, EM_SCROLLCARET, 0, 0); 1183 } 1184 HeapFree(GetProcessHeap(), 0, pszText); 1185 } 1186 1187 VOID DIALOG_StatusBarUpdateCaretPos(VOID) 1188 { 1189 int line, col; 1190 TCHAR buff[MAX_PATH]; 1191 DWORD dwStart, dwSize; 1192 1193 SendMessage(Globals.hEdit, EM_GETSEL, (WPARAM)&dwStart, (LPARAM)&dwSize); 1194 line = SendMessage(Globals.hEdit, EM_LINEFROMCHAR, (WPARAM)dwStart, 0); 1195 col = dwStart - SendMessage(Globals.hEdit, EM_LINEINDEX, (WPARAM)line, 0); 1196 1197 _stprintf(buff, Globals.szStatusBarLineCol, line + 1, col + 1); 1198 SendMessage(Globals.hStatusBar, SB_SETTEXT, SB_SIMPLEID, (LPARAM)buff); 1199 } 1200 1201 VOID DIALOG_ViewStatusBar(VOID) 1202 { 1203 Globals.bShowStatusBar = !Globals.bShowStatusBar; 1204 1205 DoCreateStatusBar(); 1206 } 1207 1208 VOID DIALOG_HelpContents(VOID) 1209 { 1210 WinHelp(Globals.hMainWnd, helpfile, HELP_INDEX, 0); 1211 } 1212 1213 VOID DIALOG_HelpAboutNotepad(VOID) 1214 { 1215 TCHAR szNotepad[MAX_STRING_LEN]; 1216 TCHAR szNotepadAuthors[MAX_STRING_LEN]; 1217 1218 HICON notepadIcon = LoadIcon(Globals.hInstance, MAKEINTRESOURCE(IDI_NPICON)); 1219 1220 LoadString(Globals.hInstance, STRING_NOTEPAD, szNotepad, ARRAY_SIZE(szNotepad)); 1221 LoadString(Globals.hInstance, STRING_NOTEPAD_AUTHORS, szNotepadAuthors, ARRAY_SIZE(szNotepadAuthors)); 1222 1223 ShellAbout(Globals.hMainWnd, szNotepad, szNotepadAuthors, notepadIcon); 1224 DeleteObject(notepadIcon); 1225 } 1226 1227 /*********************************************************************** 1228 * 1229 * DIALOG_FilePageSetup 1230 */ 1231 VOID DIALOG_FilePageSetup(void) 1232 { 1233 PAGESETUPDLG page; 1234 1235 ZeroMemory(&page, sizeof(page)); 1236 page.lStructSize = sizeof(page); 1237 page.hwndOwner = Globals.hMainWnd; 1238 page.Flags = PSD_ENABLEPAGESETUPTEMPLATE | PSD_ENABLEPAGESETUPHOOK | PSD_MARGINS; 1239 page.hInstance = Globals.hInstance; 1240 page.rtMargin = Globals.lMargins; 1241 page.hDevMode = Globals.hDevMode; 1242 page.hDevNames = Globals.hDevNames; 1243 page.lpPageSetupTemplateName = MAKEINTRESOURCE(DIALOG_PAGESETUP); 1244 page.lpfnPageSetupHook = DIALOG_PAGESETUP_Hook; 1245 1246 PageSetupDlg(&page); 1247 1248 Globals.hDevMode = page.hDevMode; 1249 Globals.hDevNames = page.hDevNames; 1250 Globals.lMargins = page.rtMargin; 1251 } 1252 1253 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 1254 * 1255 * DIALOG_PAGESETUP_Hook 1256 */ 1257 1258 static UINT_PTR CALLBACK DIALOG_PAGESETUP_Hook(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) 1259 { 1260 switch (msg) 1261 { 1262 case WM_COMMAND: 1263 if (HIWORD(wParam) == BN_CLICKED) 1264 { 1265 switch (LOWORD(wParam)) 1266 { 1267 case IDOK: 1268 /* save user input and close dialog */ 1269 GetDlgItemText(hDlg, 0x141, Globals.szHeader, ARRAY_SIZE(Globals.szHeader)); 1270 GetDlgItemText(hDlg, 0x143, Globals.szFooter, ARRAY_SIZE(Globals.szFooter)); 1271 return FALSE; 1272 1273 case IDCANCEL: 1274 /* discard user input and close dialog */ 1275 return FALSE; 1276 1277 case IDHELP: 1278 { 1279 /* FIXME: Bring this to work */ 1280 static const TCHAR sorry[] = _T("Sorry, no help available"); 1281 static const TCHAR help[] = _T("Help"); 1282 MessageBox(Globals.hMainWnd, sorry, help, MB_ICONEXCLAMATION); 1283 return TRUE; 1284 } 1285 1286 default: 1287 break; 1288 } 1289 } 1290 break; 1291 1292 case WM_INITDIALOG: 1293 /* fetch last user input prior to display dialog */ 1294 SetDlgItemText(hDlg, 0x141, Globals.szHeader); 1295 SetDlgItemText(hDlg, 0x143, Globals.szFooter); 1296 break; 1297 } 1298 1299 return FALSE; 1300 } 1301